ToolExample

From Atlas Wiki
Jump to navigation Jump to search

introduction

During the workshop only one participant managed to get this exercise working. The "ToolExample.cxx" contained bugs causing ATHENA to crash. In this section, this exercise will be explained in detail.

Getting the complete answer

A tar file with the whole AnalysisExample package containing the result of the exercise is to be found here. Compiling this package and running ATHENA should work out-of-the-box. In the section below the key lines in the package will be discussed. To get this package working copy the .tgz file into your Tutorial directory and type:

* tar xzf ToolExample.tgz ExampleAnalysis
* cd ExampleAnalysis/cmt
* source setup.csh
* gmake

Running ATHENA should show the output of EvtMax events with a dump stating that the ToolExample->useTool() method is indeed called every event.

Retrieving the ToolExample from ToolSvc

In ExampleAlg.cxx, one can see the following lines in the initialize() method:

 1  StatusCode sc = toolSvc()->retrieveTool("ToolExample", m_tool);
 2  if(sc.isFailure()) {
 3    log << MSG::ERROR << "ToolSvc could not retrieve ToolExample" << endreq;
 4  } else log << MSG::INFO << "ToolSvc retrieved ToolExample" << endreq;

The first line uses the toolSvc() method to retrieve the ToolSvc. Any algorithm can do this, since they inherit this method from the base Algorithm class. The ToolService itself calls the method retrieveTool(<tool_name>,<tool_instance>), which loads the Tool 'ToolExample' into the instance m_tool. Mind, that this instance should be declared in your headerfile!

    class IToolExample;
    class ExampleAlg : public Algorithm {
      ...
      private :
      IToolExample* m_tool;
    };

Note, that m_tool is an instance of the Interface of the Tool! The ToolService is told to retrieve the desired concrete Tool ToolExample, m_tool doesn't need to know this at forehand.

Implementing the ToolExample

The reason that ATHENA crashed was that it was unable to initialize the Tool. This had nothing to do with the way the ToolService retrieved the tool, but it was due to a bug in ToolExample.cxx.

 1  StatusCode ToolExample::initialize(){  
 2    MsgStream log(msgSvc(), name());
 3    log << MSG::INFO << "intialize() called" << endreq;
 4    return StatusCode::SUCCESS;
 5  }
 6
 7  StatusCode ToolExample::finalize(){
 8    MsgStream log(msgSvc(), name());
 9    log << MSG::INFO << "finalize() called" << endreq;
10    return StatusCode::SUCCESS;
11  }
12
13  StatusCode ToolExample::useTool() const {
14    MsgStream log(msgSvc(), name());
15    log << MSG::INFO << "Using the Tool" << endreq;
16    return StatusCode::SUCCESS;
17  }

The return-statements in lines 4, 10 and 16 were missing! The compiler did not complain, but ATHENA crashed mercilessly without giving any usefull errormessages. Note that in this example, the return value of the useTool() method is changed from bool to StatusCode and that the method is made const.

Calling the ExampleTool

In the ExampleAlg::execute() method, the instance of ToolExample is used to call the method useTool() (line 4) :

 1  StatusCode ExampleAlg::execute(){
 2    MsgStream log(messageService(), name());
 3    log << MSG::INFO << "execute() called" << endreq;
 4    StatusCode sc = m_tool->useTool();
 5    return StatusCode::SUCCESS;
 6  }  

Tool Factory

Remember? Tools (and Algorithms) are dynamically loaded within ATHENA, we should provide the appropriate factories in order to do so. The Algorithm_entries.cxx file (in /src/components) takes care of the building of the factory. One should add the following lines to the file:

    #include "AlgorithmExample/ToolExample.h"
    DECLARE_TOOL_FACTORY ( ToolExample )
    DECLARE_FACTORY_ENTRIES(AlgorithmExample) {
      DECLARE_TOOL(ToolExample)
    }