From 063d1dad05b4a7fe87d4bca7f85bc81d41bc90fd Mon Sep 17 00:00:00 2001 From: Yi Jiang <y.jiang@cern.ch> Date: Mon, 27 Jan 2025 05:55:03 +0100 Subject: [PATCH 1/2] add B -> D(*s) D(*s) phi data --- Bs2DDphi_Run12/dv_tupling.py | 229 +++++++++++++++++++++++++++++++++++ Bs2DDphi_Run12/info.yaml | 31 +++++ 2 files changed, 260 insertions(+) create mode 100644 Bs2DDphi_Run12/dv_tupling.py create mode 100644 Bs2DDphi_Run12/info.yaml diff --git a/Bs2DDphi_Run12/dv_tupling.py b/Bs2DDphi_Run12/dv_tupling.py new file mode 100644 index 0000000000..6851372fa0 --- /dev/null +++ b/Bs2DDphi_Run12/dv_tupling.py @@ -0,0 +1,229 @@ + +### +from Gaudi.Configuration import * +from Configurables import GaudiSequencer +from Configurables import DaVinci +from Configurables import DecayTreeTuple, CheckPV, SubstitutePID, SubPIDMMFilter, FilterInTrees +from PhysSelPython.Wrappers import AutomaticData, Selection, SelectionSequence, DataOnDemand, MergedSelection +from Configurables import CombineParticles, FilterDesktop, OfflineVertexFitter +from Configurables import DecayTreeTuple, LoKi__Hybrid__TupleTool, TupleToolDecay, TupleToolTrigger, TupleToolTISTOS, TupleToolTagging +from Configurables import FitDecayTrees, TupleToolGeometry +from Configurables import DecayTreeTuple, LoKi__Hybrid__TupleTool, TupleToolDecay, TupleToolTrigger, TupleToolTISTOS, TupleToolTagging, TupleToolRecoStats +from Configurables import FitDecayTrees, TupleToolGeometry +from Configurables import TupleToolDecayTreeFitter +from Configurables import LoKi__Hybrid__EvtTupleTool as LoKiTool +from Configurables import CondDB +from Configurables import TupleToolMCTruth, TupleToolMCBackgroundInfo +from Configurables import LoKi__Hybrid__DictOfFunctors +from Configurables import LoKi__Hybrid__Dict2Tuple +from Configurables import LoKi__Hybrid__DTFDict +# from StandardParticles import StdLooseResolvedPi0 as pi0, StdLoosePhotons as gamma, StdLooseKsLL as KS_LL, StdLooseKsDD as KS_DD, StdAllNoPIDsKaons as Kpi, StdAllNoPIDspions as pipm + + +lines = [ 'B2DDphi_B2DDPhiLine','B2DDphi_B2DsDsPhiLine','B2DDphi_B2DstDpPhiLine','B2DDphi_B2DstDstPhiLine'] + +#hlt filters +from PhysConf.Filters import LoKi_Filters +fltrs = LoKi_Filters(STRIP_Code = "("+"|".join(["HLT_PASS_RE('Stripping{}Decision')".format(line) for line in lines]) +")") +#make the candidates + +# KFromB = FilterInTrees('KFromB', Code="('K+'==ABSID)") +# selKFromB = Selection("selKFromB", +# Algorithm = KFromB, +# RequiredSelections = [DataOnDemand("/Phys/{}/Particles".format(lines[0]))]) + +seqs = [] + +##DecayTree +from DecayTreeTuple.Configuration import * +#Dm Dsp pi pi +def make_dtf(dtt, name, mass_constains, pv): + tup1 = dtt.B.addTupleTool(LoKi__Hybrid__Dict2Tuple, name + "FitTupTuple") + tup1.NumVar = 200 + tup2 = tup1.addTool(LoKi__Hybrid__DTFDict, name + "FitTup") + tup1.Source = "LoKi::Hybrid::DTFDict/"+name+"FitTup" + tup2.constrainToOriginVertex = pv + tup2.daughtersToConstrain = mass_constains # [ "D-", "D_s+", "B0", "phi(1020)"] + tup3 = tup2.addTool(LoKi__Hybrid__DictOfFunctors, name+"FitTupdict") + tup2.Source = "LoKi::Hybrid::DictOfFunctors/"+name+"FitTupdict" + tup3.Variables = {} + for branch, decaychain in dtt.Branches.items(): + for var in ['E','PX','PY','PZ','PT','ETA','M','ID']: + if branch == 'B': + tup3.Variables.update( {"{}_{}".format(branch, var): var}) + else: + tup3.Variables.update( {"{}_{}".format(branch, var): "CHILD({},'{}')".format(var, decaychain)}) + +# tuple.setDescriptorTemplate("${B}[B0 -> ${D1}(D- -> ${D1_K}K+ ${D1_pi1}pi- ${D1_pi2}pi-) ${D2}(D_s+ -> ${D2_K1}K- ${D2_K2}K+ ${D2_pi}pi+) ${phi}(phi(1020) -> ${K1}K+ ${K2}K-)]CC") +#add tools +triglist = [ + "L0DiMuonDecision","L0ElectronDecision","L0ElectronHiDecision", + "L0HadronDecision","L0MuonDecision", + "L0PhotonDecision","L0HadronDecision", + "Hlt1TrackAllL0Decision","Hlt1TrackMVADecision","Hlt1TwoTrackMVADecision", + "Hlt2Topo2BodyBBDTDecision","Hlt2Topo3BodyBBDTDecision","Hlt2Topo4BodyBBDTDecision","Hlt2IncPhiDecision","Hlt2PhiIncPhiDecision", + "Hlt2Topo2BodyDecision","Hlt2Topo3BodyDecision","Hlt2Topo4BodyDecision" + ] +tistos = TupleToolTISTOS('tistos') +tistos.VerboseL0 = True +tistos.VerboseHlt1 = True +tistos.VerboseHlt2 = True +tistos.TriggerList = triglist[:] + +tupletools = ["TupleToolGeometry", + "TupleToolKinematic", + "TupleToolEventInfo", + "TupleToolPid", + "TupleToolTrackInfo", + "TupleToolRecoStats", + "TupleToolMCTruth", + "TupleToolMCBackgroundInfo" + ] + + +def make_tuple(name, location, d1, d2): + ret = DecayTreeTuple( name ) + ret.Inputs = [ location ] + ret.TupleName = "DecayTree" + if d1 == "D": + d1_d = "^(D+ -> ^K- ^pi+ ^pi+)" + d1_n = ["D1_K", "D1_pi1", "D1_pi2"] + elif d1 == "Dst": + d1_d = "^(D*(2010)+ -> ^([D0]CC -> ^K- ^pi+) ^pi+)" + d1_n = ["D1_D", "D1_D_K", "D1_D_pi", "D1_pi"] + elif d1 == "Ds": + d1_d = "^(D_s+ -> ^K- ^K+ ^pi+)" + d1_n = ["D1_K1", "D1_K2", "D1_pi"] + if d2 == "D": + d2_d = "^(D- -> ^K+ ^pi- ^pi-)" + d2_n = ["D2_K", "D2_pi1", "D2_pi2"] + elif d2 == "Dst": + d2_d = "^(D*(2010)- -> ^([D~0]CC -> ^K+ ^pi-) ^pi-)" + d2_n = ["D2_D", "D2_D_K", "D2_D_pi", "D2_pi"] + elif d2 == "Ds": + d2_d = "^(D_s- -> ^K+ ^K- ^pi-)" + d2_n = ["D2_K1", "D2_K2", "D2_pi"] + decay_temp = " [B_s0]CC -> {} {} ^K+ ^K- ".format(d1_d, d2_d) + if d1 == d2: + decay_temp = "^( " + decay_temp + " )" + else: + decay_temp = "^[ " + decay_temp + " ]CC" + names = ['B','D1'] + d1_n + ["D2"]+ d2_n + ["Kp", "Km"] + decay_temp = decay_temp.replace("^", "{{{}}}").format(*names) + + ret.Decay = decay_temp.format(**{k: "^" for k in names}) + ret.addBranches({k1: decay_temp.format(**{k2: "^" if k2 == k1 else "" for k2 in names}) for k1 in names}) + for part in names: + ret.addTupleTool(TupleToolDecay, name = part) + ret.ToolList+=tupletools + ret.B.ToolList = [ "TupleToolPropertime" ] + #TISTOS + ret.B.addTool(tistos) + ret.B.ToolList+=["TupleToolTISTOS/tistos"] + #loki + ret.ReFitPVs = True + LoKi_Lb=LoKi__Hybrid__TupleTool("LoKi_Lb") + LoKi_Lb.Variables = { + "ETA" : "ETA", + "Y" : "Y", + "LOKI_DTF_CTAU" : "DTF_CTAU( 0, True )", + "LOKI_DTF_CHI2NDOF" : "DTF_CHI2NDOF( True )", + "LOKI_DTF_CTAUERR" : "DTF_CTAUERR( 0, True )", + "FDCHI2_BPV" : "BPVVDCHI2", + "FD_BPV" : "BPVVD", + } + ret.B.addTool(LoKi_Lb) + ret.B.ToolList+=["LoKi::Hybrid::TupleTool/LoKi_Lb"] + if False: + tagtuple = ret.B.addTool(TupleToolTagging, name="B0Tag") + ret.B.ToolList+=["TupleToolTagging/B0Tag"] + tagtuple.UseFTfromDST = True # tell TTT to read the FT info from the dst + tagtuple.ActiveTaggerTypes = [ + "OSCharm", + "OSElectron", + "OSElectronLatest", + "OSKaon", + "OSKaonLatest", + "OSMuon", + "OSMuonLatest", + "OSVtxCh", + "SSKaon", + "SSKaonLatest", + "SSPion", + "SSProton", + ] + tagtuple.OutputLevel = 6 + + #DTF + extra_mass = [] + d_m = [] + if d1 == "D" or d2 == "D": + d_m.append("D+") + if d1 == "Ds" or d2 == "Ds": + d_m.append("D_s+") + if d1 == "Dst" or d2 == "Dst": + d_m.append("D0") + extra_mass.append("D*(2010)+") + make_dtf(ret, "PV", [], True) + make_dtf(ret, "PVALL", ["B_s0"] + d_m + extra_mass, True) + make_dtf(ret, "PVDau", d_m + extra_mass, True) + if len(extra_mass) > 0: + make_dtf(ret, "PVDauD0", d_m, True) + make_dtf(ret, "NOPV", [], False) + return ret + + +dtts = [] +for idx, (d1, d2) in enumerate([["D", "D"], ["Ds", "Ds"], ["Dst", "D"], ["Dst", "Dst"]]): + name = "Bs2{}{}Phi".format(d1, d2) + location = "/Phys/{}/Particles".format(lines[idx]) + dtts.append(make_tuple(name, location, d1, d2)) + + +if False: + from Configurables import PrintDecayTree, PrintDecayTreeTool + tree = PrintDecayTree("PrintFoundBs") + tree.Inputs = [ SeqB2DDK.outputLocation() ] + tree.addTool( PrintDecayTreeTool, name = "PrintDecay" ) + tree.PrintDecay.Information = "Name M P Px Py Pz Pt chi2" + DaVinci().MoniSequence += [ tree ] + + + +tuples = dtts + + +from Configurables import CheckPV +checkpv = CheckPV() +from Configurables import TrackScaleState as SCALER +scaler = SCALER('Scaler') +from Configurables import TrackSmearState as SMEAR +smear = SMEAR('Smear') + +###davinci +DaVinci().EvtMax = -1 # Number of events +DaVinci().Simulation = False +DaVinci().Lumi = not DaVinci().Simulation +DaVinci().EventPreFilters = fltrs.filters('Filter') +DaVinci().UserAlgorithms = [ checkpv] +if(DaVinci().Simulation == False): + DaVinci().UserAlgorithms += [scaler]; +else: + DaVinci().UserAlgorithms += [smear] +DaVinci().UserAlgorithms += seqs + tuples + +#DaVinci().TupleFile = "B02DmDspipi.root" +DaVinci().PrintFreq = 1000 +#locationRoot = "/Event/CharmCompleteEvent" +#DaVinci().RootInTES = locationRoot +# DaVinci().InputType = 'DST' + +######################################################################## +MessageSvc().Format = "% F%60W%S%7W%R%T %0W%M" +from Configurables import DaVinciInit, GetIntegratedLuminosity +# DaVinciInit().OutputLevel = 6 +# MessageSvc().OutputLevel = 6 +GetIntegratedLuminosity().OutputLevel = INFO +ToolSvc().OutputLevel = 6 +NTupleSvc().OutputLevel = 6 + diff --git a/Bs2DDphi_Run12/info.yaml b/Bs2DDphi_Run12/info.yaml new file mode 100644 index 0000000000..c60e47097b --- /dev/null +++ b/Bs2DDphi_Run12/info.yaml @@ -0,0 +1,31 @@ +defaults: + application: DaVinci/v46r11 + wg: B2OC + automatically_configure: yes + turbo: no + inform: + - y.jiang@cern.ch + +# Real data (collision) +{%- set collision_datasets2 = [ + ('11', '3500', '14', '21r1'), + ('12', '4000', '14', '21'), + ('15', '6500', '15a', '24r2'), + ('16', '6500', '16', '28r2'), + ('17', '6500', '17', '29r2'), + ('18', '6500', '18', '34'), +]%} + +{%- for year, beam, reco, strip in collision_datasets2 %} + {%- for polarity in ['MagDown','MagUp'] %} +20{{year}}_{{polarity}}_collision_Bs2DDPhi: + input: + bk_query: /LHCb/Collision{{year}}/Beam{{beam}}GeV-VeloClosed-{{polarity}}/Real Data/Reco{{reco}}/Stripping{{strip}}/90000000/BHADRON.MDST + n_test_lfns: 1 + options: + - dv_tupling.py + output: Bs2DDPhi.ROOT + root_in_tes: /Event/Bhadron + {%- endfor %} +{%- endfor %} + -- GitLab From a116dd157510fd6ab196b8b8d8aa776e820d7427 Mon Sep 17 00:00:00 2001 From: Yi Jiang <y.jiang@cern.ch> Date: Tue, 28 Jan 2025 04:45:58 +0100 Subject: [PATCH 2/2] add more cuts to reduce output size --- Bs2DDphi_Run12/dv_tupling.py | 67 ++++++++++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 6 deletions(-) diff --git a/Bs2DDphi_Run12/dv_tupling.py b/Bs2DDphi_Run12/dv_tupling.py index 6851372fa0..238042ac36 100644 --- a/Bs2DDphi_Run12/dv_tupling.py +++ b/Bs2DDphi_Run12/dv_tupling.py @@ -27,7 +27,44 @@ from PhysConf.Filters import LoKi_Filters fltrs = LoKi_Filters(STRIP_Code = "("+"|".join(["HLT_PASS_RE('Stripping{}Decision')".format(line) for line in lines]) +")") #make the candidates -# KFromB = FilterInTrees('KFromB', Code="('K+'==ABSID)") +KFromB = FilterInTrees('KFromB', Code="('K+'==ABSID)") +DFromB = FilterInTrees('DFromB', Code="('D+'==ABSID)|('D_s+'==ABSID)|('D*(2010)+'==ABSID)") + +_phi = CombineParticles('comb_phi', + DecayDescriptors=["phi(1020) -> K+ K-"], + CombinationCut="(AM<1100*MeV) & (ADOCACHI2CUT(30, ''))", + MotherCut="(VFASPF(VCHI2) < 25.0)", + DaughtersCuts = {'K+': "ALL",'K-': "ALL"}, + ReFitPVs = True) + +combine_b = {"DD": + CombineParticles('comb_B1', + DecayDescriptors=["B_s0 -> D+ D- phi(1020)"], + CombinationCut="(AM<5800*MeV)", + MotherCut="(VFASPF(VCHI2/VDOF) < 15) & (BPVDIRA > 0.999) & (BPVLTIME() > 0.2*ps)", + DaughtersCuts = {'D+': "ALL",'D-': "ALL", "phi(1020)": "ALL"}, + ReFitPVs = True), + "DsDs": CombineParticles('comb_B2', + DecayDescriptors=["B_s0 -> D_s+ D_s- phi(1020)"], + CombinationCut="(AM<5800*MeV)", + MotherCut="(VFASPF(VCHI2/VDOF) < 15) & (BPVDIRA > 0.999) & (BPVLTIME() > 0.2*ps)", + DaughtersCuts = {'D_s+': "ALL",'D_s-': "ALL", "phi(1020)": "ALL"}, + ReFitPVs = True), + "DstD":CombineParticles('comb_B3', + DecayDescriptors=["[B_s0 -> D*(2010)+ D- phi(1020)]cc"], + CombinationCut="(AM<5800*MeV)", + MotherCut="(VFASPF(VCHI2/VDOF) < 15) & (BPVDIRA > 0.999) & (BPVLTIME() > 0.2*ps)", + DaughtersCuts = {'D*(2010)+': "ALL",'D-': "ALL", "phi(1020)": "ALL"}, + ReFitPVs = True), + "DstDst": CombineParticles('comb_B4', + DecayDescriptors=["B_s0 -> D*(2010)+ D*(2010)- phi(1020)"], + CombinationCut="(AM<5800*MeV)", + MotherCut="(VFASPF(VCHI2/VDOF) < 15) & (BPVDIRA > 0.999) & (BPVLTIME() > 0.2*ps)", + DaughtersCuts = {'D*(2010)+': "ALL",'D*(2010)-': "ALL", "phi(1020)": "ALL"}, + ReFitPVs = True) +} + + # selKFromB = Selection("selKFromB", # Algorithm = KFromB, # RequiredSelections = [DataOnDemand("/Phys/{}/Particles".format(lines[0]))]) @@ -82,8 +119,22 @@ tupletools = ["TupleToolGeometry", def make_tuple(name, location, d1, d2): + data_in_line = DataOnDemand(location) + sel_k = Selection( name+"_K", + Algorithm = KFromB , + RequiredSelections = [ data_in_line ] ) + sel_d = Selection( name+"_D", + Algorithm = DFromB , + RequiredSelections = [ data_in_line ] ) + sel_phi = Selection( name+"_phi", + Algorithm = _phi , + RequiredSelections = [sel_k ] ) + sel_b = Selection( name+"_B", + Algorithm = combine_b[d1+d2] , + RequiredSelections = [sel_d, sel_phi ] ) + seq = SelectionSequence("Seq" +name, TopSelection = sel_b) ret = DecayTreeTuple( name ) - ret.Inputs = [ location ] + ret.Inputs = [seq.outputLocation() ] ret.TupleName = "DecayTree" if d1 == "D": d1_d = "^(D+ -> ^K- ^pi+ ^pi+)" @@ -103,12 +154,12 @@ def make_tuple(name, location, d1, d2): elif d2 == "Ds": d2_d = "^(D_s- -> ^K+ ^K- ^pi-)" d2_n = ["D2_K1", "D2_K2", "D2_pi"] - decay_temp = " [B_s0]CC -> {} {} ^K+ ^K- ".format(d1_d, d2_d) + decay_temp = " [B_s0]CC -> {} {} ^(phi(1020) -> ^K+ ^K-) ".format(d1_d, d2_d) if d1 == d2: decay_temp = "^( " + decay_temp + " )" else: decay_temp = "^[ " + decay_temp + " ]CC" - names = ['B','D1'] + d1_n + ["D2"]+ d2_n + ["Kp", "Km"] + names = ['B','D1'] + d1_n + ["D2"]+ d2_n + ["phi", "Kp", "Km"] decay_temp = decay_temp.replace("^", "{{{}}}").format(*names) ret.Decay = decay_temp.format(**{k: "^" for k in names}) @@ -166,18 +217,22 @@ def make_tuple(name, location, d1, d2): extra_mass.append("D*(2010)+") make_dtf(ret, "PV", [], True) make_dtf(ret, "PVALL", ["B_s0"] + d_m + extra_mass, True) + make_dtf(ret, "PVALLphi", ["B_s0", "phi(1020)"] + d_m + extra_mass, True) make_dtf(ret, "PVDau", d_m + extra_mass, True) + make_dtf(ret, "PVDauphi", ["phi(1020)"] + d_m + extra_mass, True) if len(extra_mass) > 0: make_dtf(ret, "PVDauD0", d_m, True) make_dtf(ret, "NOPV", [], False) - return ret + return seq, ret dtts = [] for idx, (d1, d2) in enumerate([["D", "D"], ["Ds", "Ds"], ["Dst", "D"], ["Dst", "Dst"]]): name = "Bs2{}{}Phi".format(d1, d2) location = "/Phys/{}/Particles".format(lines[idx]) - dtts.append(make_tuple(name, location, d1, d2)) + seq, tup = make_tuple(name, location, d1, d2) + seqs.append(seq) + dtts.append(tup) if False: -- GitLab