Difference: GaudiPython (26 vs. 27)

Revision 272013-06-25 - JaapPanman

Line: 1 to 1
 
META TOPICPARENT name="LHCbComputing"

Gaudi Python FAQ

Line: 19 to 19
 

FAQs


Deleted:
<
<
 

How to get access and instantiate an LHCb Event class

Changed:
<
<
The LHCb Event classes now live in the namespace "LHCb". In order to get access you have to use this namespace. GaudiPythin.Bindings.gbl represents the C++ global namespace (::) You can abbreviate the namespace with assignments:
>
>
The LHCb Event classes now live in the namespace "LHCb". In order to get access you have to use this namespace. GaudiPythin.Bindings.gbl represents the C++ global namespace (::) You can abbreviate the namespace with assignments:
 
from GaudiPython.Bindings import gbl
std  = gbl.std
Line: 66 to 66
 

How to access to DoxyGen documentation for C++ class/instances?

Changed:
<
<
Starting from LHCb v22r9 it is very easy to get an easy access to the DoxyGen documentation pages for the certain classes, types, objects and instances:
<!-- SyntaxHighlightingPlugin -->
 1800&gt;<cite>&gt;&gt; import LoKiCore.doxygenurl as doxy </cite><br /> &gt;<cite>&gt;&gt; o = ... ## arbitrary object </cite><br /> &gt;<cite>&gt;&gt; doxy.browse ( o ) ## ask DoxyGen for the objects</cite><br /> &gt;<cite>&gt;&gt; doxy.browse ( "LHCb::MCVertex") ## ask doxyGen for the class by name</cite><br /> 
 1810
<!-- end SyntaxHighlightingPlugin -->
The idea from Thomas Ruf has been used.
>
>
Starting from LHCb v22r9 it is very easy to get an easy access to the DoxyGen documentation pages for the certain classes, types, objects and instances:
<!-- SyntaxHighlightingPlugin -->
 1800>>> import LoKiCore.doxygenurl as doxy 
 1810>>> o = ...    ## arbitrary object 
 1820>>> doxy.browse ( o )     ## ask DoxyGen for the objects
 1830>>> doxy.browse ( "LHCb::MCVertex")     ## ask doxyGen for the class by name
 1840
<!-- end SyntaxHighlightingPlugin -->
The idea from Thomas Ruf has been used.
 
Deleted:
<
<
 

How to run using a job options file several iterations

This is a minimalistic example on how to run a gaudi job (DaVinci in this case) for a number of events several times. In between the runs the user can access any information or change the algorithms or their properties.

Line: 88 to 93
 


Deleted:
<
<
 

How to access Linker tables

Changed:
<
<
The LHCb linker tables can be accessed in Python via the eventassoc.py module in Event/LinkerInstances.
>
>
The LHCb linker tables can be accessed in Python via the eventassoc.py module in Event/LinkerInstances.
  First, do not forget to add in the requirements file the line
Line: 99 to 103
 use LinkerInstances v* Event
Changed:
<
<
Then the usage is standard. For the sake of example, let's assume that the variable track contains a VELO Track you are interested in, from the 'Rec/Track/Velo' container. A simple manipulation is:
>
>
Then the usage is standard. For the sake of example, let's assume that the variable track contains a VELO Track you are interested in, from the 'Rec/Track/Velo' container. A simple manipulation is:
 
>>> from eventassoc import linkedTo
Line: 159 to 164
 
  • Direct manipulation with histogram service
  • Usage of functionality offered by HistoUtils module
  • Access to "the nice" histogramming through the base-class inheritance (OO-spirit)
Changed:
<
<
Direct manipulation with the histogram service allows to book and fill hisrogram from the simple (Gaudi)Python scripts in a relatively intuitive way:
>
>
Direct manipulation with the histogram service allows to book and fill hisrogram from the simple (Gaudi)Python scripts in a relatively intuitive way:
  %SYNTAX{ syntax="python" numbered="1000" numstep="10"}%
Line: 228 to 221
 fill ( histo , tracks , lambda t : t.pt() )

# use the sequnce, applythe function, but filter out even values:

Deleted:
<
<
 fill ( histo , [1,2,3,4,5,6,7] , lambda x : x*x , lambda y : 0==y%2 )
Deleted:
<
<
# use the sequence and apply the function:
 
Added:
>
>
# use the sequence and apply the function:
 # for each track in sequence evaluate "p()" and fill the histogram with track momentum,
Deleted:
<
<
 # keepingonly track with small transverse momentum:
Deleted:
<
<
 tracks = ...
Added:
>
>
fill ( histo , tracks , lambda t : t.p() , lambda t : t.pt() < 1000 )
 
Deleted:
<
<
fill ( histo , tracks , lambda t : t.p() , lambda t : t.pt() < 1000 )
  %ENDSYNTAX%
Line: 256 to 245
 aida = HistoUtils.getAsAIDA ( path )

# get as native ROOT:

Deleted:
<
<
 root = HistoUtils.getAsROOT( path )
Changed:
<
<
%ENDSYNTAX% HistoUtils are partly inspired by Tadashi Maeno' API from ATLAS' PyKernel
>
>
%ENDSYNTAX% HistoUtils are partly inspired by Tadashi Maeno' API from ATLAS' PyKernel
 
Changed:
<
<
OO-spirit is described in detail here and it allows to reuse the whole functionality of easy-and-friendly histograms, including booking-on-demand. Also it is a recommended way for prototyping, since the resulting code is very easy to be converted into C++ lines using almost "1->1" correspondence.
>
>
OO-spirit is described in detail here and it allows to reuse the whole functionality of easy-and-friendly histograms, including booking-on-demand. Also it is a recommended way for prototyping, since the resulting code is very easy to be converted into C++ lines using almost "1->1" correspondence.
 

How to deal with Gaudi N-tuples in GaudiPython ?

Changed:
<
<
The direct manipulation (booking&filling of columns) with the native Gaudi N-tuples in Python seems to be a very difficult task. Up to now no good and easy disprove of this statement are known. Therefore one needs to find an alternative way. Three relatively easy options have been demonstrated
  1. A direct manipulation with ROOT (T)-trees&N-tuples
  2. Use of "smart-and-easy" N-tuples via TupleUtils module (starting from Gaudi version v19r5)
  3. Access to "the nice" N-tuples through the base-class inheritance (OO-spirit)
Please consult ROOT manual for the first way, here we describe only the second way. The third way (OO-spirit) is described in detail here and it allows to reuse the whole functionality of easy-and-friendly N-tuples, including booking-on-demand. It is nice, simple, safe and it represents the recommended way for prototyping, since the resulting code is very easy to be converted into C++ lines using almost "1->1" correspondence.
>
>
The direct manipulation (booking&filling of columns) with the native Gaudi N-tuples in Python seems to be a very difficult task. Up to now no good and easy disprove of this statement are known. Therefore one needs to find an alternative way. Three relatively easy options have been demonstrated
  1. A direct manipulation with ROOT (T)-trees&N-tuples
  2. Use of "smart-and-easy" N-tuples via TupleUtils module (starting from Gaudi version v19r5)
  3. Access to "the nice" N-tuples through the base-class inheritance (OO-spirit)

Please consult ROOT manual for the first way, here we describe only the second way. The third way (OO-spirit) is described in detail here and it allows to reuse the whole functionality of easy-and-friendly N-tuples, including booking-on-demand. It is nice, simple, safe and it represents the recommended way for prototyping, since the resulting code is very easy to be converted into C++ lines using almost "1->1" correspondence.

  The module GaudiPython.TupleUtils (appears in Gaudi v19r5) contains essentially one important function nTuple :
Line: 339 to 319
 

How to access Relation tables in (Gaudi)Python?

There are many Relation tables flying around in Gaudi/LHCb software. They are used in many areas:

Changed:
<
<
  1. As representationof Monte Carlo truth links for Calorimeter objects
  2. As the dynamic extension of recontruction classes, e.g. -matching of Calorimeter clusters with recontructed tracks
  3. As the main representation of Monte Carlo links for (Proto)Particles for LoKi
The relation tables provides easy, intuitive and efficient way for relation between any objects in Gaudi. The python interface looks very similar to C++ interface. E.g. the following example shows how one can use the relation table of C++ type Relation::RelationWeighted for selection of Monte Carlo "merged" neutral pions.
>
>
  1. As representationof Monte Carlo truth links for Calorimeter objects
  2. As the dynamic extension of recontruction classes, e.g. -matching of Calorimeter clusters with recontructed tracks
  3. As the main representation of Monte Carlo links for (Proto)Particles for LoKi

The relation tables provides easy, intuitive and efficient way for relation between any objects in Gaudi. The python interface looks very similar to C++ interface. E.g. the following example shows how one can use the relation table of C++ type Relation::RelationWeighted<LHCb::CaloCluster,LHCb::MCParticle,float> for selection of Monte Carlo "merged" neutral pions.

  %SYNTAX{ syntax="python" numbered="1000" numstep="10"}%
Deleted:
<
<
 #!/usr/bin/env python2.4
Changed:
<
<
# ========================================================================= ## import everything from bender
>
>
# ========================================================================= ## import everything from bender
 from MainMC import *
Changed:
<
<
# ========================================================================= ## Simple examples of manipulations with relation tables
>
>
# ========================================================================= ## Simple examples of manipulations with relation tables
 # @author Vanya BELYAEV ibelyaev@physicsNOSPAMPLEASE.syr.edu
Deleted:
<
<
 # @date 2007-09-26
Deleted:
<
<
 class MergedPi0(AlgoMC) :
Deleted:
<
<
 """ simple class to plot dikaon mass peak """

## standard constructor

Line: 371 to 346
 return AlgoMC.__init__ ( self , name )

## standard mehtod for analyses

Deleted:
<
<
 def analyse( self ) :
Deleted:
<
<
 """ Standard method for Analysis """
Changed:
<
<
finder = self.mcFinder(" pi0->2gamma MC-finder")
>
>
finder = self.mcFinder(" pi0->2gamma MC-finder")
 
Changed:
<
<
mcpi0 = finder.find ( "pi0 -> gamma gamma" ) ;
>
>
mcpi0 = finder.find ( "pi0 -> gamma gamma" ) ;
  if mcpi0.empty() : return self.Warning("No MC-pi0 is found (1)", SUCCESS )
Line: 383 to 356
 if mcpi0.empty() : return self.Warning("No MC-pi0 is found (1)", SUCCESS )

#get only pi0s, which satisfy the criteria:

Deleted:
<
<
 #1) large Pt
Changed:
<
<
mc1 = MCPT > 500 # * MeV
>
>
mc1 = MCPT > 500 # * MeV
 # 2) valid origin vertex
Deleted:
<
<
 mc2 = MCOVALID
Changed:
<
<
# 3) vertex near the primary vertex

mc3 = abs ( MCVFASPF( MCVZ ) ) < 500 # * Gaudi.Units.mm

>
>
# 2) vertex near the primary vertex mc3 = abs ( MCVFASPF( MCVZ ) ) < 500 # * Gaudi.Units.mm
  mccut = mc1 & mc2 & mc3
Line: 413 to 377
 itable = iTable( table , 1 )

# consruct "Ecal-acceptance" cuts

Changed:
<
<
outer = ( abs(MCPY/MCPZ) < 3.00/12.5 ) & ( abs(MCPX/MCPZ) < 4.00/12.5 )

inner = ( abs(MCPY/MCPZ) > 0.32/12.5 ) | ( abs(MCPX/MCPZ) > 0.32/12.5 )

>
>
outer = ( abs(MCPY/MCPZ) < 3.00/12.5 ) & ( abs(MCPX/MCPZ) < 4.00/12.5 ) inner = ( abs(MCPY/MCPZ) > 0.32/12.5 ) | ( abs(MCPX/MCPZ) > 0.32/12.5 )
 accept = outer &inner

# loop over mcpi0:

Line: 441 to 395
 if not accept ( gamma2 ) : continue

pt = MCPT ( pi0 ) / 1000

Deleted:
<
<
 mnpt = min( MCPT ( gamma1 ) , MCPT ( gamma2 ) ) / 1000
Changed:
<
<
self.plot ( pt , "ALL pi0->gamma gamma " , 0 , 5 )

self.plot ( mnpt , "ALL pi0->gamma gamma : min pt of photon " , 0 , 5 )

>
>
self.plot ( pt , "ALL pi0->gamma gamma " , 0 , 5 ) self.plot ( mnpt , "ALL pi0->gamma gamma : min pt of photon " , 0 , 5 )
  clus1 = itable.relations ( gamma1 )
Deleted:
<
<
 clus2 = itable.relations ( gamma1 )

# each photon have some associated cluster(s) in ECAL

Line: 453 to 404
 clus2 = itable.relations ( gamma1 )

# each photon have some associated cluster(s) in ECAL

Deleted:
<
<
 if clus1.empty() or clus2.empty() : continue
Changed:
<
<
self.plot ( pt , "ECAL pi0->gamma gamma " , 0 , 5 )

self.plot ( mnpt , "ECAL pi0->gamma gamma : min pt of photon " , 0 , 5 )

>
>
self.plot ( pt , "ECAL pi0->gamma gamma " , 0 , 5 ) self.plot ( mnpt , "ECAL pi0->gamma gamma : min pt of photon " , 0 , 5 )
  # select only 1 or 2-cluster pi0s
Deleted:
<
<
 clus0 = itable.relations ( pi0 )
Deleted:
<
<
 if 1 = clus0.size() and 2 = clus0.size() : continue
Changed:
<
<
self.plot ( pt , " 1||2 pi0->gamma gamma " , 0 , 5 )

self.plot ( mnpt , " 1||2 pi0->gamma gamma : min pt of photon " , 0 , 5 )

>
>
self.plot ( pt , " 1||2 pi0->gamma gamma " , 0 , 5 ) self.plot ( mnpt , " 1||2 pi0->gamma gamma : min pt of photon " , 0 , 5 )
  # select only true "2-cluster" pi0
Changed:
<
<
if 2 = clus0.size() and 1 clus1.size() and 1 = clus2.size() and clus1.front().to() = clus2.front().to() :

self.plot ( pt , " 2 pi0->gamma gamma " , 0 , 5 )

self.plot ( mnpt , " 2 pi0->gamma gamma : min pt of photon " , 0 , 5 )

>
>
if 2 = clus0.size() and 1 = clus1.size() and 1 = clus2.size() and clus1.front().to() clus2.front().to() : self.plot ( pt , " 2 pi0->gamma gamma " , 0 , 5 ) self.plot ( mnpt , " 2 pi0->gamma gamma : min pt of photon " , 0 , 5 )
  # select only true "1-cluster" pi0
Added:
>
>
if 1 = clus0.size() and 1 = clus1.size() and 1 = clus2.size() and clus1.front().to() = clus2.front().to() : self.plot ( pt , " 1 pi0->gamma gamma " , 0 , 5 ) self.plot ( mnpt , " 1 pi0->gamma gamma : min pt of photon " , 0 , 5 )
 
Changed:
<
<
if 1 = clus0.size() and 1 clus1.size() and 1 clus2.size() and clus1.front().to() = clus2.front().to() :

self.plot ( pt , " 1 pi0->gamma gamma " , 0 , 5 )

self.plot ( mnpt , " 1 pi0->gamma gamma : min pt of photon " , 0 , 5 )

return SUCCESS # =========================================================================

>
>
return SUCCESS # =========================================================================
 %ENDSYNTAX%

The example illustrate:

  • retrival the relation table from Transient Event Store (the line 01410)
Changed:
<
<
  • inversion of table (on-flight conversion to the C++ type Relations::RelationWeigted , see the lines 01440-01450)
>
>
  • inversion of table (on-flight conversion to the C++ type Relations::RelationWeigted<LHCb::MCParticle,LHCb::CaloCluster,float> , see the lines 01440-01450)
 
  • selection of , which:
Changed:
<
<
    • satisfy the decay pattern "pi0 -> gamma gamma" (the line 01220)
>
>
    • satisfy the decay pattern "pi0 -> gamma gamma" (the line 01220)
 
    • have an origin vertex within +-50 centimeters in z-direction around the primary vertex (the line 01320)
    • each of the photon is in the geometrical acceptance of Ecal (the lines 01620-01630)
  • Retrieve from the relation table the number of associated Ecal clusters for and each of the daughter photons (the lines 01710-01720&01810)
Line: 520 to 454
  %ENDSYNTAX%
Deleted:
<
<
It is worth to compare these lines with corrresponding C++ example from Ex/LoKiExample package, see the file $LOKIEXAMPLEROOT/src/LoKi_MCMergedPi0s.cpp
 
Deleted:
<
<

How to access LHCb::Track -> MC truth Relation tables in (Gaudi)Python?

 
Changed:
<
<
To access Relation tables for LHCb::Track-> MC Truth in python one needs to activate "on-demand" conversion of Linker objects into Relation tables. it can be done just in one line:
>
>
It is worth to compare these lines with corrresponding C++ example from Ex/LoKiExample package, see the file $LOKIEXAMPLEROOT/src/LoKi_MCMergedPi0s.cpp
 
Deleted:
<
<
%SYNTAX{ syntax="python" numbered="1800" numstep="10"}%
 
Changed:
<
<
# activate automatic "on-demand" converison of LHcbTrack->MC Linker objects into Relation Tables
>
>

How to access LHCb::Track -> MC truth Relation tables in (Gaudi)Python?

 
Added:
>
>
To access Relation tables for LHCb::Track-> MC Truth in python one needs to activate "on-demand" conversion of Linker objects into Relation tables. it can be done just in one line:

%SYNTAX{ syntax="python" numbered="1800" numstep="10"}%

# activate automatic "on-demand" converison of LHcbTrack->MC Linker objects into Relation Tables

 import Track2MC _Configuration

# OPTIONALLY: decorate the relation tables,e.g. for easy iteration

Line: 542 to 478
  %ENDSYNTAX%
Changed:
<
<
As soon as it is done, the rest is trivial. e.g. exploiting "direct" relations ( LHCb::Track -> MC) :
>
>
As soon as it is done, the rest is trivial. e.g. exploiting "direct" relations ( LHCb::Track -> MC) :
  %SYNTAX{ syntax="python" numbered="1800" numstep="10"}%
Line: 553 to 487
 print ' #number of tracks: ', tracks.size()

# get the relation table from the Transient Event Store

Changed:
<
<
table = evt['Relations/Rec/Trac/Default']
>
>
table = evt['Relations/Rec/Track/Default']
 print ' Relation table, # of links', table.relations().size()

# loop over the tracks

Line: 584 to 510
  %ENDSYNTAX%
Changed:
<
<
The inverse relations ( MC -> LHCb::Track) are also trivial:
>
>
The inverse relations ( MC -> LHCb::Track) are also trivial:
  %SYNTAX{ syntax="python" numbered="1800" numstep="10"}%
 
This site is powered by the TWiki collaboration platform Powered by PerlCopyright & 2008-2019 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback