470 likes | 682 Views
Bender v15r0 as your analysis environment. Vanya BELYAEV. References. Bender Pages and Bender pages by Lena Mayatskaya Bender mailing list Bender Savannah portal ( news , bugs , tasks , …) Bender Tutorial TWiki Bender HyperNews , TWiki , FAQ, User Guide and Manual :
E N D
Benderv15r0as your analysis environment Vanya BELYAEV
References • Bender Pages and Benderpages by Lena Mayatskaya • Bender mailing list • Bender Savannah portal ( news, bugs, tasks, …) • Bender Tutorial TWiki • Bender HyperNews, TWiki, FAQ, User Guide and Manual: • not yet. still in the bottle of inc • Phys/BenderExample & Tutorial/BenderTutorpackage • “Bender-helpdesk@lhcb.cern.ch” • 13-1-018at CERN • +41 (0) 22 767 40 24 Vanya BELYAEV
When use Bender • Python: perfect for prototyping • e.g. develop the cuts for preselection/stripping • Interactive: perfect for “short” (“supervising”) tasks • resolutions, efficiencies, • spectra • “reflections” • Flexible & Friendly: • good for “the final” analysis of small data sets • combine with Root, Panoramix, RooFit,… Vanya BELYAEV
When no Bender • Stripping does not support Bender. • Reasons? • Some CPU penalty for Bender selections vsLoKi selections is unavoidable (PythonvsC++) • could be visible/sizeable for “minimal” job • mainly comes from the explicit loops, N-Tuples and explicit manipulations with dictionaries: sqrt(p.px()*p.px()+p.py()*p.py()) • usually negligible for realistic selection • And of course for well-coded lines Totally negligible with patterns (C++) Beer offer: Everyone who demonstrates visible CPU penalty with the proper usage of Bender with respect to the similar code using e.g. DaVinci/LoKi/CombineParticles etc. Vanya BELYAEV
The goal • To be able in one hour to make following steps • selection of particles • extraction of the basic information • fill the histograms • looping over the particles • fill N-Tuples • save interesting combinations • Match to Monte Carlo truth Covers >95% of functionality needed for event selection Vanya BELYAEV
Bender > SetupProject Bender v15r0 Vanya BELYAEV
Minimal Bender script from Bender.Mainimport * from Configurables import DaVinci DaVinci ( DataType = ‘2010’ , ) gaudi = appMgr() run(10) Well, It is not Bender, it is Configurables+ GaudiPython BUT:Takecare about input data!! $BENDERTUTORROOT/solution/Minimalistic_0.py Vanya BELYAEV
Minimal Bendermodule from Bender.Mainimport * def configure( files ,catalogs = []) : from Configurable import DaVinci DaVinci ( … ) setData ( files , catalogs ) gaudi=appMgr() … return SUCCESS if __name__ == ‘__main__’ : inputfiles= … configure( inputfiles ) run(100) Application and Components Configuration Job steering $BENDERTUTORROOT/solution/Minimalistic.py Vanya BELYAEV
Scripts vs modules • Dilemma in Python: scriptsvsmodules • Scripts are a bit more intuitive and a bit easier to write • Problems with reusing • Modules require some discipline & conventions • Full power of OO, including classes & extensions • Easy to import and reuse • The only way to assemble “large” application from pieces • Be friendly: code modules • loose nothing • gain a lot Ganga assumes that you code is module Vanya BELYAEV
Scripts versus modules • Script above: import myscript Execute everything out of control. To change something – copy, cut-n-paste (and of course duplicate your colleague’s bugs + introduce some of your own) • Module above – easy reusable by your colleagues: import mymodule mymodule.config( inputdata ) gaudi.run(100) Vanya BELYAEV
“Hello, World!” (I) • The simplest possible BENDER “algorithm” • Follow LoKi’s style: • inherit the algorithm from useful base class • (re)implement the “analyse” method class HelloWorld(Algo) : def analyse( self ) : print ‘Hello, World!’ return SUCCESS $BENDERTUTORROOT/solution/HelloWorld.py Vanya BELYAEV
“Hello, World!” (II) • One needs to instatiate the algorithm: alg = HelloWorld( ‘Hello’ ) • Add it to the list of ‘active’ algorithms (TopAlg) gaudi.addAlgorithm ( alg ) • Or: • Substitute the current list of algorithms: gaudi.setAlgorithms ( [alg] ) • Execute run(10) $BENDERTUTORROOT/solution/HelloWorld.py Vanya BELYAEV
Access to the data (LoKi-style) • C++: GaudiAlgorithm/LoKi const LHCb::MCParticle::Container* mcps =get<LHCb::MCParticle::Container>( “MC/Particles”) • Python: Bender / GaudiAlgs mcps = self.get( ‘MC/Particles’) • Mnemonic rule: this->→self. $BENDERTUTORROOT/solution/DataAccess.py Vanya BELYAEV
Access to the data using service • Inside the algorithm dataSvc = self.evtSvc() hdr = dataSvc[‘Header’] print ‘Event #’, hdr.evtNum() • Outside algorithm-I (script) dataSvc = gaudi.evtSvc() hdr = dataSvc[’Header’] print ‘Run #’, hdr.runNum() • Outside algorithm-II (script), shortcut hdr = get(‘Header’) Vanya BELYAEV
Attributes and (python) loops MCParticle for p in mcps : print ‘ID=‘ , name( p ) print ‘PX=‘ , p.momentum().px() print ‘PY=‘ , p.momentum().py() print ‘decay: ’ , p.decay( True ) • All containers from Transient Event store are iterable From Dictionaries $BENDERTUTORROOT/solution/DataAccess.py Vanya BELYAEV
Help! And Attributes • To know the available attributes: help( obj ) help( type( obj ) ) dir (), dir ( cpp ), dir ( LoKi ), dir ( LHCb ) • ON-LINE help for ALL Python/Bender functions/classes, sometimes it is VERY useful • Doxygen pages: >>> import LoKiCore.doxygenurl as doxy >>> o = … >>> doxy.browse ( o ) >>> doxy.browse ( ‘LHCb::MCParticle’ ) Vanya BELYAEV
Decorations • Objects in python are “more rich: >>> from Bender.MainMC import * >>> help(LHCb.MCParticle) >>> doxy.browser( LHCb.MCParticle ) • Many new methods (added “on-flight” by Bender): • child, children, parents, mother, ascendents, descendent, printDecay, … • Uniform with LHCb.Particle & HepMC.GenParticle p = … for c in p.children() : print c c1 = p.child(1) p = … for c in children( p ) : print c c1 = child( p , 1) Vanya BELYAEV
Lets start with physics analysis • <Almost> all of LoKi’s idioms are in Bender • (No need to write the separate manual) • The semantics is very similar • Inspite of DIFFERENT languages • Few “obvious” exceptions • In the game • All functors (functions/predicates) “cuts” • All (v,mc,mcv,g)select methods • Loops,plots • For nTuples the functionality is a bit limited • A lack of templated methods Vanya BELYAEV
The Simplest case: make KS • Select pions according to some criteria • Track quality • (Kinematical properties) • (Pointing criteria) • Combine p+p- pairs • Vertex quality • Pointing criteria • Flight distance $BENDERTUTORROOT/solution/MakeKs.py Vanya BELYAEV
1. Select pions pi_plus = self.select ( ‘MyGoodPi+’ , ( ‘pi+’ == ID ) & ( TRCHI2DOF < 10 ) ) pi_minus = self.select ( ‘MyGoodPi-’ , ( ‘pi-’ == ID ) & ( TRCHI2DOF < 10 ) ) print “# pi+ : ”, len(pi_plus) for pi in pi_plus : print pi.pname() , pi.pt() c2(track)/nDoF<10 Select p+ & p- pions = self.select ( ‘GoodPi’ , ( ‘pi+’ == ABSID ) & ( TRCHI2DOF < 10 ) ) pi_plus = self.select ( ‘MyGoodPi+’ , pions , Q > 0 ) pi_minus = self.select ( ‘MyGoodPi-’ , pions , Q < 0 ) Vanya BELYAEV
2. Combine p+p- pairs # define the looping rules: components & the result v0s = self.loop ( ‘MyGoodPi+ MyGoodPi-’, ‘KS0’ ) for k0 in v0s : # fast check of mass from the sum of 4-momenta: m12 = k0.mass(1,2) / MeV if not 300 < m12 < 800 : continue # check vertex-fit chi2 (fit if not done yet): chi2vx = VCHI2 ( k0 ) if not 0 <= chi2vx <= 100 : continue self.plot ( M ( k0 ) , ‘mass K0S’ , 400 , 600 ) c2(vertex)<10 0 Vanya BELYAEV
(2a. Apply more cuts in loop) # get the best primary vertex from DaVinci bpv = self.bestVertex( k0.particle() ) if not bpv : continue # calculate the lifetime of Ks-candidate: ctau = LTIME( self.lifetimeFitter() , bpv ) * c_light if ctau ( k0 ) < 5 * mm : continue # calculate the chi2(IP) for Ks-candidate: chi2ip = IPCHI2 ( bpv , self.geo() ) if ch2ip ( k0 ) > 9 : continue self.plot ( M ( k0 ) , ‘mass K0S’ , 400 , 600 ) ct > 5mm c2(IP)<9 Vanya BELYAEV
(2b. Apply cuts before loop) # get all primary vertices: primaries = self.vselect( ‘pv’ , PRIMARY ) if primaries.empty() : continue # create functor for evaluation of min(chi2ip) mips = MIPCHI2( primaries , self.geo() ) # BEFORE LOOP: … = self.select ( … , … & ( mips > 9 ) ) # INSIDE THE LOOP: pi1 = k0(1) pi2 = k0(2) if mips( pi1 ) < 9 or mips(pi2) < 9 : continue c2(IP)>9 Access to the individual loop components c2(IP)>9 Vanya BELYAEV
Combine everything together from Bender.Main import * class MakeKs(Algo): def analyse ( self ) : … return SUCCESS def configure ( inputdata , catalogs = [] ) : … if ‘__main__’ == __name__ : configure ( … ) run ( 1000 ) $BENDERTUTORROOT/solution/MakeKs.py Vanya BELYAEV
Simple case-II: strip DSTs • Use V0.DST, Reco05-Stripping09 • Stripping Line: “StrippingK0SLine” • Stripping Decision “StirppingL0SLineDecision” • OutputLocation: “/Event/V0/Phys/StrippingK0S” • Get candidates from DST • Specific configuration • Analyse them Vanya BELYAEV
3. Select Ks ks_1 = self.select ( ‘MyKs’ , ‘KS0’ == ID) ks_2 = self.select ( ‘MyGoodKs’ , ks_1 , PT > 1 * GeV ) print “# Ks : ”, len(ks_1) for Ks in ks1_2 : print Ks.decay() , Ks.pt() print PT ( Ks ) self.plot ( M( Ks ) , ‘Mass Ks’ , 400 , 600 ) $BENDERTUTORROOT/solution/SelectK0S(_1,_2).py Vanya BELYAEV
Simple case-III: mDSTs • Use mDST produced to test “PromptCharm” lines from CHARM.DST, Reco04-Stripping07 • OutputLocation: • Root-On-TES “/Event/MicroDST/PromptCharm” • Locations “Sel(Dstar,D,Ds,LambdaC)ForPromtCharm” • Get candidates from DST • Specific configuration • Analyse them Vanya BELYAEV
4. Get D*+decays # select from TES the interesting decays dstars = self.select ( ‘MyD*’, ‘[ D*(2010)+ -> ( D0 -> K- pi+) pi+]CC’ ) Dm = M – M1 for D in dstars: m1 = M1 ( D ) # mass of the first particle dm = Dm ( D ) if abs ( dm – 145 * MeV ) < 2.5 * MeV : self.plot ( m1 , ‘mass D0’ , 1.8 , 1.9 ) Use decay descriptor Cut on |dDM|<1.5 MeV/c2 $BENDERTUTORROOT/solution/SelectDstar.py Vanya BELYAEV
(4a. Loop D*+decays) ltFit = self.lifetimeFitter() # loop for D*+ decays: for D in dstars : # get daughter particle by index: D0 = D.child( 1 ) # get related primary vertex pv = self.bestVertex ( D0 ) # create the functor: ctauFun = LTIME ( ltFit , pv ) * c_light # evaluate c*tau ctau = ctauFun ( D0 ) # make histogram self.plot ( ctau , ‘c*#tau for D^{0} ’ , 0. , 1.0 ) Vanya BELYAEV
Simple case-IV: mDSTs • CHARM.DST, Reco05-Stripping07 • Sum of D+/Ds+lines by Conor&Rio • Get candidates from DST • Specific configuration • Analyse them • The same mDST produced to test “PromptCharm” lines from CHARM.DST, Reco04-Stripping07 Vanya BELYAEV
5 Get D+/Ds+decays # select from input particles according to the decay pattern: d_1 = self.select(‘d1’ , “[ D+ -> K- pi+ pi+]CC" ) ds_1 = self.select(‘ds1’, “[ D_s+ -> K- K+ pi+]CC“ ) ds_2 = self.select(‘ds2’, ”[ D_s+ -> ( phi(1020) -> K- K+ ) pi+]CC” ) for d in d_1 : self.plot ( M(d) , 'D+ -> K pi pi' , 1800 , 1900 , 100 ) pv = self.bestVertex( d ) fun = LTIME ( self.lifetimeFitter() , pv ) * c_light ctau = fun ( d ) if 0.1 < ctau < 1.0 : self.plot ( ctau , 'c*tau for D+', 0 , 1 ) for d in ds_1 : self.plot ( M(d) , 'D+/Ds+ -> Kkpi ' , 1800 , 2050 , 250 ) for d in ds_2 : self.plot ( M(d) , 'Ds+ -> phi pi+' ,1770,2070,300 ) $BENDERTUTORROOT/solution/SelectDplus(_1).py Vanya BELYAEV
(5a What about N-tuples?) # select from input particles according to the decay pattern: d_1 = self.select(‘d1’ , “[ D+ -> K- pi+ pi+]CC" ) # retrive (book-n-demand) N-tuple object tup = self.nTuple(‘MyN-tuple’) for d in d_1 : … # add the columns to n-tuple tup.column ( ‘m’ , M ( d ) ) tup.column ( ‘pt’ , PT ( d ) ) tup.column ( ‘ctau’ , ctau ) # commit the row: tup.write() $BENDERTUTORROOT/solution/SelectDplus(_1).py Vanya BELYAEV
The last step: MC-truth match • The simplest case: check if RC particles originates form certain MC-(sub)tree: • The most frequent case • Check for efficiency • Resolution • The opposite case ( RC ↔ MC ) • similar MCTRUTH ↔ RCTRUTH NB: LoKi ( and therefore Bender) uses own concept of MC loose matching Vanya BELYAEV
Select MC-particles # select Monte Carlo particles according to the decay pattern: mcD = self.mcselect ( ‘myD’ , “[ D+ => K- pi+ pi+]CC" ) # select Monte Carlo particles according to kinematics : mcD1 = self.mcselect (‘myGoodD’ , ( MCPT > 1 * GeV ) & in_range ( 1.0 , MCY , 5.0 ) ) # use marked decay descriptors: K = self.mcselect( ‘K’ , mcD1 , “[ D+ => ^K- pi+ pi+]CC” ) Pi = self.mcselect( ‘Pi’ , mcD1 , “[ D+ => K- ^pi+ ^pi+]CC” ) # loop over selected true D+ for D in mcD1 : print D.decay() , MCE( D ) $BENDERTUTORROOT/solution/SelectDplusMC(_1).py Vanya BELYAEV
MC-Truth matching functions # retrieve Monte Carlo Truth matcher match = self.mcTruth (‘My MC-truth matcher’) # prepare MC-Truth matching functors trueK = MCTRUTH ( match , K ) truePi = MCTRUTH ( match , Pi ) trueD = MCTRUTH ( match , mcD1 ) # get the reconstructed particle particle = … # check MC-truth: Ok = trueK ( particle ) $BENDERTUTORROOT/solution/SelectDplusMC(_1).py Vanya BELYAEV
Use MC-Truth functors (1) # select only MC-truth matched kaons kaons = self.select(‘k’ , (‘K+’ == ABSID ) & trueK ) kplus = self.select( ‘K+’ , kaons , Q > 0 ) kminus = self.select ( ‘K-’ , kaons , Q < 0 ) # select only MC-truth matched pions pions = self.select ( ‘pi’ , (‘pi+’ == ABSID ) & truePi) for k in kplus : print PT ( k ) for p in pions : print PT ( pi ) $BENDERTUTORROOT/solution/SelectDplusMC(_1).py Vanya BELYAEV
Use MC-Truth functors (2) # in loop over particles: D = self.loop ( ‘ K- K+ pi‘ , ‘D+’ ) for d in D : # get the loop components kaon1 = d(1) kaon2 = d(2) pion = d(3) # check MC-Truth: ok1 = trueK ( kaon1 ) ok2 = trueK ( kaon2 ) ok3 = truePi ( pion ) ok4 = trueD ( d ) $BENDERTUTORROOT/solution/SelectDplusMC(_1).py Vanya BELYAEV
Few ‘interactive’ hints I • Get application manager: gaudi = appMgr() • List the content of Event Transient Store ls () ls (‘/Event’) • Get an object from Transient Store obj = get(‘/Event/Hlt/DecReports’) • Run “n” events run ( n ) Vanya BELYAEV
Few ‘interactive’ hints - II • List the histograms in HTS: hsvc = gaudi.histSvc() hsvc.dump() • Get the histogram by ID (==title): h = hsvc[‘Phi/K+K- mass ’] • Visualize the histogram as ROOThisto: h.plot() h.Draw() import ROOT Vanya BELYAEV
Few ‘interactive’ hints - III • Get the map of all histogramaby the given component (algorithm or tool) cmp = gaudi.algorithm ( ‘AlgName’) histos = cmp.Histos() for id in histos : histo = histos[id] • Get the histogram from component (algorithm or tool) by ID id = … histo= cmt.Histos (id) Vanya BELYAEV
Few ‘interactive’ hints - IV • ASCII dump of the histogram ## Width , Height, Plot errors print histo.dump( 70 , 20 , True ) • AACII dump for all histogram of the given component (algorithm or tool) cmp = … cmt.dumpHistos ( 50 , 15 , True ) • AACII dump for all histogram of the given component by name: dumpHistos ( ‘MyAlg’ , 70, 50 , True ) Vanya BELYAEV
Few ‘interactive’ hints - V • Get all tools, acquired by given component tools = cmp.Tools() for t in tools : print t.OutputLevel • Dump all properties of given component cmp = … cmp.PropertiesPrint = True • Dump the summary of counters for the given component cmp = … cmp.StatPrint = True Vanya BELYAEV
Few ‘interactive’ hints - VI • Dump the summary of histograms cmp = … cmt.HistoPrint = True • Dump the summary of N-tuples cmp = … cmp.NTuplePrint = True • Dump the summary of ETCs cmp = … cmp.EvtColsPrint = True Vanya BELYAEV
Few ‘interactive’ hints - VII • ‘Easy’ browser for (s,r,m,x,..)DSTs content: dst_explorer[opts] file1 [ file2 [ … >>> ls() >>> ls (‘/Event’) >>> ls (‘/Event/Dimuon’) >>> ls (‘/Event/Dimuon/Phys’) Vanya BELYAEV
Other features, out of scope • Nice printout of trees, particles, events • Various “extractors” and metafunctions • HepMC + HepMCParticleMaker • Jets • Tools for background origin studies • Patterns • and much much more… As concerns the functionality needed for analysis, Bender is full scale application, widely used for many physics studies. Vanya BELYAEV
Next (obvious) steps • Integrate with DIRAC/Ganga • Integrate with Panoramix • More, more and more “on-flight” decorations: p.name() , name(p), … p.printDecay() , printDecay(p) , … Vanya BELYAEV
References again… • Bender Pages and Benderpages by Lena Mayatskaya • Bender mailing list • Bender Savannah portal ( news, bugs, tasks, …) • Bender Tutorial TWiki • Regular informal “hands-on” tutorials • You know whom to ask… • Bender Examples • “Bender-helpdesk@lhcb.cern.ch” • 13-R-018at CERN • +41 (0) 22 767 40 24 Vanya BELYAEV