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

The whole module is here:

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

  1. static configuration: the configuration of DaVinci configurable (almost unavoidable)
  2. input data and application manager: define the input data and instantiate Gaudi's application manager (mandatory)
  3. 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

results matching ""

    No results matching ""