# LHCb F.A.Q.

Did you not find the answer you were looking for? If not please submit your question here.

Current user-submitted FAQ's can be found here

## Where do I find documentation on Python Job Options?

• Tutorials:
• Presentations:
• Examples shown by Pere Mato on 19th September 2007
• Papers:
• The proposal at the Barcelona LHCb week (2005-09-15)

## How to retrieve event data from the Transient Event store?

See get and getIfExists methods in http://proj-gaudi.web.cern.ch/proj-gaudi/releases/latest/doxygen/class_gaudi_common.html. These methods are available in all Algorithms and Tools. In Services you have to use directly some of the Gaudi internal methods:
100// Locate the Event Data Service
101SmartIF<IDataProviderSvc> evtSvc(serviceLocator()->service<IDataProviderSvc>("EventSvc"));
102// Get the data from the service
103SmartDataPtr<MyDataObj> myObj( evtSvc, "path/to/object");
104if( 0 != myObj ) {
105    //use it
106}
107else {
108  // does not exist, or not of type MyDataObj
109}

## How to locate Tools and Services?

See GaudiAlgorithm reference.

The methods in the reference above are not available inside Services. In this case (and in this case only), use the following:

100SmartIF<IToolSvc> toolSvc(serviceLocator()->service<IToolSvc>("ToolSvc"));
101IMyTool *myTool = 0;
102toolSvc->retrieveTool("MyToolType/Name", myTool); // public
103toolSvc->retrieveTool("MyToolType/Name", myTool, this); // private
104myTool->doSomething();
105toolSvc->releaseTool(myTool);
106myTool = 0;

## Printing from Gaudi

### How to print using the predefined message streams?

See GaudiAlgorithm reference

### How do I set the printout format?

To change the number of characters used to print out the algorithm name, do
MessageSvc().Format = "% F%60W%S%7W%R%T %0W%M"
This will print on 60 characters:
DaVinciInit                                                 SUCCESS ==================================================================
DaVinciInit                                                 SUCCESS Requested to process 100 events
DaVinciInit                                                 SUCCESS ==================================================================
The full description of the format is to be found in the Message class doxygen.

### How do I change the OutputLevel for an arbitrary MsgStream?

The following example sets to Warning the OutputLevel of the 'Rich2/Rich2Gas' MsgStream
from Configurables import MessageSvc
MessageSvc().setWarning = [ 'Rich2/Rich2Gas' ]

## How to use easy and friendly histogramming in Gaudi?

Gaudi framework provides access to the histogramming facilities through their AIDA abstract interfaces. This powerful and flexible way of making the histogramming has one important disadvantage. The locality of the histogramming facilities is lost. For the typical Gaudi algorithm, one needs: 1 declare the local variables for pointers to AIDA histograms in the body of the algorithm (which is usually resides inside separate file), 1 explicitly book the histograms with the help of IHistogramSvc, ans store the pointer to the booked histogram in some data member field of the algorithm. Usually this operation is performed inside the initialize method of the {\it{algorithm}}. 1 the actual histogram filling is usually performed inside execute method of the algorithm.

Usually the modification of different files and different code fragments is necessary to deal with histograms. Thus standard Gaudi histogramming facilities become non-local.

### The regular 1D-histograms

The base classes GaudiHistoAlg and GaudiHistoTool provide the easy methods for simultaneous boolking and filling the histograms:

1000AIDA::IHistogram1D*  plot
1010  ( const double        value        , // the value to be added to the histogram
1020    const std::string&  title        , // the histogram title
1030    const double        low          , // the low edge of the histogram
1040    const double        high         , // the high edge of the histogram
1050    const unsigned long bins   = 100 , // the number of bins
1060    const double        weight = 1.0 ) const ; // the weight
1070
1080  AIDA::IHistogram1D*  plot
1090  ( const double        value        , // the value to be added to the histogram
1100    const HistoID&      ID           ,  // the histogram identified (string or number) with the optional subdirectory
1110    const std::string&  title        , // the histogram title
1120    const double        low          , // the low edge
1130    const double        high         , // the high edge
1140    const unsigned long bins   = 100 , // the number of bins
1150    const double        weight = 1.0 ) const ; // the weight
1160

For usage of these method one does not need to book the histogram. Booking is performed on demand. The unique integer histogram identifier for the first method is generated automatically. For the the second method the assignment of the histigram identified is under the full user control:

1000const double value = ... ;
1010
1020// use the automatically assigned ID:
1030plot (  value , "It is the title for the first histo" , 0 , 100 ) ;
1040
1050// use string ID:
1060plot ( value , "MyHisto" ,  "It is a title for the second histo" , 0 , 100 , 10 ) ;
1070
1080// use integer ID
1090plot ( value , 100         ,  "It is the title for the third histogram" , 0 , 50 , 50 ) ;
1100
1110// using the subdirectory:
1120plot ( value , "subdir/MyHisto1" , "It is the title for the fourth histo" , -100 , 100 , 200 ) ;

As it was emphasized histogram will be booked automatically on-demand. But in addition one can use book method explicitely to book the histograms:

1000// book the histo with automatically generated ID (coulbe be extracted later using the method histo
1010book ( "Transverse momentum in GeV/c" , 0 , 10 ) ;
1020
1030// book the histo with assigned integer ID:
1040AIDA::IHistogram* h15 = book ( 15 , "Momentum of the B-candidate" , -1 , 1 ) ;
Both book and plot methods return the pointer to AIDA::IHistogram1D class which can be used for explicit manipulations with histograms.

The booked histogram, previosuly booked with book or plot method could be retrieved using the method histo:

1000// get the histogram by the unique title:
1010AIDA::IHistogram1D* h1 = histo( "The histiogram unique title" ) ;
1020
1030// get the historgam by its unique numerical ID:
1040AIDA::IHistogram1D* h2 = histo( 15 )
1050
1060// get the histoigram by its unique literal ID:
1070AIDA::IHistogram1D* h3 = histo ( HistoID( "iThe historam Unique ID" ) ) ;
If no histogram with given title/ID has been booked the method histo returns zero pointer.

The existence of the histogram with the given identifier or the title could be checked using the methods exists:

1000// check the existence of the histogram by title:
1010const bool ok1 = histoExists ( "Some histogram title" ) ;
1020
1030// check the existence of the histogram by numerical ID:
1040const bool ok2 = histoExists ( 15 ) ;
1050
1060// check the existence of the histogram by literal ID:
1070const bool ok3 = histoExists ( HistoID("Soem uinque histogram ID" ) ) ;

### 2D,3D-histograms and the profile histograms

In a similar way there exist methods for manipulation with 2D, 3D histograms and profile-histograms with the similar semantics:

1000const double mass1 = ... ;
1010const double mass2 = ... ;
1020
1030// fill 2D-histogram    (book-on-demand)
1040plot2D ( mass1, mass2, "Invariant Mass2 versus Mass1" ,2.5 ,3.5, 4.5, 5.5, 100, 200 );
1050
1060// fill 1D-profile histogram (book-on-demand)
1070profile1D ( mass1, mass2, "Invariant Mass2 versus Mass1" ,2.5 ,3.5, 100 );
1080
1090const double X = ... ;
1100const double Y = ... ;
1110const double Z = ... ;
1120
1130// fill 3D histogram (book-on-demand)
1140plot3D ( X, Y, Z, "Space Points" ,2.5 ,3.5, 4.5, 5.5, 6.5, 7.5, 10, 20, 30 ) ;
1150
1160// fill 2D profile histogram (book-on-demand)
1170profile2D ( X, Y, Z, "Space Points" ,2.5 ,3.5, 4.5, 5.5, 10, 20 );
1180
1190// retrieve the booked 2D-histogram (if any)
1200AIDA::IHistohram2D* h1 = histo2D ( "Some Title" ) ;
All methods has their partners with the assigned unique histogram identifiers. For completeness it is worth to mention that all previously considered methods for the regular 1D-histograms are shortcuts for the full methods plot1D, book1D, histo1D, etc..

### Histograms and loops

Since the method plot does have some overhead, it is not recommended to use it directly inside the primitive loops. Here one can be more CPU-efficient using the direct manipulations with underlying pointer to the histogram

1000AIDA::IHistogram1D* h = histo ( "Transverse Momentum in GeV" ) ;
1010for ( int i = 0 ; i < nParticles  ; ++i )
1020   {
1030     const double p = .... ;
1040     histo->fill ( p , 1.0 ) ;   ///< fill the histogram ;
1050   }

However the base classes GaudiAlgorithm and GaudiTool provides functionality to make the efficient implicit STL-like loops:

1000// some container with data:
1010std::vector<double> data = ... ;
1020
1030// fill the histogram using implict loop (book-on-demand)
1040plot1D  ( sin  , // the function to be applied for all elements
1050         data.begin() , // the begin of the sequence
1060         data.end()   , // the end of the sequence
1070         "The sin of the all number from container" , // the title
1080          -1 ,  1      ) ; // the low and the high edges
1090
The method is templated and any sequence and function or function object could be used, e.g. one can easily reuse all LoKi functors:
1000const std::vector<const LHCb::Particle*>& particles = ... ;
1010
1020// fill the histogram through implicit loop (book-on-demand)
1030plot ( PT/GeV  ,  // the functor
1040       particles.begin() , // the begin of the sequence
1050       particles.end() , // the end of the sequence
1060       "The transverse momentum in GeV" , 0 , 10 ) ; // the title and the edges
1070

Many STL-adapters could be used as the appropriate functors:

1000const std::vector<const LHCb::Particle*>& particles = ... ;
1010
1020// fill the histogram through implicit loop (book-on-demand)
1030plot ( std::mem_fun(&LHCb::Particle::p) , // the functor
1040       particles.begin() , particles.end() , // the begin and the end of the sequence
1050       "The momentum" , 0 , 10 ) ; // the title and the edges
1060
Please note that these template methods not only very efficient but also are very compact.

## How can I use GaudiHistoAlg and GaudiHistoTool base classes?

The simplest way to use these nice features for easy and friendly histograms is through inheritance from base classes GaudiHistoAlg or GaudiHistoTool.

The base classes GaudiHistoAlg and GaudiHistoTool are very easy to use and they implement the functionality described above through template class GaudiHistos.

### Policy

To get the access to the desired functionality one needs to inherit the code from these base classes:
1000#include "GaudiAlg/GaudiHistoAlg.h"
1010
1020class MyAlg : public GaudiHistoAlg
1030{
1040   ....
1050};
For the implementation of the basic method one needs to follow the policy for the contructor, initialization and finalization methods:
1000// constructor:
1010MyAlg::MyAlg ( const std::string& name , ISvcLocator* pSvc )
1020  : GaudiHistoAlg ( name , pSvc )   ///< Invoke the constructor for the base class
1030  { ...}
1040
1050// initialization of the algorithm:
1060StatusCode MyAlg::initialize ()
1070{
1080   // Initialize the base class:
1090   StatusCode sc = GaudiHistoAlg::initilalize () ; ///< initialize the base class
1100   if ( sc.isFailure() ) { return sc ; }
1110
1120   .. perform the specific initialization here ...
1130
1140   return StatusCode::SUCCESS ;                        ///< RETURN
1150}
1160
1170// finalization of the algorithm:
1180StatusCode MyAlg::finalize ()
1190{
1200   ... perform the specific finalization here ...
1210
1220    // and at the end finalize the base class:
1230    return GaudiHistoAlg::finalize () ;
1240}

### Major properties of GaudiHistoAlg and GaudiHistoTool base classes

The major properties of the base classes GaudiHistoAlg and GaudiHistoTool relevant for the histograms are:

Property Type Default Value Description
HistoProduce bool true Switches off all histogramming actions
HistoPrint bool true Switch on/off the printout of summary information about booked histograms
HistoCheckFroNaN bool true Switch on/off the checking of the values for "Not-a-Number" and "Infinity"
HistoSplitDir bool false Switch on/off the splitting of long directory names into short name (suitable for HBOOK persistency)
HistoOffSet int 0 Start value for automatically assigned histogram identifiers
HistoTopDir string "" Optional top-level subdirectory for more granular location of histograms, e.g. "Velo/"  (note the trailing ="/")
HistoDir string name Subdirectory in the output file where all histograms are put
MonitorHistorams bool true Switch on/of the automatic registration of all booked histogram for Monitoring Service

For the general properties, inherited from the base classes GaudiAlgorithm and GaudiTool see here.

### Histogram summary

If the property HistoPrint is activated, some short summary on booked histograms is printed at the end of the job:

SimpleHistos      SUCCESS Booked 18 Histogram(s) : 1D=9 2D=4 3D=2 1DProf=1 2DProf=2
SimpleHistos      SUCCESS List of booked 1D histograms in directory         "SimpleHistos" :-
SimpleHistos      SUCCESS  ID=1                "Gaussian mean=0, sigma=1"             Ents/All=50000/50000<X>/sX=-0.010746/0.99822
SimpleHistos      SUCCESS  ID=6                "AutoID time test"                     Ents/All=50000/50000<X>/sX=-0.010746/0.99822
SimpleHistos      SUCCESS  ID=101              "Exponential"                          Ents/All=49643/50000<X>/sX=0.97244/0.91365
SimpleHistos      SUCCESS  ID=102              "Breit"                                Ents/All=46916/50000<X>/sX=-0.0047661/1.1982
SimpleHistos      SUCCESS  ID=1111             "Forced Numeric ID time test"          Ents/All=50000/50000<X>/sX=-0.010746/0.99822
SimpleHistos      SUCCESS  ID=poisson          "Poisson"                              Ents/All=47490/50000<X>/sX=1.8072/1.1794
SimpleHistos      SUCCESS  ID=subdir1/bino     "Binominal"                            Ents/All=48626/50000<X>/sX=1.9077/1.1167
SimpleHistos      SUCCESS  ID=subdir2/bino     "Binominal"                            Ents/All=48626/50000<X>/sX=1.9077/1.1167
SimpleHistos      SUCCESS  ID=test1            "Forced Alpha ID time test"            Ents/All=50000/50000<X>/sX=-0.010746/0.99822

### IHistoTool interface

There exist cases where the usage of the inheritance sceme is not possible, e.g.

• if one want to equip with histogram Gaudi component, different from algorithm or tool, e.g.
• Service
• Converter
• Auditor
• if one needs to equip temporary the component with histogramming abilities ony for debugging purposes and the change of the class structure is not possible, e.g. the algorithm is inherited from some other base class algorithm.

for these cases one can use "external" tool, which implement IHistoTool interface:

1000#include "GaudiAlg/IHistoTool.h"
1010...
1020{
1030  IHistoTool* t = tool<IHistoTool>( "HistoTool" , ... ) ;
1040
1050  // use IHistoTool::plot method:
1060  const double value = .... ;
1070  plot  ( value , "It is a histogram title" , -1 , 1 , 100 ) ;
1080  ...
1090}
Other methods, like plot, book, histo, histoExists are also implemented.

### Where can I find more examples on usage of GaudiHistoAlg and GaudiHistoTool base classes?

The package GaudiExamples contains few examples for the histograms, see here

## Can I use easy and friendly histogramming in (Gaudi)Python?

The package GaudiPython offers such functionality. One needs to inherit Python algorithm from the Python base class GaudiAlgs.HistoAlgo:

1000from   GaudiAlgs   import HistoAlgo
1010
1020class HistoEx(HistoAlgo) :
1030    """ The simple algorithm which book&fill the histograms """
1040    def execute( self ) :
1050        """ The major method 'execute', it is invoked for each event """
1060        # fill the histogram (book-on-demand)
1070        for i in range(0,10) : self.plot1D ( i , ' 1D histo ' , 0 , 20 , 20 )
1080        return SUCCESS

## How to use the Statistical Counters ?

There are three ways for usage of the statistical counters in Gaudi framework:

1. Local counters through GaudiAlgorithm and GaudiTool base classes
2. Counter form Statistical Service IStatSvc
3. Counters from Counter Service ICounterSvc

All three approaches deal with the same objects = the generic counters of the C+ type StatEntity and have the different application range. The first approach is suitable for local counters, used withing the same algorithm or tool. The counters are naturally grouped by components. The second approach allows global counters, e.g. one can modify the same counter from different components. The third approach is essentially the same as the second approach, but in addition it allows some flexible grouping of the counters. It is worth to note that the second and the third approaches unavoidably have some CPU overhead with respect to the first approach.

### The generic counters in GaudiAlgorithm and GaudiTool base classes

See GaudiAlgorithm reference

### How can I use IStatSvc for counters?

For the global counters, the approach with the usage of IStatSvc is more preferrable, however here since the generic counter is owned by the service, the special wrapper class Stat is suitable to preserve the object/instance semantic instead the pointer semantic:

1000IStatSvc* statSvc = ... ;
1010
1020// get the counter form the service ("book on-demand")
1030Stat stat ( statSvc, "Total Energy" );
1040
1050// increment it:
1060stat += eTotal ;
1070
1080// check the underlying generic counter (optional)
1090const StatEntity* counter = stat->counter() ;
1100
1110// increment the counter in the service (in one go)  ("book-on-demand")
1120Stat nTr ( statSvc , "#Tracks" , nTracks ) ;
The table of ll counters will be printed at the end of the job, if the property "StatPrintOutTable" activated:
******Stat******     INFO ****************************************************************************************************
******Stat******     INFO  The Final stat Table (ordered)
******Stat******     INFO ****************************************************************************************************
******Stat******     INFO      Counter     |     #     |    sum     | mean/eff^* | rms/err^*  |     min     |     max     |
******Stat******     INFO  "counter1"      |     20000 |   2000.452 |    0.10002 |2.2600e-005 |     0.10000 |     0.10005 |
******Stat******     INFO *"eff"           |     20000 |      10000 |( 50.00000 +- 0.3535534)%|   -------   |   -------   |
******Stat******     INFO  "counter3"      |     20000 |      13000 |    0.65000 |    0.35000 |     0.30000 |      1.0000 |
******Stat******     INFO  "counter2"      | 100020000 |    9993260 |   0.099913 |   0.010999 |     -1.0000 |     0.10005 |
******Stat******     INFO ****************************************************************************************************

The format of the table is under the control of properties.

### How can I use ICounterSvc for counters?

The usage of counters with ICounterSvc is very similar to the previous case, but in addition it allows to define the group:

1000ICounterSvc* svc = ... ;
1010
1020// get the counter from the service using "group" and "name"
1030Stat stat ( svc , "VELO" , "#Hits" ) ;
1040
1050// increment the counter:
1060stat += nHits ;
The printout of counters is performed at the end of the job:

CounterSvc        SUCCESS Number of counters : 4
CounterSvc        SUCCESS        Counter :: Group         |     #     |    sum     | mean/eff^* | rms/err^*  |     min     |     max     |
CounterSvc        SUCCESS *         "Eff1::CounterTest"   |     10000 |       5000 |( 50.00000 +- 0.5000000)%|   -------   |   -------   |
CounterSvc        SUCCESS *         "Eff2::CounterTest"   |     10000 |       3333 |( 33.33000 +- 0.4713927)%|   -------   |   -------   |
CounterSvc        SUCCESS            "Sum::CounterTest"   |     10000 |5.0005e+007 |     5000.5 |     2886.8 |      1.0000 |      10000. |
CounterSvc        SUCCESS     "TotalCount::CounterTest"   |     10000 |      10000 |     1.0000 |    0.00000 |      1.0000 |      1.0000 |

The format of the table is under the control of properties.

### How can I use my counters for monitoring?

The work here is in progress, please contact Eric van Herwijnen for the details. The overall idea is to let Monitoring Service know about the generic counter StatEntity and to allow the automatic registration of all booked counters for Monitoring Service. Some work has been done by Ulrich Kerzel and Chris Jones. Recently a bit more generic approach has been proposed by Claus Buszello.

### Where can I find code examples for the generic counters?

The package GaudiExaples provides three C++ examples:
1. The files $GAUDIEXAMPLESROOT/src/CounterAlg.cpp and$GAUDIEXAMPLESROOT/options/CounterEx.opts illustrate the usage of the local generic statistical counters

## How can I inspect/retrieve/modify the properties for the given Gaudi component?

It is easy to check if the given component has a property with the given name using the method Gaudi::Utils::hasProperty:

1000IMyComponent* component = ...;
1010
1020// check the presence of property
1030const bool OK = Gaudi::Utils::hasProperty ( component ,  "SomeProperty" ) ;
Also one can extract the given property by name:
1000IMyComponent* component = ... ;
1010
1020// get the property by name (return NULL pointer for non-existing properties)
1030Property* property = Gaudi::Utils::getProperty ( component , "SomeProperty" ) ;

The modification of the existing properties is also possible:

1000IMyComponent* component = ... ;
1010
1020// change the output level:
1030StatusCode sc = Gaudi::Utils::setProperty( component , "OutputLevel" , 2 ) ;

## How can I inspect/retrieve/modify the properties for the given Gaudi component in (Gaudi)Python ?

In (Gaudi)Python one can inspect the properties interactively:
1000# get the component by name
1010component = gaudi.algorithm('AlgName')
1020
1030# get the dictionary of all properties:
1040props = component.properties()
1050
1060# loop over all properties and print them:
1070for p in properties :
1080    value = properties[p].value()
1090    print "Property  Name/Value:   '%s'/%s " % ( p, value )
1100
1110# modify the property:
1120component.OutputLevel = 2

## What C++ types could be used as component's properties in Gaudi ?

Currently Gaudi supports following basic scalar types for properties
1. bool
2. char, unsigned char, signed char
3. short, unsigned short
4. int, unsigned int
5. long, unsigned long
6. long long, unsigned long long
7. float, double, long double
8. std::string
For each basic scalar type, the corresponding std::vector<TYPE> is also supported. Other types:
1. std::pair<double,double>
2. std::vector<std::pair>double,double> >
3. std::pair<int,int>
4. std::vector<std::vector<std::string> >
5. std::vector<std::vector<double> >
Associative properties:
1. std::map<int,double>
2. std::map<std::string,std::string>
3. std::map<std::string,int>
4. std::map<std::string,double>
5. std::map<std::string,std::vector<std::string> >
6. std::map<std::string,std::vector<int> >
7. std::map<std::string,std::vector<double> >

Essentially each type, with the implemented functions

• StatusCode Gaudi::Parsers::parse(  TYPE& result, const std::string& input )
• std::ostream& Gaudi::Utils::toStream( const TYPE& object , std::ostream& stream)
could be used as the base for properties. For all types, listed above, the corresponding parse functions have been implemented by Sascha Mazurov using Spirit & Phoenix libraries from Boost project. The great flexibility and functionality of these libraries make the extension of properties for other classes to be rather simple.

For the special case of histogram properties see here.

## How can I specify the extended properties in the options-file?

The canonical representation of each property type, listed above is defined by its representation through Gaudi::Utils::toStream function, and corresponds to the native python representation of the object using the mapping:

• std::vector is mapped to Python's list
• std::map is mapped to Python's dict
• std::pair is mapped to Python's tuple
• histogram proprty is mapped to Python's tuple with the special structure, see here.
The boolean value could be specified in three ways:
• like Python's True or False
• like C++ true or false
• as 1 or 0
The string are specified using single '...' or double "..." quotes. The curly braces {...} could be substituted by the rectangular brackets [...] and vice versa. The examples are available in GaudiExamples package in the file $GAUDIEXAMPLESROOT/options/ExtendedProperties.opts, the corresponding C++ code is$GAUDIEXAMPLESROOT/src/ExtendedProperties/ExtendedProperties.cpp

## When and why should I update the version numbers of an InterfaceID?

Each Interface in Gaudi has a unique Interface Identifier (InterfaceID) which is versioned (see section 16.3 of the Gaudi User Guide). The purpose of the version number is to check compatibility between clients of an Interface (e.g. an algorithm requesting a tool) and the component implementing the Interface (e.g. the tool) - if the two components have been compiled against different incompatible versions of the Interface, then this will result in a core dump when the Interface is accessed.

Gaudi provides a mechanism to avoid these core dumps. When you call the templated tool or svc methods to locate a tool or service, behind the scenes these methods call the queryInterface() method of the tool or service, which checks (using the InterfaceID::versionMatch() method) that the version number used in the requesting code is compatible with that used in the implementating code. Of course this only works if the implementer of the interface remembers to increment the version numbers of the interface when a change is made.

The major version number should be incremented whenever the interface is changed in a run-time incompatible way. If the change is run-time compatible, the minor version should be incremented. Note that very few changes are run-time compatible (e.g. change the constness of an argument in one of the methods, change the default value of one of the arguments, add new enum items, etc.). Even adding a method at the end of the Interface definition is not guaranteed to be run-time compatible on all platforms. If in doubt, increase the major version.

## How do I check for untested StatusCode?

ApplicationMgr.StatusCodeCheck = true;

N.B., the checking is very slow if there are lots of untested StatusCode, so you better also have something like:

ApplicationMgr.EvtMax = 5;

## How do I dump the contents of a POOL data (or ETC) file?

This can be done inside ROOT using the dumpFile macro:
root [1] .L \$GAUDIPOOLDBROOT/scripts/dumpFile.C
root [2] dumpFile("theFileName")

## How do I modify the entries of the ParticleTable.txt used by the LHCb::ParticlePropertySvc?

This can be done by using the OtherFiles and Particles properties of the LHCb::ParticlePropertySvc

## How can I use new Particle Property Service ( LHCb::ParticlePropertySvc)?

Actually the usage of new particle property service LHCb::ParticlePropertySvc= is fairly trivial and explained in detail here.

The major items:

• the abstract interface for the service has a name LHCb::IParticlePropertySvc, (doxygen)
• the major object which carry particle properties is named LHCb::ParticleProperty, (doxygen)
• GaudiPython provides set of useful "decorators" for using particle properties functionality in python, namely python class iParticlePropertySvc=, (doxygen) and various utilities, see
• all classes and utilities reside in the package Kernel/PartProp

### How to locate new service?

If one uses the base classes GaudiAlgorithm or GaudiTool, the location of the service is trivial:

1000#include "PartProp/IParticlePropertySvc.h"
1010...
1020// assuming  GaudiAlgorithm base class...
1030...
1040const LHCb::IParticlePropertySvc* ppsvc =
1050   svc<LHCb::IParticlePropertySvc>( "LHCb::ParticlePropertySvc" ) ;
1060

Please note that the base class DVAlgorithm has already the accessor to the new service:

1000// assuming DAVlgorithm base class ..
1010...
1020const LHCb::IParticlePropertySvc* ppsvc = ppSvc() ;

For usage in python it is recommended to "import" the helper module PartProp.Service:

1000import PartProp.Service

This helper module provides the class AppMgr with helper accessor to the particle property service:

1000import PartProp.Service
1010from GaudiPython.Bindings import AppMgr
1020...
1030gaudi = AppMgr()        # instantiate the Application Manager
1040...
1050ppsvc = gaudi.ppSvc()  # get the service from Gaudi
1060

### How to configure the new service?

The configuration of new service is done through the corresponding Configurables:

1000from Gaudi.Configuration import *
1010
1020from Configurables import LHCb__ParticlePropertySvc
1030
1040LHCb__ParticlePropertySvc (
1050  ParticlePropertiesFile = 'the file name' , # the name of the major file with particle properties
1060  OtherFiles = [] ,                                 # the list of additional files
1070  Particles    = [] ,                                  # the list of special additional particle properties
1080  Dump       = True    # dump the particle properties in  table format
1090  )

Please note that for real LHCb applictaion we pick up the particle properties table from database, and the corresponding lines are placed in LHCbApp :

1000from Gaudi.Configuration import *
1010
1020from Configurables import LHCbApp
1030
1040LHCbApp (
1050   ... ,
1060  DDDBtag = 'default' ,  # specify the correct DDDB tag
1070   ...
1080   )

### How to use the new service?

1000// 1) get service:
1010const LHCb::IParticlePropertySvc* ppsvc = ... ;
1020
1030// 2) look up the particle property by name:
1040const LHCb::ParticleProperty* p1 = ppsvc->find ( "B0" ) ;
1050if ( 0 == p1 ) { ... unknown particle name ... ; }
1060
1070// 3) look up the particle property using ParticleID :
1080const LHCb::ParticleID& pid = ... ;
1090const LHCb::ParticleProperty* p2 = ppsvc->find ( pid ) ;
1100if ( 0 == p2 ) { ... unknown PID here ... ; }

The same stuff in Python looks as:

1000ppsvc =    # get the service
1010
1020# find particle property by name:
1030p1 = ppsvc.find( 'B0' )
1040
1050# find particle property by PID
1060pid = LHCb.ParticleID( 511 )
1070p2  = ppsvc.find ( pid )

One also can get few particle properties which satisfy some criteria, e.g. get all leptons:

1000#include "boost/lambda/lambda.hpp"
1010#include "boost/lambda/bind.hpp"
1020...
1030using namespace boost::lambda ;
1040...
1050const LHCb::IParticlePropertySvc* svc = ... ;
1060
1070typedef LHCb::IParticlePropertySvc::ParticleProperties Vector ;
1080
1090// create the output vector:
1100Vector leptons ;
1110
1120// use the service
1130svc -> get
1140         ( bind ( &LHCb::ParticleID::isLepton ,
1150                  bind ( &LHCb::ParticleProperty::particleID , _1 ) ) ,
1160           std::back_inserter ( lepton ) ) ; // output
1170

In python it is even easier:

1000ppsvc =    # get the service
1010
1020# find all leptons
1030leptons = ppsvc.get ( lambda x : x.isLepton() )

Manipulations with particle properties and PIDs becomes very transapren if one uses the concept of "decay nodes":

1000# import all decay nodes:
1010from PartProp.Nodes import *
1020
1030ppsvc = ...   # get the service
1040
1050# find all leptons
1060leptons = ppsvc.get ( Lepton )
1070
1080# find positive leptons:
1090ellplus = ppsvc.get ( EllPlus )
1100
1110
1130tensors = ppsvc.get ( Hadron & Tensor )
1140
1150# find all baryons with spin 3/2
1160pp = ppsvc.get ( Baryon & ThreeHalfs )
1170

## How to get all known particles?

E.g. in DaVinci it can be done suing following script:

1000from Gaudi.Configuration import *
1010
1020from Configurables import DaVinci
1030
1040import PartProp.Service
1050
1060# configure DaVinci:
1070
1080DaVinci (
1090   DataType = 'MC09'
1100  )
1110
1120# get application manager:
1130
1140from GaudiKernel.Bindings import AppMgr
1150gaudi = AppMgr()
1160
1170# get the service
1180ppSvc = gaudi.ppSvc()
1190
1200print ppSvc.all()       ## print as table:
1210
1220
If one runs the script using python -i ./Script.py one gets the table of all particle properties

Alternatively, one can also

SetupProject LHCb
CondDBBrowser DDDB

and look for 'ParticleTable.txt' under the folder 'param'.

## My job re-opens the same file instead of going to the next one

This is likely because the 2 files have the same GUID (that's some hexadecimal file identifier). For every file you generate Gaudi will assign a GUID that's supposedly unique. This GUID is written in the output file and in the file catalogue. When you write out a file, Gaudi will generate a catalogue, or update the one you already have in the local directory. Look for files called *.xml. When reading the files back it will assume that 2 files with the same guid are the same file. It is thus impossible to read 2 files with the same GUID in the same job: Gaudi will just start re-reading the first one.

Now, how can 2 files have the same GUID? If you run a job that produces file.dst, gaudi will wirite the GUID in the file and add the pair (file.dst, GUID) in catalog.xml, or so. Then when you move this file away and run another job creating another file called file.dst gaudi will read back the pair from catalog.xml and not create a new GUID. The second file will get the same GUID as the previous one.

To avoid that never generate a file with gaudi using a temporary name file.dst, move it to castor (or elsewhere) or rename it and then restart gaudi generating a new file file.dst. The safest is to always set in the job the final name of the output file.

## How can I merge two files together, or copy a few events from a file?

1. You can add an InputCopyStream or MDFWriter to your existing options
2. OR you can use the new FileMerger application from within the Noether project (see FileMerger).

## How can I run only one algorithm or sequencer from within a complicated Gaudi job?

• See GaudiExcise, a wrapper around gaudirun.py to do exactly that.

## What's the difference between Python, GaudiPython, and Gaudi?

• Python: an advanced interpreter language implemented in C++.
• Gaudi: a C++ and python framework for event-wise data processing.
• gaudirun.py: a python wrapper around Gaudi's excecutable, which feeds the Gaudi executable with "options". The options may start out as python files which adjust attributes of so-called "configurables", finally these options are flattened and handed to a C++ service which uses factories to configure the required algorithms tools and services.
• GaudiPython: a pure python layer on top of Gaudi, a python module, with access to all of the options-file handling of Gaudi, but where the control of the event loop stays in the hands of python, allowing logical python-based algorithms, tools and services.

• gaudirun.py someoptions.py: interprets your options, invokes your configuration options, passes the result to the job options service and passes control to the Application Manager and gaudi state machine in C++.
• python someoptions.py: interprets your options, does nothing.
• python someoptions.py somegaudipythonoptions.py interprets your options, then depending on what you say in your gaudipython part this may invoke your options, and then may run some custom main application loop.

## What's the difference between these two jobs? Is there some intelligent way to get the differences (diff) two gaudi jobs?

• See GaudiDiff, a wrapper around gaudirun.py to do exactly that.

## Can I record all the interesting features of a gaudi job locally?

• Running within Ganga makes for a very simple, reproducable local job, including the xmlsummary.
• However sometimes you'll be deep into some development needing to run outside of Ganga, in this case See GaudiDiff, a wrapper around gaudirun.py to do exactly that.

-- MarcoCattaneo - 10-Oct-2012

-- PatrickSKoppenburg - 23-Dec-2010

-- Vanya Belyaev - 26 Feb 2009

Topic revision: r38 - 2014-04-15 - RobLambert

 Cern Search TWiki Search Google Search LHCb/FAQ All webs
Copyright &© 2008-2020 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback