The first two almost useless, but very important examples
Learning objectives
- Understand the overall structure of Bender module and the configuration of the application
Do-nothing
Learning objectives
- Understand the overall structure of Bender module using the oversimplified example
Any valid Bender module must have two essential parts
- function
run
with the predefined signature - function
configure
with the predefined signature
For the most trivial ("do-nothing") scenario function run
is
def run ( nEvents ) :
# some fictive event loop
for i in range( 0 , min( nEvents , 10 ) ) : print ' I run event %i ' % i
return 0
In a similar way, the simplest "do-nothing"-version of configure
-function is
def configure ( datafiles , catalogs = [] , castor = False , params = {} ) :
print 'I am configuration step!'
return 0
As one clearly sees, these lines do nothing useful, but they are perfectly enough to be classified as the first Bender code. Moreover, the python module with these two function can already be submitted to Ganga/Grid, and Ganga will classify it as valid Bender code. Therefore this code is already "ready-for-Ganga/Grid"!
The details for the curious students: how Ganga/Grid treat Bender modules?Click to expand
In practice, before the submission the jobs to Ganga/Grid, the code needs to be tested using some test-data.
This, formally unnecessary, but very important step can be easily embedded into your module using
python's __main__
clause:
if '__main__' == __name__ :
print 'This runs only if module is used as the script! '
configure ( [] , catalogs = [] , params = {} )
run ( 10 )
Note that these lines effectively convert the module into script, and finally one gets:
How to run it interactively?
The answer is trivial:
lb-run Bender/prod python DoNothing.py
That's all. Make a try and see what you get!
Unnecessary but very useful decorations:Click to expand
For all subsequent lessons we'll gradually extend this script
with the additional functionality, step-by-step converting
it to something much more useful.
In practice, ...Click to expand
DaVinci
Learning objectives
- Understand the internal structure of the configure function
For the typical case in practice, the function configure (as the name suggests) contains three parts
- static configuration: the configuration of
DaVinci
configurable (almost unavoidable) - input data and application manager: define the input data and instantiate Gaudi's application manager (mandatory)
- dynamic configuration: the configuration of
GaudiPython
components (optional)
Static configuration
For the first part, the instantiation of DaVinci configurable is almost unavoidable step:
from Configurables import DaVinci
rootInTES = '/Event/PSIX'
dv = DaVinci ( DataType = '2012' ,
InputType = 'MDST' ,
RootInTES = rootInTES )
Here we are preparing application to read PSIX.MDST
- uDST with few useful selections for B&Q Working Group.
Note that in this part one can use all power of DaVinci/Gaudi Congifurables
.
In practice, for physics analyzes, it is very convenient to use here Selection
framework,
that allows to configure DaVinci
in a very compact, safe, robust and nicely readable way,
e.g. let's get from Transient Store some selection
and print its content
from PhysConf.Selections import AutomaticData, PrintSelection
particles = AutomaticData ( 'Phys/SelPsi2KForPsiX/Particles' )
particle = PrintSelection ( particles )
As the last sub-step of (1), one needs to pass the selection object to DaVinci
dv.UserAlgorithms.append ( particles )
Where is `SelectionSequence` ?Click to expand
Input data and application manager
This part is rather trivial and almost always standard:
from Bender.Main import setData, appMgr
## define input data
setData ( inputdata , catalogs , castor )
## instantiate the application manager
gaudi = appMgr() ## NOTE THIS LINE!
while setData
can appear anywhere inside configure
function,
the line with appMgr()
is very special. After this line,
no static configuration can be used anymore. Therefore all the code dealing with
Configurables
and Selections
must be placed above this line.
Dynamic configuration
For this particular example, it is not used, but will be discussed further in conjunction with other lessons.
The complete configure
function is:
The prepared and ready-to-use function run
is imported Bender.Main
:
from Bender.Main import run
Now our Bender module (well, it is actually pure DaVinci
, no real Bender here!) is ready to be used with Ganga/Grid.
For local interactive tests we can use the trick with __main__
clause:
The __main__
clause in our case contains some input data for local tests:
if __name__ == '__main__' :
inputdata = [
'/lhcb/LHCb/Collision12/PSIX.MDST/00035290/0000/00035290_00000221_1.psix.mdst' ,
'/lhcb/LHCb/Collision12/PSIX.MDST/00035290/0000/00035290_00000282_1.psix.mdst' ]
configure( inputdata , castor = True )
## the event loop
run(10000)
The complete moodule can be accessed here
How to run it?
Again, the answer is trivial (and universal):
lb-run Bender/prod python DoNothing.py
That's all. Make a try and see what you get!
Challenge
Try to convert any of your existing DaVinci
simple script into Bender module and run it interactively.
You can use the result of this excersize for subsequent lessons.
What is `castor` ? Why `LFN` is used as input file name?Click to expand
Keypoints
With these two examples, you should aready be able to
- code the valid (but useless) Bender modules
- run them interactively