def random(self, odin): if self._random == None: import GaudiPython GaudiPython.loaddict('SwimmingDict') self._random = GaudiPython.Bindings.gbl.Random if not self._initialRandom: self._initialRandom = self._random.mixString( len(self._extra), self._extra) x = self._initialRandom x = self._random.mix64(x, odin.gpsTime()) x = self._random.mix32(x, odin.runNumber()) x = self._random.mix64(x, odin.eventNumber()) return float(x) / float(0xFFFFFFFF)
'EventSelector.PrintFreq = 10 ', 'EventSelector.OutputLevel = 1', 'ApplicationMgr.TopAlg.OutputLevel = 1 ' #,'ApplicationMgr.TopAlg.RootInTES = "/Event/microDST" ' #,'ApplicationMgr.TopAlg += { "StoreExplorerAlg" }' #,'StoreExplorerAlg.Load = 1' #,'StoreExplorerAlg.PrintFreq = 1.0' #,'StoreExplorerAlg.Outputlevel = 1' , 'ApplicationMgr.ExtSvc += {"ParticlePropertySvc"}', 'ApplicationMgr.ExtSvc += { "DataOnDemandSvc" }', 'DataOnDemandSvc.Nodes += { "DATA=\'/Event/MC\' TYPE=\'DataObject\'" }', 'DataOnDemandSvc.Algorithms += {"DATA=\'/Event/MC/Particles\' TYPE=\'UnpackMCParticle\'", "DATA=\'/Event/MC/Vertices\' TYPE=\'UnpackMCVertex\'"}' ]) GaudiPython.loaddict('PhysEventDict') ## ## access to the EventService, EventSelector ## sel = appMgr.evtsel() evt = appMgr.evtsvc() ## ## access to tools, etc ## OfflineVertexFitter = appMgr.toolsvc().create('OfflineVertexFitter', interface='IVertexFit') ## ## open microDST
from ROOT import gROOT, TCanvas from ROOT import RooRealVar, RooArgSet, RooFit gROOT.SetStyle( 'Plain' ) gROOT.SetBatch( False ) import GaudiPython GaudiPython.loaddict( 'B2DXFittersDict' ) from ROOT import CombBkgPTPdf # Parameters for the combinatorial background PDF in time CombBkgPdf_a = 0.1209 CombBkgPdf_f = 0.996 CombBkgPdf_alpha = 4.149 CombBkgPdf_beta = 1.139 time = RooRealVar( 'time', 'time', 0., 10., 'ps' ) combBkgPdf_a = RooRealVar( 'CombBkgPdf_a' , 'CombBkgPdf_a' , CombBkgPdf_a ) combBkgPdf_f = RooRealVar( 'CombBkgPdf_f' , 'CombBkgPdf_f' , CombBkgPdf_f ) combBkgPdf_alpha = RooRealVar( 'CombBkgPdf_alpha', 'CombBkgPdf_alpha', CombBkgPdf_alpha ) combBkgPdf_beta = RooRealVar( 'CombBkgPdf_beta' , 'CombBkgPdf_beta' , CombBkgPdf_beta ) bkgPDF = CombBkgPTPdf( 'CombBkgPTPdf', 'CombBkgPTPdf', time, combBkgPdf_a, combBkgPdf_f, combBkgPdf_alpha, combBkgPdf_beta ) fr = time.frame()
def __init__(self, gaudi, triggers): from GaudiPython import InterfaceCast tmpSvc = gaudi.service("IncidentSvc") self.incidentSvc = InterfaceCast("IIncidentSvc")(tmpSvc.getInterface()) self.gaudi = gaudi self.TES = gaudi.evtSvc() import GaudiPython from GaudiPython import InterfaceCast from GaudiPython.Bindings import gbl svc = gaudi.service('Swimming::Service') GaudiPython.loaddict('Swimming') #GaudiPython.loaddict('SwimmingEventDict') self.GaudiPython = GaudiPython self.service = InterfaceCast(gbl.Swimming.Interfaces.IService)( svc.getInterface()) self.distanceTool = gaudi.toolsvc().create( Swimming().getProp('DistCalc'), interface='IDistanceCalculator') DTFconstraints = [] for configname, constraints in Swimming().getProp( 'DecayTreeFitterConstraints').iteritems(): tmpconstraints = {} for constraint, value in constraints.iteritems(): newid = None if type(constraint) == int: newid = constraint elif isinstance(constraint, basestring): try: newid = gaudi.ppSvc().find( constraint).particleID().pid() except: print "ERROR: failed to convert", constraint, "to LHCb::ParticleID" raise else: print "ERROR: currently can't handle conversion of ", constraint, "to LHCb::ParticleID" if newid: print "Storing DTF constraint: (%d, %f)" % (newid, value) tmpconstraints[newid] = value tmpconstraints[-newid] = value DTFconstraints += [(configname, tmpconstraints)] from SwimmingUtils import LifetimeFitter, DTFFitter, BestPVFinder self.relatedPVFinder = BestPVFinder(self) self.lifetimeFitter = [] for lifetimefitter in Swimming().getProp('LifetimeFitter'): if lifetimefitter == "LifetimeFitter": self.lifetimeFitter += [LifetimeFitter(self)] else: # DecayTreeFitter # examine the constraints we have been given, and add DTFFitter objects as appropriate for configname, constraints in DTFconstraints: self.lifetimeFitter += [ DTFFitter(self, configname, constraints) ] self.tistostool = gaudi.toolsvc().create('TriggerTisTos', interface='ITriggerTisTos') self.debugtistos = gaudi.toolSvc().create( 'TriggerTisTos/SwimmingDebugTisTos', interface='ITriggerTisTos') self.tistosbools = [ self.tistostool.kAnything, self.tistostool.kTrueRequired, self.tistostool.kFalseRequired ] self.triggers = triggers self.hlt1recoline = Swimming().getProp('Hlt1RecoLine') self.hlt2recoline = Swimming().getProp('Hlt2RecoLine') self.granularityRefinement = Swimming().getProp( 'GranularityRefinement') self.DEBUGMODE = Swimming().getProp('Debug') self.startingEvent = Swimming().getProp('SkipEvents') self.swimStripping = Swimming().getProp('SwimStripping') self.swimOffline = Swimming().getProp('SwimOffSel') self.offSelName = Swimming().getProp('OffSelModuleName') self.offCands = Swimming().getProp('OffCands') self.offlinePVs = Swimming().getProp('OfflinePV') self.refitPVs = Swimming().getProp('RefitPVs') self.matchCandsUsingPID = Swimming().getProp( 'UseCompositePIDsWhenMatching') self.storeExtraTPs = Swimming().getProp('StoreExtraTPs')
#This file holds utility functions for the swimming job from Configuration import Swimming from collections import defaultdict from GaudiKernel.PhysicalConstants import c_light __all__ = [ 'getCandidateinfo', 'runSwimmingStep', 'hashParticle', 'intHashParticle', 'matchParticles', 'createObject', 'getSelector' ] # Load Swimming dictionaries import GaudiPython GaudiPython.loaddict('SwimmingEventDict') from GaudiPython.Bindings import gbl hashParticle = gbl.Swimming.Helpers.hashParticle intHashParticle = gbl.Swimming.Helpers.intHashParticle matchParticles = gbl.Swimming.Helpers.matchParticles import ROOT def createObject(t, *args): """ Function to create objects which are not owned by python. These objects will not be garbage collected and can therefore be put in the TES, which always takes ownership. """ i = t(*args) ROOT.SetOwnership(i, False) return i
* algorithm base class for N-Tuple manipulations * * * ******************************************************************************* """ # ============================================================================= __author__ = 'Vanya BELYAEV [email protected]' # ============================================================================= import GaudiPython, math Rndm = GaudiPython.gbl.Rndm Math = GaudiPython.gbl.ROOT.Math SUCCESS = GaudiPython.SUCCESS Gaudi = GaudiPython.gbl.Gaudi GaudiPython.loaddict('STLRflx') GaudiPython.loaddict('STLAddRflx') from GaudiKernel import ROOT6WorkAroundEnabled is_root6 = GaudiPython.gbl.gROOT.GetVersionCode() >= ((5 << 16) + (99 << 8)) if not (ROOT6WorkAroundEnabled('SPI-385') and is_root6): GaudiPython.loaddict('MathRflx') GaudiPython.loaddict('MathAddRflx') vct1 = GaudiPython.gbl.vector('double') GaudiPython.loaddict('CLHEPRflx') vct2 = GaudiPython.gbl.CLHEP.HepVector from GaudiPython.GaudiAlgs import TupleAlgo
from Configurables import MessageSvc, LHCbApp MessageSvc().Format = "% F%60W%S%7W%R%T %0W%M" from Gaudi.Configuration import EventSelector EventSelector().PrintFreq = 100 lhcbApp = LHCbApp() lhcbApp.DDDBtag = 'default' lhcbApp.CondDBtag = 'default' # GaudiPython from GaudiPython.Bindings import AppMgr import GaudiPython GaudiPython.loaddict('PhysDict') appMgr = AppMgr(outputlevel=3) appMgr.config(files=['$GAUDIPOOLDBROOT/options/GaudiPoolDbRoot.opts']) appMgr.ExtSvc += ['DataOnDemandSvc'] appMgr.initialize() evtSvc = appMgr.evtSvc() evtSel = appMgr.evtSel() tsvc = appMgr.toolsvc() from AnalysisPython import Functors nextEvent = Functors.NextEvent(appMgr, EvtMax=nevents) # open a DST or MicroDST evtSel.open(filename)
from __future__ import division from __future__ import print_function from collections import defaultdict from math import atan2, sqrt import GaudiPython import ROOT from LHCbMath import XYZPoint, XYZVector import LoKiAlgo.decorators from LoKiPhys.decorators import VIPCHI2 from LinkerInstances.eventassoc import linkedTo GaudiPython.loaddict('libLinkerEvent') LHCb = GaudiPython.gbl.LHCb LineTraj = LHCb.LineTraj Range = GaudiPython.gbl.std.pair('double', 'double') # LHCb Tracks appear to have the following states # > Downstream BegRich2 FirstMeasurement # > Long BegRich2 ClosestToBeam FirstMeasurement # > Ttrack BegRich2 FirstMeasurement # > Upstream ClosestToBeam FirstMeasurement # > Velo ClosestToBeam state_to_use = { LHCb.Track.Velo: LHCb.State.ClosestToBeam, LHCb.Track.Downstream: LHCb.State.FirstMeasurement, LHCb.Track.Long: LHCb.State.FirstMeasurement, LHCb.Track.Ttrack: LHCb.State.FirstMeasurement, LHCb.Track.Upstream: LHCb.State.FirstMeasurement, }
def SwimmingEventLoop(gaudi, nEvents): import GaudiPython #import PartProp.PartPropAlg import PartProp.decorators import PartProp.Service #from GaudiPython.Bindings import AppMgr #from PartProp.Nodes import * StatusCode = GaudiPython.gbl.StatusCode if gaudi.targetFSMState() < 2: gaudi.initialize() TES = gaudi.evtsvc() SEL = gaudi.evtSel() SEL.OutputLevel = 6 SEL.firstEvent = startingEvent #Now after the initialize some more job dependent stuff if swimStripping: dod = gaudi.service('DataOnDemandSvc') svc = gaudi.service('Swimming::Service') outputs = gaudi.algorithm('killStripping').Nodes for l in dod.AlgMap.keys(): if l.find('Phys') == -1: continue l = '/'.join(l.split('/')[:-1]) outputs.append(l) gaudi.algorithm('killStripping').Nodes = outputs gaudi.algorithm('killStrippingSeq').Enable = False gaudi.algorithm('StrippingGlobal').Enable = False gaudi.algorithm(writerName).Enable = False triggers = Swimming().getProp('StripCands') #Tools needed for for tistosing else: for algo in [ 'killHltSeq', 'seqL0', 'Hlt', 'HltSelReportsWriter', writerName, 'HltDecReportsWriter', 'HltVertexReportsWriter', 'HltLumiWriter', 'HltLumiStripper', 'HltRoutingBitsWriter' ]: gaudi.algorithm(algo).Enable = False hlt1triggers = Swimming().getProp('Hlt1Triggers') hlt2triggers = Swimming().getProp('Hlt2Triggers') triggers = [hlt1triggers, hlt2triggers] # Disable the FSR writer if FSR writing is enabled. if Swimming().getProp('WriteFSR'): gaudi.algorithm('FSRInputCopyStreamWriter').Enable = False #Make the class of globals for passing information around from Swimming.Globals import GlobalParams myGlobs = GlobalParams(gaudi, triggers) gaudi.__dict__['globs'] = myGlobs def __next__(): # Emit special end event Incident. myGlobs.incidentSvc.fireIncident( GaudiPython.gbl.Incident("SwimmingLoop", "SwimmingEndEvent")) # Import the utilities from Swimming.SwimmingUtils import (getCandidateInfo, runSwimmingStep, createObject, getSelector, movePVs) from Swimming.RefineTPs import refine from Swimming.SwimmingTisTos import evaluateTisTos # The turning points contain the following information # # The raw position of the turning point in mm (relative to the # point at which the B/D was measured), the lifetime of the B/D # at the turning point, the IP of the B/D at the turning point, # and of course the trigger decision at that turning point. # # In addition we store information about individual tracks in the # signal, in order to deal with inclusive triggers which only require # a part of the signal to fire. # # The information on which triggers were TOS at which stage # If a logical OR of the triggers is being requested, then # a new turning point is set every time that either one of the trigger # decisions changes. # # The information on which tracks were TOS in # HLT1. To save space this is stored as an integer, # whose first and last digits are 9 and the digits # inbetween are 1 or 0 depending on whether the # given track was TOS in HLT1 or not. This is relevant # for swimming the 1Track trigger only. # # The information on which tracks played a part in the # HLT2 decision. Important for swimming inclusive HLT2 # triggers or swimming multiple triggers in the same job. # # Which tracks were Reco'd in HLT1 and HLT2 # again this is given in the format specified above # # Which tracks were Rec'ible in the VELO, offline (3 hits) or # in HLT1 (5 hits) # # Get the candidate selector. if Swimming().getProp('SelectMethod') != 'all': selector = getSelector(Swimming().getProp('SelectMethod'))(myGlobs) # Initialize at -1 so the eventNumber can be incremented at the top of the loop. eventNumber = -1 from GaudiPython.Bindings import gbl SwimmingReport = gbl.LHCb.SwimmingReport SwimmingReports = gbl.KeyedContainer( 'LHCb::SwimmingReport', 'Containers::KeyedObjectManager<Containers::hashmap>') P2TPRelation = gbl.LHCb.Relation2D('LHCb::Particle', 'LHCb::SwimmingReport') SharedParticles = gbl.SharedObjectsContainer('LHCb::Particle') while True: # Increment event number eventNumber += 1 # Check if we've hit the maximum if (nEvents != -1 and eventNumber >= nEvents): print "Finished processing events" break elif (eventNumber % 100) == 0: print "Processing event", eventNumber gaudi.run(1) if not TES["/Event/Rec/Header"]: print "Reached end of file, we're done!" break odin = TES['/Event/DAQ/ODIN'] if DEBUGMODE: print "Processing %d %d" % (odin.runNumber(), odin.eventNumber()) if onlyEvents and not (odin.runNumber(), odin.eventNumber()) in onlyEvents: __next__() continue if not swimStripping and not Swimming().getProp('Simulation') and \ odin.triggerConfigurationKey() != int(Swimming().getProp('TCK'), 16): print "WARNING, TCK 0x%08x does not match configured TCK %s, skipping event." \ % (odin.triggerConfigurationKey(), Swimming().getProp('TCK')) __next__() continue # Safety checks if skipIfNoMuDSTCand: skipEventBools = [] for candloc in muDSTCands: skipEvent = False mdstcands = TES[candloc + "/Particles"] if not mdstcands: if DEBUGMODE: print "Incident while processing event number", startingEvent + eventNumber print "No container of muDST candidates " + candloc + " found!" skipEvent = True elif mdstcands.size() == 0: if DEBUGMODE: print "Incident while processing event number", startingEvent + eventNumber print "Empty container of muDST candidates " + candloc + " found!" skipEvent = True skipEventBools += [skipEvent] # skipIfNoMuDSTCandsAnywhere is a new flag to decide whether skipIfNoMuDSTCand means *all* MuDSTCand locations have to # be populated or just *some* if (skipIfNoMuDSTCandsAnywhere and not any(skipEventBools)) or ( not skipIfNoMuDSTCandsAnywhere and all(skipEventBools)): if DEBUGMODE: print "Skipping the event" __next__() continue # Create a list of unique candidates from Swimming.SwimmingUtils import Candidate candidates = defaultdict(list) for loc in offCands.keys(): particles = TES[loc + '/Particles'] if not particles: if DEBUGMODE: print "No particles found at %s" % loc continue elif DEBUGMODE: print "Found %d particles at %s" % (particles.size(), loc) for particle in particles: candidates[Candidate(myGlobs, particle)].append( (loc, particle)) candidates = [Candidate(myGlobs, c.particle(), dict(selections)) for \ c, selections in candidates.iteritems()] if DEBUGMODE: print "Found %s unique candidates:" % len(candidates) for c in candidates: print c #if len(candidates) < 2: # print "debug: skipping" # __next__() # continue turningPoints = {} if len(candidates) == 0: if DEBUGMODE: print "Problem while processing event number", startingEvent + eventNumber print "Container of offline candidates empty!" print "Skipping the event but this is bad, check what you are doing!!" __next__() continue if DEBUGMODE: print "Passed the safety checks OK" print "Candidates in event =", len(candidates) # Fire BeginSwimming to signal the swimming service to clear its internal PV container myGlobs.incidentSvc.fireIncident( GaudiPython.gbl.Incident("SwimmingLoop", "BeginSwimming")) # Select the candidate to swim if Swimming().getProp('SelectMethod') != 'all': candidates = [selector(candidates)] for i, candidate in enumerate(candidates): # Containers to store the turningpoints roughTurningPoints = [] finalTurningPointsForWriting = [] if not candidate: print "Somehow there is no candidate!!! This should never happen." print "Skipping this event." __next__() continue if DEBUGMODE and not swimStripping: # Use the debugging TisTos tool to dump info on what the TisTos is # wrt all the trigger lines before the swimming starts. lines = [] for level in triggers: lines.extend(level) for trigger in lines: myGlobs.debugtistos.setOfflineInput() myGlobs.debugtistos.addToOfflineInput(candidate.particle()) myGlobs.debugtistos.setTriggerInput() myGlobs.debugtistos.addToTriggerInput(trigger) print myGlobs.debugtistos.analysisReportTrigger(trigger) # If we are swimming the trigger and have a non-trivial selection method, # put the selected candidate in a separate location. if not swimStripping and Swimming().getProp( 'SelectMethod') != 'none': swimmingParticles = createObject(SharedParticles) swimmingParticles.insert(candidate.particle()) TES.unregisterObject(swimCands + '/Particles') TES.registerObject(swimCands + '/Particles', swimmingParticles) HltDecLast = None HltDec = None swimLoop = int(-1. * maxSwimDistance + -1. * extraSwimDistance) while (swimLoop <= (maxSwimDistance + extraSwimDistance)): if DEBUGMODE: print "Running over event", startingEvent + eventNumber, "swimming step", swimLoop \ , "candidate", i # We got this far now get the candidate and, for the "zero" step only # fill the corresponding event variables for it # Note that this function call also executes the stripping algorithm # having moved the primary vertices around first runSwimmingStep(myGlobs, candidate.particle(), swimLoop) # Now get the trigger decision for this swimming step HltDec = evaluateTisTos(myGlobs, candidate.particle(), candidate.selectedParticles().keys(), swimLoop) if DEBUGMODE: print "Retrieved HLT decision", HltDec, "OK for this event" # If this is the very first swimming step, set HltDecLast to the global # HltDec at this point, otherwise get it from the previous step. if swimLoop == int(-1. * maxSwimDistance + -1. * extraSwimDistance): HltDecLast = HltDec elif roughTurningPoints != []: # before we had [raw, tau, ip, dec, declast ] # now we have [raw, {info}, dec, declast ] # hence 3->2 for index HltDecLast = roughTurningPoints[-1][2] # The first and last point are a special case for the bookkeeping # as we want to record the limits of our swimming and the trigger # decisions at these limits if (abs(swimLoop) == int(1. * maxSwimDistance + 1. * extraSwimDistance)) or \ (HltDec != HltDecLast): # Get the lifetime and IP of the B/D with respect to its favourite PV info = getCandidateInfo(myGlobs, candidate.particle()) roughTurningPoints.append( [swimLoop, info, HltDec, HltDecLast]) # Now the granularity varies with the position # We swim more finely close to the actual decay point if ((swimLoop >= -int(maxSwimDistance)) and (swimLoop < int(maxSwimDistance))): swimLoop += int(initialGranularity) else: swimLoop += int(extraGranularity) # Now the refinement step # We have to refine every turning point, but the first and last # ones which we save don't count as they are just there to # demarcate the limits of our search, so we don't use them if roughTurningPoints == []: # no __next__() because this is continuing from the loop over candidates continue if DEBUGMODE: print "****************************" print "The rough turning points are" pprint(roughTurningPoints) print "****************************" for thisturn in roughTurningPoints: # Write the first and last as is, no refinement if (thisturn == roughTurningPoints[0]) or ( thisturn == roughTurningPoints[-1]): finalTurningPointsForWriting.append(thisturn) continue if DEBUGMODE: print "****************************" print "About to refine TP" pprint(thisturn) print "****************************" if ((thisturn[0] > -int(maxSwimDistance)) and (thisturn[0] <= int(maxSwimDistance))): finalTurningPointsForWriting += refine( myGlobs, candidate.particle(), candidate.selectedParticles().keys(), thisturn, initialGranularity, numberOfRefinements) else: finalTurningPointsForWriting += refine( myGlobs, candidate.particle(), candidate.selectedParticles().keys(), thisturn, extraGranularity, numberOfRefinements) if DEBUGMODE: print "****************************" print "The final turning points for writing are:" pprint(finalTurningPointsForWriting) print "****************************" turningPoints[candidate] = finalTurningPointsForWriting # Reset the PV positions so we don't end up with junk on the DST movePVs(myGlobs, candidate.particle(), 0.0) # End of loop over candidates # Which stage are we swimming stage = None if len(overrideStageName): stage = overrideStageName elif swimStripping: stage = 'Stripping' else: stage = 'Trigger' # Get or Create the KeyedContainer for the SwimmingReports reportLocation = Swimming().getProp('SwimmingPrefix') + '/Reports' reports = TES[reportLocation] hadreports = True if not reports: reports = createObject(SwimmingReports) hadreports = False if DEBUGMODE: print "Created new SwimmingReports object, storing it at " + reportLocation # Put the container in the TES sc = TES.registerObject(reportLocation, reports) if not sc.isSuccess(): print "Failed to register SwimmingReports in TES" return StatusCode(False) if DEBUGMODE: print turningPoints for candidate, tps in turningPoints.iteritems(): # Look if there is already a report present for one of the locations # of a candidate. report = reports(candidate.intHash()) if not report: report = createObject(SwimmingReport) if DEBUGMODE: print "Created new SwimmingReport object, inserting it into the SwimmingReports" reports.insert(report, candidate.intHash()) elif report.hasStage(stage): # I think this would be the outcome if the intHash method had a collision. print "WARNING, stage %s already present, this is unsupported and will fail!" return StatusCode(False) if myGlobs.storeExtraTPs: # Loop over the existing TPs + RAW=0.0 and evaluate our own decision and candidate info. oldtps = [0.0] for oldstage in report.stages(): oldtps = [0.0] for tp in report.turningPoints(oldstage): oldtps += [tp.raw()] oldtps = list(set(oldtps).difference([tp[0] for tp in tps])) extratps = [] for oldraw in oldtps: runSwimmingStep(myGlobs, candidate.particle(), oldraw) HltDec = evaluateTisTos( myGlobs, candidate.particle(), candidate.selectedParticles().keys(), oldraw) info = getCandidateInfo(myGlobs, candidate.particle()) extratps.append([oldraw, info, HltDec]) movePVs(myGlobs, candidate.particle(), 0.0) if DEBUGMODE: print "TPs for writing:", tps print "Extra TPs from old stages:", extratps tps += extratps tps.sort( ) # sort operates on the first element of each list element, i.e. the RAW value if DEBUGMODE: print candidate.selectedParticles() # Now that we have a report, relate the particles for loc, particle in candidate.selectedParticles().iteritems(): p2tploc = offCands[loc] + '/P2TPRelations' relations = TES[p2tploc] if not relations: relations = createObject(P2TPRelation) if DEBUGMODE: print "Created new P2TPRelation object, storing it at", p2tploc # Put it in the TES if not TES.registerObject(p2tploc, relations).isSuccess(): print "Failed to register relations table in TES at", p2tploc return StatusCode(False) rel = relations.relations(particle) if rel.empty(): relations.relate(particle, report) elif not hadreports: print "Found", rel.size( ), "relations already for", particle, "from", loc print "WARNING: already have relations for one of our offline candidates, this should only happen for FSPs" #return StatusCode(False) # get the list of final state particles fsps = [] from Swimming.SwimmingTisTos import appendToFSP appendToFSP(0, particle, fsps) for fsp in fsps: #rel = relations.relations(fsp['child']) # a track can be related to more than one report if more than one candidate is swum # this should do nothing if we've already related, which will happen for each swimming # stage after the first (i.e. stripping, or 2nd trigger swimming) relations.relate(fsp['child'], report) # print "WARNING: Attempted to relate the same FSP to the same report more than once..." # return StatusCode(False) # TODO MAKE THIS MAKE SENSE WITH MULTIPLE CANDIDATE SWIMMING # I guess this still makes sense, sort of. To use the information # you would have to try and relate a track with all of the different # P2TPRelations, and deal with the fact you may find it was part of # more than one B/D candidate which was swum. #from Swimming.SwimmingTisTos import appendToFSP #rel = relations.relations(mycand) #particles = [{"child" : mycand, "parent" : 0}] #appendToFSP(0, mycand, particles) #for particle in particles: # if rel.empty(): # relations.relate(particle["child"], report) # elif rel(0).to().key() != report.key(): # print "There is a relation, but it points to another swimming report, this is very bad!!" # return StatusCode(False) # END TODO # symbols for std::map; create them here the first time we pass by. They # used to be in Swimming.decorators, but something goes pear-shaped with # the dictionary loading in that case... if 'std_map_sb' not in locals(): from GaudiPython import gbl std_map_sinfo = gbl.std.map('string', 'map<unsigned long,bool>') std_map_ulb = gbl.std.map('unsigned long', 'bool') pair_ulb = gbl.std.pair('const unsigned long', 'bool') std_map_ulb.__pair = pair_ulb std_map_sb = gbl.std.map('std::string', 'bool') pair_sb = gbl.std.pair('const std::string', 'bool') std_map_sb.__pair = pair_sb #std_map_sd = gbl.std.map('std::string', 'double') #pair_sd = gbl.std.pair('std::string', 'double') # Not const according to comment in v2r4b python/Swimming/decorators.py #std_map_sd.__pair = pair_sd pair_sd = gbl.std.pair('std::string', 'double') std_vec_sd = gbl.std.vector('std::pair<std::string,double>') def set_map(self, k, v): p = self.__pair(k, v) it = self.find(k) if it != self.end(): self.erase(it) self.insert(p) std_map_ulb.__setitem__ = set_map std_map_sb.__setitem__ = set_map #std_map_sd.__setitem__ = set_map GaudiPython.loaddict("SwimmingHacksDict") createTurningPoint = gbl.SwimmingHacks.createTurningPoint # Create the TurningPoint objects and put them in the report for turn in tps: d = std_map_sb() for decision, value in turn[2][1].iteritems(): d[decision] = value m = std_map_sinfo() for decision, info in turn[2][2].iteritems(): i = std_map_ulb() for k, v in info.iteritems(): i[k] = v m[decision] = i tau = turn[1].pop('tau') mip = turn[1].pop( 'mip') # TODO make sure this is actually consistet # and we call ipchi2 ipchi2... e = std_vec_sd() for info, value in turn[1].iteritems(): e.push_back(pair_sd(info, float(value))) #tp = LHCb.TurningPoint(turn[0], tau, mip, turn[2][0], d, m, e) tp = createTurningPoint(turn[0], tau, mip, turn[2][0], d, m, e) report.addTurningPoint(stage, tp) # Write the Output myGlobs.gaudi.algorithm(writerName).execute() if not swimStripping and Swimming().getProp('WriteFSR'): gaudi.algorithm('FSRInputCopyStreamWriter').execute() __next__() # re-enable the output algorithms to allow correct finalisation gaudi.algorithm(writerName).Enable = True if not swimStripping and Swimming().getProp('WriteFSR'): gaudi.algorithm('FSRInputCopyStreamWriter').Enable = True # Print the number of events processed print Swimming().getProp('EventPrint') % eventNumber return StatusCode(True)