Difference: GaudiPython (25 vs. 26)

Revision 262013-06-24 - JessicaElevant

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

Gaudi Python FAQ

Line: 19 to 19
 

FAQs


Added:
>
>
 

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>>> 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.
>
>
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.
 
Added:
>
>
 

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: 93 to 88
 


Added:
>
>
 

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: 103 to 99
 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: 164 to 159
 
  • 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: 221 to 228
 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 )
 
Added:
>
>
fill ( histo , [1,2,3,4,5,6,7] , lambda x : x*x , lambda y : 0==y%2 )
  # use the sequence and apply the function:
Added:
>
>
 # for each track in sequence evaluate "p()" and fill the histogram with track momentum,
Added:
>
>
 # keepingonly track with small transverse momentum:
Added:
>
>
 tracks = ...
Deleted:
<
<
fill ( histo , tracks , lambda t : t.p() , lambda t : t.pt() < 1000 )
 
Added:
>
>
fill ( histo , tracks , lambda t : t.p() , lambda t : t.pt() < 1000 )
  %ENDSYNTAX%

Line: 245 to 256
 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
>
>
root = HistoUtils.getAsROOT( path )
 
Added:
>
>
%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: 319 to 339
 

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<LHCb::CaloCluster,LHCb::MCParticle,float> 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 for selection of Monte Carlo "merged" neutral pions.
  %SYNTAX{ syntax="python" numbered="1000" numstep="10"}%
Added:
>
>
 #!/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
Added:
>
>
 # @date 2007-09-26
Added:
>
>
 class MergedPi0(AlgoMC) :
Added:
>
>
  """ simple class to plot dikaon mass peak """

## standard constructor

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

## standard mehtod for analyses

Added:
>
>
  def analyse( self ) :
Added:
>
>
  """ 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: 356 to 383
  if mcpi0.empty() : return self.Warning("No MC-pi0 is found (1)", SUCCESS )

#get only pi0s, which satisfy the criteria:

Added:
>
>
  #1) large Pt
Changed:
<
<
mc1 = MCPT > 500 # * MeV
>
>
mc1 = MCPT > 500 # * MeV
  # 2) valid origin vertex
Added:
>
>
  mc2 = MCOVALID
Changed:
<
<
# 2) vertex near the primary vertex mc3 = abs ( MCVFASPF( MCVZ ) ) < 500 # * Gaudi.Units.mm
>
>
# 3) vertex near the primary vertex

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

  mccut = mc1 & mc2 & mc3

Line: 377 to 413
  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: 395 to 441
  if not accept ( gamma2 ) : continue

pt = MCPT ( pi0 ) / 1000

Added:
>
>
  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 )
Added:
>
>
  clus2 = itable.relations ( gamma1 )

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

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

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

Added:
>
>
  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
Added:
>
>
  clus0 = itable.relations ( pi0 )
Added:
>
>
  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
Deleted:
<
<
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:
<
<
return SUCCESS # =========================================================================
>
>
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 # =========================================================================

 %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<LHCb::MCParticle,LHCb::CaloCluster,float> , see the lines 01440-01450)
>
>
  • inversion of table (on-flight conversion to the C++ type Relations::RelationWeigted , 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: 454 to 520
  %ENDSYNTAX%
Added:
>
>
It is worth to compare these lines with corrresponding C++ example from Ex/LoKiExample package, see the file $LOKIEXAMPLEROOT/src/LoKi_MCMergedPi0s.cpp
 
Added:
>
>

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

 
Changed:
<
<
It is worth to compare these lines with corrresponding C++ example from Ex/LoKiExample package, see the file $LOKIEXAMPLEROOT/src/LoKi_MCMergedPi0s.cpp

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

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:

>
>
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"}%

Changed:
<
<
# activate automatic "on-demand" converison of LHcbTrack->MC Linker objects into Relation Tables import LoKiPhysMC.track2MC_Configuration
>
>
# 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
Added:
>
>
 import Relations.Rels

# OPTIONALLY: decorate MC-particles for "nice" methods

Line: 478 to 542
  %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: 510 to 584
  %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