def configure_for_line(self, decaydesc, inputloc, linename, version, simulation, toolList = ["TupleToolPropertime", "TupleToolKinematic", "TupleToolGeometry", "TupleToolEventInfo", "TupleToolPrimaries", "TupleToolPid", "TupleToolANNPID", "TupleToolTrackInfo", "TupleToolRecoStats",], mcToolList = ['TupleToolMCTruth', 'TupleToolMCBackgroundInfo', 'MCTupleToolPrompt'], L0List = [], HLT1List = [], HLT2List = [], strippingList = []) : self.Decay = decaydesc.to_string(carets = True) self.Inputs = [inputloc] isTrigger = is_trigger(version) if isTrigger : self.WriteP2PVRelations = False # Not sure if this is necessary since RootInTES will be set for turbo data. #self.InputPrimaryVertices = '/Event/Turbo/Primary' if not linename in HLT2List : HLT2List.append(linename) else : if not linename in strippingList : strippingList.append(linename) self.addBranches(decaydesc.branches()) headBranch = getattr(self, decaydesc.get_alias()) self.configure_tools(toolList = toolList, mcToolList = (mcToolList if simulation else []), L0List = L0List, HLT1List = HLT1List, HLT2List = HLT2List, strippingList = strippingList, headBranch = headBranch, isTrigger = isTrigger) if simulation : lokituple = headBranch.addTupleTool('LoKi::Hybrid::TupleTool') lokituple.Preambulo = ['from LoKiPhysMC.decorators import *', 'from LoKiPhysMC.functions import mcMatch'] if isTrigger : # Need this for 2015 #relations = TeslaTruthUtils.getRelLoc(inputloc.split('/')[-2] + '/') # This for 2015 ... relations = TeslaTruthUtils.getRelLoc('') mcmatch = 'switch(mcMatch({0!r}, {1!r}), 1, 0)'.format(decaydesc.to_string(carets = False, arrow = '==>'), relations) else : mcmatch = 'switch(mcMatch({0!r}), 1, 0)'.format(decaydesc.to_string(carets = False, arrow = '==>')) lokituple.Variables = {'mcMatch' : mcmatch}
def configure_for_line(self, decaydesc, inputloc, linename, version, simulation, toolList = ["TupleToolPropertime", "TupleToolKinematic", "TupleToolGeometry", "TupleToolEventInfo", "TupleToolPrimaries", "TupleToolPid", "TupleToolANNPID", "TupleToolTrackInfo", "TupleToolRecoStats",], mcToolList = ['TupleToolMCTruth', 'TupleToolMCBackgroundInfo', 'MCTupleToolPrompt'], L0List = [], HLT1List = [], HLT2List = [], strippingList = []) : self.Decay = decaydesc.to_string(carets = True) self.Inputs = [inputloc] isTrigger = is_trigger(version) if isTrigger : self.WriteP2PVRelations = False # Not sure if this is necessary since RootInTES will be set for turbo data. #self.InputPrimaryVertices = '/Event/Turbo/Primary' if not linename in HLT2List : HLT2List.append(linename) else : if not linename in strippingList : strippingList.append(linename) self.addBranches(decaydesc.branches()) headBranch = getattr(self, decaydesc.get_alias()) self.configure_tools(toolList = toolList, mcToolList = mcToolList if simulation else [], L0List = L0List, HLT1List = HLT1List, HLT2List = HLT2List, strippingList = strippingList, headBranch = headBranch, isTrigger = isTrigger) if simulation : lokituple = headBranch.addTupleTool('LoKi::Hybrid::TupleTool') lokituple.Preambulo = ['from LoKiPhysMC.decorators import *', 'from LoKiPhysMC.functions import mcMatch'] if isTrigger : relations = TeslaTruthUtils.getRelLoc('') mcmatch = 'switch(mcMatch({0!r}, {1!r}), 1, 0)'.format(decaydesc.to_string(carets = False, arrow = '==>'), relations) else : mcmatch = 'switch(mcMatch({0!r}), 1, 0)'.format(decaydesc.to_string(carets = False, arrow = '==>')) lokituple.Variables = {'mcMatch' : mcmatch}
def execute(simulation=True, turbo=True, decay_descriptor="J/psi(1S) -> mu- mu+"): # Configure all the unpacking, algorithms, tags and input files appConf = ApplicationMgr() appConf.ExtSvc+= ['ToolSvc', 'DataOnDemandSvc', LoKiSvc()] ConfigTarFileAccessSvc().File = 'config.tar' dv = DaVinci() dv.DataType = "2012" lhcbApp = LHCbApp() lhcbApp.Simulation = simulation CondDB().Upgrade = False dtt = DecayTreeTuple("Early2015") if turbo: tesla_prefix = "Hlt2DiMuonJPsi" dtt.Inputs = ["/Event/"+tesla_prefix+"/Particles"] dtt.InputPrimaryVertices = "/Event/"+tesla_prefix+"/Primary" dtt.WriteP2PVRelations = False else: LHCbApp().DDDBtag = "dddb-20140729" polarity = "u" LHCbApp().CondDBtag = "sim-20140730-vc-m%s100"%polarity muons = AutomaticData(Location="Phys/StdAllLooseMuons/Particles") jpsi = CombineParticles('MyJPsi') jpsi.DecayDescriptors = [decay_descriptor] jpsi.CombinationCut = "(AM < 7100.0 *GeV)" jpsi.DaughtersCuts = {"": "ALL", "mu+": "ALL", "mu-": "ALL"} jpsi.MotherCut = "(VFASPF(VCHI2/VDOF) < 999999.0)" code = """ ('J/psi(1S)' == ID) & in_range(2.990*GeV, M, 3.210*GeV) & DECTREE('%s') & CHILDCUT(1, HASMUON & ISMUON) & CHILDCUT(2, HASMUON & ISMUON) & (MINTREE('mu+' == ABSID, PT) > 700*MeV) & (MAXTREE(ISBASIC & HASTRACK, TRCHI2DOF) < 5) & (MINTREE(ISBASIC & HASTRACK, CLONEDIST) > 5000) & (VFASPF(VPCHI2) > 0.5/100) & (abs(BPV(VZ)) < 0.5*meter) & (BPV(vrho2) < (10*mm)**2) """%(decay_descriptor) # similar to the HLT2 line code = """ (ADMASS('J/psi(1S)')< 120*MeV) & DECTREE('%s') & (PT>0*MeV) & (MAXTREE('mu-'==ABSID,TRCHI2DOF) < 4) & (MINTREE('mu-'==ABSID,PT)> 0*MeV) & (VFASPF(VCHI2PDOF)< 25) """%(decay_descriptor) filter_jpsi = FilterDesktop("MyFilterJPsi", Code=code, Preambulo=["vrho2 = VX**2 + VY**2"], ReFitPVs=True, #IgnoreP2PVFromInputLocations=True, #WriteP2PVRelations=True ) jpsi_sel = Selection("SelMyJPsi", Algorithm=jpsi, RequiredSelections=[muons]) filter_jpsi_sel = Selection("SelFilterMyJPsi", Algorithm=filter_jpsi, RequiredSelections=[jpsi_sel]) jpsi_seq = SelectionSequence("SeqMyJPsi", TopSelection=filter_jpsi_sel) dtt.Inputs = [jpsi_seq.outputLocation()] # Overwriting default list of TupleTools dtt.ToolList = ["TupleToolKinematic", "TupleToolPid", "TupleToolEventInfo", "TupleToolMCBackgroundInfo", "TupleToolMCTruth", #"MCTupleToolHierarchy", #"MCTupleToolPID", "TupleToolGeometry", "TupleToolTISTOS", # with turbo this crashes #"TupleToolTrackInfo", "TupleToolTrigger", ] tlist = ["L0HadronDecision", "L0MuonDecision", "L0DiMuonDecision", "L0ElectronDecision", "L0PhotonDecision", "Hlt1DiMuonHighMassDecision", "Hlt1DiMuonLowMassDecision", "Hlt1TrackMuonDecision", "Hlt1TrackAllL0Decision", "Hlt2DiMuonJPsiDecision", "Hlt2SingleMuonDecision", ] dtt.addTool(TupleToolTrigger, name="TupleToolTrigger") dtt.addTool(TupleToolTISTOS, name="TupleToolTISTOS") # Get trigger info dtt.TupleToolTrigger.Verbose = True dtt.TupleToolTrigger.TriggerList = tlist dtt.TupleToolTISTOS.Verbose = True dtt.TupleToolTISTOS.TriggerList = tlist from Configurables import TupleToolMCTruth, MCTupleToolHierarchy dtt.addTool(TupleToolMCBackgroundInfo, name="TupleToolMCBackgroundInfo") dtt.TupleToolMCBackgroundInfo.Verbose = True dtt.addTool(MCTupleToolHierarchy, name="MCTupleToolHierarchy") dtt.MCTupleToolHierarchy.Verbose = True dtt.addTool(TupleToolMCTruth, name="TupleToolMCTruth") dtt.TupleToolMCTruth.Verbose = True if turbo: assoc_seq = TeslaTruthUtils.associateSequence(tesla_prefix, False) ChargedPP2MC(tesla_prefix+"ProtoAssocPP").OutputLevel = 1 assoc_seq.Members.insert(0, PatLHCbID2MCParticle()) from Configurables import MuonCoord2MCParticleLink muon_coords = MuonCoord2MCParticleLink("TeslaMuonCoordLinker") assoc_seq.Members.insert(1, muon_coords) TrackAssociator("TeslaAssocTr").DecideUsingMuons = True relations = TeslaTruthUtils.getRelLoc(tesla_prefix) else: relations = "Relations/Rec/ProtoP/Charged" TeslaTruthUtils.makeTruth(dtt, relations, ["MCTupleToolKinematic", "MCTupleToolHierarchy", "MCTupleToolPID", ] ) dtt.Decay = mark(2, mark(3, decay_descriptor)) #"J/psi(1S) -> ^mu- ^mu+" dtt.addBranches({"X": "^(%s)"%(decay_descriptor), "muplus": mark(3, decay_descriptor),#"J/psi(1S) -> mu- ^mu+", "muminus": mark(2, decay_descriptor),#"J/psi(1S) -> ^mu- mu+", }) x_preamble = ["DZ = VFASPF(VZ) - BPV(VZ)", ] x_vars = {"ETA": "ETA", "Y": "Y", "PHI": "PHI", "VPCHI2": "VFASPF(VPCHI2)", "DELTAZ": "DZ", # DZ * M / PZ / c with c in units of mm/s # XXX should this be the PDG mass or measured mass? #"TZ": "DZ*M / PZ / 299792458000.0", #seconds "TZ": "DZ*3096.916 / PZ/299792458000.0*(10**12)", #ps "minpt": "MINTREE('mu+' == ABSID, PT)", "minclonedist": "MINTREE(ISBASIC & HASTRACK, CLONEDIST)", "maxtrchi2dof": "MAXTREE(ISBASIC & HASTRACK, TRCHI2DOF)", } muon_vars = {"ETA": "ETA", "Y": "Y", "PHI": "PHI", "CHARGE": "Q", "CLONEDIST": "CLONEDIST", "TRCHI2DOF": "TRCHI2DOF", } loki_X = dtt.X.addTupleTool("LoKi::Hybrid::TupleTool/LoKi_X") loki_X.Variables = x_vars loki_X.Preambulo = x_preamble loki_mup = dtt.muplus.addTupleTool("LoKi::Hybrid::TupleTool/LoKi_MuPlus") loki_mup.Variables = muon_vars #dtt.muplus.addTupleTool("TupleToolGeometry") loki_mum = dtt.muminus.addTupleTool("LoKi::Hybrid::TupleTool/LoKi_MuMinus") loki_mum.Variables = muon_vars #dtt.muminus.addTupleTool("TupleToolGeometry") dv.TupleFile = "DVNtuples.root" if turbo: dv.UserAlgorithms = [assoc_seq, dtt] else: assocpp = ChargedPP2MC("TimsChargedPP2MC") assocpp.OutputLevel = 1 dv.UserAlgorithms = [jpsi_seq.sequence(), assocpp, dtt]
def configure_tools(self, toolList = ["TupleToolPropertime", "TupleToolKinematic", "TupleToolGeometry", "TupleToolEventInfo", "TupleToolPrimaries", "TupleToolPid", "TupleToolANNPID", "TupleToolTrackInfo", "TupleToolRecoStats",], mcToolList = ['TupleToolMCTruth', 'TupleToolMCBackgroundInfo', 'MCTupleToolPrompt'], L0List = [], HLT1List = [], HLT2List = [], strippingList = [], headBranch = None, isTrigger = False) : for trigList in L0List, HLT1List, HLT2List, strippingList : for i, trig in enumerate(trigList) : if trig[-8:] != 'Decision' : trigList[i] += 'Decision' for tool in toolList : self.addTupleTool(tool) if mcToolList : ttmc = self.addTupleTool('TupleToolMCTruth') for tool in mcToolList : if tool == 'TupleToolMCTruth' : continue if tool.find('MCTupleTool') == 0 : ttmc.addTupleTool(tool) else : self.addTupleTool(tool) if isTrigger : # Is this right? Or should I pass it the list of sub-tools of TupleToolMCTruth? relations = TeslaTruthUtils.getRelLoc('') TeslaTruthUtils.makeTruth(self, [relations], mcToolList) if strippingList : ttstrip = self.addTupleTool('TupleToolStripping') ttstrip.TriggerList = strippingList ttstrip.VerboseStripping = True # This doesn't currently work. There doesn't seem to be an easy way # to TISTOS stripping lines currently, which is infuriating. Surely everyone # needs to do this for MC studies? It might be possible to do it using # TESTisTos in a Bender algorithm, or INTES functor. #ttstriptistos = headBranch.addTupleTool('TupleToolTISTOS/tistos_stripping') #ttstriptistos.TriggerTisTosName = 'TESTisTos' #ttstriptistos.TriggerList = [os.path.join(rootInTES, inputLocation)] if L0List or HLT1List or HLT2List : if headBranch == None : headBranch = self ttrig = headBranch.addTupleTool('TupleToolTISTOS') # TupleToolTISTOS can't do stripping this way either. ttrig.TriggerList = L0List + HLT1List + HLT2List ttrig.Verbose = True ttrig.VerboseL0 = True ttrig.VerboseHlt1 = True ttrig.VerboseHlt2 = True
#tlist = ["L0HadronDecision","L0MuonDecision","L0DiMuonDecision","L0ElectronDecision","L0PhotonDecision","Hlt1DiMuonHighMassDecision","Hlt1DiMuonLowMassDecision","Hlt1TrackMuonDecision","Hlt1TrackAllL0Decision","Hlt2DiMuonJPsi","Hlt2IncPhiDecision","Hlt2Topo4BodySimpleDecision","Hlt2Topo3BodySimpleDecision","Hlt2Topo3BodyBBDTDecision","Hlt2Topo2BodySimpleDecision","Hlt2Topo2BodyBBDTDecision","Hlt2Topo4BodyBBDTDecision","Hlt2TopoMu4BodyBBDTDecision","Hlt2IncPhiSidebandsDecision","Hlt2B2HHDecision","Hlt2DiPhiDecision"] tlist = ["Hlt2DiMuonJPsi"] tuple.Decay = "J/psi(1S) -> ^mu+ ^mu-" #tuple.Decay = "[D*(2010)+ -> ^(K*(892)0 -> ^K+ ^pi-) ^pi+]CC" tuple.addTool(TupleToolTrigger, name="TupleToolTrigger") tuple.addTool(TupleToolTISTOS, name="TupleToolTISTOS") # Get trigger info tuple.TupleToolTrigger.Verbose = True tuple.TupleToolTrigger.TriggerList = tlist tuple.TupleToolTISTOS.Verbose = True tuple.TupleToolTISTOS.TriggerList = tlist from TeslaTools import TeslaTruthUtils seq = TeslaTruthUtils.associateSequence("Tesla", False) relations = TeslaTruthUtils.getRelLoc("Tesla") TeslaTruthUtils.makeTruth( tuple, relations, ["MCTupleToolKinematic", "MCTupleToolHierarchy", "MCTupleToolPID"]) tuple2 = MCDecayTreeTuple("MCTeslaTuple") tuple2.Inputs = ['/Event/Tesla/Particles'] tuple2.Decay = tuple.Decay from Configurables import DataOnDemandSvc, L0SelReportsMaker, L0DecReportsMaker DataOnDemandSvc().AlgMap["HltLikeL0/DecReports"] = L0DecReportsMaker() DataOnDemandSvc().AlgMap["HltLikeL0/SelReports"] = L0SelReportsMaker() from Configurables import L0Conf L0Conf().FullL0MuonDecoding = True L0Conf().EnableL0DecodingOnDemand = True
def decay_tree_tuple(name, decay, mothers, intermediate, daughters, inputs, mc): """Return a configured DecayTreeTuple instance. A DecayTreeTuple is configured with the given decay descriptor. The mothers dictionary is used to give exclusive tools to vertices, and it should be, as daughters, a dictionary of tuple branch names to branch descriptors. A typical method call might look like decay_tree_tuple( 'TupleDstToD0pi_D0ToKpi', '[D*(2010)+ -> K- pi+]CC', { 'Dst': '[D*(2010) -> (D0 -> K- pi+) pi+]CC', 'D0': '[D*(2010) -> ^(D0 -> K- pi+) pi+]CC' }, { 'D0_K': '[D*(2010) -> (D0 -> ^K- pi+) pi+]CC', 'D0_pi': '[D*(2010) -> (D0 -> K- ^pi+) pi+]CC', 'Dst_pi': '[D*(2010) -> (D0 -> K- pi+) ^pi+]CC' }, 'Phys/StrippingLineName/Particles' ) Keyword arguments: name -- TDirectory the DecayTreeTuple TTree will be saved in decay -- Decay descriptor mothers -- Branch descriptors to be added to the tuple as mothers; decaying particles daughters -- Branch descriptors to be added to the tuple as daughters; final state particles inputs -- str of list of str, as the value of DecayTreeTuple.Inputs mc -- Extra MC information is included if True """ # Define tuple tools to add tools = [ "TupleToolPropertime", 'TupleToolEventInfo', ] # Extra variables, added using LoKi hybrid tuple tools basic_loki_vars = { 'ETA': 'ETA', 'PHI': 'PHI', 'PT': 'PT', 'ID': 'ID', 'P': 'P', 'Loki_BPVIPCHI2': 'BPVIPCHI2()', 'Loki_MIPCHI2DV': 'MIPCHI2DV(PRIMARY)', } intermediate_loki_vars = { 'Loki_AM34': 'LoKi.Particles.PFunA(AM34)', 'Loki_AM4': 'LoKi.Particles.PFunA(AM4)', 'Loki_BPVDIRA': "BPVDIRA", 'Loki_acosBPVDIRA': "acos(BPVDIRA)", } daughter_loki_vars = { 'PIDK': 'PIDK', 'PIDe': 'PIDe', 'PIDmu': 'PIDmu', 'PIDp': 'PIDp', 'Loki_TRACKCHI2NDOF': 'TRCHI2DOF', 'Loki_TRACKGHOSTPROB': 'TRGHOSTPROB', } mother_loki_vars = { 'M': 'M', 'Loki_BPVVDCHI2': 'BPVVDCHI2', 'Loki_BPVIPCHI2': 'BPVIPCHI2()', 'Loki_DOCAMAX': 'DOCAMAX', 'Loki_AMAXDOCA': "LoKi.Particles.PFunA(AMAXDOCA(''))", 'Loki_AMINDOCA': "LoKi.Particles.PFunA(AMINDOCA(''))", 'Loki_DOCACHI2MAX': 'DOCACHI2MAX', 'Loki_VCHI2NDOF': 'VFASPF(VCHI2/VDOF)', 'Loki_VX': 'VFASPF(VX)', 'Loki_VY': 'VFASPF(VY)', 'Loki_VZ': 'VFASPF(VZ)', 'Loki_SUMPT': 'SUMTREE(PT, ISBASIC)', 'Loki_BPVLTIME': "BPVLTIME()", } # Template DecayTreeTuple t = DecayTreeTuple(name) # Providing str will throw an exception, so wrap it in a list try: t.Inputs = inputs except ValueError: t.Inputs = [inputs] t.Decay = decay # Merge the mother and daughter dictionaries t.addBranches( dict(mothers.items() + intermediate.items() + daughters.items())) # Tools for all branches t.ToolList = tools # Verbose reconstruction information t.addTupleTool('TupleToolANNPID').ANNPIDTunes = ["MC15TuneV1"] # t.addTupleTool('TupleToolRecoStats') # MC truth information if mc: if has_turbo_inputs(t): print 'Adding MC truth information for Turbo' from TeslaTools import TeslaTruthUtils relations = TeslaTruthUtils.getRelLoc("") print 'relations = {}'.format(relations) toollist = ['MCTupleToolPrompt'] rels = [relations] MCTruth = TupleToolMCTruth() #MCTruth.OutputLevel = 1 MCTruth = t.addTupleTool('TupleToolMCTruth') MCTruth.ToolList = toollist MCTruth.addTool(DaVinciSmartAssociator) MCTruth.DaVinciSmartAssociator.RedoNeutral = False MCTruth.DaVinciSmartAssociator.addTool(P2MCPFromProtoP) MCTruth.DaVinciSmartAssociator.P2MCPFromProtoP.Locations = rels MCTruth.addTool(MCMatchObjP2MCRelator) MCTruth.MCMatchObjP2MCRelator.RelTableLocations = rels MCTruth.DaVinciSmartAssociator.addTool(BackgroundCategory) MCTruth.DaVinciSmartAssociator.BackgroundCategory.addTool( P2MCPFromProtoP) MCTruth.DaVinciSmartAssociator.BackgroundCategory.vetoNeutralRedo = True MCTruth.DaVinciSmartAssociator.BackgroundCategory.P2MCPFromProtoP.Locations = rels bkgcat = t.addTupleTool('TupleToolMCBackgroundInfo') bkgcat.addTool(BackgroundCategory) bkgcat.OutputLevel = 10 bkgcat.BackgroundCategory.vetoNeutralRedo = True bkgcat.BackgroundCategory.addTool(P2MCPFromProtoP) bkgcat.BackgroundCategory.P2MCPFromProtoP.Locations = rels t.OutputLevel = 10 else: print 'Adding MC truth information' t.addTupleTool('TupleToolMCTruth') t.addTupleTool('TupleToolMCBackgroundInfo') # Extra information from LoKi hybrid_tt = t.addTupleTool('LoKi::Hybrid::TupleTool/basicLoKiTT') hybrid_tt.Variables = basic_loki_vars hybrid_tt.Preambulo = ['from LoKiTracks.decorators import TrIDC'] # Add mother-specific varaibles to each mother branch for mother in mothers: branch = getattr(t, mother) branch.addTupleTool('LoKi::Hybrid::TupleTool/{0}LoKiTT'.format( mother)).Variables = mother_loki_vars # For some unknown reason this doesn't work with Turbo candidates, so # the information for them has to be added to every branch DictTuple = branch.addTupleTool(LoKi__Hybrid__Dict2Tuple, name="DTFTuple") DictTuple.addTool(DTFDict, name="DTF") DictTuple.Source = "LoKi::Hybrid::DTFDict/DTF" DictTuple.NumVar = 6 * (len(mothers) + len(intermediate) + len(daughters)) # configure the DecayTreeFitter in the usual way DictTuple.DTF.constrainToOriginVertex = True DictTuple.DTF.daughtersToConstrain = ['D0'] DictTuple.DTF.addTool(LoKi__Hybrid__DictOfFunctors, name="dict") DictTuple.DTF.Source = "LoKi::Hybrid::DictOfFunctors/dict" DictTuple.DTF.dict.Variables = { "DTFDict_{}_PT".format(mother): "PT", "DTFDict_{}_ETA".format(mother): "ETA", "DTFDict_{}_PHI".format(mother): "PHI", "DTFDict_{}_P".format(mother): "P", "DTFDict_{}_M".format(mother): "M", } for part, decay in intermediate.items() + daughters.items(): DictTuple.DTF.dict.Variables["DTFDict_{}_PT".format( part)] = "CHILD(PT,'{}')".format(decay) DictTuple.DTF.dict.Variables["DTFDict_{}_ETA".format( part)] = "CHILD(ETA,'{}')".format(decay) DictTuple.DTF.dict.Variables["DTFDict_{}_PHI".format( part)] = "CHILD(PHI,'{}')".format(decay) DictTuple.DTF.dict.Variables["DTFDict_{}_P".format( part)] = "CHILD(P,'{}')".format(decay) DictTuple.DTF.dict.Variables["DTFDict_{}_M".format( part)] = "CHILD(M,'{}')".format(decay) # Add intermediate-specific varaibles to each mother branch mom_int = mother_loki_vars.copy() mom_int.update(intermediate_loki_vars) for mother in intermediate: branch = getattr(t, mother) branch.addTupleTool('LoKi::Hybrid::TupleTool/{0}LoKiTT'.format( mother)).Variables = mom_int # For some unknown reason this doesn't work with Turbo candidates, so # the information for them has to be added to every branch for daughter in daughters: branch = getattr(t, daughter) branch.addTupleTool('LoKi::Hybrid::TupleTool/{0}LoKiTT'.format( daughter)).Variables = daughter_loki_vars return t
def configure_tools(self, toolList = ["TupleToolPropertime", "TupleToolKinematic", "TupleToolGeometry", "TupleToolEventInfo", "TupleToolPrimaries", "TupleToolPid", "TupleToolANNPID", "TupleToolTrackInfo", "TupleToolRecoStats",], mcToolList = ['TupleToolMCTruth', 'TupleToolMCBackgroundInfo', 'MCTupleToolPrompt'], L0List = [], HLT1List = [], HLT2List = [], strippingList = [], headBranch = None, isTrigger = False) : for trigList in L0List, HLT1List, HLT2List, strippingList : for i, trig in enumerate(trigList) : if trig[-8:] != 'Decision' : trigList[i] += 'Decision' for tool in toolList : self.addTupleTool(tool) if mcToolList : ttmc = self.addTupleTool('TupleToolMCTruth') for tool in mcToolList : if tool == 'TupleToolMCTruth' : continue if tool.find('MCTupleTool') == 0 : ttmc.addTupleTool(tool) else : self.addTupleTool(tool) if isTrigger and mcToolList : # Is this right? Or should I pass it the list of sub-tools of TupleToolMCTruth? hlt2line = self.Inputs[0].split('/')[-2] # Need this for 2015 #relations = TeslaTruthUtils.getRelLoc(hlt2line + '/') # This for 2016 ... relations = TeslaTruthUtils.getRelLoc('') TeslaTruthUtils.makeTruth(self, [relations], ttmc.ToolList) if strippingList : ttstrip = self.addTupleTool('TupleToolStripping') ttstrip.TriggerList = strippingList ttstrip.VerboseStripping = True # This doesn't currently work. There doesn't seem to be an easy way # to TISTOS stripping lines currently, which is infuriating. Surely everyone # needs to do this for MC studies? It might be possible to do it using # TESTisTos in a Bender algorithm, or INTES functor. #ttstriptistos = headBranch.addTupleTool('TupleToolTISTOS/tistos_stripping') #ttstriptistos.TriggerTisTosName = 'TESTisTos' #ttstriptistos.TriggerList = [os.path.join(rootInTES, inputLocation)] if L0List or HLT1List or HLT2List : if headBranch == None : headBranch = self ttrig = headBranch.addTupleTool('TupleToolTISTOS') # TupleToolTISTOS can't do stripping this way either. ttrig.TriggerList = L0List + HLT1List + HLT2List ttrig.Verbose = True ttrig.VerboseL0 = True ttrig.VerboseHlt1 = True ttrig.VerboseHlt2 = True
#tlist = ["L0HadronDecision","L0MuonDecision","L0DiMuonDecision","L0ElectronDecision","L0PhotonDecision","Hlt1DiMuonHighMassDecision","Hlt1DiMuonLowMassDecision","Hlt1TrackMuonDecision","Hlt1TrackAllL0Decision","Hlt2DiMuonJPsi","Hlt2IncPhiDecision","Hlt2Topo4BodySimpleDecision","Hlt2Topo3BodySimpleDecision","Hlt2Topo3BodyBBDTDecision","Hlt2Topo2BodySimpleDecision","Hlt2Topo2BodyBBDTDecision","Hlt2Topo4BodyBBDTDecision","Hlt2TopoMu4BodyBBDTDecision","Hlt2IncPhiSidebandsDecision","Hlt2B2HHDecision","Hlt2DiPhiDecision"] tlist = ["Hlt2DiMuonJPsi"] tuple.Decay = "J/psi(1S) -> ^mu+ ^mu-" #tuple.Decay = "[D*(2010)+ -> ^(K*(892)0 -> ^K+ ^pi-) ^pi+]CC" tuple.addTool(TupleToolTrigger, name="TupleToolTrigger") tuple.addTool(TupleToolTISTOS, name="TupleToolTISTOS") # Get trigger info tuple.TupleToolTrigger.Verbose = True tuple.TupleToolTrigger.TriggerList = tlist tuple.TupleToolTISTOS.Verbose = True tuple.TupleToolTISTOS.TriggerList = tlist from TeslaTools import TeslaTruthUtils seq = TeslaTruthUtils.associateSequence("Tesla",False) relations = TeslaTruthUtils.getRelLoc("Tesla") TeslaTruthUtils.makeTruth(tuple, relations, [ "MCTupleToolKinematic" , "MCTupleToolHierarchy" , "MCTupleToolPID" ]) tuple2 = MCDecayTreeTuple("MCTeslaTuple") tuple2.Inputs = ['/Event/Tesla/Particles'] tuple2.Decay = tuple.Decay from Configurables import DataOnDemandSvc, L0SelReportsMaker, L0DecReportsMaker DataOnDemandSvc().AlgMap["HltLikeL0/DecReports"] = L0DecReportsMaker() DataOnDemandSvc().AlgMap["HltLikeL0/SelReports"] = L0SelReportsMaker() from Configurables import L0Conf L0Conf().FullL0MuonDecoding = True L0Conf().EnableL0DecodingOnDemand = True L0Conf().EnsureKnownTCK=False
def execute(simulation=True, turbo=True, decay_descriptor="J/psi(1S) -> mu- mu+"): # Configure all the unpacking, algorithms, tags and input files appConf = ApplicationMgr() appConf.ExtSvc += ['ToolSvc', 'DataOnDemandSvc', LoKiSvc()] ConfigTarFileAccessSvc().File = 'config.tar' dv = DaVinci() dv.DataType = "2012" lhcbApp = LHCbApp() lhcbApp.Simulation = simulation CondDB().Upgrade = False dtt = DecayTreeTuple("Early2015") if turbo: tesla_prefix = "Hlt2DiMuonJPsi" dtt.Inputs = ["/Event/" + tesla_prefix + "/Particles"] dtt.InputPrimaryVertices = "/Event/" + tesla_prefix + "/Primary" dtt.WriteP2PVRelations = False else: LHCbApp().DDDBtag = "dddb-20140729" polarity = "u" LHCbApp().CondDBtag = "sim-20140730-vc-m%s100" % polarity muons = AutomaticData(Location="Phys/StdAllLooseMuons/Particles") jpsi = CombineParticles('MyJPsi') jpsi.DecayDescriptors = [decay_descriptor] jpsi.CombinationCut = "(AM < 7100.0 *GeV)" jpsi.DaughtersCuts = {"": "ALL", "mu+": "ALL", "mu-": "ALL"} jpsi.MotherCut = "(VFASPF(VCHI2/VDOF) < 999999.0)" code = """ ('J/psi(1S)' == ID) & in_range(2.990*GeV, M, 3.210*GeV) & DECTREE('%s') & CHILDCUT(1, HASMUON & ISMUON) & CHILDCUT(2, HASMUON & ISMUON) & (MINTREE('mu+' == ABSID, PT) > 700*MeV) & (MAXTREE(ISBASIC & HASTRACK, TRCHI2DOF) < 5) & (MINTREE(ISBASIC & HASTRACK, CLONEDIST) > 5000) & (VFASPF(VPCHI2) > 0.5/100) & (abs(BPV(VZ)) < 0.5*meter) & (BPV(vrho2) < (10*mm)**2) """ % (decay_descriptor) # similar to the HLT2 line code = """ (ADMASS('J/psi(1S)')< 120*MeV) & DECTREE('%s') & (PT>0*MeV) & (MAXTREE('mu-'==ABSID,TRCHI2DOF) < 4) & (MINTREE('mu-'==ABSID,PT)> 0*MeV) & (VFASPF(VCHI2PDOF)< 25) """ % (decay_descriptor) filter_jpsi = FilterDesktop( "MyFilterJPsi", Code=code, Preambulo=["vrho2 = VX**2 + VY**2"], ReFitPVs=True, #IgnoreP2PVFromInputLocations=True, #WriteP2PVRelations=True ) jpsi_sel = Selection("SelMyJPsi", Algorithm=jpsi, RequiredSelections=[muons]) filter_jpsi_sel = Selection("SelFilterMyJPsi", Algorithm=filter_jpsi, RequiredSelections=[jpsi_sel]) jpsi_seq = SelectionSequence("SeqMyJPsi", TopSelection=filter_jpsi_sel) dtt.Inputs = [jpsi_seq.outputLocation()] # Overwriting default list of TupleTools dtt.ToolList = [ "TupleToolKinematic", "TupleToolPid", "TupleToolEventInfo", "TupleToolMCBackgroundInfo", "TupleToolMCTruth", #"MCTupleToolHierarchy", #"MCTupleToolPID", "TupleToolGeometry", "TupleToolTISTOS", # with turbo this crashes #"TupleToolTrackInfo", "TupleToolTrigger", ] tlist = [ "L0HadronDecision", "L0MuonDecision", "L0DiMuonDecision", "L0ElectronDecision", "L0PhotonDecision", "Hlt1DiMuonHighMassDecision", "Hlt1DiMuonLowMassDecision", "Hlt1TrackMuonDecision", "Hlt1TrackAllL0Decision", "Hlt2DiMuonJPsiDecision", "Hlt2SingleMuonDecision", ] dtt.addTool(TupleToolTrigger, name="TupleToolTrigger") dtt.addTool(TupleToolTISTOS, name="TupleToolTISTOS") # Get trigger info dtt.TupleToolTrigger.Verbose = True dtt.TupleToolTrigger.TriggerList = tlist dtt.TupleToolTISTOS.Verbose = True dtt.TupleToolTISTOS.TriggerList = tlist from Configurables import TupleToolMCTruth, MCTupleToolHierarchy dtt.addTool(TupleToolMCBackgroundInfo, name="TupleToolMCBackgroundInfo") dtt.TupleToolMCBackgroundInfo.Verbose = True dtt.addTool(MCTupleToolHierarchy, name="MCTupleToolHierarchy") dtt.MCTupleToolHierarchy.Verbose = True dtt.addTool(TupleToolMCTruth, name="TupleToolMCTruth") dtt.TupleToolMCTruth.Verbose = True if turbo: assoc_seq = TeslaTruthUtils.associateSequence(tesla_prefix, False) ChargedPP2MC(tesla_prefix + "ProtoAssocPP").OutputLevel = 1 assoc_seq.Members.insert(0, PatLHCbID2MCParticle()) from Configurables import MuonCoord2MCParticleLink muon_coords = MuonCoord2MCParticleLink("TeslaMuonCoordLinker") assoc_seq.Members.insert(1, muon_coords) TrackAssociator("TeslaAssocTr").DecideUsingMuons = True relations = TeslaTruthUtils.getRelLoc(tesla_prefix) else: relations = "Relations/Rec/ProtoP/Charged" TeslaTruthUtils.makeTruth(dtt, relations, [ "MCTupleToolKinematic", "MCTupleToolHierarchy", "MCTupleToolPID", ]) dtt.Decay = mark(2, mark(3, decay_descriptor)) #"J/psi(1S) -> ^mu- ^mu+" dtt.addBranches({ "X": "^(%s)" % (decay_descriptor), "muplus": mark(3, decay_descriptor), #"J/psi(1S) -> mu- ^mu+", "muminus": mark(2, decay_descriptor), #"J/psi(1S) -> ^mu- mu+", }) x_preamble = [ "DZ = VFASPF(VZ) - BPV(VZ)", ] x_vars = { "ETA": "ETA", "Y": "Y", "PHI": "PHI", "VPCHI2": "VFASPF(VPCHI2)", "DELTAZ": "DZ", # DZ * M / PZ / c with c in units of mm/s # XXX should this be the PDG mass or measured mass? #"TZ": "DZ*M / PZ / 299792458000.0", #seconds "TZ": "DZ*3096.916 / PZ/299792458000.0*(10**12)", #ps "minpt": "MINTREE('mu+' == ABSID, PT)", "minclonedist": "MINTREE(ISBASIC & HASTRACK, CLONEDIST)", "maxtrchi2dof": "MAXTREE(ISBASIC & HASTRACK, TRCHI2DOF)", } muon_vars = { "ETA": "ETA", "Y": "Y", "PHI": "PHI", "CHARGE": "Q", "CLONEDIST": "CLONEDIST", "TRCHI2DOF": "TRCHI2DOF", } loki_X = dtt.X.addTupleTool("LoKi::Hybrid::TupleTool/LoKi_X") loki_X.Variables = x_vars loki_X.Preambulo = x_preamble loki_mup = dtt.muplus.addTupleTool("LoKi::Hybrid::TupleTool/LoKi_MuPlus") loki_mup.Variables = muon_vars #dtt.muplus.addTupleTool("TupleToolGeometry") loki_mum = dtt.muminus.addTupleTool("LoKi::Hybrid::TupleTool/LoKi_MuMinus") loki_mum.Variables = muon_vars #dtt.muminus.addTupleTool("TupleToolGeometry") dv.TupleFile = "DVNtuples.root" if turbo: dv.UserAlgorithms = [assoc_seq, dtt] else: assocpp = ChargedPP2MC("TimsChargedPP2MC") assocpp.OutputLevel = 1 dv.UserAlgorithms = [jpsi_seq.sequence(), assocpp, dtt]