Documentation:
Terminology:
Job Options Files
Transient Event Store and Converters:
Persistency:
Development:
http://lhcb-comp.web.cern.ch/lhcb-comp/Frameworks/Gaudi/Gaudi_v6/GUG/GUG.html
http://proj-gaudi.web.cern.ch/proj-gaudi/GDG/v2/Output/GDG.htm
http://lhcb-comp.web.cern.ch/lhcb-comp/Meetings/offline/pdf/add.pdf
The mailing list is:
gaudi-developers@cern.ch
To sign up send mail to:
listbox.server@cern.ch
with the single line in the message body
subscribe gaudi-developers
The mailing list archives are available
here.
Back to Top
http://lhcbcvs.cern.ch/cgi-bin/cvsweb.cgi/?cvsroot=Gaudi
You can also access their CVS repository in read-only mode:"...makes use of framework services to perform their work." Each algorithm is called once per event. Implements the IAlgorithm interface, all algorithms used within Gaudi must implement the following three methods: initialize( ), execute( ), and finalize( ).
initialize( ) is called once before event processing. It is used for setup - accessing required services, accessing input files, etc.
execute( ) is called once per event. This method performs event processing for the algorithm.
finalize( ) is called once after event processing. This method cleans up.
Service are the glue that allows all the pieces of Gaudi to communicate....nothing useful would get done without the services! Gaudi Examples: Message Service, Event Data Service, Ntuple Service.
Services
Are a special type of algorithm that may be called multiple times per event. Typically, tools would be small algorithms that have some general applicability.
A converter is a specific class that handles the actual conversion of data from its persistent storage representation into an object from a class that is somehow derived from DataObject, so that it may be stored in the Transient Data Store....or converts data from the Data Store into the appropriate representation so that it can be saved to a persistent store.
It is an ASCII file that is used to setup the parameters for a particular run. One can specify the algorithms that should be run, what services to use, number of events, input and output files, etc. All Gaudi applications require a Job Options file.
It appears that environment variables cannot be used within a job options file to define an input parameter. The only way one can use an environment variable is to specify an include file for a given job options file.
However, we have provided a mechanism to resolve environment variables, so that they can be used as input parameters. See the facilities package's Util class method extractEnvVar.
Sometimes we may want to access parameters that are already available to an existing algorithm or service. We can obtain the value for these parameters as shown in the following code:
IProperty* appPropMgr=0;
// retrieve a pointer to the ApplicationMgr, who has the parameter we want to obtain
StatusCode status = serviceLocator()->getService("ApplicationMgr", IID_IProperty,
reinterpret_cast<IInterface*&>( appPropMgr ));
if( status.isFailure() ) return;
// Declare our property type, and set it to zero
IntegerProperty evtMax("EvtMax",0);
status = appPropMgr->getProperty( &evtMax ); /// retrieve the data
In a nutshell, the Transient Event Store is a mechanism for shared memory. It is a tree that stores all data pertinent to a particular execution of the code. All algorithms, services, tools, etc, within Gaudi use the data store to both retrieve the data needed to do its particular task, and to store any output data. The data store only exists while a program is executing - data is saved for later use via the Persistency Service...but that's another story. For more detailed information, see Chapter 6 in the Gaudi User's Guide and Chapter 9 in the Architecture Design Document.
There are 2 main ways...either data is created within an algorithm, and is stored in the Transient Event Store via some call to registerObject() or some piece of code makes a request for some data. The request is performed by a call to findObject() or retrieveObject() - or through the use of a SmartPointer. When a request is made, first the Transient Event Store is checked to see if the data is already available - if so that's great and it passed to the requestor. If the data is not available...then the Persistency Service is called and an appropriate Converter is used to retrieve the data from a persistent store, probably some file somewhere. There is some magic going on in the background - usage of OpaqueAddresses so that proper converter is called....we'll ignore that for now. The converter's createObj() method is called which allocates the necessary space, and then a call to updateObj() retrieves the data and stores it in an object derived from Gaudi's DataObject class - only objects derived from a DataObject (or one of Gaudi's ObjectContainers, see section 6.4 in the Gaudi user's guide) can be stored in the Transient Event Store.
With care :)
To put it simply...storing data to be used later. The idea is that the data exists after a particular run is finished. We are currently using ROOT files to store our data.
Actually, for now we will not be using the persistency service...we will handle writing out our ROOT files directly. In the coming months, we will be evaluating our requirements for a ROOT converter service.
This requires some steps that are not written down in the Gaudi Manual. To put an object into the TDS you need to be sure that the full path exists on the TDS before storing your particular object. For example, you want to register an object at /Event/Raw/Foo, you need to be sure that /Event/Raw already exists on the TDS.
At the start of each event, the TDS is cleared. Then the /Event branch is created. So the /Event branch always exists. All other branches must be created at some point during the execution of an event. One should not assume that a particular branch exists.
The best way to ensure that a branch exists is to try to retrieve it from the TDS. You can do this using either a call to findObject or retrieveObject. findObject will only search the TDS, if the object is not found, null is returned. retrieveObject will search the TDS, if the object is not found, then the appropriate converter is called to create the object.
Here is the code to register /Event/Raw/Foo from an algorithm:
DataObject* pnode=0; //check the sub directory sc = eventSvc()->retrieveObject( "/Event/Raw", pnode ); if( sc.isFailure() ) { log << MSG::ERROR << "Could not create Raw directory" << endreq; return sc; }
sc = eventSvc()->registerObject("/Event/Raw/Foo", m_foo);
Once an object has been put on the TDS, it should not be deleted. Gaudi takes ownership of the object once it is on the TDS. Gaudi will handling deleted all allocated memory at the end of each event.
Debugging the Gaudi apps is somewhat tricky because Visual Studio disables all the break points you set within the code that is going to be linked into a DLL. Therefore you need to step into the app past the configure stage before you can re-enable your break points. Currently (02/20/2001) the best procedure for doing this is as follows.
There is also a macro available that will step past the configure line in the Application manager and pop up the breakpoint window if you start while at the "status = appMgr->run():" line.
Macro Listing:
Sub stepdll() 'DESCRIPTION: this steps into the area where the dll is loaded 'Begin Recording ExecuteCommand "DebugStepInto" ExecuteCommand "DebugStepOver" ExecuteCommand "DebugStepOver" ExecuteCommand "DebugStepOver" ExecuteCommand "DebugStepInto" ExecuteCommand "DebugStepOver" ExecuteCommand "DebugStepInto" ExecuteCommand "DebugStepOver" ExecuteCommand "DebugStepOver" ExecuteCommand "DebugStepOver" ExecuteCommand "DebugBreakpoints" 'End Recording End Sub
Text file containing the macro: DebugMacro.txt