From b1d808fcd5bb87d7c69bba0b2f9e02be84968a72 Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <chinghua@lxplus710.cern.ch> Date: Thu, 15 Feb 2024 13:40:12 +0100 Subject: [PATCH 01/57] Add D02KK MC production for starterkit --- D02HH_Practice/README.md | 1 + D02HH_Practice/info.yaml | 14 ++++++++++++ D02HH_Practice/ntuple_options.py | 38 ++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 D02HH_Practice/README.md create mode 100644 D02HH_Practice/info.yaml create mode 100755 D02HH_Practice/ntuple_options.py diff --git a/D02HH_Practice/README.md b/D02HH_Practice/README.md new file mode 100644 index 0000000000..518eb21598 --- /dev/null +++ b/D02HH_Practice/README.md @@ -0,0 +1 @@ +I want weed diff --git a/D02HH_Practice/info.yaml b/D02HH_Practice/info.yaml new file mode 100644 index 0000000000..510dce396d --- /dev/null +++ b/D02HH_Practice/info.yaml @@ -0,0 +1,14 @@ +defaults: + application: DaVinci/v46r10 + wg: Charm + automatically_configure: yes + turbo: no + inform: + - chinghua@cern.ch + options: + - ntuple_options.py + output: D02KK.ROOT + +2016_MagDown_PromptMC_D02KK: + input: + bk_query: "/MC/2016/Beam6500GeV-2016-MagDown-Nu1.6-25ns-Pythia8/Sim09c/Trig0x6138160F/Reco16/Turbo03/Stripping28r1NoPrescalingFlagged/27163002/ALLSTREAMS.DST" diff --git a/D02HH_Practice/ntuple_options.py b/D02HH_Practice/ntuple_options.py new file mode 100755 index 0000000000..0297e5cc85 --- /dev/null +++ b/D02HH_Practice/ntuple_options.py @@ -0,0 +1,38 @@ +from Configurables import DecayTreeTuple + +## Specify the stream and stripping line +stream = "AllStreams" +line = "D2hhPromptDst2D2KKLine" + +## We create the DecayTreeTuple object, and indicate the Input +## (i.e., the TES location where the desired candidates may be) +## as well as the decay descriptor +dtt = DecayTreeTuple("TupleDstToD0pi_D0ToKK") +dtt.Inputs = ["/Event/{0}/Phys/{1}/Particles".format(stream, line)] +dtt.Decay = "[D*(2010)+ -> (D0 -> K- K+) pi+]CC" + +from Configurables import DaVinci + +DaVinci().UserAlgorithms += [dtt] + +# In general, thanks to using the automatically_configure setting, you don't need what's below so it can be removed +""" +DaVinci().InputType = "DST" +DaVinci().TupleFile = "DVntuple.root" +DaVinci().PrintFreq = 1000 +DaVinci().DataType = "2016" +DaVinci().Simulation = True +DaVinci().Lumi = not DaVinci().Simulation +DaVinci().EvtMax = -1 +DaVinci().CondDBtag = "sim-20170721-2-vc-md100" +DaVinci().DDDBtag = "dddb-20170721-3" +""" + +# The Analysis Productions software automatically finds a valid remote file to test on so we can drop this bit +""" +from GaudiConf import IOHelper + +IOHelper().inputFiles([ + "./00070793_00000001_7.AllStreams.dst" +], clear=True) +""" \ No newline at end of file -- GitLab From 7bfcaf775f07203a40d312225c8f26270fdbb3ef Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <chinghua@lxplus710.cern.ch> Date: Thu, 15 Feb 2024 13:50:51 +0100 Subject: [PATCH 02/57] test --- D02HH_Practice/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/D02HH_Practice/README.md b/D02HH_Practice/README.md index 518eb21598..cc34fb0b7a 100644 --- a/D02HH_Practice/README.md +++ b/D02HH_Practice/README.md @@ -1 +1 @@ -I want weed +I want weed XDDDD -- GitLab From b5cb213ea22c8fd13517218df27df0b2e65c5128 Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <chinghua@lxplus710.cern.ch> Date: Thu, 15 Feb 2024 14:10:52 +0100 Subject: [PATCH 03/57] test check --- D02HH_Practice/info.yaml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/D02HH_Practice/info.yaml b/D02HH_Practice/info.yaml index 510dce396d..dbe57daefb 100644 --- a/D02HH_Practice/info.yaml +++ b/D02HH_Practice/info.yaml @@ -8,7 +8,31 @@ defaults: options: - ntuple_options.py output: D02KK.ROOT +checks: + histogram: + type: range + expression: Dst_2010_plus_M + limits: + min: 1900 + max: 2300 + blind_ranges: + min: 2000 + max: 2020 + histogram_fail: + type: range + expression: Dst_2010_plus_M + limits: + min: 0 + max: 10 + at_least_50_entries: + type: num_entries + tree_pattern: TupleDstToD0pi_D0ToKK/DecayTree + count: 50 2016_MagDown_PromptMC_D02KK: input: bk_query: "/MC/2016/Beam6500GeV-2016-MagDown-Nu1.6-25ns-Pythia8/Sim09c/Trig0x6138160F/Reco16/Turbo03/Stripping28r1NoPrescalingFlagged/27163002/ALLSTREAMS.DST" + checks: + - histogram + - histogram_fail + - at_least_50_entries -- GitLab From 103ceab929520ca10b1667e20d0ac87626eb0503 Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Mon, 6 May 2024 11:39:24 +0200 Subject: [PATCH 04/57] Add RDstar_taue production for 2024 data checking --- RDstar_taue_2024data/info.yaml | 43 +++++ RDstar_taue_2024data/run_Dzl.py | 311 ++++++++++++++++++++++++++++++++ 2 files changed, 354 insertions(+) create mode 100644 RDstar_taue_2024data/info.yaml create mode 100644 RDstar_taue_2024data/run_Dzl.py diff --git a/RDstar_taue_2024data/info.yaml b/RDstar_taue_2024data/info.yaml new file mode 100644 index 0000000000..2681a0a72b --- /dev/null +++ b/RDstar_taue_2024data/info.yaml @@ -0,0 +1,43 @@ +checks: + hist_Sb_M: + type: range + expression: Sb_M + limits: + min: 2_000 + max: 8_000 + n_bins: 100 + +defaults: + application: "DaVinci/v64r4" + output: DATA.ROOT + options: + entrypoint: RDstar_taue_2024data.run_Dzl:main + extra_options: + input_raw_format: 0.5 + input_type: ROOT # ROOT for SprucingPass, RAW for RAW data (Hlt2 output) + simulation: False + data_type: "Upgrade" + geometry_version: run3/2024.Q1.2-v00.00 + conditions_version: master + input_process: "Spruce" # Spruce for SprucingPass, "Hlt2" for RAW data (Hlt2 output) + input_stream: "sl" # for streamed data + evt_max: 1000 + inform: + - ching-hua.li@cern.ch + wg: SL + +{%- set datasets = [ + ('2024Data', 'Down'), +]%} +{%- for evttype, polarity in datasets %} +RDstar_taue_{{ evttype }}_{{ polarity }}: + input: + bk_query: "/LHCb/Collision24/Beam6800GeV-VeloClosed-Mag{{ polarity }}-Excl-UT/Real Data/Sprucing24c1/90000000/SL.DST" + dq_flags: + - UNCHECKED + - OK + keep_running: true + n_test_lfns: 1 + checks: + - hist_Sb_M +{%- endfor %} diff --git a/RDstar_taue_2024data/run_Dzl.py b/RDstar_taue_2024data/run_Dzl.py new file mode 100644 index 0000000000..56c3ea074d --- /dev/null +++ b/RDstar_taue_2024data/run_Dzl.py @@ -0,0 +1,311 @@ +import sys,os,math +from PyConf.reading import get_pvs, get_rec_summary, get_particles +import Functors as F +from FunTuple import FunctorCollection +from FunTuple import FunTuple_Particles as Funtuple +from DaVinci.algorithms import create_lines_filter +from DaVinci import Options,make_config +import FunTuple.functorcollections as FC +from DaVinciMCTools import MCTruthAndBkgCat +from Hlt2Conf.algorithms_thor import ParticleCombiner, ParticleFilter +from Hlt2Conf.algorithms_thor import ParticleContainersMerger +from Functors.grammar import Functor +from Hlt2Conf.standard_particles import make_has_rich_long_pions,make_has_rich_up_pions,make_has_rich_down_pions + +_BPVCORRM = Functor('_BPVCORRM', 'Composite::CorrectedMass','Compute the corrected mass') +_allpv_FDVEC = (F.ENDVERTEX_POS @ F.FORWARDARG1 - F.TOLINALG @ F.POSITION @ F.FORWARDARG0) +_allpv_NORMEDDOT = F.NORMEDDOT.bind(F.THREEMOMENTUM @ F.FORWARDARG1, _allpv_FDVEC) +#ALLPV_CHI2 = lambda Vertices: F.MAP(F.CHI2) @ F.TES(Vertices) +#ALLPV_CHI2DOF = lambda Vertices: F.MAP(F.CHI2DOF) @ F.TES(Vertices) +ALLPV_IPCHI2 = lambda Vertices: F.MAP(F.IPCHI2).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_FDCHI2 = lambda Vertices: F.MAP(F.VTX_FDCHI2).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_DIRA = lambda Vertices: F.MAP(_allpv_NORMEDDOT).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_CORRM = lambda Vertices: F.MAP(_BPVCORRM).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_LTIME = lambda Vertices: F.MAP(F.VTX_LTIME).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_DLS = lambda Vertices: F.MAP(F.VTX_DLS).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_FD_COORDINATE = lambda coordinate, Vertices: F.MAP(coordinate @ _allpv_FDVEC).bind(F.TES(Vertices), F.FORWARDARGS) +#MCNEUTRINO = F.FIND_MCDECAY("[ Lambda_b0 => Lambda_c+ mu- ^nu_mu~ ]CC") + +TRUE_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.PARTICLE_ID) == id) +#MCMOTHER_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.MC_MOTHER(1, F.PARTICLE_ID)) == id) +#GD_MCMOTHER_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.MC_MOTHER(2, F.PARTICLE_ID)) == id) +#GD_GD_MCMOTHER_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.MC_MOTHER(3, F.PARTICLE_ID)) == id) + +def make_Bst(B, pions,lepton, hadron_candidate_id,v2_pvs,do_truth_matching = True): + if do_truth_matching == True : + #filter B keeping only true D0 and true leptons + MCTRUTH_B = MCTruthAndBkgCat(B, name='MCTRUTH_Bu') + Dz_child = F.CHILD(1, F.FORWARDARG0) #get the first child of B*- which is D0 + lep_child = F.CHILD(2, F.FORWARDARG0) #get the second child of B*- which is lepton + Dz_truth_cut = TRUE_ID_IS(hadron_candidate_id, MCTRUTH_B) @ Dz_child #require that D0 is true + lep_truth_cut = F.require_any(TRUE_ID_IS(11, MCTRUTH_B) @ lep_child , TRUE_ID_IS(13, MCTRUTH_B) @ lep_child) #require that lepton is true i.e. electron or muon + cut_b = F.require_all(Dz_truth_cut, lep_truth_cut) #make a cut + signal_B = ParticleFilter(Input=B, Cut=F.FILTER(cut_b), name='signal_Dzmu') #filter the B candidates + else : signal_B = B + + #combine to make [B*0 -> B*- pi+]cc + Bst_1 = ParticleCombiner( + Inputs=[B, pions], + name=f'Bst_1_{lepton}', + DecayDescriptor='[B0 -> B- pi+]cc', + CombinationCut=F.ALL, + CompositeCut=F.ALL, + ParticleCombiner="ParticleVertexFitter", + PrimaryVertices=v2_pvs + #OutputLevel=1 + ) + #combine to make [B*0 -> B*- pi-]cc + Bst_2 = ParticleCombiner( + Inputs=[B, pions], + name=f'Bst_2_{lepton}', + DecayDescriptor='[B0 -> B- pi-]cc', + CombinationCut=F.ALL, + CompositeCut=F.ALL, + ParticleCombiner="ParticleVertexFitter", + PrimaryVertices=v2_pvs + #OutputLevel=1 + ) + #merge the two Bst candidates + Bst = ParticleContainersMerger([Bst_1, Bst_2], name = f'Bst_combiner_{lepton}') + return Bst + +def get_functors(MCTRUTH, v2_pvs, rec_summary): + #define common variables for all fields (composite and basic) + vars_common = FunctorCollection() + #all pvs: ip, ipchi2. The PV positions are stored in event variables + vars_common['ALLPV_IP[pv_indx]'] = F.ALLPV_IP(v2_pvs) + vars_common['ALLPV_IPCHI2[pv_indx]'] = ALLPV_IPCHI2(v2_pvs) + #best pv: x, y, z, ip, ipchi2 + vars_common['BPV_X'] = F.BPVX(v2_pvs) + vars_common['BPV_Y'] = F.BPVY(v2_pvs) + vars_common['BPV_Z'] = F.BPVZ(v2_pvs) + vars_common['BPV_IP'] = F.BPVIP(v2_pvs) + vars_common['BPV_IPCHI2'] = F.BPVIPCHI2(v2_pvs) + vars_common['BPV_CHI2'] = F.CHI2 @ F.BPV(v2_pvs) + vars_common['BPV_CHI2DOF'] = F.CHI2DOF @ F.BPV(v2_pvs) + #particle id, key, truekey. The trueid is stored in MCHierarchy + vars_common['ID'] = F.PARTICLE_ID + vars_common['KEY'] = F.OBJECT_KEY + #get charge, min ip and min ipchi2 + vars_common['CHARGE'] = F.CHARGE + vars_common['MINIP'] = F.MINIP(v2_pvs) + vars_common['MINIPCHI2'] = F.MINIPCHI2(v2_pvs) + #reco kinematics + vars_common += FC.Kinematics() + vars_common['ETA'] = F.ETA + vars_common['PHI'] = F.PHI + if MCTRUTH != 'None': + #mc vars + vars_common['TRUEKEY'] = F.VALUE_OR(-1) @ MCTRUTH(F.OBJECT_KEY) + vars_common += FC.MCKinematics(mctruth_alg = MCTRUTH) + vars_common['TRUEETA'] = MCTRUTH(F.ETA) + vars_common['TRUEPHI'] = MCTRUTH(F.PHI) + #type of the origin vertex + vars_common['MC_VTX_TYPE'] = MCTRUTH(F.VALUE_OR(-1) @ F.MC_VTX_TYPE @ F.MC_ORIGINVERTEX) + ##mc truth hierarchy (done seperately) + #vars_common += FC.MCHierarchy(mctruth_alg = MCTRUTH) + #make some helper functions + MCMOTHER_ID = lambda n: F.VALUE_OR(0) @ MCTRUTH(F.MC_MOTHER(n, F.PARTICLE_ID)) + MCMOTHER_KEY = lambda n: F.VALUE_OR(-1) @ MCTRUTH(F.MC_MOTHER(n, F.OBJECT_KEY )) + vars_common["TRUEID"] = F.VALUE_OR(0) @ MCTRUTH(F.PARTICLE_ID) + vars_common["MCKEY"] = F.VALUE_OR(0) @ MCTRUTH(F.OBJECT_KEY) + vars_common["MC_MOTHER_ID"] = MCMOTHER_ID(1) + vars_common["MC_MOTHER_KEY"] = MCMOTHER_KEY(1) + for i in range(2,14): + prefix = "MC_GD_MOTHER_{}".format(i) + vars_common[f"{prefix}_ID"] = MCMOTHER_ID(i) + vars_common[f"{prefix}_KEY"] = MCMOTHER_KEY(i) + + #variables for composite particles + vars_composite = FunctorCollection() + #end vertex position and end vertex chi2 + vars_composite['ENDVERTEX_POS_'] = F.ENDVERTEX_POS + vars_composite['ENDVERTEX_CHI2'] = F.CHI2 @ F.ENDVERTEX + vars_composite['ENDVERTEX_CHI2DOF'] = F.CHI2DOF @ F.ENDVERTEX + #all pvs: dira, fd, fdchi2 + vars_composite['ALLPV_DIRA[pv_indx]'] = ALLPV_DIRA(v2_pvs) + vars_composite['ALLPV_FD_X[pv_indx]'] = ALLPV_FD_COORDINATE(F.X_COORDINATE, v2_pvs) + vars_composite['ALLPV_FD_Y[pv_indx]'] = ALLPV_FD_COORDINATE(F.Y_COORDINATE, v2_pvs) + vars_composite['ALLPV_FD_Z[pv_indx]'] = ALLPV_FD_COORDINATE(F.Z_COORDINATE, v2_pvs) + vars_composite['ALLPV_FDCHI2[pv_indx]'] = ALLPV_FDCHI2(v2_pvs) + vars_composite['ALLPV_CORRM[pv_indx]'] = ALLPV_CORRM(v2_pvs) + vars_composite['ALLPV_LTIME[pv_indx]'] = ALLPV_LTIME(v2_pvs) + vars_composite['ALLPV_DLS[pv_indx]'] = ALLPV_DLS(v2_pvs) + #best pv: dira, fd, fdchi2, corrm, ltime, dls + vars_composite['BPV_DIRA'] = F.BPVDIRA(v2_pvs) + vars_composite['BPV_FD_'] = F.BPVFDVEC(v2_pvs) + vars_composite['BPV_FDCHI2'] = F.BPVFDCHI2(v2_pvs) + vars_composite['BPV_CORRM'] = F.BPVCORRM(v2_pvs) + vars_composite['BPV_LTIME'] = F.BPVLTIME(v2_pvs) + vars_composite['BPV_DLS'] = F.BPVDLS(v2_pvs) + #mc composite vertex information + + if MCTRUTH != 'None': vars_composite += FC.MCVertexInfo(mctruth_alg = MCTRUTH) + #Compute maximum DOCA and maximum DOCACHI2. Since there are + # only two daughters of Sb particles, the maximum DOCA/DOCACHI2 is + # the DOCA/DOCACHI2 see below. + vars_composite['MAX_DOCA'] = F.MAXDOCA + vars_composite['MAX_DOCACHI2'] = F.MAXDOCACHI2 + vars_composite['MAX_SDOCA'] = F.MAXSDOCA + vars_composite['MAX_SDOCACHI2'] = F.MAXSDOCACHI2 + + #variables for Lb field + var_B = FunctorCollection() + #var_B['TRUENU_PX'] = MCTRUTH(F.PX @ MCNEUTRINO) + #var_B['TRUENU_PY'] = MCTRUTH(F.PY @ MCNEUTRINO) + #var_B['TRUENU_PZ'] = MCTRUTH(F.PZ @ MCNEUTRINO) + #var_B['TRUENU_ENERGY'] = MCTRUTH(F.ENERGY @ MCNEUTRINO) + ###Bkg category + ##var_B["BKGCAT"] = MCTRUTH.BkgCat + + #variables for basics + vars_basic = FunctorCollection() + vars_basic['TRACKTYPE'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKTYPE @ F.TRACK + vars_basic['TRACKHISTORY'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKHISTORY @ F.TRACK + vars_basic['TRACKFLAG'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKFLAG @ F.TRACK + vars_basic['TRACKNDOF'] = F.VALUE_OR(-1) @ F.NDOF @ F.TRACK + vars_basic['TRACKCHI2'] = F.CHI2 @ F.TRACK + vars_basic['TRACKCHI2DOF'] = F.CHI2DOF @ F.TRACK + vars_basic['GHOSTPROB'] = F.GHOSTPROB + vars_basic['PIDpi'] = F.PID_PI + vars_basic['PIDk'] = F.PID_K + vars_basic['PIDp'] = F.PID_P + vars_basic['PIDe'] = F.PID_E + vars_basic['PIDmu'] = F.PID_MU + if MCTRUTH != 'None': + vars_basic['TRUEORIGINVERTEX_X'] = MCTRUTH(F.ORIGIN_VX) + vars_basic['TRUEORIGINVERTEX_Y'] = MCTRUTH(F.ORIGIN_VY) + vars_basic['TRUEORIGINVERTEX_Z'] = MCTRUTH(F.ORIGIN_VZ) + + #variables for event + evt_vars = FunctorCollection() + #evt_vars['ALLPV_X[pv_indx]'] = F.ALLPVX(v2_pvs) + #evt_vars['ALLPV_Y[pv_indx]'] = F.ALLPVY(v2_pvs) + #evt_vars['ALLPV_Z[pv_indx]'] = F.ALLPVZ(v2_pvs) + #evt_vars['ALLPV_CHI2[pv_indx]'] = ALLPV_CHI2(v2_pvs) + #evt_vars['ALLPV_CHI2DOF[pv_indx]']= ALLPV_CHI2DOF(v2_pvs) + evt_vars['nTracks'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nTracks") + evt_vars['nLongTracks'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nLongTracks") + evt_vars['nPVs'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nPVs") + + #return all functors + functors = (vars_common, vars_composite, var_B, vars_basic, evt_vars) + return functors + +def tuple_Bst(Bst,lepton, MCTRUTH, v2_pvs, rec_summary): + #get functors + functors = get_functors(MCTRUTH, v2_pvs, rec_summary) + vars_common = functors[0] + vars_composite = functors[1] + var_B = functors[2] + vars_basic = functors[3] + evt_vars = functors[4] + + #variables for Sb field + vars_Bst = FunctorCollection() + B_child = F.CHILD(1, F.FORWARDARG0) + Epi_child = F.CHILD(2, F.FORWARDARG0) + bpv_pi = F.BPV(v2_pvs).bind(Epi_child) + #diff in vtx chi2 with and without extra particle + vars_Bst['DELTA_ENDVERTEX_CHI2'] = (F.CHI2 @ F.ENDVERTEX) - (F.CHI2 @ F.ENDVERTEX.bind(B_child)) + #IP and IPChi2 of extra particle wrt to Sb end vertex + vars_Bst['Epi_IP_WRT_SbENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ F.FORWARDARG0 , Epi_child) + vars_Bst['Epi_IPCHI2_WRT_SbENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ F.FORWARDARG0 , Epi_child) + #IP and IPChi2 of extra particle wrt to Lb end vertex + vars_Bst['Epi_IP_WRT_LbENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ B_child , Epi_child) + vars_Bst['Epi_IPCHI2_WRT_LbENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ B_child , Epi_child) + #angle between extra particle and Lb + vars_Bst['Epi_COSANGLE_Lb'] = F.COSANGLE.bind(F.THREEMOMENTUM @ B_child, F.THREEMOMENTUM @ Epi_child) + #diff in fd chi2 with and without extra particle + vars_Bst['Delta_BPV_of_Epi_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi, F.FORWARDARGS) - F.VTX_FDCHI2.bind(bpv_pi, B_child) + vars_Bst['BPV_of_Epi_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi, F.FORWARDARGS) + #IP chi2 of extra particle wrt PV and SV of Sb + vars_Bst['Epi_IP_WRT_SbBPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child) + vars_Bst['Epi_IPCHI2_WRT_SbBPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child) + #IP chi2 of extra particle wrt PV and SV of Bb + vars_Bst['Epi_IP_WRT_LbBPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ B_child, Epi_child) + vars_Bst['Epi_IPCHI2_WRT_LbBPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ B_child, Epi_child) + #DOCA and DOCACHI2 b/w Lb and extra particle + vars_Bst['DOCA12'] = F.DOCA(1, 2) + vars_Bst['DOCA12_CHI2_12'] = F.DOCACHI2(1, 2) + #vars_Bst['SDOCA12'] = F.SDOCA(1, 2) + #vars_Bst['SDOCA_CHI2_12'] = F.SDOCACHI2(1, 2) + #DOCACHI2 of extra particle wrt to mother i.e. Sb + vars_Bst['MTDOCACHI2_1'] = F.MTDOCACHI2(1, v2_pvs) + vars_Bst['MTDOCACHI2_2'] = F.MTDOCACHI2(2, v2_pvs) + + #define fields + fields = {} + fields['Sb'] = f'[B0 -> (B- -> (D0 -> K- pi+) e-) [pi+]CC]CC' + fields['Lb'] = f'[B0 -> ^(B- -> (D0 -> K- pi+) e-) [pi+]CC]CC' + fields['Lc'] = f'[B0 -> (B- -> ^(D0 -> K- pi+) e-) [pi+]CC]CC' + fields['Lep'] = f'[B0 -> (B- -> (D0 -> K- pi+) ^e-) [pi+]CC]CC' + fields['Epi'] = f'[B0 -> (B- -> (D0 -> K- pi+) e-) ^[pi+]CC]CC' + fields['Km'] = f'[B0 -> (B- -> (D0 -> ^K- pi+) e-) [pi+]CC]CC' + fields['pip'] = f'[B0 -> (B- -> (D0 -> K- ^pi+) e-) [pi+]CC]CC' + + #add variables + variables = {} + variables["ALL"] = vars_common + variables["Sb"] = vars_composite + vars_Bst + variables["Lb"] = vars_composite + var_B + variables["Lc"] = vars_composite + variables["Lep"] = vars_basic + variables["Epi"] = vars_basic + variables["Km"] = vars_basic + variables["pip"] = vars_basic + + #define tuple + my_tuple = Funtuple( + name=f"Tuple_{lepton}", + tuple_name="DecayTree", + fields=fields, + variables=variables, + inputs=Bst) + + return my_tuple + +def get_extra_pions(): + """ + Note this function in DaVinci requires: + https://gitlab.cern.ch/lhcb/Moore/-/merge_requests/3203 + and it's related LHCb, DaVinci and Rec MRs + """ + long_pions = make_has_rich_long_pions() + up_pions = make_has_rich_up_pions() + down_pions = make_has_rich_down_pions() + return ParticleContainersMerger([long_pions, up_pions, down_pions], + name='Pions_combiner') + +#def main(options): +def main(options: Options): + line_name = ['SpruceSLB_BuToD0ENu_D0ToKPi','SpruceSLB_BuToD0TauNu_D0ToKPi_TauToENuNu'] + + #define filer + my_filter_e = create_lines_filter(name="Filter_e", lines=[line_name[0]]) + my_filter_tau = create_lines_filter(name="Filter_tau", lines=[line_name[1]]) + + #get data and extra particles + lb_e = get_particles(f"/Event/Spruce/{line_name[0]}/Particles") + lb_tau = get_particles(f"/Event/Spruce/{line_name[1]}/Particles") + extra_particles = get_extra_pions() + + #get v2_pvs and rec_summary + v2_pvs = get_pvs() + rec_summary = get_rec_summary() + hadron_candidate_id = 421 + #make sb candidate + Bst_e = make_Bst(lb_e, extra_particles,'e',hadron_candidate_id,v2_pvs,False) + Bst_tau = make_Bst(lb_tau, extra_particles,'tau', hadron_candidate_id,v2_pvs,False) + #MCTRUTH_Bst = MCTruthAndBkgCat(Bst, name='MCTRUTH_Bst') + + + tuple_file_e = tuple_Bst(Bst_e,'e', 'None', v2_pvs, rec_summary) + tuple_file_tau = tuple_Bst(Bst_tau,'tau', 'None', v2_pvs, rec_summary) + + #define algorithms + user_algorithms = {} + user_algorithms['Alg_e'] = [my_filter_e, tuple_file_e] + user_algorithms['Alg_tau'] = [my_filter_tau, tuple_file_tau] + + return make_config(options, user_algorithms) -- GitLab From 282823d1b1372b4cbc352b59c5431a3eedb101ba Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Mon, 6 May 2024 11:58:24 +0200 Subject: [PATCH 05/57] Remove D02HH_Practice --- D02HH_Practice/README.md | 1 - D02HH_Practice/info.yaml | 38 -------------------------------- D02HH_Practice/ntuple_options.py | 38 -------------------------------- 3 files changed, 77 deletions(-) delete mode 100644 D02HH_Practice/README.md delete mode 100644 D02HH_Practice/info.yaml delete mode 100755 D02HH_Practice/ntuple_options.py diff --git a/D02HH_Practice/README.md b/D02HH_Practice/README.md deleted file mode 100644 index cc34fb0b7a..0000000000 --- a/D02HH_Practice/README.md +++ /dev/null @@ -1 +0,0 @@ -I want weed XDDDD diff --git a/D02HH_Practice/info.yaml b/D02HH_Practice/info.yaml deleted file mode 100644 index dbe57daefb..0000000000 --- a/D02HH_Practice/info.yaml +++ /dev/null @@ -1,38 +0,0 @@ -defaults: - application: DaVinci/v46r10 - wg: Charm - automatically_configure: yes - turbo: no - inform: - - chinghua@cern.ch - options: - - ntuple_options.py - output: D02KK.ROOT -checks: - histogram: - type: range - expression: Dst_2010_plus_M - limits: - min: 1900 - max: 2300 - blind_ranges: - min: 2000 - max: 2020 - histogram_fail: - type: range - expression: Dst_2010_plus_M - limits: - min: 0 - max: 10 - at_least_50_entries: - type: num_entries - tree_pattern: TupleDstToD0pi_D0ToKK/DecayTree - count: 50 - -2016_MagDown_PromptMC_D02KK: - input: - bk_query: "/MC/2016/Beam6500GeV-2016-MagDown-Nu1.6-25ns-Pythia8/Sim09c/Trig0x6138160F/Reco16/Turbo03/Stripping28r1NoPrescalingFlagged/27163002/ALLSTREAMS.DST" - checks: - - histogram - - histogram_fail - - at_least_50_entries diff --git a/D02HH_Practice/ntuple_options.py b/D02HH_Practice/ntuple_options.py deleted file mode 100755 index 0297e5cc85..0000000000 --- a/D02HH_Practice/ntuple_options.py +++ /dev/null @@ -1,38 +0,0 @@ -from Configurables import DecayTreeTuple - -## Specify the stream and stripping line -stream = "AllStreams" -line = "D2hhPromptDst2D2KKLine" - -## We create the DecayTreeTuple object, and indicate the Input -## (i.e., the TES location where the desired candidates may be) -## as well as the decay descriptor -dtt = DecayTreeTuple("TupleDstToD0pi_D0ToKK") -dtt.Inputs = ["/Event/{0}/Phys/{1}/Particles".format(stream, line)] -dtt.Decay = "[D*(2010)+ -> (D0 -> K- K+) pi+]CC" - -from Configurables import DaVinci - -DaVinci().UserAlgorithms += [dtt] - -# In general, thanks to using the automatically_configure setting, you don't need what's below so it can be removed -""" -DaVinci().InputType = "DST" -DaVinci().TupleFile = "DVntuple.root" -DaVinci().PrintFreq = 1000 -DaVinci().DataType = "2016" -DaVinci().Simulation = True -DaVinci().Lumi = not DaVinci().Simulation -DaVinci().EvtMax = -1 -DaVinci().CondDBtag = "sim-20170721-2-vc-md100" -DaVinci().DDDBtag = "dddb-20170721-3" -""" - -# The Analysis Productions software automatically finds a valid remote file to test on so we can drop this bit -""" -from GaudiConf import IOHelper - -IOHelper().inputFiles([ - "./00070793_00000001_7.AllStreams.dst" -], clear=True) -""" \ No newline at end of file -- GitLab From 50dc7fcc7789aecfd50f50a164adf4fc561a1b49 Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Mon, 6 May 2024 12:02:11 +0200 Subject: [PATCH 06/57] Fix info.yaml --- RDstar_taue_2024data/info.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RDstar_taue_2024data/info.yaml b/RDstar_taue_2024data/info.yaml index 2681a0a72b..49eb72ae27 100644 --- a/RDstar_taue_2024data/info.yaml +++ b/RDstar_taue_2024data/info.yaml @@ -21,7 +21,7 @@ defaults: conditions_version: master input_process: "Spruce" # Spruce for SprucingPass, "Hlt2" for RAW data (Hlt2 output) input_stream: "sl" # for streamed data - evt_max: 1000 + #evt_max: 1000 inform: - ching-hua.li@cern.ch wg: SL -- GitLab From 9c1cf33fab3bcf8d5f9c85cc5ba0efcbe56fe30a Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Mon, 6 May 2024 13:17:33 +0200 Subject: [PATCH 07/57] add Brems variables --- RDstar_taue_2024data/info.yaml | 6 +++--- RDstar_taue_2024data/run_Dzl.py | 34 ++++++++++++++++++++++++++++----- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/RDstar_taue_2024data/info.yaml b/RDstar_taue_2024data/info.yaml index 49eb72ae27..808f8ee379 100644 --- a/RDstar_taue_2024data/info.yaml +++ b/RDstar_taue_2024data/info.yaml @@ -1,7 +1,7 @@ checks: - hist_Sb_M: + hist: type: range - expression: Sb_M + expression: Lb_M limits: min: 2_000 max: 8_000 @@ -39,5 +39,5 @@ RDstar_taue_{{ evttype }}_{{ polarity }}: keep_running: true n_test_lfns: 1 checks: - - hist_Sb_M + - hist {%- endfor %} diff --git a/RDstar_taue_2024data/run_Dzl.py b/RDstar_taue_2024data/run_Dzl.py index 56c3ea074d..24107c0c61 100644 --- a/RDstar_taue_2024data/run_Dzl.py +++ b/RDstar_taue_2024data/run_Dzl.py @@ -188,8 +188,31 @@ def get_functors(MCTRUTH, v2_pvs, rec_summary): evt_vars['nLongTracks'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nLongTracks") evt_vars['nPVs'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nPVs") + vars_brems = FunctorCollection({}) + vars_brems.update({"HASBREM": F.HASBREM}) + #vars_brems.update({"HASBREMADDED": F.HASBREMADDED}) + vars_brems.update({"BREMENERGY": F.BREMENERGY}) + vars_brems.update({"BREMBENDCORR": F.BREMBENDCORR}) + vars_brems.update({"BREMPIDE": F.BREMPIDE}) + vars_brems.update({"ECALPIDE": F.ECALPIDE}) + vars_brems.update({"ECALPIDMU": F.ECALPIDMU}) + vars_brems.update({"HCALPIDE": F.HCALPIDE}) + vars_brems.update({"HCALPIDMU": F.HCALPIDMU}) + vars_brems.update({"ELECTRONSHOWEREOP": F.ELECTRONSHOWEREOP}) + vars_brems.update({"ELECTRONSHOWERDLL": F.ELECTRONSHOWERDLL}) + vars_brems.update({"CLUSTERMATCH": F.CLUSTERMATCH_CHI2}) + vars_brems.update({"ELECTRONMATCH": F.ELECTRONMATCH_CHI2}) + vars_brems.update({"BREMHYPOMATCH": F.BREMHYPOMATCH_CHI2}) + vars_brems.update({"ELECTRONENERGY": F.ELECTRONENERGY}) + vars_brems.update({"BREMHYPOENERGY": F.BREMHYPOENERGY}) + vars_brems.update({"BREMHYPODELTAX": F.BREMHYPODELTAX}) + #vars_brems.update({"BREMTRACKBASEDENERGY": F.BREMTRACKBASEDENERGY}) + vars_brems.update({"INBREM": F.INBREM}) + vars_brems.update({"PT_WITH_BREM": F.PT_WITH_BREM}) + vars_brems.update({"P_WITH_BREM": F.P_WITH_BREM}) + #return all functors - functors = (vars_common, vars_composite, var_B, vars_basic, evt_vars) + functors = (vars_common, vars_composite, var_B, vars_basic, evt_vars,vars_brems) return functors def tuple_Bst(Bst,lepton, MCTRUTH, v2_pvs, rec_summary): @@ -200,6 +223,7 @@ def tuple_Bst(Bst,lepton, MCTRUTH, v2_pvs, rec_summary): var_B = functors[2] vars_basic = functors[3] evt_vars = functors[4] + vars_brems = functors[5] #variables for Sb field vars_Bst = FunctorCollection() @@ -250,10 +274,10 @@ def tuple_Bst(Bst,lepton, MCTRUTH, v2_pvs, rec_summary): variables["Sb"] = vars_composite + vars_Bst variables["Lb"] = vars_composite + var_B variables["Lc"] = vars_composite - variables["Lep"] = vars_basic - variables["Epi"] = vars_basic - variables["Km"] = vars_basic - variables["pip"] = vars_basic + variables["Lep"] = vars_basic + vars_brems + variables["Epi"] = vars_basic + vars_brems + variables["Km"] = vars_basic + vars_brems + variables["pip"] = vars_basic + vars_brems #define tuple my_tuple = Funtuple( -- GitLab From 0d4930ad4ce95927ff52fc71698b692216e82732 Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Mon, 6 May 2024 15:54:20 +0200 Subject: [PATCH 08/57] Fix info.yaml --- RDstar_taue_2024data/info.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RDstar_taue_2024data/info.yaml b/RDstar_taue_2024data/info.yaml index 808f8ee379..0651abb089 100644 --- a/RDstar_taue_2024data/info.yaml +++ b/RDstar_taue_2024data/info.yaml @@ -16,7 +16,7 @@ defaults: input_raw_format: 0.5 input_type: ROOT # ROOT for SprucingPass, RAW for RAW data (Hlt2 output) simulation: False - data_type: "Upgrade" + #data_type: "Upgrade" geometry_version: run3/2024.Q1.2-v00.00 conditions_version: master input_process: "Spruce" # Spruce for SprucingPass, "Hlt2" for RAW data (Hlt2 output) -- GitLab From 5664720ad90b134a2a0b8c05ca947ec25745b09e Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Thu, 9 May 2024 13:54:03 +0200 Subject: [PATCH 09/57] Add info.yaml and run_Dzl.py --- .../info.yaml | 12 +++---- .../run_Dzl.py | 31 +++++++++++-------- 2 files changed, 24 insertions(+), 19 deletions(-) rename {RDstar_taue_2024data => SL_mu_nu_D0toKpi_2024_data}/info.yaml (83%) rename {RDstar_taue_2024data => SL_mu_nu_D0toKpi_2024_data}/run_Dzl.py (91%) diff --git a/RDstar_taue_2024data/info.yaml b/SL_mu_nu_D0toKpi_2024_data/info.yaml similarity index 83% rename from RDstar_taue_2024data/info.yaml rename to SL_mu_nu_D0toKpi_2024_data/info.yaml index 0651abb089..6192c47c82 100644 --- a/RDstar_taue_2024data/info.yaml +++ b/SL_mu_nu_D0toKpi_2024_data/info.yaml @@ -1,17 +1,17 @@ checks: hist: type: range - expression: Lb_M + expression: Sb_Delta_M limits: - min: 2_000 - max: 8_000 - n_bins: 100 + min: 130 + max: 200 + n_bins: 70 defaults: application: "DaVinci/v64r4" output: DATA.ROOT options: - entrypoint: RDstar_taue_2024data.run_Dzl:main + entrypoint: SL_mu_nu_D0toKpi_2024_data.run_Dzl:main extra_options: input_raw_format: 0.5 input_type: ROOT # ROOT for SprucingPass, RAW for RAW data (Hlt2 output) @@ -30,7 +30,7 @@ defaults: ('2024Data', 'Down'), ]%} {%- for evttype, polarity in datasets %} -RDstar_taue_{{ evttype }}_{{ polarity }}: +b0_dstp_muon_and_taumu_{{ evttype }}_{{ polarity }}: input: bk_query: "/LHCb/Collision24/Beam6800GeV-VeloClosed-Mag{{ polarity }}-Excl-UT/Real Data/Sprucing24c1/90000000/SL.DST" dq_flags: diff --git a/RDstar_taue_2024data/run_Dzl.py b/SL_mu_nu_D0toKpi_2024_data/run_Dzl.py similarity index 91% rename from RDstar_taue_2024data/run_Dzl.py rename to SL_mu_nu_D0toKpi_2024_data/run_Dzl.py index 24107c0c61..0f0491375b 100644 --- a/RDstar_taue_2024data/run_Dzl.py +++ b/SL_mu_nu_D0toKpi_2024_data/run_Dzl.py @@ -228,6 +228,7 @@ def tuple_Bst(Bst,lepton, MCTRUTH, v2_pvs, rec_summary): #variables for Sb field vars_Bst = FunctorCollection() B_child = F.CHILD(1, F.FORWARDARG0) + D0_child = F.CHILD(1, F.CHILD(1,F.FORWARDARG0)) Epi_child = F.CHILD(2, F.FORWARDARG0) bpv_pi = F.BPV(v2_pvs).bind(Epi_child) #diff in vtx chi2 with and without extra particle @@ -257,16 +258,20 @@ def tuple_Bst(Bst,lepton, MCTRUTH, v2_pvs, rec_summary): #DOCACHI2 of extra particle wrt to mother i.e. Sb vars_Bst['MTDOCACHI2_1'] = F.MTDOCACHI2(1, v2_pvs) vars_Bst['MTDOCACHI2_2'] = F.MTDOCACHI2(2, v2_pvs) + #vars_Bst['Dstar_M'] = F.MASS @ ((F.FOURMOMENTUM @ D0_child)+(F.FOURMOMENTUM @ Epi_child)) + #vars_Bst['D0_M'] = F.MASS @ (F.FOURMOMENTUM @ D0_child) + #vars_Bst['test_id'] = F.PARTICLE_ID @ D0_child + vars_Bst['Delta_M'] = F.ABS @ ((F.MASS @ ((F.FOURMOMENTUM @ D0_child)+(F.FOURMOMENTUM @ Epi_child))) - (F.MASS @ D0_child)) #define fields fields = {} - fields['Sb'] = f'[B0 -> (B- -> (D0 -> K- pi+) e-) [pi+]CC]CC' - fields['Lb'] = f'[B0 -> ^(B- -> (D0 -> K- pi+) e-) [pi+]CC]CC' - fields['Lc'] = f'[B0 -> (B- -> ^(D0 -> K- pi+) e-) [pi+]CC]CC' - fields['Lep'] = f'[B0 -> (B- -> (D0 -> K- pi+) ^e-) [pi+]CC]CC' - fields['Epi'] = f'[B0 -> (B- -> (D0 -> K- pi+) e-) ^[pi+]CC]CC' - fields['Km'] = f'[B0 -> (B- -> (D0 -> ^K- pi+) e-) [pi+]CC]CC' - fields['pip'] = f'[B0 -> (B- -> (D0 -> K- ^pi+) e-) [pi+]CC]CC' + fields['Sb'] = f'[B0 -> (B- -> (D0 -> K- pi+) mu-) [pi+]CC]CC' + fields['Lb'] = f'[B0 -> ^(B- -> (D0 -> K- pi+) mu-) [pi+]CC]CC' + fields['Lc'] = f'[B0 -> (B- -> ^(D0 -> K- pi+) mu-) [pi+]CC]CC' + fields['Lep'] = f'[B0 -> (B- -> (D0 -> K- pi+) ^mu-) [pi+]CC]CC' + fields['Epi'] = f'[B0 -> (B- -> (D0 -> K- pi+) mu-) ^[pi+]CC]CC' + fields['Km'] = f'[B0 -> (B- -> (D0 -> ^K- pi+) mu-) [pi+]CC]CC' + fields['pip'] = f'[B0 -> (B- -> (D0 -> K- ^pi+) mu-) [pi+]CC]CC' #add variables variables = {} @@ -303,14 +308,14 @@ def get_extra_pions(): #def main(options): def main(options: Options): - line_name = ['SpruceSLB_BuToD0ENu_D0ToKPi','SpruceSLB_BuToD0TauNu_D0ToKPi_TauToENuNu'] + line_name = ['SpruceSLB_BuToD0MuNu_D0ToKPi','SpruceSLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu'] #define filer - my_filter_e = create_lines_filter(name="Filter_e", lines=[line_name[0]]) + my_filter_mu = create_lines_filter(name="Filter_mu", lines=[line_name[0]]) my_filter_tau = create_lines_filter(name="Filter_tau", lines=[line_name[1]]) #get data and extra particles - lb_e = get_particles(f"/Event/Spruce/{line_name[0]}/Particles") + lb_mu = get_particles(f"/Event/Spruce/{line_name[0]}/Particles") lb_tau = get_particles(f"/Event/Spruce/{line_name[1]}/Particles") extra_particles = get_extra_pions() @@ -319,17 +324,17 @@ def main(options: Options): rec_summary = get_rec_summary() hadron_candidate_id = 421 #make sb candidate - Bst_e = make_Bst(lb_e, extra_particles,'e',hadron_candidate_id,v2_pvs,False) + Bst_mu = make_Bst(lb_mu, extra_particles,'mu',hadron_candidate_id,v2_pvs,False) Bst_tau = make_Bst(lb_tau, extra_particles,'tau', hadron_candidate_id,v2_pvs,False) #MCTRUTH_Bst = MCTruthAndBkgCat(Bst, name='MCTRUTH_Bst') - tuple_file_e = tuple_Bst(Bst_e,'e', 'None', v2_pvs, rec_summary) + tuple_file_mu = tuple_Bst(Bst_mu,'mu', 'None', v2_pvs, rec_summary) tuple_file_tau = tuple_Bst(Bst_tau,'tau', 'None', v2_pvs, rec_summary) #define algorithms user_algorithms = {} - user_algorithms['Alg_e'] = [my_filter_e, tuple_file_e] + user_algorithms['Alg_mu'] = [my_filter_mu, tuple_file_mu] user_algorithms['Alg_tau'] = [my_filter_tau, tuple_file_tau] return make_config(options, user_algorithms) -- GitLab From ea6815408de350f57d4671b4d059ab4c8219f4b9 Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <chinghua@lxplus710.cern.ch> Date: Thu, 15 Feb 2024 13:40:12 +0100 Subject: [PATCH 10/57] Add D02KK MC production for starterkit --- D02HH_Practice/README.md | 1 + D02HH_Practice/info.yaml | 14 ++++++++++++ D02HH_Practice/ntuple_options.py | 38 ++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 D02HH_Practice/README.md create mode 100644 D02HH_Practice/info.yaml create mode 100755 D02HH_Practice/ntuple_options.py diff --git a/D02HH_Practice/README.md b/D02HH_Practice/README.md new file mode 100644 index 0000000000..518eb21598 --- /dev/null +++ b/D02HH_Practice/README.md @@ -0,0 +1 @@ +I want weed diff --git a/D02HH_Practice/info.yaml b/D02HH_Practice/info.yaml new file mode 100644 index 0000000000..510dce396d --- /dev/null +++ b/D02HH_Practice/info.yaml @@ -0,0 +1,14 @@ +defaults: + application: DaVinci/v46r10 + wg: Charm + automatically_configure: yes + turbo: no + inform: + - chinghua@cern.ch + options: + - ntuple_options.py + output: D02KK.ROOT + +2016_MagDown_PromptMC_D02KK: + input: + bk_query: "/MC/2016/Beam6500GeV-2016-MagDown-Nu1.6-25ns-Pythia8/Sim09c/Trig0x6138160F/Reco16/Turbo03/Stripping28r1NoPrescalingFlagged/27163002/ALLSTREAMS.DST" diff --git a/D02HH_Practice/ntuple_options.py b/D02HH_Practice/ntuple_options.py new file mode 100755 index 0000000000..0297e5cc85 --- /dev/null +++ b/D02HH_Practice/ntuple_options.py @@ -0,0 +1,38 @@ +from Configurables import DecayTreeTuple + +## Specify the stream and stripping line +stream = "AllStreams" +line = "D2hhPromptDst2D2KKLine" + +## We create the DecayTreeTuple object, and indicate the Input +## (i.e., the TES location where the desired candidates may be) +## as well as the decay descriptor +dtt = DecayTreeTuple("TupleDstToD0pi_D0ToKK") +dtt.Inputs = ["/Event/{0}/Phys/{1}/Particles".format(stream, line)] +dtt.Decay = "[D*(2010)+ -> (D0 -> K- K+) pi+]CC" + +from Configurables import DaVinci + +DaVinci().UserAlgorithms += [dtt] + +# In general, thanks to using the automatically_configure setting, you don't need what's below so it can be removed +""" +DaVinci().InputType = "DST" +DaVinci().TupleFile = "DVntuple.root" +DaVinci().PrintFreq = 1000 +DaVinci().DataType = "2016" +DaVinci().Simulation = True +DaVinci().Lumi = not DaVinci().Simulation +DaVinci().EvtMax = -1 +DaVinci().CondDBtag = "sim-20170721-2-vc-md100" +DaVinci().DDDBtag = "dddb-20170721-3" +""" + +# The Analysis Productions software automatically finds a valid remote file to test on so we can drop this bit +""" +from GaudiConf import IOHelper + +IOHelper().inputFiles([ + "./00070793_00000001_7.AllStreams.dst" +], clear=True) +""" \ No newline at end of file -- GitLab From a46bbf0725fb82e3f577b4133c04ebfa05ae7796 Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <chinghua@lxplus710.cern.ch> Date: Thu, 15 Feb 2024 13:50:51 +0100 Subject: [PATCH 11/57] test --- D02HH_Practice/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/D02HH_Practice/README.md b/D02HH_Practice/README.md index 518eb21598..cc34fb0b7a 100644 --- a/D02HH_Practice/README.md +++ b/D02HH_Practice/README.md @@ -1 +1 @@ -I want weed +I want weed XDDDD -- GitLab From c57ccaa2a9dad21d826c635b9a69bb869a312a4c Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <chinghua@lxplus710.cern.ch> Date: Thu, 15 Feb 2024 14:10:52 +0100 Subject: [PATCH 12/57] test check --- D02HH_Practice/info.yaml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/D02HH_Practice/info.yaml b/D02HH_Practice/info.yaml index 510dce396d..dbe57daefb 100644 --- a/D02HH_Practice/info.yaml +++ b/D02HH_Practice/info.yaml @@ -8,7 +8,31 @@ defaults: options: - ntuple_options.py output: D02KK.ROOT +checks: + histogram: + type: range + expression: Dst_2010_plus_M + limits: + min: 1900 + max: 2300 + blind_ranges: + min: 2000 + max: 2020 + histogram_fail: + type: range + expression: Dst_2010_plus_M + limits: + min: 0 + max: 10 + at_least_50_entries: + type: num_entries + tree_pattern: TupleDstToD0pi_D0ToKK/DecayTree + count: 50 2016_MagDown_PromptMC_D02KK: input: bk_query: "/MC/2016/Beam6500GeV-2016-MagDown-Nu1.6-25ns-Pythia8/Sim09c/Trig0x6138160F/Reco16/Turbo03/Stripping28r1NoPrescalingFlagged/27163002/ALLSTREAMS.DST" + checks: + - histogram + - histogram_fail + - at_least_50_entries -- GitLab From 7d1376a0107adfd9749c13f3af5880c5d9188c75 Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Mon, 6 May 2024 11:39:24 +0200 Subject: [PATCH 13/57] Add RDstar_taue production for 2024 data checking --- RDstar_taue_2024data/info.yaml | 43 +++++ RDstar_taue_2024data/run_Dzl.py | 311 ++++++++++++++++++++++++++++++++ 2 files changed, 354 insertions(+) create mode 100644 RDstar_taue_2024data/info.yaml create mode 100644 RDstar_taue_2024data/run_Dzl.py diff --git a/RDstar_taue_2024data/info.yaml b/RDstar_taue_2024data/info.yaml new file mode 100644 index 0000000000..2681a0a72b --- /dev/null +++ b/RDstar_taue_2024data/info.yaml @@ -0,0 +1,43 @@ +checks: + hist_Sb_M: + type: range + expression: Sb_M + limits: + min: 2_000 + max: 8_000 + n_bins: 100 + +defaults: + application: "DaVinci/v64r4" + output: DATA.ROOT + options: + entrypoint: RDstar_taue_2024data.run_Dzl:main + extra_options: + input_raw_format: 0.5 + input_type: ROOT # ROOT for SprucingPass, RAW for RAW data (Hlt2 output) + simulation: False + data_type: "Upgrade" + geometry_version: run3/2024.Q1.2-v00.00 + conditions_version: master + input_process: "Spruce" # Spruce for SprucingPass, "Hlt2" for RAW data (Hlt2 output) + input_stream: "sl" # for streamed data + evt_max: 1000 + inform: + - ching-hua.li@cern.ch + wg: SL + +{%- set datasets = [ + ('2024Data', 'Down'), +]%} +{%- for evttype, polarity in datasets %} +RDstar_taue_{{ evttype }}_{{ polarity }}: + input: + bk_query: "/LHCb/Collision24/Beam6800GeV-VeloClosed-Mag{{ polarity }}-Excl-UT/Real Data/Sprucing24c1/90000000/SL.DST" + dq_flags: + - UNCHECKED + - OK + keep_running: true + n_test_lfns: 1 + checks: + - hist_Sb_M +{%- endfor %} diff --git a/RDstar_taue_2024data/run_Dzl.py b/RDstar_taue_2024data/run_Dzl.py new file mode 100644 index 0000000000..56c3ea074d --- /dev/null +++ b/RDstar_taue_2024data/run_Dzl.py @@ -0,0 +1,311 @@ +import sys,os,math +from PyConf.reading import get_pvs, get_rec_summary, get_particles +import Functors as F +from FunTuple import FunctorCollection +from FunTuple import FunTuple_Particles as Funtuple +from DaVinci.algorithms import create_lines_filter +from DaVinci import Options,make_config +import FunTuple.functorcollections as FC +from DaVinciMCTools import MCTruthAndBkgCat +from Hlt2Conf.algorithms_thor import ParticleCombiner, ParticleFilter +from Hlt2Conf.algorithms_thor import ParticleContainersMerger +from Functors.grammar import Functor +from Hlt2Conf.standard_particles import make_has_rich_long_pions,make_has_rich_up_pions,make_has_rich_down_pions + +_BPVCORRM = Functor('_BPVCORRM', 'Composite::CorrectedMass','Compute the corrected mass') +_allpv_FDVEC = (F.ENDVERTEX_POS @ F.FORWARDARG1 - F.TOLINALG @ F.POSITION @ F.FORWARDARG0) +_allpv_NORMEDDOT = F.NORMEDDOT.bind(F.THREEMOMENTUM @ F.FORWARDARG1, _allpv_FDVEC) +#ALLPV_CHI2 = lambda Vertices: F.MAP(F.CHI2) @ F.TES(Vertices) +#ALLPV_CHI2DOF = lambda Vertices: F.MAP(F.CHI2DOF) @ F.TES(Vertices) +ALLPV_IPCHI2 = lambda Vertices: F.MAP(F.IPCHI2).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_FDCHI2 = lambda Vertices: F.MAP(F.VTX_FDCHI2).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_DIRA = lambda Vertices: F.MAP(_allpv_NORMEDDOT).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_CORRM = lambda Vertices: F.MAP(_BPVCORRM).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_LTIME = lambda Vertices: F.MAP(F.VTX_LTIME).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_DLS = lambda Vertices: F.MAP(F.VTX_DLS).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_FD_COORDINATE = lambda coordinate, Vertices: F.MAP(coordinate @ _allpv_FDVEC).bind(F.TES(Vertices), F.FORWARDARGS) +#MCNEUTRINO = F.FIND_MCDECAY("[ Lambda_b0 => Lambda_c+ mu- ^nu_mu~ ]CC") + +TRUE_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.PARTICLE_ID) == id) +#MCMOTHER_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.MC_MOTHER(1, F.PARTICLE_ID)) == id) +#GD_MCMOTHER_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.MC_MOTHER(2, F.PARTICLE_ID)) == id) +#GD_GD_MCMOTHER_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.MC_MOTHER(3, F.PARTICLE_ID)) == id) + +def make_Bst(B, pions,lepton, hadron_candidate_id,v2_pvs,do_truth_matching = True): + if do_truth_matching == True : + #filter B keeping only true D0 and true leptons + MCTRUTH_B = MCTruthAndBkgCat(B, name='MCTRUTH_Bu') + Dz_child = F.CHILD(1, F.FORWARDARG0) #get the first child of B*- which is D0 + lep_child = F.CHILD(2, F.FORWARDARG0) #get the second child of B*- which is lepton + Dz_truth_cut = TRUE_ID_IS(hadron_candidate_id, MCTRUTH_B) @ Dz_child #require that D0 is true + lep_truth_cut = F.require_any(TRUE_ID_IS(11, MCTRUTH_B) @ lep_child , TRUE_ID_IS(13, MCTRUTH_B) @ lep_child) #require that lepton is true i.e. electron or muon + cut_b = F.require_all(Dz_truth_cut, lep_truth_cut) #make a cut + signal_B = ParticleFilter(Input=B, Cut=F.FILTER(cut_b), name='signal_Dzmu') #filter the B candidates + else : signal_B = B + + #combine to make [B*0 -> B*- pi+]cc + Bst_1 = ParticleCombiner( + Inputs=[B, pions], + name=f'Bst_1_{lepton}', + DecayDescriptor='[B0 -> B- pi+]cc', + CombinationCut=F.ALL, + CompositeCut=F.ALL, + ParticleCombiner="ParticleVertexFitter", + PrimaryVertices=v2_pvs + #OutputLevel=1 + ) + #combine to make [B*0 -> B*- pi-]cc + Bst_2 = ParticleCombiner( + Inputs=[B, pions], + name=f'Bst_2_{lepton}', + DecayDescriptor='[B0 -> B- pi-]cc', + CombinationCut=F.ALL, + CompositeCut=F.ALL, + ParticleCombiner="ParticleVertexFitter", + PrimaryVertices=v2_pvs + #OutputLevel=1 + ) + #merge the two Bst candidates + Bst = ParticleContainersMerger([Bst_1, Bst_2], name = f'Bst_combiner_{lepton}') + return Bst + +def get_functors(MCTRUTH, v2_pvs, rec_summary): + #define common variables for all fields (composite and basic) + vars_common = FunctorCollection() + #all pvs: ip, ipchi2. The PV positions are stored in event variables + vars_common['ALLPV_IP[pv_indx]'] = F.ALLPV_IP(v2_pvs) + vars_common['ALLPV_IPCHI2[pv_indx]'] = ALLPV_IPCHI2(v2_pvs) + #best pv: x, y, z, ip, ipchi2 + vars_common['BPV_X'] = F.BPVX(v2_pvs) + vars_common['BPV_Y'] = F.BPVY(v2_pvs) + vars_common['BPV_Z'] = F.BPVZ(v2_pvs) + vars_common['BPV_IP'] = F.BPVIP(v2_pvs) + vars_common['BPV_IPCHI2'] = F.BPVIPCHI2(v2_pvs) + vars_common['BPV_CHI2'] = F.CHI2 @ F.BPV(v2_pvs) + vars_common['BPV_CHI2DOF'] = F.CHI2DOF @ F.BPV(v2_pvs) + #particle id, key, truekey. The trueid is stored in MCHierarchy + vars_common['ID'] = F.PARTICLE_ID + vars_common['KEY'] = F.OBJECT_KEY + #get charge, min ip and min ipchi2 + vars_common['CHARGE'] = F.CHARGE + vars_common['MINIP'] = F.MINIP(v2_pvs) + vars_common['MINIPCHI2'] = F.MINIPCHI2(v2_pvs) + #reco kinematics + vars_common += FC.Kinematics() + vars_common['ETA'] = F.ETA + vars_common['PHI'] = F.PHI + if MCTRUTH != 'None': + #mc vars + vars_common['TRUEKEY'] = F.VALUE_OR(-1) @ MCTRUTH(F.OBJECT_KEY) + vars_common += FC.MCKinematics(mctruth_alg = MCTRUTH) + vars_common['TRUEETA'] = MCTRUTH(F.ETA) + vars_common['TRUEPHI'] = MCTRUTH(F.PHI) + #type of the origin vertex + vars_common['MC_VTX_TYPE'] = MCTRUTH(F.VALUE_OR(-1) @ F.MC_VTX_TYPE @ F.MC_ORIGINVERTEX) + ##mc truth hierarchy (done seperately) + #vars_common += FC.MCHierarchy(mctruth_alg = MCTRUTH) + #make some helper functions + MCMOTHER_ID = lambda n: F.VALUE_OR(0) @ MCTRUTH(F.MC_MOTHER(n, F.PARTICLE_ID)) + MCMOTHER_KEY = lambda n: F.VALUE_OR(-1) @ MCTRUTH(F.MC_MOTHER(n, F.OBJECT_KEY )) + vars_common["TRUEID"] = F.VALUE_OR(0) @ MCTRUTH(F.PARTICLE_ID) + vars_common["MCKEY"] = F.VALUE_OR(0) @ MCTRUTH(F.OBJECT_KEY) + vars_common["MC_MOTHER_ID"] = MCMOTHER_ID(1) + vars_common["MC_MOTHER_KEY"] = MCMOTHER_KEY(1) + for i in range(2,14): + prefix = "MC_GD_MOTHER_{}".format(i) + vars_common[f"{prefix}_ID"] = MCMOTHER_ID(i) + vars_common[f"{prefix}_KEY"] = MCMOTHER_KEY(i) + + #variables for composite particles + vars_composite = FunctorCollection() + #end vertex position and end vertex chi2 + vars_composite['ENDVERTEX_POS_'] = F.ENDVERTEX_POS + vars_composite['ENDVERTEX_CHI2'] = F.CHI2 @ F.ENDVERTEX + vars_composite['ENDVERTEX_CHI2DOF'] = F.CHI2DOF @ F.ENDVERTEX + #all pvs: dira, fd, fdchi2 + vars_composite['ALLPV_DIRA[pv_indx]'] = ALLPV_DIRA(v2_pvs) + vars_composite['ALLPV_FD_X[pv_indx]'] = ALLPV_FD_COORDINATE(F.X_COORDINATE, v2_pvs) + vars_composite['ALLPV_FD_Y[pv_indx]'] = ALLPV_FD_COORDINATE(F.Y_COORDINATE, v2_pvs) + vars_composite['ALLPV_FD_Z[pv_indx]'] = ALLPV_FD_COORDINATE(F.Z_COORDINATE, v2_pvs) + vars_composite['ALLPV_FDCHI2[pv_indx]'] = ALLPV_FDCHI2(v2_pvs) + vars_composite['ALLPV_CORRM[pv_indx]'] = ALLPV_CORRM(v2_pvs) + vars_composite['ALLPV_LTIME[pv_indx]'] = ALLPV_LTIME(v2_pvs) + vars_composite['ALLPV_DLS[pv_indx]'] = ALLPV_DLS(v2_pvs) + #best pv: dira, fd, fdchi2, corrm, ltime, dls + vars_composite['BPV_DIRA'] = F.BPVDIRA(v2_pvs) + vars_composite['BPV_FD_'] = F.BPVFDVEC(v2_pvs) + vars_composite['BPV_FDCHI2'] = F.BPVFDCHI2(v2_pvs) + vars_composite['BPV_CORRM'] = F.BPVCORRM(v2_pvs) + vars_composite['BPV_LTIME'] = F.BPVLTIME(v2_pvs) + vars_composite['BPV_DLS'] = F.BPVDLS(v2_pvs) + #mc composite vertex information + + if MCTRUTH != 'None': vars_composite += FC.MCVertexInfo(mctruth_alg = MCTRUTH) + #Compute maximum DOCA and maximum DOCACHI2. Since there are + # only two daughters of Sb particles, the maximum DOCA/DOCACHI2 is + # the DOCA/DOCACHI2 see below. + vars_composite['MAX_DOCA'] = F.MAXDOCA + vars_composite['MAX_DOCACHI2'] = F.MAXDOCACHI2 + vars_composite['MAX_SDOCA'] = F.MAXSDOCA + vars_composite['MAX_SDOCACHI2'] = F.MAXSDOCACHI2 + + #variables for Lb field + var_B = FunctorCollection() + #var_B['TRUENU_PX'] = MCTRUTH(F.PX @ MCNEUTRINO) + #var_B['TRUENU_PY'] = MCTRUTH(F.PY @ MCNEUTRINO) + #var_B['TRUENU_PZ'] = MCTRUTH(F.PZ @ MCNEUTRINO) + #var_B['TRUENU_ENERGY'] = MCTRUTH(F.ENERGY @ MCNEUTRINO) + ###Bkg category + ##var_B["BKGCAT"] = MCTRUTH.BkgCat + + #variables for basics + vars_basic = FunctorCollection() + vars_basic['TRACKTYPE'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKTYPE @ F.TRACK + vars_basic['TRACKHISTORY'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKHISTORY @ F.TRACK + vars_basic['TRACKFLAG'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKFLAG @ F.TRACK + vars_basic['TRACKNDOF'] = F.VALUE_OR(-1) @ F.NDOF @ F.TRACK + vars_basic['TRACKCHI2'] = F.CHI2 @ F.TRACK + vars_basic['TRACKCHI2DOF'] = F.CHI2DOF @ F.TRACK + vars_basic['GHOSTPROB'] = F.GHOSTPROB + vars_basic['PIDpi'] = F.PID_PI + vars_basic['PIDk'] = F.PID_K + vars_basic['PIDp'] = F.PID_P + vars_basic['PIDe'] = F.PID_E + vars_basic['PIDmu'] = F.PID_MU + if MCTRUTH != 'None': + vars_basic['TRUEORIGINVERTEX_X'] = MCTRUTH(F.ORIGIN_VX) + vars_basic['TRUEORIGINVERTEX_Y'] = MCTRUTH(F.ORIGIN_VY) + vars_basic['TRUEORIGINVERTEX_Z'] = MCTRUTH(F.ORIGIN_VZ) + + #variables for event + evt_vars = FunctorCollection() + #evt_vars['ALLPV_X[pv_indx]'] = F.ALLPVX(v2_pvs) + #evt_vars['ALLPV_Y[pv_indx]'] = F.ALLPVY(v2_pvs) + #evt_vars['ALLPV_Z[pv_indx]'] = F.ALLPVZ(v2_pvs) + #evt_vars['ALLPV_CHI2[pv_indx]'] = ALLPV_CHI2(v2_pvs) + #evt_vars['ALLPV_CHI2DOF[pv_indx]']= ALLPV_CHI2DOF(v2_pvs) + evt_vars['nTracks'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nTracks") + evt_vars['nLongTracks'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nLongTracks") + evt_vars['nPVs'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nPVs") + + #return all functors + functors = (vars_common, vars_composite, var_B, vars_basic, evt_vars) + return functors + +def tuple_Bst(Bst,lepton, MCTRUTH, v2_pvs, rec_summary): + #get functors + functors = get_functors(MCTRUTH, v2_pvs, rec_summary) + vars_common = functors[0] + vars_composite = functors[1] + var_B = functors[2] + vars_basic = functors[3] + evt_vars = functors[4] + + #variables for Sb field + vars_Bst = FunctorCollection() + B_child = F.CHILD(1, F.FORWARDARG0) + Epi_child = F.CHILD(2, F.FORWARDARG0) + bpv_pi = F.BPV(v2_pvs).bind(Epi_child) + #diff in vtx chi2 with and without extra particle + vars_Bst['DELTA_ENDVERTEX_CHI2'] = (F.CHI2 @ F.ENDVERTEX) - (F.CHI2 @ F.ENDVERTEX.bind(B_child)) + #IP and IPChi2 of extra particle wrt to Sb end vertex + vars_Bst['Epi_IP_WRT_SbENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ F.FORWARDARG0 , Epi_child) + vars_Bst['Epi_IPCHI2_WRT_SbENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ F.FORWARDARG0 , Epi_child) + #IP and IPChi2 of extra particle wrt to Lb end vertex + vars_Bst['Epi_IP_WRT_LbENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ B_child , Epi_child) + vars_Bst['Epi_IPCHI2_WRT_LbENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ B_child , Epi_child) + #angle between extra particle and Lb + vars_Bst['Epi_COSANGLE_Lb'] = F.COSANGLE.bind(F.THREEMOMENTUM @ B_child, F.THREEMOMENTUM @ Epi_child) + #diff in fd chi2 with and without extra particle + vars_Bst['Delta_BPV_of_Epi_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi, F.FORWARDARGS) - F.VTX_FDCHI2.bind(bpv_pi, B_child) + vars_Bst['BPV_of_Epi_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi, F.FORWARDARGS) + #IP chi2 of extra particle wrt PV and SV of Sb + vars_Bst['Epi_IP_WRT_SbBPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child) + vars_Bst['Epi_IPCHI2_WRT_SbBPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child) + #IP chi2 of extra particle wrt PV and SV of Bb + vars_Bst['Epi_IP_WRT_LbBPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ B_child, Epi_child) + vars_Bst['Epi_IPCHI2_WRT_LbBPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ B_child, Epi_child) + #DOCA and DOCACHI2 b/w Lb and extra particle + vars_Bst['DOCA12'] = F.DOCA(1, 2) + vars_Bst['DOCA12_CHI2_12'] = F.DOCACHI2(1, 2) + #vars_Bst['SDOCA12'] = F.SDOCA(1, 2) + #vars_Bst['SDOCA_CHI2_12'] = F.SDOCACHI2(1, 2) + #DOCACHI2 of extra particle wrt to mother i.e. Sb + vars_Bst['MTDOCACHI2_1'] = F.MTDOCACHI2(1, v2_pvs) + vars_Bst['MTDOCACHI2_2'] = F.MTDOCACHI2(2, v2_pvs) + + #define fields + fields = {} + fields['Sb'] = f'[B0 -> (B- -> (D0 -> K- pi+) e-) [pi+]CC]CC' + fields['Lb'] = f'[B0 -> ^(B- -> (D0 -> K- pi+) e-) [pi+]CC]CC' + fields['Lc'] = f'[B0 -> (B- -> ^(D0 -> K- pi+) e-) [pi+]CC]CC' + fields['Lep'] = f'[B0 -> (B- -> (D0 -> K- pi+) ^e-) [pi+]CC]CC' + fields['Epi'] = f'[B0 -> (B- -> (D0 -> K- pi+) e-) ^[pi+]CC]CC' + fields['Km'] = f'[B0 -> (B- -> (D0 -> ^K- pi+) e-) [pi+]CC]CC' + fields['pip'] = f'[B0 -> (B- -> (D0 -> K- ^pi+) e-) [pi+]CC]CC' + + #add variables + variables = {} + variables["ALL"] = vars_common + variables["Sb"] = vars_composite + vars_Bst + variables["Lb"] = vars_composite + var_B + variables["Lc"] = vars_composite + variables["Lep"] = vars_basic + variables["Epi"] = vars_basic + variables["Km"] = vars_basic + variables["pip"] = vars_basic + + #define tuple + my_tuple = Funtuple( + name=f"Tuple_{lepton}", + tuple_name="DecayTree", + fields=fields, + variables=variables, + inputs=Bst) + + return my_tuple + +def get_extra_pions(): + """ + Note this function in DaVinci requires: + https://gitlab.cern.ch/lhcb/Moore/-/merge_requests/3203 + and it's related LHCb, DaVinci and Rec MRs + """ + long_pions = make_has_rich_long_pions() + up_pions = make_has_rich_up_pions() + down_pions = make_has_rich_down_pions() + return ParticleContainersMerger([long_pions, up_pions, down_pions], + name='Pions_combiner') + +#def main(options): +def main(options: Options): + line_name = ['SpruceSLB_BuToD0ENu_D0ToKPi','SpruceSLB_BuToD0TauNu_D0ToKPi_TauToENuNu'] + + #define filer + my_filter_e = create_lines_filter(name="Filter_e", lines=[line_name[0]]) + my_filter_tau = create_lines_filter(name="Filter_tau", lines=[line_name[1]]) + + #get data and extra particles + lb_e = get_particles(f"/Event/Spruce/{line_name[0]}/Particles") + lb_tau = get_particles(f"/Event/Spruce/{line_name[1]}/Particles") + extra_particles = get_extra_pions() + + #get v2_pvs and rec_summary + v2_pvs = get_pvs() + rec_summary = get_rec_summary() + hadron_candidate_id = 421 + #make sb candidate + Bst_e = make_Bst(lb_e, extra_particles,'e',hadron_candidate_id,v2_pvs,False) + Bst_tau = make_Bst(lb_tau, extra_particles,'tau', hadron_candidate_id,v2_pvs,False) + #MCTRUTH_Bst = MCTruthAndBkgCat(Bst, name='MCTRUTH_Bst') + + + tuple_file_e = tuple_Bst(Bst_e,'e', 'None', v2_pvs, rec_summary) + tuple_file_tau = tuple_Bst(Bst_tau,'tau', 'None', v2_pvs, rec_summary) + + #define algorithms + user_algorithms = {} + user_algorithms['Alg_e'] = [my_filter_e, tuple_file_e] + user_algorithms['Alg_tau'] = [my_filter_tau, tuple_file_tau] + + return make_config(options, user_algorithms) -- GitLab From 43973ff1ff8b60f4029d6f4fc374fbe1844d1c1f Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Mon, 6 May 2024 11:58:24 +0200 Subject: [PATCH 14/57] Remove D02HH_Practice --- D02HH_Practice/README.md | 1 - D02HH_Practice/info.yaml | 38 -------------------------------- D02HH_Practice/ntuple_options.py | 38 -------------------------------- 3 files changed, 77 deletions(-) delete mode 100644 D02HH_Practice/README.md delete mode 100644 D02HH_Practice/info.yaml delete mode 100755 D02HH_Practice/ntuple_options.py diff --git a/D02HH_Practice/README.md b/D02HH_Practice/README.md deleted file mode 100644 index cc34fb0b7a..0000000000 --- a/D02HH_Practice/README.md +++ /dev/null @@ -1 +0,0 @@ -I want weed XDDDD diff --git a/D02HH_Practice/info.yaml b/D02HH_Practice/info.yaml deleted file mode 100644 index dbe57daefb..0000000000 --- a/D02HH_Practice/info.yaml +++ /dev/null @@ -1,38 +0,0 @@ -defaults: - application: DaVinci/v46r10 - wg: Charm - automatically_configure: yes - turbo: no - inform: - - chinghua@cern.ch - options: - - ntuple_options.py - output: D02KK.ROOT -checks: - histogram: - type: range - expression: Dst_2010_plus_M - limits: - min: 1900 - max: 2300 - blind_ranges: - min: 2000 - max: 2020 - histogram_fail: - type: range - expression: Dst_2010_plus_M - limits: - min: 0 - max: 10 - at_least_50_entries: - type: num_entries - tree_pattern: TupleDstToD0pi_D0ToKK/DecayTree - count: 50 - -2016_MagDown_PromptMC_D02KK: - input: - bk_query: "/MC/2016/Beam6500GeV-2016-MagDown-Nu1.6-25ns-Pythia8/Sim09c/Trig0x6138160F/Reco16/Turbo03/Stripping28r1NoPrescalingFlagged/27163002/ALLSTREAMS.DST" - checks: - - histogram - - histogram_fail - - at_least_50_entries diff --git a/D02HH_Practice/ntuple_options.py b/D02HH_Practice/ntuple_options.py deleted file mode 100755 index 0297e5cc85..0000000000 --- a/D02HH_Practice/ntuple_options.py +++ /dev/null @@ -1,38 +0,0 @@ -from Configurables import DecayTreeTuple - -## Specify the stream and stripping line -stream = "AllStreams" -line = "D2hhPromptDst2D2KKLine" - -## We create the DecayTreeTuple object, and indicate the Input -## (i.e., the TES location where the desired candidates may be) -## as well as the decay descriptor -dtt = DecayTreeTuple("TupleDstToD0pi_D0ToKK") -dtt.Inputs = ["/Event/{0}/Phys/{1}/Particles".format(stream, line)] -dtt.Decay = "[D*(2010)+ -> (D0 -> K- K+) pi+]CC" - -from Configurables import DaVinci - -DaVinci().UserAlgorithms += [dtt] - -# In general, thanks to using the automatically_configure setting, you don't need what's below so it can be removed -""" -DaVinci().InputType = "DST" -DaVinci().TupleFile = "DVntuple.root" -DaVinci().PrintFreq = 1000 -DaVinci().DataType = "2016" -DaVinci().Simulation = True -DaVinci().Lumi = not DaVinci().Simulation -DaVinci().EvtMax = -1 -DaVinci().CondDBtag = "sim-20170721-2-vc-md100" -DaVinci().DDDBtag = "dddb-20170721-3" -""" - -# The Analysis Productions software automatically finds a valid remote file to test on so we can drop this bit -""" -from GaudiConf import IOHelper - -IOHelper().inputFiles([ - "./00070793_00000001_7.AllStreams.dst" -], clear=True) -""" \ No newline at end of file -- GitLab From b5d648f89203b647ecd7739970c6ecd4b03a36c8 Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Mon, 6 May 2024 12:02:11 +0200 Subject: [PATCH 15/57] Fix info.yaml --- RDstar_taue_2024data/info.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RDstar_taue_2024data/info.yaml b/RDstar_taue_2024data/info.yaml index 2681a0a72b..49eb72ae27 100644 --- a/RDstar_taue_2024data/info.yaml +++ b/RDstar_taue_2024data/info.yaml @@ -21,7 +21,7 @@ defaults: conditions_version: master input_process: "Spruce" # Spruce for SprucingPass, "Hlt2" for RAW data (Hlt2 output) input_stream: "sl" # for streamed data - evt_max: 1000 + #evt_max: 1000 inform: - ching-hua.li@cern.ch wg: SL -- GitLab From fa3cc070535567c335b5472f104eb01695a5f3cf Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Mon, 6 May 2024 13:17:33 +0200 Subject: [PATCH 16/57] add Brems variables --- RDstar_taue_2024data/info.yaml | 6 +++--- RDstar_taue_2024data/run_Dzl.py | 34 ++++++++++++++++++++++++++++----- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/RDstar_taue_2024data/info.yaml b/RDstar_taue_2024data/info.yaml index 49eb72ae27..808f8ee379 100644 --- a/RDstar_taue_2024data/info.yaml +++ b/RDstar_taue_2024data/info.yaml @@ -1,7 +1,7 @@ checks: - hist_Sb_M: + hist: type: range - expression: Sb_M + expression: Lb_M limits: min: 2_000 max: 8_000 @@ -39,5 +39,5 @@ RDstar_taue_{{ evttype }}_{{ polarity }}: keep_running: true n_test_lfns: 1 checks: - - hist_Sb_M + - hist {%- endfor %} diff --git a/RDstar_taue_2024data/run_Dzl.py b/RDstar_taue_2024data/run_Dzl.py index 56c3ea074d..24107c0c61 100644 --- a/RDstar_taue_2024data/run_Dzl.py +++ b/RDstar_taue_2024data/run_Dzl.py @@ -188,8 +188,31 @@ def get_functors(MCTRUTH, v2_pvs, rec_summary): evt_vars['nLongTracks'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nLongTracks") evt_vars['nPVs'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nPVs") + vars_brems = FunctorCollection({}) + vars_brems.update({"HASBREM": F.HASBREM}) + #vars_brems.update({"HASBREMADDED": F.HASBREMADDED}) + vars_brems.update({"BREMENERGY": F.BREMENERGY}) + vars_brems.update({"BREMBENDCORR": F.BREMBENDCORR}) + vars_brems.update({"BREMPIDE": F.BREMPIDE}) + vars_brems.update({"ECALPIDE": F.ECALPIDE}) + vars_brems.update({"ECALPIDMU": F.ECALPIDMU}) + vars_brems.update({"HCALPIDE": F.HCALPIDE}) + vars_brems.update({"HCALPIDMU": F.HCALPIDMU}) + vars_brems.update({"ELECTRONSHOWEREOP": F.ELECTRONSHOWEREOP}) + vars_brems.update({"ELECTRONSHOWERDLL": F.ELECTRONSHOWERDLL}) + vars_brems.update({"CLUSTERMATCH": F.CLUSTERMATCH_CHI2}) + vars_brems.update({"ELECTRONMATCH": F.ELECTRONMATCH_CHI2}) + vars_brems.update({"BREMHYPOMATCH": F.BREMHYPOMATCH_CHI2}) + vars_brems.update({"ELECTRONENERGY": F.ELECTRONENERGY}) + vars_brems.update({"BREMHYPOENERGY": F.BREMHYPOENERGY}) + vars_brems.update({"BREMHYPODELTAX": F.BREMHYPODELTAX}) + #vars_brems.update({"BREMTRACKBASEDENERGY": F.BREMTRACKBASEDENERGY}) + vars_brems.update({"INBREM": F.INBREM}) + vars_brems.update({"PT_WITH_BREM": F.PT_WITH_BREM}) + vars_brems.update({"P_WITH_BREM": F.P_WITH_BREM}) + #return all functors - functors = (vars_common, vars_composite, var_B, vars_basic, evt_vars) + functors = (vars_common, vars_composite, var_B, vars_basic, evt_vars,vars_brems) return functors def tuple_Bst(Bst,lepton, MCTRUTH, v2_pvs, rec_summary): @@ -200,6 +223,7 @@ def tuple_Bst(Bst,lepton, MCTRUTH, v2_pvs, rec_summary): var_B = functors[2] vars_basic = functors[3] evt_vars = functors[4] + vars_brems = functors[5] #variables for Sb field vars_Bst = FunctorCollection() @@ -250,10 +274,10 @@ def tuple_Bst(Bst,lepton, MCTRUTH, v2_pvs, rec_summary): variables["Sb"] = vars_composite + vars_Bst variables["Lb"] = vars_composite + var_B variables["Lc"] = vars_composite - variables["Lep"] = vars_basic - variables["Epi"] = vars_basic - variables["Km"] = vars_basic - variables["pip"] = vars_basic + variables["Lep"] = vars_basic + vars_brems + variables["Epi"] = vars_basic + vars_brems + variables["Km"] = vars_basic + vars_brems + variables["pip"] = vars_basic + vars_brems #define tuple my_tuple = Funtuple( -- GitLab From 3d45d905053f527c8b031b71de3edde87c7f2441 Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Mon, 6 May 2024 15:54:20 +0200 Subject: [PATCH 17/57] Fix info.yaml --- RDstar_taue_2024data/info.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RDstar_taue_2024data/info.yaml b/RDstar_taue_2024data/info.yaml index 808f8ee379..0651abb089 100644 --- a/RDstar_taue_2024data/info.yaml +++ b/RDstar_taue_2024data/info.yaml @@ -16,7 +16,7 @@ defaults: input_raw_format: 0.5 input_type: ROOT # ROOT for SprucingPass, RAW for RAW data (Hlt2 output) simulation: False - data_type: "Upgrade" + #data_type: "Upgrade" geometry_version: run3/2024.Q1.2-v00.00 conditions_version: master input_process: "Spruce" # Spruce for SprucingPass, "Hlt2" for RAW data (Hlt2 output) -- GitLab From ac96cb639a83ab180964700942f55f8a1e6f761e Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Thu, 9 May 2024 13:54:03 +0200 Subject: [PATCH 18/57] Add info.yaml and run_Dzl.py --- .../info.yaml | 12 +++---- .../run_Dzl.py | 31 +++++++++++-------- 2 files changed, 24 insertions(+), 19 deletions(-) rename {RDstar_taue_2024data => SL_mu_nu_D0toKpi_2024_data}/info.yaml (83%) rename {RDstar_taue_2024data => SL_mu_nu_D0toKpi_2024_data}/run_Dzl.py (91%) diff --git a/RDstar_taue_2024data/info.yaml b/SL_mu_nu_D0toKpi_2024_data/info.yaml similarity index 83% rename from RDstar_taue_2024data/info.yaml rename to SL_mu_nu_D0toKpi_2024_data/info.yaml index 0651abb089..6192c47c82 100644 --- a/RDstar_taue_2024data/info.yaml +++ b/SL_mu_nu_D0toKpi_2024_data/info.yaml @@ -1,17 +1,17 @@ checks: hist: type: range - expression: Lb_M + expression: Sb_Delta_M limits: - min: 2_000 - max: 8_000 - n_bins: 100 + min: 130 + max: 200 + n_bins: 70 defaults: application: "DaVinci/v64r4" output: DATA.ROOT options: - entrypoint: RDstar_taue_2024data.run_Dzl:main + entrypoint: SL_mu_nu_D0toKpi_2024_data.run_Dzl:main extra_options: input_raw_format: 0.5 input_type: ROOT # ROOT for SprucingPass, RAW for RAW data (Hlt2 output) @@ -30,7 +30,7 @@ defaults: ('2024Data', 'Down'), ]%} {%- for evttype, polarity in datasets %} -RDstar_taue_{{ evttype }}_{{ polarity }}: +b0_dstp_muon_and_taumu_{{ evttype }}_{{ polarity }}: input: bk_query: "/LHCb/Collision24/Beam6800GeV-VeloClosed-Mag{{ polarity }}-Excl-UT/Real Data/Sprucing24c1/90000000/SL.DST" dq_flags: diff --git a/RDstar_taue_2024data/run_Dzl.py b/SL_mu_nu_D0toKpi_2024_data/run_Dzl.py similarity index 91% rename from RDstar_taue_2024data/run_Dzl.py rename to SL_mu_nu_D0toKpi_2024_data/run_Dzl.py index 24107c0c61..0f0491375b 100644 --- a/RDstar_taue_2024data/run_Dzl.py +++ b/SL_mu_nu_D0toKpi_2024_data/run_Dzl.py @@ -228,6 +228,7 @@ def tuple_Bst(Bst,lepton, MCTRUTH, v2_pvs, rec_summary): #variables for Sb field vars_Bst = FunctorCollection() B_child = F.CHILD(1, F.FORWARDARG0) + D0_child = F.CHILD(1, F.CHILD(1,F.FORWARDARG0)) Epi_child = F.CHILD(2, F.FORWARDARG0) bpv_pi = F.BPV(v2_pvs).bind(Epi_child) #diff in vtx chi2 with and without extra particle @@ -257,16 +258,20 @@ def tuple_Bst(Bst,lepton, MCTRUTH, v2_pvs, rec_summary): #DOCACHI2 of extra particle wrt to mother i.e. Sb vars_Bst['MTDOCACHI2_1'] = F.MTDOCACHI2(1, v2_pvs) vars_Bst['MTDOCACHI2_2'] = F.MTDOCACHI2(2, v2_pvs) + #vars_Bst['Dstar_M'] = F.MASS @ ((F.FOURMOMENTUM @ D0_child)+(F.FOURMOMENTUM @ Epi_child)) + #vars_Bst['D0_M'] = F.MASS @ (F.FOURMOMENTUM @ D0_child) + #vars_Bst['test_id'] = F.PARTICLE_ID @ D0_child + vars_Bst['Delta_M'] = F.ABS @ ((F.MASS @ ((F.FOURMOMENTUM @ D0_child)+(F.FOURMOMENTUM @ Epi_child))) - (F.MASS @ D0_child)) #define fields fields = {} - fields['Sb'] = f'[B0 -> (B- -> (D0 -> K- pi+) e-) [pi+]CC]CC' - fields['Lb'] = f'[B0 -> ^(B- -> (D0 -> K- pi+) e-) [pi+]CC]CC' - fields['Lc'] = f'[B0 -> (B- -> ^(D0 -> K- pi+) e-) [pi+]CC]CC' - fields['Lep'] = f'[B0 -> (B- -> (D0 -> K- pi+) ^e-) [pi+]CC]CC' - fields['Epi'] = f'[B0 -> (B- -> (D0 -> K- pi+) e-) ^[pi+]CC]CC' - fields['Km'] = f'[B0 -> (B- -> (D0 -> ^K- pi+) e-) [pi+]CC]CC' - fields['pip'] = f'[B0 -> (B- -> (D0 -> K- ^pi+) e-) [pi+]CC]CC' + fields['Sb'] = f'[B0 -> (B- -> (D0 -> K- pi+) mu-) [pi+]CC]CC' + fields['Lb'] = f'[B0 -> ^(B- -> (D0 -> K- pi+) mu-) [pi+]CC]CC' + fields['Lc'] = f'[B0 -> (B- -> ^(D0 -> K- pi+) mu-) [pi+]CC]CC' + fields['Lep'] = f'[B0 -> (B- -> (D0 -> K- pi+) ^mu-) [pi+]CC]CC' + fields['Epi'] = f'[B0 -> (B- -> (D0 -> K- pi+) mu-) ^[pi+]CC]CC' + fields['Km'] = f'[B0 -> (B- -> (D0 -> ^K- pi+) mu-) [pi+]CC]CC' + fields['pip'] = f'[B0 -> (B- -> (D0 -> K- ^pi+) mu-) [pi+]CC]CC' #add variables variables = {} @@ -303,14 +308,14 @@ def get_extra_pions(): #def main(options): def main(options: Options): - line_name = ['SpruceSLB_BuToD0ENu_D0ToKPi','SpruceSLB_BuToD0TauNu_D0ToKPi_TauToENuNu'] + line_name = ['SpruceSLB_BuToD0MuNu_D0ToKPi','SpruceSLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu'] #define filer - my_filter_e = create_lines_filter(name="Filter_e", lines=[line_name[0]]) + my_filter_mu = create_lines_filter(name="Filter_mu", lines=[line_name[0]]) my_filter_tau = create_lines_filter(name="Filter_tau", lines=[line_name[1]]) #get data and extra particles - lb_e = get_particles(f"/Event/Spruce/{line_name[0]}/Particles") + lb_mu = get_particles(f"/Event/Spruce/{line_name[0]}/Particles") lb_tau = get_particles(f"/Event/Spruce/{line_name[1]}/Particles") extra_particles = get_extra_pions() @@ -319,17 +324,17 @@ def main(options: Options): rec_summary = get_rec_summary() hadron_candidate_id = 421 #make sb candidate - Bst_e = make_Bst(lb_e, extra_particles,'e',hadron_candidate_id,v2_pvs,False) + Bst_mu = make_Bst(lb_mu, extra_particles,'mu',hadron_candidate_id,v2_pvs,False) Bst_tau = make_Bst(lb_tau, extra_particles,'tau', hadron_candidate_id,v2_pvs,False) #MCTRUTH_Bst = MCTruthAndBkgCat(Bst, name='MCTRUTH_Bst') - tuple_file_e = tuple_Bst(Bst_e,'e', 'None', v2_pvs, rec_summary) + tuple_file_mu = tuple_Bst(Bst_mu,'mu', 'None', v2_pvs, rec_summary) tuple_file_tau = tuple_Bst(Bst_tau,'tau', 'None', v2_pvs, rec_summary) #define algorithms user_algorithms = {} - user_algorithms['Alg_e'] = [my_filter_e, tuple_file_e] + user_algorithms['Alg_mu'] = [my_filter_mu, tuple_file_mu] user_algorithms['Alg_tau'] = [my_filter_tau, tuple_file_tau] return make_config(options, user_algorithms) -- GitLab From d27d5fa1a9bf6e27cc018652d75e7ffa8474e9da Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Sun, 12 May 2024 11:40:41 +0200 Subject: [PATCH 19/57] Add D0toKpi l nu fakeline --- SL_e_nu_D0toKpi_fakeline_2024_data/info.yaml | 43 +++ SL_e_nu_D0toKpi_fakeline_2024_data/run_Dzl.py | 340 ++++++++++++++++++ SL_mu_nu_D0toKpi_2024_data/run_Dzl.py | 26 +- SL_mu_nu_D0toKpi_fakeline_2024_data/info.yaml | 43 +++ .../run_Dzl.py | 340 ++++++++++++++++++ 5 files changed, 779 insertions(+), 13 deletions(-) create mode 100644 SL_e_nu_D0toKpi_fakeline_2024_data/info.yaml create mode 100644 SL_e_nu_D0toKpi_fakeline_2024_data/run_Dzl.py create mode 100644 SL_mu_nu_D0toKpi_fakeline_2024_data/info.yaml create mode 100644 SL_mu_nu_D0toKpi_fakeline_2024_data/run_Dzl.py diff --git a/SL_e_nu_D0toKpi_fakeline_2024_data/info.yaml b/SL_e_nu_D0toKpi_fakeline_2024_data/info.yaml new file mode 100644 index 0000000000..c4f455a0ee --- /dev/null +++ b/SL_e_nu_D0toKpi_fakeline_2024_data/info.yaml @@ -0,0 +1,43 @@ +checks: + hist: + type: range + expression: Sb_Delta_M + limits: + min: 130 + max: 200 + n_bins: 70 + +defaults: + application: "DaVinci/v64r4" + output: DATA.ROOT + options: + entrypoint: SL_e_nu_D0toKpi_fakeline_2024_data.run_Dzl:main + extra_options: + input_raw_format: 0.5 + input_type: ROOT # ROOT for SprucingPass, RAW for RAW data (Hlt2 output) + simulation: False + #data_type: "Upgrade" + geometry_version: run3/2024.Q1.2-v00.00 + conditions_version: master + input_process: "Spruce" # Spruce for SprucingPass, "Hlt2" for RAW data (Hlt2 output) + input_stream: "sl" # for streamed data + #evt_max: 1000 + inform: + - ching-hua.li@cern.ch + wg: SL + +{%- set datasets = [ + ('2024Data', 'Down'), +]%} +{%- for evttype, polarity in datasets %} +b0_dstp_e_and_taue_fake_{{ evttype }}_{{ polarity }}: + input: + bk_query: "/LHCb/Collision24/Beam6800GeV-VeloClosed-Mag{{ polarity }}-Excl-UT/Real Data/Sprucing24c1/90000000/SL.DST" + dq_flags: + - UNCHECKED + - OK + keep_running: true + n_test_lfns: 1 + checks: + - hist +{%- endfor %} diff --git a/SL_e_nu_D0toKpi_fakeline_2024_data/run_Dzl.py b/SL_e_nu_D0toKpi_fakeline_2024_data/run_Dzl.py new file mode 100644 index 0000000000..8bc45c7c87 --- /dev/null +++ b/SL_e_nu_D0toKpi_fakeline_2024_data/run_Dzl.py @@ -0,0 +1,340 @@ +import sys,os,math +from PyConf.reading import get_pvs, get_rec_summary, get_particles +import Functors as F +from FunTuple import FunctorCollection +from FunTuple import FunTuple_Particles as Funtuple +from DaVinci.algorithms import create_lines_filter +from DaVinci import Options,make_config +import FunTuple.functorcollections as FC +from DaVinciMCTools import MCTruthAndBkgCat +from Hlt2Conf.algorithms_thor import ParticleCombiner, ParticleFilter +from Hlt2Conf.algorithms_thor import ParticleContainersMerger +from Functors.grammar import Functor +from Hlt2Conf.standard_particles import make_has_rich_long_pions,make_has_rich_up_pions,make_has_rich_down_pions + +_BPVCORRM = Functor('_BPVCORRM', 'Composite::CorrectedMass','Compute the corrected mass') +_allpv_FDVEC = (F.ENDVERTEX_POS @ F.FORWARDARG1 - F.TOLINALG @ F.POSITION @ F.FORWARDARG0) +_allpv_NORMEDDOT = F.NORMEDDOT.bind(F.THREEMOMENTUM @ F.FORWARDARG1, _allpv_FDVEC) +#ALLPV_CHI2 = lambda Vertices: F.MAP(F.CHI2) @ F.TES(Vertices) +#ALLPV_CHI2DOF = lambda Vertices: F.MAP(F.CHI2DOF) @ F.TES(Vertices) +ALLPV_IPCHI2 = lambda Vertices: F.MAP(F.IPCHI2).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_FDCHI2 = lambda Vertices: F.MAP(F.VTX_FDCHI2).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_DIRA = lambda Vertices: F.MAP(_allpv_NORMEDDOT).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_CORRM = lambda Vertices: F.MAP(_BPVCORRM).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_LTIME = lambda Vertices: F.MAP(F.VTX_LTIME).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_DLS = lambda Vertices: F.MAP(F.VTX_DLS).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_FD_COORDINATE = lambda coordinate, Vertices: F.MAP(coordinate @ _allpv_FDVEC).bind(F.TES(Vertices), F.FORWARDARGS) +#MCNEUTRINO = F.FIND_MCDECAY("[ Lambda_b0 => Lambda_c+ mu- ^nu_mu~ ]CC") + +TRUE_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.PARTICLE_ID) == id) +#MCMOTHER_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.MC_MOTHER(1, F.PARTICLE_ID)) == id) +#GD_MCMOTHER_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.MC_MOTHER(2, F.PARTICLE_ID)) == id) +#GD_GD_MCMOTHER_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.MC_MOTHER(3, F.PARTICLE_ID)) == id) + +def make_Bst(B, pions,lepton, hadron_candidate_id,v2_pvs,do_truth_matching = True): + if do_truth_matching == True : + #filter B keeping only true D0 and true leptons + MCTRUTH_B = MCTruthAndBkgCat(B, name='MCTRUTH_Bu') + Dz_child = F.CHILD(1, F.FORWARDARG0) #get the first child of B*- which is D0 + lep_child = F.CHILD(2, F.FORWARDARG0) #get the second child of B*- which is lepton + Dz_truth_cut = TRUE_ID_IS(hadron_candidate_id, MCTRUTH_B) @ Dz_child #require that D0 is true + lep_truth_cut = F.require_any(TRUE_ID_IS(11, MCTRUTH_B) @ lep_child , TRUE_ID_IS(13, MCTRUTH_B) @ lep_child) #require that lepton is true i.e. electron or muon + cut_b = F.require_all(Dz_truth_cut, lep_truth_cut) #make a cut + signal_B = ParticleFilter(Input=B, Cut=F.FILTER(cut_b), name='signal_Dzmu') #filter the B candidates + else : signal_B = B + + #combine to make [B*0 -> B*- pi+]cc + Bst_1 = ParticleCombiner( + Inputs=[B, pions], + name=f'Bst_1_{lepton}', + DecayDescriptor='[B0 -> B- pi+]cc', + CombinationCut=F.ALL, + CompositeCut=F.ALL, + ParticleCombiner="ParticleVertexFitter", + PrimaryVertices=v2_pvs + #OutputLevel=1 + ) + #combine to make [B*0 -> B*- pi-]cc + Bst_2 = ParticleCombiner( + Inputs=[B, pions], + name=f'Bst_2_{lepton}', + DecayDescriptor='[B0 -> B- pi-]cc', + CombinationCut=F.ALL, + CompositeCut=F.ALL, + ParticleCombiner="ParticleVertexFitter", + PrimaryVertices=v2_pvs + #OutputLevel=1 + ) + #merge the two Bst candidates + Bst = ParticleContainersMerger([Bst_1, Bst_2], name = f'Bst_combiner_{lepton}') + return Bst + +def get_functors(MCTRUTH, v2_pvs, rec_summary): + #define common variables for all fields (composite and basic) + vars_common = FunctorCollection() + #all pvs: ip, ipchi2. The PV positions are stored in event variables + vars_common['ALLPV_IP[pv_indx]'] = F.ALLPV_IP(v2_pvs) + vars_common['ALLPV_IPCHI2[pv_indx]'] = ALLPV_IPCHI2(v2_pvs) + #best pv: x, y, z, ip, ipchi2 + vars_common['BPV_X'] = F.BPVX(v2_pvs) + vars_common['BPV_Y'] = F.BPVY(v2_pvs) + vars_common['BPV_Z'] = F.BPVZ(v2_pvs) + vars_common['BPV_IP'] = F.BPVIP(v2_pvs) + vars_common['BPV_IPCHI2'] = F.BPVIPCHI2(v2_pvs) + vars_common['BPV_CHI2'] = F.CHI2 @ F.BPV(v2_pvs) + vars_common['BPV_CHI2DOF'] = F.CHI2DOF @ F.BPV(v2_pvs) + #particle id, key, truekey. The trueid is stored in MCHierarchy + vars_common['ID'] = F.PARTICLE_ID + vars_common['KEY'] = F.OBJECT_KEY + #get charge, min ip and min ipchi2 + vars_common['CHARGE'] = F.CHARGE + vars_common['MINIP'] = F.MINIP(v2_pvs) + vars_common['MINIPCHI2'] = F.MINIPCHI2(v2_pvs) + #reco kinematics + vars_common += FC.Kinematics() + vars_common['ETA'] = F.ETA + vars_common['PHI'] = F.PHI + if MCTRUTH != 'None': + #mc vars + vars_common['TRUEKEY'] = F.VALUE_OR(-1) @ MCTRUTH(F.OBJECT_KEY) + vars_common += FC.MCKinematics(mctruth_alg = MCTRUTH) + vars_common['TRUEETA'] = MCTRUTH(F.ETA) + vars_common['TRUEPHI'] = MCTRUTH(F.PHI) + #type of the origin vertex + vars_common['MC_VTX_TYPE'] = MCTRUTH(F.VALUE_OR(-1) @ F.MC_VTX_TYPE @ F.MC_ORIGINVERTEX) + ##mc truth hierarchy (done seperately) + #vars_common += FC.MCHierarchy(mctruth_alg = MCTRUTH) + #make some helper functions + MCMOTHER_ID = lambda n: F.VALUE_OR(0) @ MCTRUTH(F.MC_MOTHER(n, F.PARTICLE_ID)) + MCMOTHER_KEY = lambda n: F.VALUE_OR(-1) @ MCTRUTH(F.MC_MOTHER(n, F.OBJECT_KEY )) + vars_common["TRUEID"] = F.VALUE_OR(0) @ MCTRUTH(F.PARTICLE_ID) + vars_common["MCKEY"] = F.VALUE_OR(0) @ MCTRUTH(F.OBJECT_KEY) + vars_common["MC_MOTHER_ID"] = MCMOTHER_ID(1) + vars_common["MC_MOTHER_KEY"] = MCMOTHER_KEY(1) + for i in range(2,14): + prefix = "MC_GD_MOTHER_{}".format(i) + vars_common[f"{prefix}_ID"] = MCMOTHER_ID(i) + vars_common[f"{prefix}_KEY"] = MCMOTHER_KEY(i) + + #variables for composite particles + vars_composite = FunctorCollection() + #end vertex position and end vertex chi2 + vars_composite['ENDVERTEX_POS_'] = F.ENDVERTEX_POS + vars_composite['ENDVERTEX_CHI2'] = F.CHI2 @ F.ENDVERTEX + vars_composite['ENDVERTEX_CHI2DOF'] = F.CHI2DOF @ F.ENDVERTEX + #all pvs: dira, fd, fdchi2 + vars_composite['ALLPV_DIRA[pv_indx]'] = ALLPV_DIRA(v2_pvs) + vars_composite['ALLPV_FD_X[pv_indx]'] = ALLPV_FD_COORDINATE(F.X_COORDINATE, v2_pvs) + vars_composite['ALLPV_FD_Y[pv_indx]'] = ALLPV_FD_COORDINATE(F.Y_COORDINATE, v2_pvs) + vars_composite['ALLPV_FD_Z[pv_indx]'] = ALLPV_FD_COORDINATE(F.Z_COORDINATE, v2_pvs) + vars_composite['ALLPV_FDCHI2[pv_indx]'] = ALLPV_FDCHI2(v2_pvs) + vars_composite['ALLPV_CORRM[pv_indx]'] = ALLPV_CORRM(v2_pvs) + vars_composite['ALLPV_LTIME[pv_indx]'] = ALLPV_LTIME(v2_pvs) + vars_composite['ALLPV_DLS[pv_indx]'] = ALLPV_DLS(v2_pvs) + #best pv: dira, fd, fdchi2, corrm, ltime, dls + vars_composite['BPV_DIRA'] = F.BPVDIRA(v2_pvs) + vars_composite['BPV_FD_'] = F.BPVFDVEC(v2_pvs) + vars_composite['BPV_FDCHI2'] = F.BPVFDCHI2(v2_pvs) + vars_composite['BPV_CORRM'] = F.BPVCORRM(v2_pvs) + vars_composite['BPV_LTIME'] = F.BPVLTIME(v2_pvs) + vars_composite['BPV_DLS'] = F.BPVDLS(v2_pvs) + #mc composite vertex information + + if MCTRUTH != 'None': vars_composite += FC.MCVertexInfo(mctruth_alg = MCTRUTH) + #Compute maximum DOCA and maximum DOCACHI2. Since there are + # only two daughters of Sb particles, the maximum DOCA/DOCACHI2 is + # the DOCA/DOCACHI2 see below. + vars_composite['MAX_DOCA'] = F.MAXDOCA + vars_composite['MAX_DOCACHI2'] = F.MAXDOCACHI2 + vars_composite['MAX_SDOCA'] = F.MAXSDOCA + vars_composite['MAX_SDOCACHI2'] = F.MAXSDOCACHI2 + + #variables for Lb field + var_B = FunctorCollection() + #var_B['TRUENU_PX'] = MCTRUTH(F.PX @ MCNEUTRINO) + #var_B['TRUENU_PY'] = MCTRUTH(F.PY @ MCNEUTRINO) + #var_B['TRUENU_PZ'] = MCTRUTH(F.PZ @ MCNEUTRINO) + #var_B['TRUENU_ENERGY'] = MCTRUTH(F.ENERGY @ MCNEUTRINO) + ###Bkg category + ##var_B["BKGCAT"] = MCTRUTH.BkgCat + + #variables for basics + vars_basic = FunctorCollection() + vars_basic['TRACKTYPE'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKTYPE @ F.TRACK + vars_basic['TRACKHISTORY'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKHISTORY @ F.TRACK + vars_basic['TRACKFLAG'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKFLAG @ F.TRACK + vars_basic['TRACKNDOF'] = F.VALUE_OR(-1) @ F.NDOF @ F.TRACK + vars_basic['TRACKCHI2'] = F.CHI2 @ F.TRACK + vars_basic['TRACKCHI2DOF'] = F.CHI2DOF @ F.TRACK + vars_basic['GHOSTPROB'] = F.GHOSTPROB + vars_basic['PIDpi'] = F.PID_PI + vars_basic['PIDk'] = F.PID_K + vars_basic['PIDp'] = F.PID_P + vars_basic['PIDe'] = F.PID_E + vars_basic['PIDmu'] = F.PID_MU + if MCTRUTH != 'None': + vars_basic['TRUEORIGINVERTEX_X'] = MCTRUTH(F.ORIGIN_VX) + vars_basic['TRUEORIGINVERTEX_Y'] = MCTRUTH(F.ORIGIN_VY) + vars_basic['TRUEORIGINVERTEX_Z'] = MCTRUTH(F.ORIGIN_VZ) + + #variables for event + evt_vars = FunctorCollection() + #evt_vars['ALLPV_X[pv_indx]'] = F.ALLPVX(v2_pvs) + #evt_vars['ALLPV_Y[pv_indx]'] = F.ALLPVY(v2_pvs) + #evt_vars['ALLPV_Z[pv_indx]'] = F.ALLPVZ(v2_pvs) + #evt_vars['ALLPV_CHI2[pv_indx]'] = ALLPV_CHI2(v2_pvs) + #evt_vars['ALLPV_CHI2DOF[pv_indx]']= ALLPV_CHI2DOF(v2_pvs) + evt_vars['nTracks'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nTracks") + evt_vars['nLongTracks'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nLongTracks") + evt_vars['nPVs'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nPVs") + + vars_brems = FunctorCollection({}) + vars_brems.update({"HASBREM": F.HASBREM}) + #vars_brems.update({"HASBREMADDED": F.HASBREMADDED}) + vars_brems.update({"BREMENERGY": F.BREMENERGY}) + vars_brems.update({"BREMBENDCORR": F.BREMBENDCORR}) + vars_brems.update({"BREMPIDE": F.BREMPIDE}) + vars_brems.update({"ECALPIDE": F.ECALPIDE}) + vars_brems.update({"ECALPIDMU": F.ECALPIDMU}) + vars_brems.update({"HCALPIDE": F.HCALPIDE}) + vars_brems.update({"HCALPIDMU": F.HCALPIDMU}) + vars_brems.update({"ELECTRONSHOWEREOP": F.ELECTRONSHOWEREOP}) + vars_brems.update({"ELECTRONSHOWERDLL": F.ELECTRONSHOWERDLL}) + vars_brems.update({"CLUSTERMATCH": F.CLUSTERMATCH_CHI2}) + vars_brems.update({"ELECTRONMATCH": F.ELECTRONMATCH_CHI2}) + vars_brems.update({"BREMHYPOMATCH": F.BREMHYPOMATCH_CHI2}) + vars_brems.update({"ELECTRONENERGY": F.ELECTRONENERGY}) + vars_brems.update({"BREMHYPOENERGY": F.BREMHYPOENERGY}) + vars_brems.update({"BREMHYPODELTAX": F.BREMHYPODELTAX}) + #vars_brems.update({"BREMTRACKBASEDENERGY": F.BREMTRACKBASEDENERGY}) + vars_brems.update({"INBREM": F.INBREM}) + vars_brems.update({"PT_WITH_BREM": F.PT_WITH_BREM}) + vars_brems.update({"P_WITH_BREM": F.P_WITH_BREM}) + + #return all functors + functors = (vars_common, vars_composite, var_B, vars_basic, evt_vars,vars_brems) + return functors + +def tuple_Bst(Bst,lepton, MCTRUTH, v2_pvs, rec_summary): + #get functors + functors = get_functors(MCTRUTH, v2_pvs, rec_summary) + vars_common = functors[0] + vars_composite = functors[1] + var_B = functors[2] + vars_basic = functors[3] + evt_vars = functors[4] + vars_brems = functors[5] + + #variables for Sb field + vars_Bst = FunctorCollection() + B_child = F.CHILD(1, F.FORWARDARG0) + D0_child = F.CHILD(1, F.CHILD(1,F.FORWARDARG0)) + Epi_child = F.CHILD(2, F.FORWARDARG0) + bpv_pi = F.BPV(v2_pvs).bind(Epi_child) + #diff in vtx chi2 with and without extra particle + vars_Bst['DELTA_ENDVERTEX_CHI2'] = (F.CHI2 @ F.ENDVERTEX) - (F.CHI2 @ F.ENDVERTEX.bind(B_child)) + #IP and IPChi2 of extra particle wrt to Sb end vertex + vars_Bst['Epi_IP_WRT_SbENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ F.FORWARDARG0 , Epi_child) + vars_Bst['Epi_IPCHI2_WRT_SbENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ F.FORWARDARG0 , Epi_child) + #IP and IPChi2 of extra particle wrt to Lb end vertex + vars_Bst['Epi_IP_WRT_LbENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ B_child , Epi_child) + vars_Bst['Epi_IPCHI2_WRT_LbENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ B_child , Epi_child) + #angle between extra particle and Lb + vars_Bst['Epi_COSANGLE_Lb'] = F.COSANGLE.bind(F.THREEMOMENTUM @ B_child, F.THREEMOMENTUM @ Epi_child) + #diff in fd chi2 with and without extra particle + vars_Bst['Delta_BPV_of_Epi_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi, F.FORWARDARGS) - F.VTX_FDCHI2.bind(bpv_pi, B_child) + vars_Bst['BPV_of_Epi_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi, F.FORWARDARGS) + #IP chi2 of extra particle wrt PV and SV of Sb + vars_Bst['Epi_IP_WRT_SbBPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child) + vars_Bst['Epi_IPCHI2_WRT_SbBPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child) + #IP chi2 of extra particle wrt PV and SV of Bb + vars_Bst['Epi_IP_WRT_LbBPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ B_child, Epi_child) + vars_Bst['Epi_IPCHI2_WRT_LbBPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ B_child, Epi_child) + #DOCA and DOCACHI2 b/w Lb and extra particle + vars_Bst['DOCA12'] = F.DOCA(1, 2) + vars_Bst['DOCA12_CHI2_12'] = F.DOCACHI2(1, 2) + #vars_Bst['SDOCA12'] = F.SDOCA(1, 2) + #vars_Bst['SDOCA_CHI2_12'] = F.SDOCACHI2(1, 2) + #DOCACHI2 of extra particle wrt to mother i.e. Sb + vars_Bst['MTDOCACHI2_1'] = F.MTDOCACHI2(1, v2_pvs) + vars_Bst['MTDOCACHI2_2'] = F.MTDOCACHI2(2, v2_pvs) + #vars_Bst['Dstar_M'] = F.MASS @ ((F.FOURMOMENTUM @ D0_child)+(F.FOURMOMENTUM @ Epi_child)) + #vars_Bst['D0_M'] = F.MASS @ (F.FOURMOMENTUM @ D0_child) + #vars_Bst['test_id'] = F.PARTICLE_ID @ D0_child + vars_Bst['Delta_M'] = F.ABS @ ((F.MASS @ ((F.FOURMOMENTUM @ D0_child)+(F.FOURMOMENTUM @ Epi_child))) - (F.MASS @ D0_child)) + + #define fields + fields = {} + fields['Sb'] = f'[B0 -> (B- -> (D0 -> K- pi+) {lepton}-) [pi+]CC]CC' + fields['Lb'] = f'[B0 -> ^(B- -> (D0 -> K- pi+) {lepton}-) [pi+]CC]CC' + fields['Lc'] = f'[B0 -> (B- -> ^(D0 -> K- pi+) {lepton}-) [pi+]CC]CC' + fields['Lep'] = f'[B0 -> (B- -> (D0 -> K- pi+) ^{lepton}-) [pi+]CC]CC' + fields['Epi'] = f'[B0 -> (B- -> (D0 -> K- pi+) {lepton}-) ^[pi+]CC]CC' + fields['Km'] = f'[B0 -> (B- -> (D0 -> ^K- pi+) {lepton}-) [pi+]CC]CC' + fields['pip'] = f'[B0 -> (B- -> (D0 -> K- ^pi+) {lepton}-) [pi+]CC]CC' + + #add variables + variables = {} + variables["ALL"] = vars_common + variables["Sb"] = vars_composite + vars_Bst + variables["Lb"] = vars_composite + var_B + variables["Lc"] = vars_composite + variables["Lep"] = vars_basic + vars_brems + variables["Epi"] = vars_basic + vars_brems + variables["Km"] = vars_basic + vars_brems + variables["pip"] = vars_basic + vars_brems + + #define tuple + my_tuple = Funtuple( + name=f"Tuple_{lepton}", + tuple_name="DecayTree", + fields=fields, + variables=variables, + inputs=Bst) + + return my_tuple + +def get_extra_pions(): + """ + Note this function in DaVinci requires: + https://gitlab.cern.ch/lhcb/Moore/-/merge_requests/3203 + and it's related LHCb, DaVinci and Rec MRs + """ + long_pions = make_has_rich_long_pions() + up_pions = make_has_rich_up_pions() + down_pions = make_has_rich_down_pions() + return ParticleContainersMerger([long_pions, up_pions, down_pions], + name='Pions_combiner') + +#def main(options): +def main(options: Options): + line_name = ['SpruceSLB_BuToD0ENu_D0ToKPi_FakeElectron','SpruceSLB_BuToD0TauNu_D0ToKPi_FakeElectron'] + + #define filer + my_filter_l = create_lines_filter(name="Filter_l", lines=[line_name[0]]) + my_filter_tau = create_lines_filter(name="Filter_tau", lines=[line_name[1]]) + + #get data and extra particles + lb_l = get_particles(f"/Event/Spruce/{line_name[0]}/Particles") + lb_tau = get_particles(f"/Event/Spruce/{line_name[1]}/Particles") + extra_particles = get_extra_pions() + + #get v2_pvs and rec_summary + v2_pvs = get_pvs() + rec_summary = get_rec_summary() + hadron_candidate_id = 421 + #make sb candidate + Bst_l = make_Bst(lb_l, extra_particles,'e',hadron_candidate_id,v2_pvs,False) + Bst_tau = make_Bst(lb_tau, extra_particles,'tau', hadron_candidate_id,v2_pvs,False) + #MCTRUTH_Bst = MCTruthAndBkgCat(Bst, name='MCTRUTH_Bst') + + + tuple_file_l = tuple_Bst(Bst_l,'e', 'None', v2_pvs, rec_summary) + tuple_file_tau = tuple_Bst(Bst_tau,'tau', 'None', v2_pvs, rec_summary) + + #define algorithms + user_algorithms = {} + user_algorithms['Alg_l'] = [my_filter_l, tuple_file_l] + user_algorithms['Alg_tau'] = [my_filter_tau, tuple_file_tau] + + return make_config(options, user_algorithms) diff --git a/SL_mu_nu_D0toKpi_2024_data/run_Dzl.py b/SL_mu_nu_D0toKpi_2024_data/run_Dzl.py index 0f0491375b..0cb5e40d2a 100644 --- a/SL_mu_nu_D0toKpi_2024_data/run_Dzl.py +++ b/SL_mu_nu_D0toKpi_2024_data/run_Dzl.py @@ -265,13 +265,13 @@ def tuple_Bst(Bst,lepton, MCTRUTH, v2_pvs, rec_summary): #define fields fields = {} - fields['Sb'] = f'[B0 -> (B- -> (D0 -> K- pi+) mu-) [pi+]CC]CC' - fields['Lb'] = f'[B0 -> ^(B- -> (D0 -> K- pi+) mu-) [pi+]CC]CC' - fields['Lc'] = f'[B0 -> (B- -> ^(D0 -> K- pi+) mu-) [pi+]CC]CC' - fields['Lep'] = f'[B0 -> (B- -> (D0 -> K- pi+) ^mu-) [pi+]CC]CC' - fields['Epi'] = f'[B0 -> (B- -> (D0 -> K- pi+) mu-) ^[pi+]CC]CC' - fields['Km'] = f'[B0 -> (B- -> (D0 -> ^K- pi+) mu-) [pi+]CC]CC' - fields['pip'] = f'[B0 -> (B- -> (D0 -> K- ^pi+) mu-) [pi+]CC]CC' + fields['Sb'] = f'[B0 -> (B- -> (D0 -> K- pi+) {lepton}-) [pi+]CC]CC' + fields['Lb'] = f'[B0 -> ^(B- -> (D0 -> K- pi+) {lepton}-) [pi+]CC]CC' + fields['Lc'] = f'[B0 -> (B- -> ^(D0 -> K- pi+) {lepton}-) [pi+]CC]CC' + fields['Lep'] = f'[B0 -> (B- -> (D0 -> K- pi+) ^{lepton}-) [pi+]CC]CC' + fields['Epi'] = f'[B0 -> (B- -> (D0 -> K- pi+) {lepton}-) ^[pi+]CC]CC' + fields['Km'] = f'[B0 -> (B- -> (D0 -> ^K- pi+) {lepton}-) [pi+]CC]CC' + fields['pip'] = f'[B0 -> (B- -> (D0 -> K- ^pi+) {lepton}-) [pi+]CC]CC' #add variables variables = {} @@ -308,14 +308,14 @@ def get_extra_pions(): #def main(options): def main(options: Options): - line_name = ['SpruceSLB_BuToD0MuNu_D0ToKPi','SpruceSLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu'] + line_name = ['SpruceSLB_BuToD0MuNu_D0ToKPi','SpruceSLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu'] #define filer - my_filter_mu = create_lines_filter(name="Filter_mu", lines=[line_name[0]]) + my_filter_l = create_lines_filter(name="Filter_l", lines=[line_name[0]]) my_filter_tau = create_lines_filter(name="Filter_tau", lines=[line_name[1]]) #get data and extra particles - lb_mu = get_particles(f"/Event/Spruce/{line_name[0]}/Particles") + lb_l = get_particles(f"/Event/Spruce/{line_name[0]}/Particles") lb_tau = get_particles(f"/Event/Spruce/{line_name[1]}/Particles") extra_particles = get_extra_pions() @@ -324,17 +324,17 @@ def main(options: Options): rec_summary = get_rec_summary() hadron_candidate_id = 421 #make sb candidate - Bst_mu = make_Bst(lb_mu, extra_particles,'mu',hadron_candidate_id,v2_pvs,False) + Bst_l = make_Bst(lb_l, extra_particles,'mu',hadron_candidate_id,v2_pvs,False) Bst_tau = make_Bst(lb_tau, extra_particles,'tau', hadron_candidate_id,v2_pvs,False) #MCTRUTH_Bst = MCTruthAndBkgCat(Bst, name='MCTRUTH_Bst') - tuple_file_mu = tuple_Bst(Bst_mu,'mu', 'None', v2_pvs, rec_summary) + tuple_file_l = tuple_Bst(Bst_l,'mu', 'None', v2_pvs, rec_summary) tuple_file_tau = tuple_Bst(Bst_tau,'tau', 'None', v2_pvs, rec_summary) #define algorithms user_algorithms = {} - user_algorithms['Alg_mu'] = [my_filter_mu, tuple_file_mu] + user_algorithms['Alg_l'] = [my_filter_l, tuple_file_l] user_algorithms['Alg_tau'] = [my_filter_tau, tuple_file_tau] return make_config(options, user_algorithms) diff --git a/SL_mu_nu_D0toKpi_fakeline_2024_data/info.yaml b/SL_mu_nu_D0toKpi_fakeline_2024_data/info.yaml new file mode 100644 index 0000000000..c2d8975aac --- /dev/null +++ b/SL_mu_nu_D0toKpi_fakeline_2024_data/info.yaml @@ -0,0 +1,43 @@ +checks: + hist: + type: range + expression: Sb_Delta_M + limits: + min: 130 + max: 200 + n_bins: 70 + +defaults: + application: "DaVinci/v64r4" + output: DATA.ROOT + options: + entrypoint: SL_mu_nu_D0toKpi_fakeline_2024_data.run_Dzl:main + extra_options: + input_raw_format: 0.5 + input_type: ROOT # ROOT for SprucingPass, RAW for RAW data (Hlt2 output) + simulation: False + #data_type: "Upgrade" + geometry_version: run3/2024.Q1.2-v00.00 + conditions_version: master + input_process: "Spruce" # Spruce for SprucingPass, "Hlt2" for RAW data (Hlt2 output) + input_stream: "sl" # for streamed data + #evt_max: 1000 + inform: + - ching-hua.li@cern.ch + wg: SL + +{%- set datasets = [ + ('2024Data', 'Down'), +]%} +{%- for evttype, polarity in datasets %} +b0_dstp_muon_and_taumu_fake_{{ evttype }}_{{ polarity }}: + input: + bk_query: "/LHCb/Collision24/Beam6800GeV-VeloClosed-Mag{{ polarity }}-Excl-UT/Real Data/Sprucing24c1/90000000/SL.DST" + dq_flags: + - UNCHECKED + - OK + keep_running: true + n_test_lfns: 1 + checks: + - hist +{%- endfor %} diff --git a/SL_mu_nu_D0toKpi_fakeline_2024_data/run_Dzl.py b/SL_mu_nu_D0toKpi_fakeline_2024_data/run_Dzl.py new file mode 100644 index 0000000000..2d3d332375 --- /dev/null +++ b/SL_mu_nu_D0toKpi_fakeline_2024_data/run_Dzl.py @@ -0,0 +1,340 @@ +import sys,os,math +from PyConf.reading import get_pvs, get_rec_summary, get_particles +import Functors as F +from FunTuple import FunctorCollection +from FunTuple import FunTuple_Particles as Funtuple +from DaVinci.algorithms import create_lines_filter +from DaVinci import Options,make_config +import FunTuple.functorcollections as FC +from DaVinciMCTools import MCTruthAndBkgCat +from Hlt2Conf.algorithms_thor import ParticleCombiner, ParticleFilter +from Hlt2Conf.algorithms_thor import ParticleContainersMerger +from Functors.grammar import Functor +from Hlt2Conf.standard_particles import make_has_rich_long_pions,make_has_rich_up_pions,make_has_rich_down_pions + +_BPVCORRM = Functor('_BPVCORRM', 'Composite::CorrectedMass','Compute the corrected mass') +_allpv_FDVEC = (F.ENDVERTEX_POS @ F.FORWARDARG1 - F.TOLINALG @ F.POSITION @ F.FORWARDARG0) +_allpv_NORMEDDOT = F.NORMEDDOT.bind(F.THREEMOMENTUM @ F.FORWARDARG1, _allpv_FDVEC) +#ALLPV_CHI2 = lambda Vertices: F.MAP(F.CHI2) @ F.TES(Vertices) +#ALLPV_CHI2DOF = lambda Vertices: F.MAP(F.CHI2DOF) @ F.TES(Vertices) +ALLPV_IPCHI2 = lambda Vertices: F.MAP(F.IPCHI2).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_FDCHI2 = lambda Vertices: F.MAP(F.VTX_FDCHI2).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_DIRA = lambda Vertices: F.MAP(_allpv_NORMEDDOT).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_CORRM = lambda Vertices: F.MAP(_BPVCORRM).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_LTIME = lambda Vertices: F.MAP(F.VTX_LTIME).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_DLS = lambda Vertices: F.MAP(F.VTX_DLS).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_FD_COORDINATE = lambda coordinate, Vertices: F.MAP(coordinate @ _allpv_FDVEC).bind(F.TES(Vertices), F.FORWARDARGS) +#MCNEUTRINO = F.FIND_MCDECAY("[ Lambda_b0 => Lambda_c+ mu- ^nu_mu~ ]CC") + +TRUE_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.PARTICLE_ID) == id) +#MCMOTHER_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.MC_MOTHER(1, F.PARTICLE_ID)) == id) +#GD_MCMOTHER_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.MC_MOTHER(2, F.PARTICLE_ID)) == id) +#GD_GD_MCMOTHER_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.MC_MOTHER(3, F.PARTICLE_ID)) == id) + +def make_Bst(B, pions,lepton, hadron_candidate_id,v2_pvs,do_truth_matching = True): + if do_truth_matching == True : + #filter B keeping only true D0 and true leptons + MCTRUTH_B = MCTruthAndBkgCat(B, name='MCTRUTH_Bu') + Dz_child = F.CHILD(1, F.FORWARDARG0) #get the first child of B*- which is D0 + lep_child = F.CHILD(2, F.FORWARDARG0) #get the second child of B*- which is lepton + Dz_truth_cut = TRUE_ID_IS(hadron_candidate_id, MCTRUTH_B) @ Dz_child #require that D0 is true + lep_truth_cut = F.require_any(TRUE_ID_IS(11, MCTRUTH_B) @ lep_child , TRUE_ID_IS(13, MCTRUTH_B) @ lep_child) #require that lepton is true i.e. electron or muon + cut_b = F.require_all(Dz_truth_cut, lep_truth_cut) #make a cut + signal_B = ParticleFilter(Input=B, Cut=F.FILTER(cut_b), name='signal_Dzmu') #filter the B candidates + else : signal_B = B + + #combine to make [B*0 -> B*- pi+]cc + Bst_1 = ParticleCombiner( + Inputs=[B, pions], + name=f'Bst_1_{lepton}', + DecayDescriptor='[B0 -> B- pi+]cc', + CombinationCut=F.ALL, + CompositeCut=F.ALL, + ParticleCombiner="ParticleVertexFitter", + PrimaryVertices=v2_pvs + #OutputLevel=1 + ) + #combine to make [B*0 -> B*- pi-]cc + Bst_2 = ParticleCombiner( + Inputs=[B, pions], + name=f'Bst_2_{lepton}', + DecayDescriptor='[B0 -> B- pi-]cc', + CombinationCut=F.ALL, + CompositeCut=F.ALL, + ParticleCombiner="ParticleVertexFitter", + PrimaryVertices=v2_pvs + #OutputLevel=1 + ) + #merge the two Bst candidates + Bst = ParticleContainersMerger([Bst_1, Bst_2], name = f'Bst_combiner_{lepton}') + return Bst + +def get_functors(MCTRUTH, v2_pvs, rec_summary): + #define common variables for all fields (composite and basic) + vars_common = FunctorCollection() + #all pvs: ip, ipchi2. The PV positions are stored in event variables + vars_common['ALLPV_IP[pv_indx]'] = F.ALLPV_IP(v2_pvs) + vars_common['ALLPV_IPCHI2[pv_indx]'] = ALLPV_IPCHI2(v2_pvs) + #best pv: x, y, z, ip, ipchi2 + vars_common['BPV_X'] = F.BPVX(v2_pvs) + vars_common['BPV_Y'] = F.BPVY(v2_pvs) + vars_common['BPV_Z'] = F.BPVZ(v2_pvs) + vars_common['BPV_IP'] = F.BPVIP(v2_pvs) + vars_common['BPV_IPCHI2'] = F.BPVIPCHI2(v2_pvs) + vars_common['BPV_CHI2'] = F.CHI2 @ F.BPV(v2_pvs) + vars_common['BPV_CHI2DOF'] = F.CHI2DOF @ F.BPV(v2_pvs) + #particle id, key, truekey. The trueid is stored in MCHierarchy + vars_common['ID'] = F.PARTICLE_ID + vars_common['KEY'] = F.OBJECT_KEY + #get charge, min ip and min ipchi2 + vars_common['CHARGE'] = F.CHARGE + vars_common['MINIP'] = F.MINIP(v2_pvs) + vars_common['MINIPCHI2'] = F.MINIPCHI2(v2_pvs) + #reco kinematics + vars_common += FC.Kinematics() + vars_common['ETA'] = F.ETA + vars_common['PHI'] = F.PHI + if MCTRUTH != 'None': + #mc vars + vars_common['TRUEKEY'] = F.VALUE_OR(-1) @ MCTRUTH(F.OBJECT_KEY) + vars_common += FC.MCKinematics(mctruth_alg = MCTRUTH) + vars_common['TRUEETA'] = MCTRUTH(F.ETA) + vars_common['TRUEPHI'] = MCTRUTH(F.PHI) + #type of the origin vertex + vars_common['MC_VTX_TYPE'] = MCTRUTH(F.VALUE_OR(-1) @ F.MC_VTX_TYPE @ F.MC_ORIGINVERTEX) + ##mc truth hierarchy (done seperately) + #vars_common += FC.MCHierarchy(mctruth_alg = MCTRUTH) + #make some helper functions + MCMOTHER_ID = lambda n: F.VALUE_OR(0) @ MCTRUTH(F.MC_MOTHER(n, F.PARTICLE_ID)) + MCMOTHER_KEY = lambda n: F.VALUE_OR(-1) @ MCTRUTH(F.MC_MOTHER(n, F.OBJECT_KEY )) + vars_common["TRUEID"] = F.VALUE_OR(0) @ MCTRUTH(F.PARTICLE_ID) + vars_common["MCKEY"] = F.VALUE_OR(0) @ MCTRUTH(F.OBJECT_KEY) + vars_common["MC_MOTHER_ID"] = MCMOTHER_ID(1) + vars_common["MC_MOTHER_KEY"] = MCMOTHER_KEY(1) + for i in range(2,14): + prefix = "MC_GD_MOTHER_{}".format(i) + vars_common[f"{prefix}_ID"] = MCMOTHER_ID(i) + vars_common[f"{prefix}_KEY"] = MCMOTHER_KEY(i) + + #variables for composite particles + vars_composite = FunctorCollection() + #end vertex position and end vertex chi2 + vars_composite['ENDVERTEX_POS_'] = F.ENDVERTEX_POS + vars_composite['ENDVERTEX_CHI2'] = F.CHI2 @ F.ENDVERTEX + vars_composite['ENDVERTEX_CHI2DOF'] = F.CHI2DOF @ F.ENDVERTEX + #all pvs: dira, fd, fdchi2 + vars_composite['ALLPV_DIRA[pv_indx]'] = ALLPV_DIRA(v2_pvs) + vars_composite['ALLPV_FD_X[pv_indx]'] = ALLPV_FD_COORDINATE(F.X_COORDINATE, v2_pvs) + vars_composite['ALLPV_FD_Y[pv_indx]'] = ALLPV_FD_COORDINATE(F.Y_COORDINATE, v2_pvs) + vars_composite['ALLPV_FD_Z[pv_indx]'] = ALLPV_FD_COORDINATE(F.Z_COORDINATE, v2_pvs) + vars_composite['ALLPV_FDCHI2[pv_indx]'] = ALLPV_FDCHI2(v2_pvs) + vars_composite['ALLPV_CORRM[pv_indx]'] = ALLPV_CORRM(v2_pvs) + vars_composite['ALLPV_LTIME[pv_indx]'] = ALLPV_LTIME(v2_pvs) + vars_composite['ALLPV_DLS[pv_indx]'] = ALLPV_DLS(v2_pvs) + #best pv: dira, fd, fdchi2, corrm, ltime, dls + vars_composite['BPV_DIRA'] = F.BPVDIRA(v2_pvs) + vars_composite['BPV_FD_'] = F.BPVFDVEC(v2_pvs) + vars_composite['BPV_FDCHI2'] = F.BPVFDCHI2(v2_pvs) + vars_composite['BPV_CORRM'] = F.BPVCORRM(v2_pvs) + vars_composite['BPV_LTIME'] = F.BPVLTIME(v2_pvs) + vars_composite['BPV_DLS'] = F.BPVDLS(v2_pvs) + #mc composite vertex information + + if MCTRUTH != 'None': vars_composite += FC.MCVertexInfo(mctruth_alg = MCTRUTH) + #Compute maximum DOCA and maximum DOCACHI2. Since there are + # only two daughters of Sb particles, the maximum DOCA/DOCACHI2 is + # the DOCA/DOCACHI2 see below. + vars_composite['MAX_DOCA'] = F.MAXDOCA + vars_composite['MAX_DOCACHI2'] = F.MAXDOCACHI2 + vars_composite['MAX_SDOCA'] = F.MAXSDOCA + vars_composite['MAX_SDOCACHI2'] = F.MAXSDOCACHI2 + + #variables for Lb field + var_B = FunctorCollection() + #var_B['TRUENU_PX'] = MCTRUTH(F.PX @ MCNEUTRINO) + #var_B['TRUENU_PY'] = MCTRUTH(F.PY @ MCNEUTRINO) + #var_B['TRUENU_PZ'] = MCTRUTH(F.PZ @ MCNEUTRINO) + #var_B['TRUENU_ENERGY'] = MCTRUTH(F.ENERGY @ MCNEUTRINO) + ###Bkg category + ##var_B["BKGCAT"] = MCTRUTH.BkgCat + + #variables for basics + vars_basic = FunctorCollection() + vars_basic['TRACKTYPE'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKTYPE @ F.TRACK + vars_basic['TRACKHISTORY'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKHISTORY @ F.TRACK + vars_basic['TRACKFLAG'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKFLAG @ F.TRACK + vars_basic['TRACKNDOF'] = F.VALUE_OR(-1) @ F.NDOF @ F.TRACK + vars_basic['TRACKCHI2'] = F.CHI2 @ F.TRACK + vars_basic['TRACKCHI2DOF'] = F.CHI2DOF @ F.TRACK + vars_basic['GHOSTPROB'] = F.GHOSTPROB + vars_basic['PIDpi'] = F.PID_PI + vars_basic['PIDk'] = F.PID_K + vars_basic['PIDp'] = F.PID_P + vars_basic['PIDe'] = F.PID_E + vars_basic['PIDmu'] = F.PID_MU + if MCTRUTH != 'None': + vars_basic['TRUEORIGINVERTEX_X'] = MCTRUTH(F.ORIGIN_VX) + vars_basic['TRUEORIGINVERTEX_Y'] = MCTRUTH(F.ORIGIN_VY) + vars_basic['TRUEORIGINVERTEX_Z'] = MCTRUTH(F.ORIGIN_VZ) + + #variables for event + evt_vars = FunctorCollection() + #evt_vars['ALLPV_X[pv_indx]'] = F.ALLPVX(v2_pvs) + #evt_vars['ALLPV_Y[pv_indx]'] = F.ALLPVY(v2_pvs) + #evt_vars['ALLPV_Z[pv_indx]'] = F.ALLPVZ(v2_pvs) + #evt_vars['ALLPV_CHI2[pv_indx]'] = ALLPV_CHI2(v2_pvs) + #evt_vars['ALLPV_CHI2DOF[pv_indx]']= ALLPV_CHI2DOF(v2_pvs) + evt_vars['nTracks'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nTracks") + evt_vars['nLongTracks'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nLongTracks") + evt_vars['nPVs'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nPVs") + + vars_brems = FunctorCollection({}) + vars_brems.update({"HASBREM": F.HASBREM}) + #vars_brems.update({"HASBREMADDED": F.HASBREMADDED}) + vars_brems.update({"BREMENERGY": F.BREMENERGY}) + vars_brems.update({"BREMBENDCORR": F.BREMBENDCORR}) + vars_brems.update({"BREMPIDE": F.BREMPIDE}) + vars_brems.update({"ECALPIDE": F.ECALPIDE}) + vars_brems.update({"ECALPIDMU": F.ECALPIDMU}) + vars_brems.update({"HCALPIDE": F.HCALPIDE}) + vars_brems.update({"HCALPIDMU": F.HCALPIDMU}) + vars_brems.update({"ELECTRONSHOWEREOP": F.ELECTRONSHOWEREOP}) + vars_brems.update({"ELECTRONSHOWERDLL": F.ELECTRONSHOWERDLL}) + vars_brems.update({"CLUSTERMATCH": F.CLUSTERMATCH_CHI2}) + vars_brems.update({"ELECTRONMATCH": F.ELECTRONMATCH_CHI2}) + vars_brems.update({"BREMHYPOMATCH": F.BREMHYPOMATCH_CHI2}) + vars_brems.update({"ELECTRONENERGY": F.ELECTRONENERGY}) + vars_brems.update({"BREMHYPOENERGY": F.BREMHYPOENERGY}) + vars_brems.update({"BREMHYPODELTAX": F.BREMHYPODELTAX}) + #vars_brems.update({"BREMTRACKBASEDENERGY": F.BREMTRACKBASEDENERGY}) + vars_brems.update({"INBREM": F.INBREM}) + vars_brems.update({"PT_WITH_BREM": F.PT_WITH_BREM}) + vars_brems.update({"P_WITH_BREM": F.P_WITH_BREM}) + + #return all functors + functors = (vars_common, vars_composite, var_B, vars_basic, evt_vars,vars_brems) + return functors + +def tuple_Bst(Bst,lepton, MCTRUTH, v2_pvs, rec_summary): + #get functors + functors = get_functors(MCTRUTH, v2_pvs, rec_summary) + vars_common = functors[0] + vars_composite = functors[1] + var_B = functors[2] + vars_basic = functors[3] + evt_vars = functors[4] + vars_brems = functors[5] + + #variables for Sb field + vars_Bst = FunctorCollection() + B_child = F.CHILD(1, F.FORWARDARG0) + D0_child = F.CHILD(1, F.CHILD(1,F.FORWARDARG0)) + Epi_child = F.CHILD(2, F.FORWARDARG0) + bpv_pi = F.BPV(v2_pvs).bind(Epi_child) + #diff in vtx chi2 with and without extra particle + vars_Bst['DELTA_ENDVERTEX_CHI2'] = (F.CHI2 @ F.ENDVERTEX) - (F.CHI2 @ F.ENDVERTEX.bind(B_child)) + #IP and IPChi2 of extra particle wrt to Sb end vertex + vars_Bst['Epi_IP_WRT_SbENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ F.FORWARDARG0 , Epi_child) + vars_Bst['Epi_IPCHI2_WRT_SbENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ F.FORWARDARG0 , Epi_child) + #IP and IPChi2 of extra particle wrt to Lb end vertex + vars_Bst['Epi_IP_WRT_LbENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ B_child , Epi_child) + vars_Bst['Epi_IPCHI2_WRT_LbENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ B_child , Epi_child) + #angle between extra particle and Lb + vars_Bst['Epi_COSANGLE_Lb'] = F.COSANGLE.bind(F.THREEMOMENTUM @ B_child, F.THREEMOMENTUM @ Epi_child) + #diff in fd chi2 with and without extra particle + vars_Bst['Delta_BPV_of_Epi_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi, F.FORWARDARGS) - F.VTX_FDCHI2.bind(bpv_pi, B_child) + vars_Bst['BPV_of_Epi_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi, F.FORWARDARGS) + #IP chi2 of extra particle wrt PV and SV of Sb + vars_Bst['Epi_IP_WRT_SbBPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child) + vars_Bst['Epi_IPCHI2_WRT_SbBPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child) + #IP chi2 of extra particle wrt PV and SV of Bb + vars_Bst['Epi_IP_WRT_LbBPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ B_child, Epi_child) + vars_Bst['Epi_IPCHI2_WRT_LbBPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ B_child, Epi_child) + #DOCA and DOCACHI2 b/w Lb and extra particle + vars_Bst['DOCA12'] = F.DOCA(1, 2) + vars_Bst['DOCA12_CHI2_12'] = F.DOCACHI2(1, 2) + #vars_Bst['SDOCA12'] = F.SDOCA(1, 2) + #vars_Bst['SDOCA_CHI2_12'] = F.SDOCACHI2(1, 2) + #DOCACHI2 of extra particle wrt to mother i.e. Sb + vars_Bst['MTDOCACHI2_1'] = F.MTDOCACHI2(1, v2_pvs) + vars_Bst['MTDOCACHI2_2'] = F.MTDOCACHI2(2, v2_pvs) + #vars_Bst['Dstar_M'] = F.MASS @ ((F.FOURMOMENTUM @ D0_child)+(F.FOURMOMENTUM @ Epi_child)) + #vars_Bst['D0_M'] = F.MASS @ (F.FOURMOMENTUM @ D0_child) + #vars_Bst['test_id'] = F.PARTICLE_ID @ D0_child + vars_Bst['Delta_M'] = F.ABS @ ((F.MASS @ ((F.FOURMOMENTUM @ D0_child)+(F.FOURMOMENTUM @ Epi_child))) - (F.MASS @ D0_child)) + + #define fields + fields = {} + fields['Sb'] = f'[B0 -> (B- -> (D0 -> K- pi+) {lepton}-) [pi+]CC]CC' + fields['Lb'] = f'[B0 -> ^(B- -> (D0 -> K- pi+) {lepton}-) [pi+]CC]CC' + fields['Lc'] = f'[B0 -> (B- -> ^(D0 -> K- pi+) {lepton}-) [pi+]CC]CC' + fields['Lep'] = f'[B0 -> (B- -> (D0 -> K- pi+) ^{lepton}-) [pi+]CC]CC' + fields['Epi'] = f'[B0 -> (B- -> (D0 -> K- pi+) {lepton}-) ^[pi+]CC]CC' + fields['Km'] = f'[B0 -> (B- -> (D0 -> ^K- pi+) {lepton}-) [pi+]CC]CC' + fields['pip'] = f'[B0 -> (B- -> (D0 -> K- ^pi+) {lepton}-) [pi+]CC]CC' + + #add variables + variables = {} + variables["ALL"] = vars_common + variables["Sb"] = vars_composite + vars_Bst + variables["Lb"] = vars_composite + var_B + variables["Lc"] = vars_composite + variables["Lep"] = vars_basic + vars_brems + variables["Epi"] = vars_basic + vars_brems + variables["Km"] = vars_basic + vars_brems + variables["pip"] = vars_basic + vars_brems + + #define tuple + my_tuple = Funtuple( + name=f"Tuple_{lepton}", + tuple_name="DecayTree", + fields=fields, + variables=variables, + inputs=Bst) + + return my_tuple + +def get_extra_pions(): + """ + Note this function in DaVinci requires: + https://gitlab.cern.ch/lhcb/Moore/-/merge_requests/3203 + and it's related LHCb, DaVinci and Rec MRs + """ + long_pions = make_has_rich_long_pions() + up_pions = make_has_rich_up_pions() + down_pions = make_has_rich_down_pions() + return ParticleContainersMerger([long_pions, up_pions, down_pions], + name='Pions_combiner') + +#def main(options): +def main(options: Options): + line_name = ['SpruceSLB_BuToD0MuNu_D0ToKPi_FakeMuon','SpruceSLB_BuToD0TauNu_D0ToKPi_FakeMuon'] + + #define filer + my_filter_l = create_lines_filter(name="Filter_l", lines=[line_name[0]]) + my_filter_tau = create_lines_filter(name="Filter_tau", lines=[line_name[1]]) + + #get data and extra particles + lb_l = get_particles(f"/Event/Spruce/{line_name[0]}/Particles") + lb_tau = get_particles(f"/Event/Spruce/{line_name[1]}/Particles") + extra_particles = get_extra_pions() + + #get v2_pvs and rec_summary + v2_pvs = get_pvs() + rec_summary = get_rec_summary() + hadron_candidate_id = 421 + #make sb candidate + Bst_l = make_Bst(lb_l, extra_particles,'mu',hadron_candidate_id,v2_pvs,False) + Bst_tau = make_Bst(lb_tau, extra_particles,'tau', hadron_candidate_id,v2_pvs,False) + #MCTRUTH_Bst = MCTruthAndBkgCat(Bst, name='MCTRUTH_Bst') + + + tuple_file_l = tuple_Bst(Bst_l,'mu', 'None', v2_pvs, rec_summary) + tuple_file_tau = tuple_Bst(Bst_tau,'tau', 'None', v2_pvs, rec_summary) + + #define algorithms + user_algorithms = {} + user_algorithms['Alg_l'] = [my_filter_l, tuple_file_l] + user_algorithms['Alg_tau'] = [my_filter_tau, tuple_file_tau] + + return make_config(options, user_algorithms) -- GitLab From 3835191813e2e80e5256655f9dfad9a5e910c03c Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <chinghua@lxplus710.cern.ch> Date: Thu, 15 Feb 2024 13:40:12 +0100 Subject: [PATCH 20/57] Add D02KK MC production for starterkit --- D02HH_Practice/README.md | 1 + D02HH_Practice/info.yaml | 14 ++++++++++++ D02HH_Practice/ntuple_options.py | 38 ++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 D02HH_Practice/README.md create mode 100644 D02HH_Practice/info.yaml create mode 100755 D02HH_Practice/ntuple_options.py diff --git a/D02HH_Practice/README.md b/D02HH_Practice/README.md new file mode 100644 index 0000000000..518eb21598 --- /dev/null +++ b/D02HH_Practice/README.md @@ -0,0 +1 @@ +I want weed diff --git a/D02HH_Practice/info.yaml b/D02HH_Practice/info.yaml new file mode 100644 index 0000000000..510dce396d --- /dev/null +++ b/D02HH_Practice/info.yaml @@ -0,0 +1,14 @@ +defaults: + application: DaVinci/v46r10 + wg: Charm + automatically_configure: yes + turbo: no + inform: + - chinghua@cern.ch + options: + - ntuple_options.py + output: D02KK.ROOT + +2016_MagDown_PromptMC_D02KK: + input: + bk_query: "/MC/2016/Beam6500GeV-2016-MagDown-Nu1.6-25ns-Pythia8/Sim09c/Trig0x6138160F/Reco16/Turbo03/Stripping28r1NoPrescalingFlagged/27163002/ALLSTREAMS.DST" diff --git a/D02HH_Practice/ntuple_options.py b/D02HH_Practice/ntuple_options.py new file mode 100755 index 0000000000..0297e5cc85 --- /dev/null +++ b/D02HH_Practice/ntuple_options.py @@ -0,0 +1,38 @@ +from Configurables import DecayTreeTuple + +## Specify the stream and stripping line +stream = "AllStreams" +line = "D2hhPromptDst2D2KKLine" + +## We create the DecayTreeTuple object, and indicate the Input +## (i.e., the TES location where the desired candidates may be) +## as well as the decay descriptor +dtt = DecayTreeTuple("TupleDstToD0pi_D0ToKK") +dtt.Inputs = ["/Event/{0}/Phys/{1}/Particles".format(stream, line)] +dtt.Decay = "[D*(2010)+ -> (D0 -> K- K+) pi+]CC" + +from Configurables import DaVinci + +DaVinci().UserAlgorithms += [dtt] + +# In general, thanks to using the automatically_configure setting, you don't need what's below so it can be removed +""" +DaVinci().InputType = "DST" +DaVinci().TupleFile = "DVntuple.root" +DaVinci().PrintFreq = 1000 +DaVinci().DataType = "2016" +DaVinci().Simulation = True +DaVinci().Lumi = not DaVinci().Simulation +DaVinci().EvtMax = -1 +DaVinci().CondDBtag = "sim-20170721-2-vc-md100" +DaVinci().DDDBtag = "dddb-20170721-3" +""" + +# The Analysis Productions software automatically finds a valid remote file to test on so we can drop this bit +""" +from GaudiConf import IOHelper + +IOHelper().inputFiles([ + "./00070793_00000001_7.AllStreams.dst" +], clear=True) +""" \ No newline at end of file -- GitLab From c5173fbf862e56bed184cacc1a650068278fd723 Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <chinghua@lxplus710.cern.ch> Date: Thu, 15 Feb 2024 13:50:51 +0100 Subject: [PATCH 21/57] test --- D02HH_Practice/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/D02HH_Practice/README.md b/D02HH_Practice/README.md index 518eb21598..cc34fb0b7a 100644 --- a/D02HH_Practice/README.md +++ b/D02HH_Practice/README.md @@ -1 +1 @@ -I want weed +I want weed XDDDD -- GitLab From e8f70de7a412434638f4eb92f2354bce1823540c Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <chinghua@lxplus710.cern.ch> Date: Thu, 15 Feb 2024 14:10:52 +0100 Subject: [PATCH 22/57] test check --- D02HH_Practice/info.yaml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/D02HH_Practice/info.yaml b/D02HH_Practice/info.yaml index 510dce396d..dbe57daefb 100644 --- a/D02HH_Practice/info.yaml +++ b/D02HH_Practice/info.yaml @@ -8,7 +8,31 @@ defaults: options: - ntuple_options.py output: D02KK.ROOT +checks: + histogram: + type: range + expression: Dst_2010_plus_M + limits: + min: 1900 + max: 2300 + blind_ranges: + min: 2000 + max: 2020 + histogram_fail: + type: range + expression: Dst_2010_plus_M + limits: + min: 0 + max: 10 + at_least_50_entries: + type: num_entries + tree_pattern: TupleDstToD0pi_D0ToKK/DecayTree + count: 50 2016_MagDown_PromptMC_D02KK: input: bk_query: "/MC/2016/Beam6500GeV-2016-MagDown-Nu1.6-25ns-Pythia8/Sim09c/Trig0x6138160F/Reco16/Turbo03/Stripping28r1NoPrescalingFlagged/27163002/ALLSTREAMS.DST" + checks: + - histogram + - histogram_fail + - at_least_50_entries -- GitLab From 855404aa5d399fcb6c5527b96a32c2dc8e6e1419 Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Mon, 6 May 2024 11:39:24 +0200 Subject: [PATCH 23/57] Add RDstar_taue production for 2024 data checking --- RDstar_taue_2024data/info.yaml | 43 +++++ RDstar_taue_2024data/run_Dzl.py | 311 ++++++++++++++++++++++++++++++++ 2 files changed, 354 insertions(+) create mode 100644 RDstar_taue_2024data/info.yaml create mode 100644 RDstar_taue_2024data/run_Dzl.py diff --git a/RDstar_taue_2024data/info.yaml b/RDstar_taue_2024data/info.yaml new file mode 100644 index 0000000000..2681a0a72b --- /dev/null +++ b/RDstar_taue_2024data/info.yaml @@ -0,0 +1,43 @@ +checks: + hist_Sb_M: + type: range + expression: Sb_M + limits: + min: 2_000 + max: 8_000 + n_bins: 100 + +defaults: + application: "DaVinci/v64r4" + output: DATA.ROOT + options: + entrypoint: RDstar_taue_2024data.run_Dzl:main + extra_options: + input_raw_format: 0.5 + input_type: ROOT # ROOT for SprucingPass, RAW for RAW data (Hlt2 output) + simulation: False + data_type: "Upgrade" + geometry_version: run3/2024.Q1.2-v00.00 + conditions_version: master + input_process: "Spruce" # Spruce for SprucingPass, "Hlt2" for RAW data (Hlt2 output) + input_stream: "sl" # for streamed data + evt_max: 1000 + inform: + - ching-hua.li@cern.ch + wg: SL + +{%- set datasets = [ + ('2024Data', 'Down'), +]%} +{%- for evttype, polarity in datasets %} +RDstar_taue_{{ evttype }}_{{ polarity }}: + input: + bk_query: "/LHCb/Collision24/Beam6800GeV-VeloClosed-Mag{{ polarity }}-Excl-UT/Real Data/Sprucing24c1/90000000/SL.DST" + dq_flags: + - UNCHECKED + - OK + keep_running: true + n_test_lfns: 1 + checks: + - hist_Sb_M +{%- endfor %} diff --git a/RDstar_taue_2024data/run_Dzl.py b/RDstar_taue_2024data/run_Dzl.py new file mode 100644 index 0000000000..56c3ea074d --- /dev/null +++ b/RDstar_taue_2024data/run_Dzl.py @@ -0,0 +1,311 @@ +import sys,os,math +from PyConf.reading import get_pvs, get_rec_summary, get_particles +import Functors as F +from FunTuple import FunctorCollection +from FunTuple import FunTuple_Particles as Funtuple +from DaVinci.algorithms import create_lines_filter +from DaVinci import Options,make_config +import FunTuple.functorcollections as FC +from DaVinciMCTools import MCTruthAndBkgCat +from Hlt2Conf.algorithms_thor import ParticleCombiner, ParticleFilter +from Hlt2Conf.algorithms_thor import ParticleContainersMerger +from Functors.grammar import Functor +from Hlt2Conf.standard_particles import make_has_rich_long_pions,make_has_rich_up_pions,make_has_rich_down_pions + +_BPVCORRM = Functor('_BPVCORRM', 'Composite::CorrectedMass','Compute the corrected mass') +_allpv_FDVEC = (F.ENDVERTEX_POS @ F.FORWARDARG1 - F.TOLINALG @ F.POSITION @ F.FORWARDARG0) +_allpv_NORMEDDOT = F.NORMEDDOT.bind(F.THREEMOMENTUM @ F.FORWARDARG1, _allpv_FDVEC) +#ALLPV_CHI2 = lambda Vertices: F.MAP(F.CHI2) @ F.TES(Vertices) +#ALLPV_CHI2DOF = lambda Vertices: F.MAP(F.CHI2DOF) @ F.TES(Vertices) +ALLPV_IPCHI2 = lambda Vertices: F.MAP(F.IPCHI2).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_FDCHI2 = lambda Vertices: F.MAP(F.VTX_FDCHI2).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_DIRA = lambda Vertices: F.MAP(_allpv_NORMEDDOT).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_CORRM = lambda Vertices: F.MAP(_BPVCORRM).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_LTIME = lambda Vertices: F.MAP(F.VTX_LTIME).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_DLS = lambda Vertices: F.MAP(F.VTX_DLS).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_FD_COORDINATE = lambda coordinate, Vertices: F.MAP(coordinate @ _allpv_FDVEC).bind(F.TES(Vertices), F.FORWARDARGS) +#MCNEUTRINO = F.FIND_MCDECAY("[ Lambda_b0 => Lambda_c+ mu- ^nu_mu~ ]CC") + +TRUE_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.PARTICLE_ID) == id) +#MCMOTHER_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.MC_MOTHER(1, F.PARTICLE_ID)) == id) +#GD_MCMOTHER_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.MC_MOTHER(2, F.PARTICLE_ID)) == id) +#GD_GD_MCMOTHER_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.MC_MOTHER(3, F.PARTICLE_ID)) == id) + +def make_Bst(B, pions,lepton, hadron_candidate_id,v2_pvs,do_truth_matching = True): + if do_truth_matching == True : + #filter B keeping only true D0 and true leptons + MCTRUTH_B = MCTruthAndBkgCat(B, name='MCTRUTH_Bu') + Dz_child = F.CHILD(1, F.FORWARDARG0) #get the first child of B*- which is D0 + lep_child = F.CHILD(2, F.FORWARDARG0) #get the second child of B*- which is lepton + Dz_truth_cut = TRUE_ID_IS(hadron_candidate_id, MCTRUTH_B) @ Dz_child #require that D0 is true + lep_truth_cut = F.require_any(TRUE_ID_IS(11, MCTRUTH_B) @ lep_child , TRUE_ID_IS(13, MCTRUTH_B) @ lep_child) #require that lepton is true i.e. electron or muon + cut_b = F.require_all(Dz_truth_cut, lep_truth_cut) #make a cut + signal_B = ParticleFilter(Input=B, Cut=F.FILTER(cut_b), name='signal_Dzmu') #filter the B candidates + else : signal_B = B + + #combine to make [B*0 -> B*- pi+]cc + Bst_1 = ParticleCombiner( + Inputs=[B, pions], + name=f'Bst_1_{lepton}', + DecayDescriptor='[B0 -> B- pi+]cc', + CombinationCut=F.ALL, + CompositeCut=F.ALL, + ParticleCombiner="ParticleVertexFitter", + PrimaryVertices=v2_pvs + #OutputLevel=1 + ) + #combine to make [B*0 -> B*- pi-]cc + Bst_2 = ParticleCombiner( + Inputs=[B, pions], + name=f'Bst_2_{lepton}', + DecayDescriptor='[B0 -> B- pi-]cc', + CombinationCut=F.ALL, + CompositeCut=F.ALL, + ParticleCombiner="ParticleVertexFitter", + PrimaryVertices=v2_pvs + #OutputLevel=1 + ) + #merge the two Bst candidates + Bst = ParticleContainersMerger([Bst_1, Bst_2], name = f'Bst_combiner_{lepton}') + return Bst + +def get_functors(MCTRUTH, v2_pvs, rec_summary): + #define common variables for all fields (composite and basic) + vars_common = FunctorCollection() + #all pvs: ip, ipchi2. The PV positions are stored in event variables + vars_common['ALLPV_IP[pv_indx]'] = F.ALLPV_IP(v2_pvs) + vars_common['ALLPV_IPCHI2[pv_indx]'] = ALLPV_IPCHI2(v2_pvs) + #best pv: x, y, z, ip, ipchi2 + vars_common['BPV_X'] = F.BPVX(v2_pvs) + vars_common['BPV_Y'] = F.BPVY(v2_pvs) + vars_common['BPV_Z'] = F.BPVZ(v2_pvs) + vars_common['BPV_IP'] = F.BPVIP(v2_pvs) + vars_common['BPV_IPCHI2'] = F.BPVIPCHI2(v2_pvs) + vars_common['BPV_CHI2'] = F.CHI2 @ F.BPV(v2_pvs) + vars_common['BPV_CHI2DOF'] = F.CHI2DOF @ F.BPV(v2_pvs) + #particle id, key, truekey. The trueid is stored in MCHierarchy + vars_common['ID'] = F.PARTICLE_ID + vars_common['KEY'] = F.OBJECT_KEY + #get charge, min ip and min ipchi2 + vars_common['CHARGE'] = F.CHARGE + vars_common['MINIP'] = F.MINIP(v2_pvs) + vars_common['MINIPCHI2'] = F.MINIPCHI2(v2_pvs) + #reco kinematics + vars_common += FC.Kinematics() + vars_common['ETA'] = F.ETA + vars_common['PHI'] = F.PHI + if MCTRUTH != 'None': + #mc vars + vars_common['TRUEKEY'] = F.VALUE_OR(-1) @ MCTRUTH(F.OBJECT_KEY) + vars_common += FC.MCKinematics(mctruth_alg = MCTRUTH) + vars_common['TRUEETA'] = MCTRUTH(F.ETA) + vars_common['TRUEPHI'] = MCTRUTH(F.PHI) + #type of the origin vertex + vars_common['MC_VTX_TYPE'] = MCTRUTH(F.VALUE_OR(-1) @ F.MC_VTX_TYPE @ F.MC_ORIGINVERTEX) + ##mc truth hierarchy (done seperately) + #vars_common += FC.MCHierarchy(mctruth_alg = MCTRUTH) + #make some helper functions + MCMOTHER_ID = lambda n: F.VALUE_OR(0) @ MCTRUTH(F.MC_MOTHER(n, F.PARTICLE_ID)) + MCMOTHER_KEY = lambda n: F.VALUE_OR(-1) @ MCTRUTH(F.MC_MOTHER(n, F.OBJECT_KEY )) + vars_common["TRUEID"] = F.VALUE_OR(0) @ MCTRUTH(F.PARTICLE_ID) + vars_common["MCKEY"] = F.VALUE_OR(0) @ MCTRUTH(F.OBJECT_KEY) + vars_common["MC_MOTHER_ID"] = MCMOTHER_ID(1) + vars_common["MC_MOTHER_KEY"] = MCMOTHER_KEY(1) + for i in range(2,14): + prefix = "MC_GD_MOTHER_{}".format(i) + vars_common[f"{prefix}_ID"] = MCMOTHER_ID(i) + vars_common[f"{prefix}_KEY"] = MCMOTHER_KEY(i) + + #variables for composite particles + vars_composite = FunctorCollection() + #end vertex position and end vertex chi2 + vars_composite['ENDVERTEX_POS_'] = F.ENDVERTEX_POS + vars_composite['ENDVERTEX_CHI2'] = F.CHI2 @ F.ENDVERTEX + vars_composite['ENDVERTEX_CHI2DOF'] = F.CHI2DOF @ F.ENDVERTEX + #all pvs: dira, fd, fdchi2 + vars_composite['ALLPV_DIRA[pv_indx]'] = ALLPV_DIRA(v2_pvs) + vars_composite['ALLPV_FD_X[pv_indx]'] = ALLPV_FD_COORDINATE(F.X_COORDINATE, v2_pvs) + vars_composite['ALLPV_FD_Y[pv_indx]'] = ALLPV_FD_COORDINATE(F.Y_COORDINATE, v2_pvs) + vars_composite['ALLPV_FD_Z[pv_indx]'] = ALLPV_FD_COORDINATE(F.Z_COORDINATE, v2_pvs) + vars_composite['ALLPV_FDCHI2[pv_indx]'] = ALLPV_FDCHI2(v2_pvs) + vars_composite['ALLPV_CORRM[pv_indx]'] = ALLPV_CORRM(v2_pvs) + vars_composite['ALLPV_LTIME[pv_indx]'] = ALLPV_LTIME(v2_pvs) + vars_composite['ALLPV_DLS[pv_indx]'] = ALLPV_DLS(v2_pvs) + #best pv: dira, fd, fdchi2, corrm, ltime, dls + vars_composite['BPV_DIRA'] = F.BPVDIRA(v2_pvs) + vars_composite['BPV_FD_'] = F.BPVFDVEC(v2_pvs) + vars_composite['BPV_FDCHI2'] = F.BPVFDCHI2(v2_pvs) + vars_composite['BPV_CORRM'] = F.BPVCORRM(v2_pvs) + vars_composite['BPV_LTIME'] = F.BPVLTIME(v2_pvs) + vars_composite['BPV_DLS'] = F.BPVDLS(v2_pvs) + #mc composite vertex information + + if MCTRUTH != 'None': vars_composite += FC.MCVertexInfo(mctruth_alg = MCTRUTH) + #Compute maximum DOCA and maximum DOCACHI2. Since there are + # only two daughters of Sb particles, the maximum DOCA/DOCACHI2 is + # the DOCA/DOCACHI2 see below. + vars_composite['MAX_DOCA'] = F.MAXDOCA + vars_composite['MAX_DOCACHI2'] = F.MAXDOCACHI2 + vars_composite['MAX_SDOCA'] = F.MAXSDOCA + vars_composite['MAX_SDOCACHI2'] = F.MAXSDOCACHI2 + + #variables for Lb field + var_B = FunctorCollection() + #var_B['TRUENU_PX'] = MCTRUTH(F.PX @ MCNEUTRINO) + #var_B['TRUENU_PY'] = MCTRUTH(F.PY @ MCNEUTRINO) + #var_B['TRUENU_PZ'] = MCTRUTH(F.PZ @ MCNEUTRINO) + #var_B['TRUENU_ENERGY'] = MCTRUTH(F.ENERGY @ MCNEUTRINO) + ###Bkg category + ##var_B["BKGCAT"] = MCTRUTH.BkgCat + + #variables for basics + vars_basic = FunctorCollection() + vars_basic['TRACKTYPE'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKTYPE @ F.TRACK + vars_basic['TRACKHISTORY'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKHISTORY @ F.TRACK + vars_basic['TRACKFLAG'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKFLAG @ F.TRACK + vars_basic['TRACKNDOF'] = F.VALUE_OR(-1) @ F.NDOF @ F.TRACK + vars_basic['TRACKCHI2'] = F.CHI2 @ F.TRACK + vars_basic['TRACKCHI2DOF'] = F.CHI2DOF @ F.TRACK + vars_basic['GHOSTPROB'] = F.GHOSTPROB + vars_basic['PIDpi'] = F.PID_PI + vars_basic['PIDk'] = F.PID_K + vars_basic['PIDp'] = F.PID_P + vars_basic['PIDe'] = F.PID_E + vars_basic['PIDmu'] = F.PID_MU + if MCTRUTH != 'None': + vars_basic['TRUEORIGINVERTEX_X'] = MCTRUTH(F.ORIGIN_VX) + vars_basic['TRUEORIGINVERTEX_Y'] = MCTRUTH(F.ORIGIN_VY) + vars_basic['TRUEORIGINVERTEX_Z'] = MCTRUTH(F.ORIGIN_VZ) + + #variables for event + evt_vars = FunctorCollection() + #evt_vars['ALLPV_X[pv_indx]'] = F.ALLPVX(v2_pvs) + #evt_vars['ALLPV_Y[pv_indx]'] = F.ALLPVY(v2_pvs) + #evt_vars['ALLPV_Z[pv_indx]'] = F.ALLPVZ(v2_pvs) + #evt_vars['ALLPV_CHI2[pv_indx]'] = ALLPV_CHI2(v2_pvs) + #evt_vars['ALLPV_CHI2DOF[pv_indx]']= ALLPV_CHI2DOF(v2_pvs) + evt_vars['nTracks'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nTracks") + evt_vars['nLongTracks'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nLongTracks") + evt_vars['nPVs'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nPVs") + + #return all functors + functors = (vars_common, vars_composite, var_B, vars_basic, evt_vars) + return functors + +def tuple_Bst(Bst,lepton, MCTRUTH, v2_pvs, rec_summary): + #get functors + functors = get_functors(MCTRUTH, v2_pvs, rec_summary) + vars_common = functors[0] + vars_composite = functors[1] + var_B = functors[2] + vars_basic = functors[3] + evt_vars = functors[4] + + #variables for Sb field + vars_Bst = FunctorCollection() + B_child = F.CHILD(1, F.FORWARDARG0) + Epi_child = F.CHILD(2, F.FORWARDARG0) + bpv_pi = F.BPV(v2_pvs).bind(Epi_child) + #diff in vtx chi2 with and without extra particle + vars_Bst['DELTA_ENDVERTEX_CHI2'] = (F.CHI2 @ F.ENDVERTEX) - (F.CHI2 @ F.ENDVERTEX.bind(B_child)) + #IP and IPChi2 of extra particle wrt to Sb end vertex + vars_Bst['Epi_IP_WRT_SbENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ F.FORWARDARG0 , Epi_child) + vars_Bst['Epi_IPCHI2_WRT_SbENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ F.FORWARDARG0 , Epi_child) + #IP and IPChi2 of extra particle wrt to Lb end vertex + vars_Bst['Epi_IP_WRT_LbENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ B_child , Epi_child) + vars_Bst['Epi_IPCHI2_WRT_LbENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ B_child , Epi_child) + #angle between extra particle and Lb + vars_Bst['Epi_COSANGLE_Lb'] = F.COSANGLE.bind(F.THREEMOMENTUM @ B_child, F.THREEMOMENTUM @ Epi_child) + #diff in fd chi2 with and without extra particle + vars_Bst['Delta_BPV_of_Epi_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi, F.FORWARDARGS) - F.VTX_FDCHI2.bind(bpv_pi, B_child) + vars_Bst['BPV_of_Epi_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi, F.FORWARDARGS) + #IP chi2 of extra particle wrt PV and SV of Sb + vars_Bst['Epi_IP_WRT_SbBPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child) + vars_Bst['Epi_IPCHI2_WRT_SbBPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child) + #IP chi2 of extra particle wrt PV and SV of Bb + vars_Bst['Epi_IP_WRT_LbBPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ B_child, Epi_child) + vars_Bst['Epi_IPCHI2_WRT_LbBPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ B_child, Epi_child) + #DOCA and DOCACHI2 b/w Lb and extra particle + vars_Bst['DOCA12'] = F.DOCA(1, 2) + vars_Bst['DOCA12_CHI2_12'] = F.DOCACHI2(1, 2) + #vars_Bst['SDOCA12'] = F.SDOCA(1, 2) + #vars_Bst['SDOCA_CHI2_12'] = F.SDOCACHI2(1, 2) + #DOCACHI2 of extra particle wrt to mother i.e. Sb + vars_Bst['MTDOCACHI2_1'] = F.MTDOCACHI2(1, v2_pvs) + vars_Bst['MTDOCACHI2_2'] = F.MTDOCACHI2(2, v2_pvs) + + #define fields + fields = {} + fields['Sb'] = f'[B0 -> (B- -> (D0 -> K- pi+) e-) [pi+]CC]CC' + fields['Lb'] = f'[B0 -> ^(B- -> (D0 -> K- pi+) e-) [pi+]CC]CC' + fields['Lc'] = f'[B0 -> (B- -> ^(D0 -> K- pi+) e-) [pi+]CC]CC' + fields['Lep'] = f'[B0 -> (B- -> (D0 -> K- pi+) ^e-) [pi+]CC]CC' + fields['Epi'] = f'[B0 -> (B- -> (D0 -> K- pi+) e-) ^[pi+]CC]CC' + fields['Km'] = f'[B0 -> (B- -> (D0 -> ^K- pi+) e-) [pi+]CC]CC' + fields['pip'] = f'[B0 -> (B- -> (D0 -> K- ^pi+) e-) [pi+]CC]CC' + + #add variables + variables = {} + variables["ALL"] = vars_common + variables["Sb"] = vars_composite + vars_Bst + variables["Lb"] = vars_composite + var_B + variables["Lc"] = vars_composite + variables["Lep"] = vars_basic + variables["Epi"] = vars_basic + variables["Km"] = vars_basic + variables["pip"] = vars_basic + + #define tuple + my_tuple = Funtuple( + name=f"Tuple_{lepton}", + tuple_name="DecayTree", + fields=fields, + variables=variables, + inputs=Bst) + + return my_tuple + +def get_extra_pions(): + """ + Note this function in DaVinci requires: + https://gitlab.cern.ch/lhcb/Moore/-/merge_requests/3203 + and it's related LHCb, DaVinci and Rec MRs + """ + long_pions = make_has_rich_long_pions() + up_pions = make_has_rich_up_pions() + down_pions = make_has_rich_down_pions() + return ParticleContainersMerger([long_pions, up_pions, down_pions], + name='Pions_combiner') + +#def main(options): +def main(options: Options): + line_name = ['SpruceSLB_BuToD0ENu_D0ToKPi','SpruceSLB_BuToD0TauNu_D0ToKPi_TauToENuNu'] + + #define filer + my_filter_e = create_lines_filter(name="Filter_e", lines=[line_name[0]]) + my_filter_tau = create_lines_filter(name="Filter_tau", lines=[line_name[1]]) + + #get data and extra particles + lb_e = get_particles(f"/Event/Spruce/{line_name[0]}/Particles") + lb_tau = get_particles(f"/Event/Spruce/{line_name[1]}/Particles") + extra_particles = get_extra_pions() + + #get v2_pvs and rec_summary + v2_pvs = get_pvs() + rec_summary = get_rec_summary() + hadron_candidate_id = 421 + #make sb candidate + Bst_e = make_Bst(lb_e, extra_particles,'e',hadron_candidate_id,v2_pvs,False) + Bst_tau = make_Bst(lb_tau, extra_particles,'tau', hadron_candidate_id,v2_pvs,False) + #MCTRUTH_Bst = MCTruthAndBkgCat(Bst, name='MCTRUTH_Bst') + + + tuple_file_e = tuple_Bst(Bst_e,'e', 'None', v2_pvs, rec_summary) + tuple_file_tau = tuple_Bst(Bst_tau,'tau', 'None', v2_pvs, rec_summary) + + #define algorithms + user_algorithms = {} + user_algorithms['Alg_e'] = [my_filter_e, tuple_file_e] + user_algorithms['Alg_tau'] = [my_filter_tau, tuple_file_tau] + + return make_config(options, user_algorithms) -- GitLab From 4d9d79b57c07279c9559d9f36408f36570bdd63a Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Mon, 6 May 2024 11:58:24 +0200 Subject: [PATCH 24/57] Remove D02HH_Practice --- D02HH_Practice/README.md | 1 - D02HH_Practice/info.yaml | 38 -------------------------------- D02HH_Practice/ntuple_options.py | 38 -------------------------------- 3 files changed, 77 deletions(-) delete mode 100644 D02HH_Practice/README.md delete mode 100644 D02HH_Practice/info.yaml delete mode 100755 D02HH_Practice/ntuple_options.py diff --git a/D02HH_Practice/README.md b/D02HH_Practice/README.md deleted file mode 100644 index cc34fb0b7a..0000000000 --- a/D02HH_Practice/README.md +++ /dev/null @@ -1 +0,0 @@ -I want weed XDDDD diff --git a/D02HH_Practice/info.yaml b/D02HH_Practice/info.yaml deleted file mode 100644 index dbe57daefb..0000000000 --- a/D02HH_Practice/info.yaml +++ /dev/null @@ -1,38 +0,0 @@ -defaults: - application: DaVinci/v46r10 - wg: Charm - automatically_configure: yes - turbo: no - inform: - - chinghua@cern.ch - options: - - ntuple_options.py - output: D02KK.ROOT -checks: - histogram: - type: range - expression: Dst_2010_plus_M - limits: - min: 1900 - max: 2300 - blind_ranges: - min: 2000 - max: 2020 - histogram_fail: - type: range - expression: Dst_2010_plus_M - limits: - min: 0 - max: 10 - at_least_50_entries: - type: num_entries - tree_pattern: TupleDstToD0pi_D0ToKK/DecayTree - count: 50 - -2016_MagDown_PromptMC_D02KK: - input: - bk_query: "/MC/2016/Beam6500GeV-2016-MagDown-Nu1.6-25ns-Pythia8/Sim09c/Trig0x6138160F/Reco16/Turbo03/Stripping28r1NoPrescalingFlagged/27163002/ALLSTREAMS.DST" - checks: - - histogram - - histogram_fail - - at_least_50_entries diff --git a/D02HH_Practice/ntuple_options.py b/D02HH_Practice/ntuple_options.py deleted file mode 100755 index 0297e5cc85..0000000000 --- a/D02HH_Practice/ntuple_options.py +++ /dev/null @@ -1,38 +0,0 @@ -from Configurables import DecayTreeTuple - -## Specify the stream and stripping line -stream = "AllStreams" -line = "D2hhPromptDst2D2KKLine" - -## We create the DecayTreeTuple object, and indicate the Input -## (i.e., the TES location where the desired candidates may be) -## as well as the decay descriptor -dtt = DecayTreeTuple("TupleDstToD0pi_D0ToKK") -dtt.Inputs = ["/Event/{0}/Phys/{1}/Particles".format(stream, line)] -dtt.Decay = "[D*(2010)+ -> (D0 -> K- K+) pi+]CC" - -from Configurables import DaVinci - -DaVinci().UserAlgorithms += [dtt] - -# In general, thanks to using the automatically_configure setting, you don't need what's below so it can be removed -""" -DaVinci().InputType = "DST" -DaVinci().TupleFile = "DVntuple.root" -DaVinci().PrintFreq = 1000 -DaVinci().DataType = "2016" -DaVinci().Simulation = True -DaVinci().Lumi = not DaVinci().Simulation -DaVinci().EvtMax = -1 -DaVinci().CondDBtag = "sim-20170721-2-vc-md100" -DaVinci().DDDBtag = "dddb-20170721-3" -""" - -# The Analysis Productions software automatically finds a valid remote file to test on so we can drop this bit -""" -from GaudiConf import IOHelper - -IOHelper().inputFiles([ - "./00070793_00000001_7.AllStreams.dst" -], clear=True) -""" \ No newline at end of file -- GitLab From 12ff95b386cbf36cb8a21809b3f7e2fbaad3aa2c Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Mon, 6 May 2024 12:02:11 +0200 Subject: [PATCH 25/57] Fix info.yaml --- RDstar_taue_2024data/info.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RDstar_taue_2024data/info.yaml b/RDstar_taue_2024data/info.yaml index 2681a0a72b..49eb72ae27 100644 --- a/RDstar_taue_2024data/info.yaml +++ b/RDstar_taue_2024data/info.yaml @@ -21,7 +21,7 @@ defaults: conditions_version: master input_process: "Spruce" # Spruce for SprucingPass, "Hlt2" for RAW data (Hlt2 output) input_stream: "sl" # for streamed data - evt_max: 1000 + #evt_max: 1000 inform: - ching-hua.li@cern.ch wg: SL -- GitLab From b78916a57b7e0ee6eebfae540b68c6018a88d53c Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Mon, 6 May 2024 13:17:33 +0200 Subject: [PATCH 26/57] add Brems variables --- RDstar_taue_2024data/info.yaml | 6 +++--- RDstar_taue_2024data/run_Dzl.py | 34 ++++++++++++++++++++++++++++----- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/RDstar_taue_2024data/info.yaml b/RDstar_taue_2024data/info.yaml index 49eb72ae27..808f8ee379 100644 --- a/RDstar_taue_2024data/info.yaml +++ b/RDstar_taue_2024data/info.yaml @@ -1,7 +1,7 @@ checks: - hist_Sb_M: + hist: type: range - expression: Sb_M + expression: Lb_M limits: min: 2_000 max: 8_000 @@ -39,5 +39,5 @@ RDstar_taue_{{ evttype }}_{{ polarity }}: keep_running: true n_test_lfns: 1 checks: - - hist_Sb_M + - hist {%- endfor %} diff --git a/RDstar_taue_2024data/run_Dzl.py b/RDstar_taue_2024data/run_Dzl.py index 56c3ea074d..24107c0c61 100644 --- a/RDstar_taue_2024data/run_Dzl.py +++ b/RDstar_taue_2024data/run_Dzl.py @@ -188,8 +188,31 @@ def get_functors(MCTRUTH, v2_pvs, rec_summary): evt_vars['nLongTracks'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nLongTracks") evt_vars['nPVs'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nPVs") + vars_brems = FunctorCollection({}) + vars_brems.update({"HASBREM": F.HASBREM}) + #vars_brems.update({"HASBREMADDED": F.HASBREMADDED}) + vars_brems.update({"BREMENERGY": F.BREMENERGY}) + vars_brems.update({"BREMBENDCORR": F.BREMBENDCORR}) + vars_brems.update({"BREMPIDE": F.BREMPIDE}) + vars_brems.update({"ECALPIDE": F.ECALPIDE}) + vars_brems.update({"ECALPIDMU": F.ECALPIDMU}) + vars_brems.update({"HCALPIDE": F.HCALPIDE}) + vars_brems.update({"HCALPIDMU": F.HCALPIDMU}) + vars_brems.update({"ELECTRONSHOWEREOP": F.ELECTRONSHOWEREOP}) + vars_brems.update({"ELECTRONSHOWERDLL": F.ELECTRONSHOWERDLL}) + vars_brems.update({"CLUSTERMATCH": F.CLUSTERMATCH_CHI2}) + vars_brems.update({"ELECTRONMATCH": F.ELECTRONMATCH_CHI2}) + vars_brems.update({"BREMHYPOMATCH": F.BREMHYPOMATCH_CHI2}) + vars_brems.update({"ELECTRONENERGY": F.ELECTRONENERGY}) + vars_brems.update({"BREMHYPOENERGY": F.BREMHYPOENERGY}) + vars_brems.update({"BREMHYPODELTAX": F.BREMHYPODELTAX}) + #vars_brems.update({"BREMTRACKBASEDENERGY": F.BREMTRACKBASEDENERGY}) + vars_brems.update({"INBREM": F.INBREM}) + vars_brems.update({"PT_WITH_BREM": F.PT_WITH_BREM}) + vars_brems.update({"P_WITH_BREM": F.P_WITH_BREM}) + #return all functors - functors = (vars_common, vars_composite, var_B, vars_basic, evt_vars) + functors = (vars_common, vars_composite, var_B, vars_basic, evt_vars,vars_brems) return functors def tuple_Bst(Bst,lepton, MCTRUTH, v2_pvs, rec_summary): @@ -200,6 +223,7 @@ def tuple_Bst(Bst,lepton, MCTRUTH, v2_pvs, rec_summary): var_B = functors[2] vars_basic = functors[3] evt_vars = functors[4] + vars_brems = functors[5] #variables for Sb field vars_Bst = FunctorCollection() @@ -250,10 +274,10 @@ def tuple_Bst(Bst,lepton, MCTRUTH, v2_pvs, rec_summary): variables["Sb"] = vars_composite + vars_Bst variables["Lb"] = vars_composite + var_B variables["Lc"] = vars_composite - variables["Lep"] = vars_basic - variables["Epi"] = vars_basic - variables["Km"] = vars_basic - variables["pip"] = vars_basic + variables["Lep"] = vars_basic + vars_brems + variables["Epi"] = vars_basic + vars_brems + variables["Km"] = vars_basic + vars_brems + variables["pip"] = vars_basic + vars_brems #define tuple my_tuple = Funtuple( -- GitLab From 6430e46f8ab23cf38bbb3d3ac71b05d01a02868e Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Mon, 6 May 2024 15:54:20 +0200 Subject: [PATCH 27/57] Fix info.yaml --- RDstar_taue_2024data/info.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RDstar_taue_2024data/info.yaml b/RDstar_taue_2024data/info.yaml index 808f8ee379..0651abb089 100644 --- a/RDstar_taue_2024data/info.yaml +++ b/RDstar_taue_2024data/info.yaml @@ -16,7 +16,7 @@ defaults: input_raw_format: 0.5 input_type: ROOT # ROOT for SprucingPass, RAW for RAW data (Hlt2 output) simulation: False - data_type: "Upgrade" + #data_type: "Upgrade" geometry_version: run3/2024.Q1.2-v00.00 conditions_version: master input_process: "Spruce" # Spruce for SprucingPass, "Hlt2" for RAW data (Hlt2 output) -- GitLab From 69e4306c947795326967e806e28b201be945c4ad Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Thu, 9 May 2024 13:54:03 +0200 Subject: [PATCH 28/57] Add info.yaml and run_Dzl.py --- .../info.yaml | 12 +++---- .../run_Dzl.py | 31 +++++++++++-------- 2 files changed, 24 insertions(+), 19 deletions(-) rename {RDstar_taue_2024data => SL_mu_nu_D0toKpi_2024_data}/info.yaml (83%) rename {RDstar_taue_2024data => SL_mu_nu_D0toKpi_2024_data}/run_Dzl.py (91%) diff --git a/RDstar_taue_2024data/info.yaml b/SL_mu_nu_D0toKpi_2024_data/info.yaml similarity index 83% rename from RDstar_taue_2024data/info.yaml rename to SL_mu_nu_D0toKpi_2024_data/info.yaml index 0651abb089..6192c47c82 100644 --- a/RDstar_taue_2024data/info.yaml +++ b/SL_mu_nu_D0toKpi_2024_data/info.yaml @@ -1,17 +1,17 @@ checks: hist: type: range - expression: Lb_M + expression: Sb_Delta_M limits: - min: 2_000 - max: 8_000 - n_bins: 100 + min: 130 + max: 200 + n_bins: 70 defaults: application: "DaVinci/v64r4" output: DATA.ROOT options: - entrypoint: RDstar_taue_2024data.run_Dzl:main + entrypoint: SL_mu_nu_D0toKpi_2024_data.run_Dzl:main extra_options: input_raw_format: 0.5 input_type: ROOT # ROOT for SprucingPass, RAW for RAW data (Hlt2 output) @@ -30,7 +30,7 @@ defaults: ('2024Data', 'Down'), ]%} {%- for evttype, polarity in datasets %} -RDstar_taue_{{ evttype }}_{{ polarity }}: +b0_dstp_muon_and_taumu_{{ evttype }}_{{ polarity }}: input: bk_query: "/LHCb/Collision24/Beam6800GeV-VeloClosed-Mag{{ polarity }}-Excl-UT/Real Data/Sprucing24c1/90000000/SL.DST" dq_flags: diff --git a/RDstar_taue_2024data/run_Dzl.py b/SL_mu_nu_D0toKpi_2024_data/run_Dzl.py similarity index 91% rename from RDstar_taue_2024data/run_Dzl.py rename to SL_mu_nu_D0toKpi_2024_data/run_Dzl.py index 24107c0c61..0f0491375b 100644 --- a/RDstar_taue_2024data/run_Dzl.py +++ b/SL_mu_nu_D0toKpi_2024_data/run_Dzl.py @@ -228,6 +228,7 @@ def tuple_Bst(Bst,lepton, MCTRUTH, v2_pvs, rec_summary): #variables for Sb field vars_Bst = FunctorCollection() B_child = F.CHILD(1, F.FORWARDARG0) + D0_child = F.CHILD(1, F.CHILD(1,F.FORWARDARG0)) Epi_child = F.CHILD(2, F.FORWARDARG0) bpv_pi = F.BPV(v2_pvs).bind(Epi_child) #diff in vtx chi2 with and without extra particle @@ -257,16 +258,20 @@ def tuple_Bst(Bst,lepton, MCTRUTH, v2_pvs, rec_summary): #DOCACHI2 of extra particle wrt to mother i.e. Sb vars_Bst['MTDOCACHI2_1'] = F.MTDOCACHI2(1, v2_pvs) vars_Bst['MTDOCACHI2_2'] = F.MTDOCACHI2(2, v2_pvs) + #vars_Bst['Dstar_M'] = F.MASS @ ((F.FOURMOMENTUM @ D0_child)+(F.FOURMOMENTUM @ Epi_child)) + #vars_Bst['D0_M'] = F.MASS @ (F.FOURMOMENTUM @ D0_child) + #vars_Bst['test_id'] = F.PARTICLE_ID @ D0_child + vars_Bst['Delta_M'] = F.ABS @ ((F.MASS @ ((F.FOURMOMENTUM @ D0_child)+(F.FOURMOMENTUM @ Epi_child))) - (F.MASS @ D0_child)) #define fields fields = {} - fields['Sb'] = f'[B0 -> (B- -> (D0 -> K- pi+) e-) [pi+]CC]CC' - fields['Lb'] = f'[B0 -> ^(B- -> (D0 -> K- pi+) e-) [pi+]CC]CC' - fields['Lc'] = f'[B0 -> (B- -> ^(D0 -> K- pi+) e-) [pi+]CC]CC' - fields['Lep'] = f'[B0 -> (B- -> (D0 -> K- pi+) ^e-) [pi+]CC]CC' - fields['Epi'] = f'[B0 -> (B- -> (D0 -> K- pi+) e-) ^[pi+]CC]CC' - fields['Km'] = f'[B0 -> (B- -> (D0 -> ^K- pi+) e-) [pi+]CC]CC' - fields['pip'] = f'[B0 -> (B- -> (D0 -> K- ^pi+) e-) [pi+]CC]CC' + fields['Sb'] = f'[B0 -> (B- -> (D0 -> K- pi+) mu-) [pi+]CC]CC' + fields['Lb'] = f'[B0 -> ^(B- -> (D0 -> K- pi+) mu-) [pi+]CC]CC' + fields['Lc'] = f'[B0 -> (B- -> ^(D0 -> K- pi+) mu-) [pi+]CC]CC' + fields['Lep'] = f'[B0 -> (B- -> (D0 -> K- pi+) ^mu-) [pi+]CC]CC' + fields['Epi'] = f'[B0 -> (B- -> (D0 -> K- pi+) mu-) ^[pi+]CC]CC' + fields['Km'] = f'[B0 -> (B- -> (D0 -> ^K- pi+) mu-) [pi+]CC]CC' + fields['pip'] = f'[B0 -> (B- -> (D0 -> K- ^pi+) mu-) [pi+]CC]CC' #add variables variables = {} @@ -303,14 +308,14 @@ def get_extra_pions(): #def main(options): def main(options: Options): - line_name = ['SpruceSLB_BuToD0ENu_D0ToKPi','SpruceSLB_BuToD0TauNu_D0ToKPi_TauToENuNu'] + line_name = ['SpruceSLB_BuToD0MuNu_D0ToKPi','SpruceSLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu'] #define filer - my_filter_e = create_lines_filter(name="Filter_e", lines=[line_name[0]]) + my_filter_mu = create_lines_filter(name="Filter_mu", lines=[line_name[0]]) my_filter_tau = create_lines_filter(name="Filter_tau", lines=[line_name[1]]) #get data and extra particles - lb_e = get_particles(f"/Event/Spruce/{line_name[0]}/Particles") + lb_mu = get_particles(f"/Event/Spruce/{line_name[0]}/Particles") lb_tau = get_particles(f"/Event/Spruce/{line_name[1]}/Particles") extra_particles = get_extra_pions() @@ -319,17 +324,17 @@ def main(options: Options): rec_summary = get_rec_summary() hadron_candidate_id = 421 #make sb candidate - Bst_e = make_Bst(lb_e, extra_particles,'e',hadron_candidate_id,v2_pvs,False) + Bst_mu = make_Bst(lb_mu, extra_particles,'mu',hadron_candidate_id,v2_pvs,False) Bst_tau = make_Bst(lb_tau, extra_particles,'tau', hadron_candidate_id,v2_pvs,False) #MCTRUTH_Bst = MCTruthAndBkgCat(Bst, name='MCTRUTH_Bst') - tuple_file_e = tuple_Bst(Bst_e,'e', 'None', v2_pvs, rec_summary) + tuple_file_mu = tuple_Bst(Bst_mu,'mu', 'None', v2_pvs, rec_summary) tuple_file_tau = tuple_Bst(Bst_tau,'tau', 'None', v2_pvs, rec_summary) #define algorithms user_algorithms = {} - user_algorithms['Alg_e'] = [my_filter_e, tuple_file_e] + user_algorithms['Alg_mu'] = [my_filter_mu, tuple_file_mu] user_algorithms['Alg_tau'] = [my_filter_tau, tuple_file_tau] return make_config(options, user_algorithms) -- GitLab From 272e173983bbbaef4a880378fd1acee138d6d08a Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Sun, 12 May 2024 11:40:41 +0200 Subject: [PATCH 29/57] Add D0toKpi l nu fakeline --- SL_e_nu_D0toKpi_fakeline_2024_data/info.yaml | 43 +++ SL_e_nu_D0toKpi_fakeline_2024_data/run_Dzl.py | 340 ++++++++++++++++++ SL_mu_nu_D0toKpi_2024_data/run_Dzl.py | 26 +- SL_mu_nu_D0toKpi_fakeline_2024_data/info.yaml | 43 +++ .../run_Dzl.py | 340 ++++++++++++++++++ 5 files changed, 779 insertions(+), 13 deletions(-) create mode 100644 SL_e_nu_D0toKpi_fakeline_2024_data/info.yaml create mode 100644 SL_e_nu_D0toKpi_fakeline_2024_data/run_Dzl.py create mode 100644 SL_mu_nu_D0toKpi_fakeline_2024_data/info.yaml create mode 100644 SL_mu_nu_D0toKpi_fakeline_2024_data/run_Dzl.py diff --git a/SL_e_nu_D0toKpi_fakeline_2024_data/info.yaml b/SL_e_nu_D0toKpi_fakeline_2024_data/info.yaml new file mode 100644 index 0000000000..c4f455a0ee --- /dev/null +++ b/SL_e_nu_D0toKpi_fakeline_2024_data/info.yaml @@ -0,0 +1,43 @@ +checks: + hist: + type: range + expression: Sb_Delta_M + limits: + min: 130 + max: 200 + n_bins: 70 + +defaults: + application: "DaVinci/v64r4" + output: DATA.ROOT + options: + entrypoint: SL_e_nu_D0toKpi_fakeline_2024_data.run_Dzl:main + extra_options: + input_raw_format: 0.5 + input_type: ROOT # ROOT for SprucingPass, RAW for RAW data (Hlt2 output) + simulation: False + #data_type: "Upgrade" + geometry_version: run3/2024.Q1.2-v00.00 + conditions_version: master + input_process: "Spruce" # Spruce for SprucingPass, "Hlt2" for RAW data (Hlt2 output) + input_stream: "sl" # for streamed data + #evt_max: 1000 + inform: + - ching-hua.li@cern.ch + wg: SL + +{%- set datasets = [ + ('2024Data', 'Down'), +]%} +{%- for evttype, polarity in datasets %} +b0_dstp_e_and_taue_fake_{{ evttype }}_{{ polarity }}: + input: + bk_query: "/LHCb/Collision24/Beam6800GeV-VeloClosed-Mag{{ polarity }}-Excl-UT/Real Data/Sprucing24c1/90000000/SL.DST" + dq_flags: + - UNCHECKED + - OK + keep_running: true + n_test_lfns: 1 + checks: + - hist +{%- endfor %} diff --git a/SL_e_nu_D0toKpi_fakeline_2024_data/run_Dzl.py b/SL_e_nu_D0toKpi_fakeline_2024_data/run_Dzl.py new file mode 100644 index 0000000000..8bc45c7c87 --- /dev/null +++ b/SL_e_nu_D0toKpi_fakeline_2024_data/run_Dzl.py @@ -0,0 +1,340 @@ +import sys,os,math +from PyConf.reading import get_pvs, get_rec_summary, get_particles +import Functors as F +from FunTuple import FunctorCollection +from FunTuple import FunTuple_Particles as Funtuple +from DaVinci.algorithms import create_lines_filter +from DaVinci import Options,make_config +import FunTuple.functorcollections as FC +from DaVinciMCTools import MCTruthAndBkgCat +from Hlt2Conf.algorithms_thor import ParticleCombiner, ParticleFilter +from Hlt2Conf.algorithms_thor import ParticleContainersMerger +from Functors.grammar import Functor +from Hlt2Conf.standard_particles import make_has_rich_long_pions,make_has_rich_up_pions,make_has_rich_down_pions + +_BPVCORRM = Functor('_BPVCORRM', 'Composite::CorrectedMass','Compute the corrected mass') +_allpv_FDVEC = (F.ENDVERTEX_POS @ F.FORWARDARG1 - F.TOLINALG @ F.POSITION @ F.FORWARDARG0) +_allpv_NORMEDDOT = F.NORMEDDOT.bind(F.THREEMOMENTUM @ F.FORWARDARG1, _allpv_FDVEC) +#ALLPV_CHI2 = lambda Vertices: F.MAP(F.CHI2) @ F.TES(Vertices) +#ALLPV_CHI2DOF = lambda Vertices: F.MAP(F.CHI2DOF) @ F.TES(Vertices) +ALLPV_IPCHI2 = lambda Vertices: F.MAP(F.IPCHI2).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_FDCHI2 = lambda Vertices: F.MAP(F.VTX_FDCHI2).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_DIRA = lambda Vertices: F.MAP(_allpv_NORMEDDOT).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_CORRM = lambda Vertices: F.MAP(_BPVCORRM).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_LTIME = lambda Vertices: F.MAP(F.VTX_LTIME).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_DLS = lambda Vertices: F.MAP(F.VTX_DLS).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_FD_COORDINATE = lambda coordinate, Vertices: F.MAP(coordinate @ _allpv_FDVEC).bind(F.TES(Vertices), F.FORWARDARGS) +#MCNEUTRINO = F.FIND_MCDECAY("[ Lambda_b0 => Lambda_c+ mu- ^nu_mu~ ]CC") + +TRUE_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.PARTICLE_ID) == id) +#MCMOTHER_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.MC_MOTHER(1, F.PARTICLE_ID)) == id) +#GD_MCMOTHER_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.MC_MOTHER(2, F.PARTICLE_ID)) == id) +#GD_GD_MCMOTHER_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.MC_MOTHER(3, F.PARTICLE_ID)) == id) + +def make_Bst(B, pions,lepton, hadron_candidate_id,v2_pvs,do_truth_matching = True): + if do_truth_matching == True : + #filter B keeping only true D0 and true leptons + MCTRUTH_B = MCTruthAndBkgCat(B, name='MCTRUTH_Bu') + Dz_child = F.CHILD(1, F.FORWARDARG0) #get the first child of B*- which is D0 + lep_child = F.CHILD(2, F.FORWARDARG0) #get the second child of B*- which is lepton + Dz_truth_cut = TRUE_ID_IS(hadron_candidate_id, MCTRUTH_B) @ Dz_child #require that D0 is true + lep_truth_cut = F.require_any(TRUE_ID_IS(11, MCTRUTH_B) @ lep_child , TRUE_ID_IS(13, MCTRUTH_B) @ lep_child) #require that lepton is true i.e. electron or muon + cut_b = F.require_all(Dz_truth_cut, lep_truth_cut) #make a cut + signal_B = ParticleFilter(Input=B, Cut=F.FILTER(cut_b), name='signal_Dzmu') #filter the B candidates + else : signal_B = B + + #combine to make [B*0 -> B*- pi+]cc + Bst_1 = ParticleCombiner( + Inputs=[B, pions], + name=f'Bst_1_{lepton}', + DecayDescriptor='[B0 -> B- pi+]cc', + CombinationCut=F.ALL, + CompositeCut=F.ALL, + ParticleCombiner="ParticleVertexFitter", + PrimaryVertices=v2_pvs + #OutputLevel=1 + ) + #combine to make [B*0 -> B*- pi-]cc + Bst_2 = ParticleCombiner( + Inputs=[B, pions], + name=f'Bst_2_{lepton}', + DecayDescriptor='[B0 -> B- pi-]cc', + CombinationCut=F.ALL, + CompositeCut=F.ALL, + ParticleCombiner="ParticleVertexFitter", + PrimaryVertices=v2_pvs + #OutputLevel=1 + ) + #merge the two Bst candidates + Bst = ParticleContainersMerger([Bst_1, Bst_2], name = f'Bst_combiner_{lepton}') + return Bst + +def get_functors(MCTRUTH, v2_pvs, rec_summary): + #define common variables for all fields (composite and basic) + vars_common = FunctorCollection() + #all pvs: ip, ipchi2. The PV positions are stored in event variables + vars_common['ALLPV_IP[pv_indx]'] = F.ALLPV_IP(v2_pvs) + vars_common['ALLPV_IPCHI2[pv_indx]'] = ALLPV_IPCHI2(v2_pvs) + #best pv: x, y, z, ip, ipchi2 + vars_common['BPV_X'] = F.BPVX(v2_pvs) + vars_common['BPV_Y'] = F.BPVY(v2_pvs) + vars_common['BPV_Z'] = F.BPVZ(v2_pvs) + vars_common['BPV_IP'] = F.BPVIP(v2_pvs) + vars_common['BPV_IPCHI2'] = F.BPVIPCHI2(v2_pvs) + vars_common['BPV_CHI2'] = F.CHI2 @ F.BPV(v2_pvs) + vars_common['BPV_CHI2DOF'] = F.CHI2DOF @ F.BPV(v2_pvs) + #particle id, key, truekey. The trueid is stored in MCHierarchy + vars_common['ID'] = F.PARTICLE_ID + vars_common['KEY'] = F.OBJECT_KEY + #get charge, min ip and min ipchi2 + vars_common['CHARGE'] = F.CHARGE + vars_common['MINIP'] = F.MINIP(v2_pvs) + vars_common['MINIPCHI2'] = F.MINIPCHI2(v2_pvs) + #reco kinematics + vars_common += FC.Kinematics() + vars_common['ETA'] = F.ETA + vars_common['PHI'] = F.PHI + if MCTRUTH != 'None': + #mc vars + vars_common['TRUEKEY'] = F.VALUE_OR(-1) @ MCTRUTH(F.OBJECT_KEY) + vars_common += FC.MCKinematics(mctruth_alg = MCTRUTH) + vars_common['TRUEETA'] = MCTRUTH(F.ETA) + vars_common['TRUEPHI'] = MCTRUTH(F.PHI) + #type of the origin vertex + vars_common['MC_VTX_TYPE'] = MCTRUTH(F.VALUE_OR(-1) @ F.MC_VTX_TYPE @ F.MC_ORIGINVERTEX) + ##mc truth hierarchy (done seperately) + #vars_common += FC.MCHierarchy(mctruth_alg = MCTRUTH) + #make some helper functions + MCMOTHER_ID = lambda n: F.VALUE_OR(0) @ MCTRUTH(F.MC_MOTHER(n, F.PARTICLE_ID)) + MCMOTHER_KEY = lambda n: F.VALUE_OR(-1) @ MCTRUTH(F.MC_MOTHER(n, F.OBJECT_KEY )) + vars_common["TRUEID"] = F.VALUE_OR(0) @ MCTRUTH(F.PARTICLE_ID) + vars_common["MCKEY"] = F.VALUE_OR(0) @ MCTRUTH(F.OBJECT_KEY) + vars_common["MC_MOTHER_ID"] = MCMOTHER_ID(1) + vars_common["MC_MOTHER_KEY"] = MCMOTHER_KEY(1) + for i in range(2,14): + prefix = "MC_GD_MOTHER_{}".format(i) + vars_common[f"{prefix}_ID"] = MCMOTHER_ID(i) + vars_common[f"{prefix}_KEY"] = MCMOTHER_KEY(i) + + #variables for composite particles + vars_composite = FunctorCollection() + #end vertex position and end vertex chi2 + vars_composite['ENDVERTEX_POS_'] = F.ENDVERTEX_POS + vars_composite['ENDVERTEX_CHI2'] = F.CHI2 @ F.ENDVERTEX + vars_composite['ENDVERTEX_CHI2DOF'] = F.CHI2DOF @ F.ENDVERTEX + #all pvs: dira, fd, fdchi2 + vars_composite['ALLPV_DIRA[pv_indx]'] = ALLPV_DIRA(v2_pvs) + vars_composite['ALLPV_FD_X[pv_indx]'] = ALLPV_FD_COORDINATE(F.X_COORDINATE, v2_pvs) + vars_composite['ALLPV_FD_Y[pv_indx]'] = ALLPV_FD_COORDINATE(F.Y_COORDINATE, v2_pvs) + vars_composite['ALLPV_FD_Z[pv_indx]'] = ALLPV_FD_COORDINATE(F.Z_COORDINATE, v2_pvs) + vars_composite['ALLPV_FDCHI2[pv_indx]'] = ALLPV_FDCHI2(v2_pvs) + vars_composite['ALLPV_CORRM[pv_indx]'] = ALLPV_CORRM(v2_pvs) + vars_composite['ALLPV_LTIME[pv_indx]'] = ALLPV_LTIME(v2_pvs) + vars_composite['ALLPV_DLS[pv_indx]'] = ALLPV_DLS(v2_pvs) + #best pv: dira, fd, fdchi2, corrm, ltime, dls + vars_composite['BPV_DIRA'] = F.BPVDIRA(v2_pvs) + vars_composite['BPV_FD_'] = F.BPVFDVEC(v2_pvs) + vars_composite['BPV_FDCHI2'] = F.BPVFDCHI2(v2_pvs) + vars_composite['BPV_CORRM'] = F.BPVCORRM(v2_pvs) + vars_composite['BPV_LTIME'] = F.BPVLTIME(v2_pvs) + vars_composite['BPV_DLS'] = F.BPVDLS(v2_pvs) + #mc composite vertex information + + if MCTRUTH != 'None': vars_composite += FC.MCVertexInfo(mctruth_alg = MCTRUTH) + #Compute maximum DOCA and maximum DOCACHI2. Since there are + # only two daughters of Sb particles, the maximum DOCA/DOCACHI2 is + # the DOCA/DOCACHI2 see below. + vars_composite['MAX_DOCA'] = F.MAXDOCA + vars_composite['MAX_DOCACHI2'] = F.MAXDOCACHI2 + vars_composite['MAX_SDOCA'] = F.MAXSDOCA + vars_composite['MAX_SDOCACHI2'] = F.MAXSDOCACHI2 + + #variables for Lb field + var_B = FunctorCollection() + #var_B['TRUENU_PX'] = MCTRUTH(F.PX @ MCNEUTRINO) + #var_B['TRUENU_PY'] = MCTRUTH(F.PY @ MCNEUTRINO) + #var_B['TRUENU_PZ'] = MCTRUTH(F.PZ @ MCNEUTRINO) + #var_B['TRUENU_ENERGY'] = MCTRUTH(F.ENERGY @ MCNEUTRINO) + ###Bkg category + ##var_B["BKGCAT"] = MCTRUTH.BkgCat + + #variables for basics + vars_basic = FunctorCollection() + vars_basic['TRACKTYPE'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKTYPE @ F.TRACK + vars_basic['TRACKHISTORY'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKHISTORY @ F.TRACK + vars_basic['TRACKFLAG'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKFLAG @ F.TRACK + vars_basic['TRACKNDOF'] = F.VALUE_OR(-1) @ F.NDOF @ F.TRACK + vars_basic['TRACKCHI2'] = F.CHI2 @ F.TRACK + vars_basic['TRACKCHI2DOF'] = F.CHI2DOF @ F.TRACK + vars_basic['GHOSTPROB'] = F.GHOSTPROB + vars_basic['PIDpi'] = F.PID_PI + vars_basic['PIDk'] = F.PID_K + vars_basic['PIDp'] = F.PID_P + vars_basic['PIDe'] = F.PID_E + vars_basic['PIDmu'] = F.PID_MU + if MCTRUTH != 'None': + vars_basic['TRUEORIGINVERTEX_X'] = MCTRUTH(F.ORIGIN_VX) + vars_basic['TRUEORIGINVERTEX_Y'] = MCTRUTH(F.ORIGIN_VY) + vars_basic['TRUEORIGINVERTEX_Z'] = MCTRUTH(F.ORIGIN_VZ) + + #variables for event + evt_vars = FunctorCollection() + #evt_vars['ALLPV_X[pv_indx]'] = F.ALLPVX(v2_pvs) + #evt_vars['ALLPV_Y[pv_indx]'] = F.ALLPVY(v2_pvs) + #evt_vars['ALLPV_Z[pv_indx]'] = F.ALLPVZ(v2_pvs) + #evt_vars['ALLPV_CHI2[pv_indx]'] = ALLPV_CHI2(v2_pvs) + #evt_vars['ALLPV_CHI2DOF[pv_indx]']= ALLPV_CHI2DOF(v2_pvs) + evt_vars['nTracks'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nTracks") + evt_vars['nLongTracks'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nLongTracks") + evt_vars['nPVs'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nPVs") + + vars_brems = FunctorCollection({}) + vars_brems.update({"HASBREM": F.HASBREM}) + #vars_brems.update({"HASBREMADDED": F.HASBREMADDED}) + vars_brems.update({"BREMENERGY": F.BREMENERGY}) + vars_brems.update({"BREMBENDCORR": F.BREMBENDCORR}) + vars_brems.update({"BREMPIDE": F.BREMPIDE}) + vars_brems.update({"ECALPIDE": F.ECALPIDE}) + vars_brems.update({"ECALPIDMU": F.ECALPIDMU}) + vars_brems.update({"HCALPIDE": F.HCALPIDE}) + vars_brems.update({"HCALPIDMU": F.HCALPIDMU}) + vars_brems.update({"ELECTRONSHOWEREOP": F.ELECTRONSHOWEREOP}) + vars_brems.update({"ELECTRONSHOWERDLL": F.ELECTRONSHOWERDLL}) + vars_brems.update({"CLUSTERMATCH": F.CLUSTERMATCH_CHI2}) + vars_brems.update({"ELECTRONMATCH": F.ELECTRONMATCH_CHI2}) + vars_brems.update({"BREMHYPOMATCH": F.BREMHYPOMATCH_CHI2}) + vars_brems.update({"ELECTRONENERGY": F.ELECTRONENERGY}) + vars_brems.update({"BREMHYPOENERGY": F.BREMHYPOENERGY}) + vars_brems.update({"BREMHYPODELTAX": F.BREMHYPODELTAX}) + #vars_brems.update({"BREMTRACKBASEDENERGY": F.BREMTRACKBASEDENERGY}) + vars_brems.update({"INBREM": F.INBREM}) + vars_brems.update({"PT_WITH_BREM": F.PT_WITH_BREM}) + vars_brems.update({"P_WITH_BREM": F.P_WITH_BREM}) + + #return all functors + functors = (vars_common, vars_composite, var_B, vars_basic, evt_vars,vars_brems) + return functors + +def tuple_Bst(Bst,lepton, MCTRUTH, v2_pvs, rec_summary): + #get functors + functors = get_functors(MCTRUTH, v2_pvs, rec_summary) + vars_common = functors[0] + vars_composite = functors[1] + var_B = functors[2] + vars_basic = functors[3] + evt_vars = functors[4] + vars_brems = functors[5] + + #variables for Sb field + vars_Bst = FunctorCollection() + B_child = F.CHILD(1, F.FORWARDARG0) + D0_child = F.CHILD(1, F.CHILD(1,F.FORWARDARG0)) + Epi_child = F.CHILD(2, F.FORWARDARG0) + bpv_pi = F.BPV(v2_pvs).bind(Epi_child) + #diff in vtx chi2 with and without extra particle + vars_Bst['DELTA_ENDVERTEX_CHI2'] = (F.CHI2 @ F.ENDVERTEX) - (F.CHI2 @ F.ENDVERTEX.bind(B_child)) + #IP and IPChi2 of extra particle wrt to Sb end vertex + vars_Bst['Epi_IP_WRT_SbENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ F.FORWARDARG0 , Epi_child) + vars_Bst['Epi_IPCHI2_WRT_SbENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ F.FORWARDARG0 , Epi_child) + #IP and IPChi2 of extra particle wrt to Lb end vertex + vars_Bst['Epi_IP_WRT_LbENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ B_child , Epi_child) + vars_Bst['Epi_IPCHI2_WRT_LbENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ B_child , Epi_child) + #angle between extra particle and Lb + vars_Bst['Epi_COSANGLE_Lb'] = F.COSANGLE.bind(F.THREEMOMENTUM @ B_child, F.THREEMOMENTUM @ Epi_child) + #diff in fd chi2 with and without extra particle + vars_Bst['Delta_BPV_of_Epi_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi, F.FORWARDARGS) - F.VTX_FDCHI2.bind(bpv_pi, B_child) + vars_Bst['BPV_of_Epi_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi, F.FORWARDARGS) + #IP chi2 of extra particle wrt PV and SV of Sb + vars_Bst['Epi_IP_WRT_SbBPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child) + vars_Bst['Epi_IPCHI2_WRT_SbBPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child) + #IP chi2 of extra particle wrt PV and SV of Bb + vars_Bst['Epi_IP_WRT_LbBPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ B_child, Epi_child) + vars_Bst['Epi_IPCHI2_WRT_LbBPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ B_child, Epi_child) + #DOCA and DOCACHI2 b/w Lb and extra particle + vars_Bst['DOCA12'] = F.DOCA(1, 2) + vars_Bst['DOCA12_CHI2_12'] = F.DOCACHI2(1, 2) + #vars_Bst['SDOCA12'] = F.SDOCA(1, 2) + #vars_Bst['SDOCA_CHI2_12'] = F.SDOCACHI2(1, 2) + #DOCACHI2 of extra particle wrt to mother i.e. Sb + vars_Bst['MTDOCACHI2_1'] = F.MTDOCACHI2(1, v2_pvs) + vars_Bst['MTDOCACHI2_2'] = F.MTDOCACHI2(2, v2_pvs) + #vars_Bst['Dstar_M'] = F.MASS @ ((F.FOURMOMENTUM @ D0_child)+(F.FOURMOMENTUM @ Epi_child)) + #vars_Bst['D0_M'] = F.MASS @ (F.FOURMOMENTUM @ D0_child) + #vars_Bst['test_id'] = F.PARTICLE_ID @ D0_child + vars_Bst['Delta_M'] = F.ABS @ ((F.MASS @ ((F.FOURMOMENTUM @ D0_child)+(F.FOURMOMENTUM @ Epi_child))) - (F.MASS @ D0_child)) + + #define fields + fields = {} + fields['Sb'] = f'[B0 -> (B- -> (D0 -> K- pi+) {lepton}-) [pi+]CC]CC' + fields['Lb'] = f'[B0 -> ^(B- -> (D0 -> K- pi+) {lepton}-) [pi+]CC]CC' + fields['Lc'] = f'[B0 -> (B- -> ^(D0 -> K- pi+) {lepton}-) [pi+]CC]CC' + fields['Lep'] = f'[B0 -> (B- -> (D0 -> K- pi+) ^{lepton}-) [pi+]CC]CC' + fields['Epi'] = f'[B0 -> (B- -> (D0 -> K- pi+) {lepton}-) ^[pi+]CC]CC' + fields['Km'] = f'[B0 -> (B- -> (D0 -> ^K- pi+) {lepton}-) [pi+]CC]CC' + fields['pip'] = f'[B0 -> (B- -> (D0 -> K- ^pi+) {lepton}-) [pi+]CC]CC' + + #add variables + variables = {} + variables["ALL"] = vars_common + variables["Sb"] = vars_composite + vars_Bst + variables["Lb"] = vars_composite + var_B + variables["Lc"] = vars_composite + variables["Lep"] = vars_basic + vars_brems + variables["Epi"] = vars_basic + vars_brems + variables["Km"] = vars_basic + vars_brems + variables["pip"] = vars_basic + vars_brems + + #define tuple + my_tuple = Funtuple( + name=f"Tuple_{lepton}", + tuple_name="DecayTree", + fields=fields, + variables=variables, + inputs=Bst) + + return my_tuple + +def get_extra_pions(): + """ + Note this function in DaVinci requires: + https://gitlab.cern.ch/lhcb/Moore/-/merge_requests/3203 + and it's related LHCb, DaVinci and Rec MRs + """ + long_pions = make_has_rich_long_pions() + up_pions = make_has_rich_up_pions() + down_pions = make_has_rich_down_pions() + return ParticleContainersMerger([long_pions, up_pions, down_pions], + name='Pions_combiner') + +#def main(options): +def main(options: Options): + line_name = ['SpruceSLB_BuToD0ENu_D0ToKPi_FakeElectron','SpruceSLB_BuToD0TauNu_D0ToKPi_FakeElectron'] + + #define filer + my_filter_l = create_lines_filter(name="Filter_l", lines=[line_name[0]]) + my_filter_tau = create_lines_filter(name="Filter_tau", lines=[line_name[1]]) + + #get data and extra particles + lb_l = get_particles(f"/Event/Spruce/{line_name[0]}/Particles") + lb_tau = get_particles(f"/Event/Spruce/{line_name[1]}/Particles") + extra_particles = get_extra_pions() + + #get v2_pvs and rec_summary + v2_pvs = get_pvs() + rec_summary = get_rec_summary() + hadron_candidate_id = 421 + #make sb candidate + Bst_l = make_Bst(lb_l, extra_particles,'e',hadron_candidate_id,v2_pvs,False) + Bst_tau = make_Bst(lb_tau, extra_particles,'tau', hadron_candidate_id,v2_pvs,False) + #MCTRUTH_Bst = MCTruthAndBkgCat(Bst, name='MCTRUTH_Bst') + + + tuple_file_l = tuple_Bst(Bst_l,'e', 'None', v2_pvs, rec_summary) + tuple_file_tau = tuple_Bst(Bst_tau,'tau', 'None', v2_pvs, rec_summary) + + #define algorithms + user_algorithms = {} + user_algorithms['Alg_l'] = [my_filter_l, tuple_file_l] + user_algorithms['Alg_tau'] = [my_filter_tau, tuple_file_tau] + + return make_config(options, user_algorithms) diff --git a/SL_mu_nu_D0toKpi_2024_data/run_Dzl.py b/SL_mu_nu_D0toKpi_2024_data/run_Dzl.py index 0f0491375b..0cb5e40d2a 100644 --- a/SL_mu_nu_D0toKpi_2024_data/run_Dzl.py +++ b/SL_mu_nu_D0toKpi_2024_data/run_Dzl.py @@ -265,13 +265,13 @@ def tuple_Bst(Bst,lepton, MCTRUTH, v2_pvs, rec_summary): #define fields fields = {} - fields['Sb'] = f'[B0 -> (B- -> (D0 -> K- pi+) mu-) [pi+]CC]CC' - fields['Lb'] = f'[B0 -> ^(B- -> (D0 -> K- pi+) mu-) [pi+]CC]CC' - fields['Lc'] = f'[B0 -> (B- -> ^(D0 -> K- pi+) mu-) [pi+]CC]CC' - fields['Lep'] = f'[B0 -> (B- -> (D0 -> K- pi+) ^mu-) [pi+]CC]CC' - fields['Epi'] = f'[B0 -> (B- -> (D0 -> K- pi+) mu-) ^[pi+]CC]CC' - fields['Km'] = f'[B0 -> (B- -> (D0 -> ^K- pi+) mu-) [pi+]CC]CC' - fields['pip'] = f'[B0 -> (B- -> (D0 -> K- ^pi+) mu-) [pi+]CC]CC' + fields['Sb'] = f'[B0 -> (B- -> (D0 -> K- pi+) {lepton}-) [pi+]CC]CC' + fields['Lb'] = f'[B0 -> ^(B- -> (D0 -> K- pi+) {lepton}-) [pi+]CC]CC' + fields['Lc'] = f'[B0 -> (B- -> ^(D0 -> K- pi+) {lepton}-) [pi+]CC]CC' + fields['Lep'] = f'[B0 -> (B- -> (D0 -> K- pi+) ^{lepton}-) [pi+]CC]CC' + fields['Epi'] = f'[B0 -> (B- -> (D0 -> K- pi+) {lepton}-) ^[pi+]CC]CC' + fields['Km'] = f'[B0 -> (B- -> (D0 -> ^K- pi+) {lepton}-) [pi+]CC]CC' + fields['pip'] = f'[B0 -> (B- -> (D0 -> K- ^pi+) {lepton}-) [pi+]CC]CC' #add variables variables = {} @@ -308,14 +308,14 @@ def get_extra_pions(): #def main(options): def main(options: Options): - line_name = ['SpruceSLB_BuToD0MuNu_D0ToKPi','SpruceSLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu'] + line_name = ['SpruceSLB_BuToD0MuNu_D0ToKPi','SpruceSLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu'] #define filer - my_filter_mu = create_lines_filter(name="Filter_mu", lines=[line_name[0]]) + my_filter_l = create_lines_filter(name="Filter_l", lines=[line_name[0]]) my_filter_tau = create_lines_filter(name="Filter_tau", lines=[line_name[1]]) #get data and extra particles - lb_mu = get_particles(f"/Event/Spruce/{line_name[0]}/Particles") + lb_l = get_particles(f"/Event/Spruce/{line_name[0]}/Particles") lb_tau = get_particles(f"/Event/Spruce/{line_name[1]}/Particles") extra_particles = get_extra_pions() @@ -324,17 +324,17 @@ def main(options: Options): rec_summary = get_rec_summary() hadron_candidate_id = 421 #make sb candidate - Bst_mu = make_Bst(lb_mu, extra_particles,'mu',hadron_candidate_id,v2_pvs,False) + Bst_l = make_Bst(lb_l, extra_particles,'mu',hadron_candidate_id,v2_pvs,False) Bst_tau = make_Bst(lb_tau, extra_particles,'tau', hadron_candidate_id,v2_pvs,False) #MCTRUTH_Bst = MCTruthAndBkgCat(Bst, name='MCTRUTH_Bst') - tuple_file_mu = tuple_Bst(Bst_mu,'mu', 'None', v2_pvs, rec_summary) + tuple_file_l = tuple_Bst(Bst_l,'mu', 'None', v2_pvs, rec_summary) tuple_file_tau = tuple_Bst(Bst_tau,'tau', 'None', v2_pvs, rec_summary) #define algorithms user_algorithms = {} - user_algorithms['Alg_mu'] = [my_filter_mu, tuple_file_mu] + user_algorithms['Alg_l'] = [my_filter_l, tuple_file_l] user_algorithms['Alg_tau'] = [my_filter_tau, tuple_file_tau] return make_config(options, user_algorithms) diff --git a/SL_mu_nu_D0toKpi_fakeline_2024_data/info.yaml b/SL_mu_nu_D0toKpi_fakeline_2024_data/info.yaml new file mode 100644 index 0000000000..c2d8975aac --- /dev/null +++ b/SL_mu_nu_D0toKpi_fakeline_2024_data/info.yaml @@ -0,0 +1,43 @@ +checks: + hist: + type: range + expression: Sb_Delta_M + limits: + min: 130 + max: 200 + n_bins: 70 + +defaults: + application: "DaVinci/v64r4" + output: DATA.ROOT + options: + entrypoint: SL_mu_nu_D0toKpi_fakeline_2024_data.run_Dzl:main + extra_options: + input_raw_format: 0.5 + input_type: ROOT # ROOT for SprucingPass, RAW for RAW data (Hlt2 output) + simulation: False + #data_type: "Upgrade" + geometry_version: run3/2024.Q1.2-v00.00 + conditions_version: master + input_process: "Spruce" # Spruce for SprucingPass, "Hlt2" for RAW data (Hlt2 output) + input_stream: "sl" # for streamed data + #evt_max: 1000 + inform: + - ching-hua.li@cern.ch + wg: SL + +{%- set datasets = [ + ('2024Data', 'Down'), +]%} +{%- for evttype, polarity in datasets %} +b0_dstp_muon_and_taumu_fake_{{ evttype }}_{{ polarity }}: + input: + bk_query: "/LHCb/Collision24/Beam6800GeV-VeloClosed-Mag{{ polarity }}-Excl-UT/Real Data/Sprucing24c1/90000000/SL.DST" + dq_flags: + - UNCHECKED + - OK + keep_running: true + n_test_lfns: 1 + checks: + - hist +{%- endfor %} diff --git a/SL_mu_nu_D0toKpi_fakeline_2024_data/run_Dzl.py b/SL_mu_nu_D0toKpi_fakeline_2024_data/run_Dzl.py new file mode 100644 index 0000000000..2d3d332375 --- /dev/null +++ b/SL_mu_nu_D0toKpi_fakeline_2024_data/run_Dzl.py @@ -0,0 +1,340 @@ +import sys,os,math +from PyConf.reading import get_pvs, get_rec_summary, get_particles +import Functors as F +from FunTuple import FunctorCollection +from FunTuple import FunTuple_Particles as Funtuple +from DaVinci.algorithms import create_lines_filter +from DaVinci import Options,make_config +import FunTuple.functorcollections as FC +from DaVinciMCTools import MCTruthAndBkgCat +from Hlt2Conf.algorithms_thor import ParticleCombiner, ParticleFilter +from Hlt2Conf.algorithms_thor import ParticleContainersMerger +from Functors.grammar import Functor +from Hlt2Conf.standard_particles import make_has_rich_long_pions,make_has_rich_up_pions,make_has_rich_down_pions + +_BPVCORRM = Functor('_BPVCORRM', 'Composite::CorrectedMass','Compute the corrected mass') +_allpv_FDVEC = (F.ENDVERTEX_POS @ F.FORWARDARG1 - F.TOLINALG @ F.POSITION @ F.FORWARDARG0) +_allpv_NORMEDDOT = F.NORMEDDOT.bind(F.THREEMOMENTUM @ F.FORWARDARG1, _allpv_FDVEC) +#ALLPV_CHI2 = lambda Vertices: F.MAP(F.CHI2) @ F.TES(Vertices) +#ALLPV_CHI2DOF = lambda Vertices: F.MAP(F.CHI2DOF) @ F.TES(Vertices) +ALLPV_IPCHI2 = lambda Vertices: F.MAP(F.IPCHI2).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_FDCHI2 = lambda Vertices: F.MAP(F.VTX_FDCHI2).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_DIRA = lambda Vertices: F.MAP(_allpv_NORMEDDOT).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_CORRM = lambda Vertices: F.MAP(_BPVCORRM).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_LTIME = lambda Vertices: F.MAP(F.VTX_LTIME).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_DLS = lambda Vertices: F.MAP(F.VTX_DLS).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_FD_COORDINATE = lambda coordinate, Vertices: F.MAP(coordinate @ _allpv_FDVEC).bind(F.TES(Vertices), F.FORWARDARGS) +#MCNEUTRINO = F.FIND_MCDECAY("[ Lambda_b0 => Lambda_c+ mu- ^nu_mu~ ]CC") + +TRUE_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.PARTICLE_ID) == id) +#MCMOTHER_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.MC_MOTHER(1, F.PARTICLE_ID)) == id) +#GD_MCMOTHER_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.MC_MOTHER(2, F.PARTICLE_ID)) == id) +#GD_GD_MCMOTHER_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.MC_MOTHER(3, F.PARTICLE_ID)) == id) + +def make_Bst(B, pions,lepton, hadron_candidate_id,v2_pvs,do_truth_matching = True): + if do_truth_matching == True : + #filter B keeping only true D0 and true leptons + MCTRUTH_B = MCTruthAndBkgCat(B, name='MCTRUTH_Bu') + Dz_child = F.CHILD(1, F.FORWARDARG0) #get the first child of B*- which is D0 + lep_child = F.CHILD(2, F.FORWARDARG0) #get the second child of B*- which is lepton + Dz_truth_cut = TRUE_ID_IS(hadron_candidate_id, MCTRUTH_B) @ Dz_child #require that D0 is true + lep_truth_cut = F.require_any(TRUE_ID_IS(11, MCTRUTH_B) @ lep_child , TRUE_ID_IS(13, MCTRUTH_B) @ lep_child) #require that lepton is true i.e. electron or muon + cut_b = F.require_all(Dz_truth_cut, lep_truth_cut) #make a cut + signal_B = ParticleFilter(Input=B, Cut=F.FILTER(cut_b), name='signal_Dzmu') #filter the B candidates + else : signal_B = B + + #combine to make [B*0 -> B*- pi+]cc + Bst_1 = ParticleCombiner( + Inputs=[B, pions], + name=f'Bst_1_{lepton}', + DecayDescriptor='[B0 -> B- pi+]cc', + CombinationCut=F.ALL, + CompositeCut=F.ALL, + ParticleCombiner="ParticleVertexFitter", + PrimaryVertices=v2_pvs + #OutputLevel=1 + ) + #combine to make [B*0 -> B*- pi-]cc + Bst_2 = ParticleCombiner( + Inputs=[B, pions], + name=f'Bst_2_{lepton}', + DecayDescriptor='[B0 -> B- pi-]cc', + CombinationCut=F.ALL, + CompositeCut=F.ALL, + ParticleCombiner="ParticleVertexFitter", + PrimaryVertices=v2_pvs + #OutputLevel=1 + ) + #merge the two Bst candidates + Bst = ParticleContainersMerger([Bst_1, Bst_2], name = f'Bst_combiner_{lepton}') + return Bst + +def get_functors(MCTRUTH, v2_pvs, rec_summary): + #define common variables for all fields (composite and basic) + vars_common = FunctorCollection() + #all pvs: ip, ipchi2. The PV positions are stored in event variables + vars_common['ALLPV_IP[pv_indx]'] = F.ALLPV_IP(v2_pvs) + vars_common['ALLPV_IPCHI2[pv_indx]'] = ALLPV_IPCHI2(v2_pvs) + #best pv: x, y, z, ip, ipchi2 + vars_common['BPV_X'] = F.BPVX(v2_pvs) + vars_common['BPV_Y'] = F.BPVY(v2_pvs) + vars_common['BPV_Z'] = F.BPVZ(v2_pvs) + vars_common['BPV_IP'] = F.BPVIP(v2_pvs) + vars_common['BPV_IPCHI2'] = F.BPVIPCHI2(v2_pvs) + vars_common['BPV_CHI2'] = F.CHI2 @ F.BPV(v2_pvs) + vars_common['BPV_CHI2DOF'] = F.CHI2DOF @ F.BPV(v2_pvs) + #particle id, key, truekey. The trueid is stored in MCHierarchy + vars_common['ID'] = F.PARTICLE_ID + vars_common['KEY'] = F.OBJECT_KEY + #get charge, min ip and min ipchi2 + vars_common['CHARGE'] = F.CHARGE + vars_common['MINIP'] = F.MINIP(v2_pvs) + vars_common['MINIPCHI2'] = F.MINIPCHI2(v2_pvs) + #reco kinematics + vars_common += FC.Kinematics() + vars_common['ETA'] = F.ETA + vars_common['PHI'] = F.PHI + if MCTRUTH != 'None': + #mc vars + vars_common['TRUEKEY'] = F.VALUE_OR(-1) @ MCTRUTH(F.OBJECT_KEY) + vars_common += FC.MCKinematics(mctruth_alg = MCTRUTH) + vars_common['TRUEETA'] = MCTRUTH(F.ETA) + vars_common['TRUEPHI'] = MCTRUTH(F.PHI) + #type of the origin vertex + vars_common['MC_VTX_TYPE'] = MCTRUTH(F.VALUE_OR(-1) @ F.MC_VTX_TYPE @ F.MC_ORIGINVERTEX) + ##mc truth hierarchy (done seperately) + #vars_common += FC.MCHierarchy(mctruth_alg = MCTRUTH) + #make some helper functions + MCMOTHER_ID = lambda n: F.VALUE_OR(0) @ MCTRUTH(F.MC_MOTHER(n, F.PARTICLE_ID)) + MCMOTHER_KEY = lambda n: F.VALUE_OR(-1) @ MCTRUTH(F.MC_MOTHER(n, F.OBJECT_KEY )) + vars_common["TRUEID"] = F.VALUE_OR(0) @ MCTRUTH(F.PARTICLE_ID) + vars_common["MCKEY"] = F.VALUE_OR(0) @ MCTRUTH(F.OBJECT_KEY) + vars_common["MC_MOTHER_ID"] = MCMOTHER_ID(1) + vars_common["MC_MOTHER_KEY"] = MCMOTHER_KEY(1) + for i in range(2,14): + prefix = "MC_GD_MOTHER_{}".format(i) + vars_common[f"{prefix}_ID"] = MCMOTHER_ID(i) + vars_common[f"{prefix}_KEY"] = MCMOTHER_KEY(i) + + #variables for composite particles + vars_composite = FunctorCollection() + #end vertex position and end vertex chi2 + vars_composite['ENDVERTEX_POS_'] = F.ENDVERTEX_POS + vars_composite['ENDVERTEX_CHI2'] = F.CHI2 @ F.ENDVERTEX + vars_composite['ENDVERTEX_CHI2DOF'] = F.CHI2DOF @ F.ENDVERTEX + #all pvs: dira, fd, fdchi2 + vars_composite['ALLPV_DIRA[pv_indx]'] = ALLPV_DIRA(v2_pvs) + vars_composite['ALLPV_FD_X[pv_indx]'] = ALLPV_FD_COORDINATE(F.X_COORDINATE, v2_pvs) + vars_composite['ALLPV_FD_Y[pv_indx]'] = ALLPV_FD_COORDINATE(F.Y_COORDINATE, v2_pvs) + vars_composite['ALLPV_FD_Z[pv_indx]'] = ALLPV_FD_COORDINATE(F.Z_COORDINATE, v2_pvs) + vars_composite['ALLPV_FDCHI2[pv_indx]'] = ALLPV_FDCHI2(v2_pvs) + vars_composite['ALLPV_CORRM[pv_indx]'] = ALLPV_CORRM(v2_pvs) + vars_composite['ALLPV_LTIME[pv_indx]'] = ALLPV_LTIME(v2_pvs) + vars_composite['ALLPV_DLS[pv_indx]'] = ALLPV_DLS(v2_pvs) + #best pv: dira, fd, fdchi2, corrm, ltime, dls + vars_composite['BPV_DIRA'] = F.BPVDIRA(v2_pvs) + vars_composite['BPV_FD_'] = F.BPVFDVEC(v2_pvs) + vars_composite['BPV_FDCHI2'] = F.BPVFDCHI2(v2_pvs) + vars_composite['BPV_CORRM'] = F.BPVCORRM(v2_pvs) + vars_composite['BPV_LTIME'] = F.BPVLTIME(v2_pvs) + vars_composite['BPV_DLS'] = F.BPVDLS(v2_pvs) + #mc composite vertex information + + if MCTRUTH != 'None': vars_composite += FC.MCVertexInfo(mctruth_alg = MCTRUTH) + #Compute maximum DOCA and maximum DOCACHI2. Since there are + # only two daughters of Sb particles, the maximum DOCA/DOCACHI2 is + # the DOCA/DOCACHI2 see below. + vars_composite['MAX_DOCA'] = F.MAXDOCA + vars_composite['MAX_DOCACHI2'] = F.MAXDOCACHI2 + vars_composite['MAX_SDOCA'] = F.MAXSDOCA + vars_composite['MAX_SDOCACHI2'] = F.MAXSDOCACHI2 + + #variables for Lb field + var_B = FunctorCollection() + #var_B['TRUENU_PX'] = MCTRUTH(F.PX @ MCNEUTRINO) + #var_B['TRUENU_PY'] = MCTRUTH(F.PY @ MCNEUTRINO) + #var_B['TRUENU_PZ'] = MCTRUTH(F.PZ @ MCNEUTRINO) + #var_B['TRUENU_ENERGY'] = MCTRUTH(F.ENERGY @ MCNEUTRINO) + ###Bkg category + ##var_B["BKGCAT"] = MCTRUTH.BkgCat + + #variables for basics + vars_basic = FunctorCollection() + vars_basic['TRACKTYPE'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKTYPE @ F.TRACK + vars_basic['TRACKHISTORY'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKHISTORY @ F.TRACK + vars_basic['TRACKFLAG'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKFLAG @ F.TRACK + vars_basic['TRACKNDOF'] = F.VALUE_OR(-1) @ F.NDOF @ F.TRACK + vars_basic['TRACKCHI2'] = F.CHI2 @ F.TRACK + vars_basic['TRACKCHI2DOF'] = F.CHI2DOF @ F.TRACK + vars_basic['GHOSTPROB'] = F.GHOSTPROB + vars_basic['PIDpi'] = F.PID_PI + vars_basic['PIDk'] = F.PID_K + vars_basic['PIDp'] = F.PID_P + vars_basic['PIDe'] = F.PID_E + vars_basic['PIDmu'] = F.PID_MU + if MCTRUTH != 'None': + vars_basic['TRUEORIGINVERTEX_X'] = MCTRUTH(F.ORIGIN_VX) + vars_basic['TRUEORIGINVERTEX_Y'] = MCTRUTH(F.ORIGIN_VY) + vars_basic['TRUEORIGINVERTEX_Z'] = MCTRUTH(F.ORIGIN_VZ) + + #variables for event + evt_vars = FunctorCollection() + #evt_vars['ALLPV_X[pv_indx]'] = F.ALLPVX(v2_pvs) + #evt_vars['ALLPV_Y[pv_indx]'] = F.ALLPVY(v2_pvs) + #evt_vars['ALLPV_Z[pv_indx]'] = F.ALLPVZ(v2_pvs) + #evt_vars['ALLPV_CHI2[pv_indx]'] = ALLPV_CHI2(v2_pvs) + #evt_vars['ALLPV_CHI2DOF[pv_indx]']= ALLPV_CHI2DOF(v2_pvs) + evt_vars['nTracks'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nTracks") + evt_vars['nLongTracks'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nLongTracks") + evt_vars['nPVs'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nPVs") + + vars_brems = FunctorCollection({}) + vars_brems.update({"HASBREM": F.HASBREM}) + #vars_brems.update({"HASBREMADDED": F.HASBREMADDED}) + vars_brems.update({"BREMENERGY": F.BREMENERGY}) + vars_brems.update({"BREMBENDCORR": F.BREMBENDCORR}) + vars_brems.update({"BREMPIDE": F.BREMPIDE}) + vars_brems.update({"ECALPIDE": F.ECALPIDE}) + vars_brems.update({"ECALPIDMU": F.ECALPIDMU}) + vars_brems.update({"HCALPIDE": F.HCALPIDE}) + vars_brems.update({"HCALPIDMU": F.HCALPIDMU}) + vars_brems.update({"ELECTRONSHOWEREOP": F.ELECTRONSHOWEREOP}) + vars_brems.update({"ELECTRONSHOWERDLL": F.ELECTRONSHOWERDLL}) + vars_brems.update({"CLUSTERMATCH": F.CLUSTERMATCH_CHI2}) + vars_brems.update({"ELECTRONMATCH": F.ELECTRONMATCH_CHI2}) + vars_brems.update({"BREMHYPOMATCH": F.BREMHYPOMATCH_CHI2}) + vars_brems.update({"ELECTRONENERGY": F.ELECTRONENERGY}) + vars_brems.update({"BREMHYPOENERGY": F.BREMHYPOENERGY}) + vars_brems.update({"BREMHYPODELTAX": F.BREMHYPODELTAX}) + #vars_brems.update({"BREMTRACKBASEDENERGY": F.BREMTRACKBASEDENERGY}) + vars_brems.update({"INBREM": F.INBREM}) + vars_brems.update({"PT_WITH_BREM": F.PT_WITH_BREM}) + vars_brems.update({"P_WITH_BREM": F.P_WITH_BREM}) + + #return all functors + functors = (vars_common, vars_composite, var_B, vars_basic, evt_vars,vars_brems) + return functors + +def tuple_Bst(Bst,lepton, MCTRUTH, v2_pvs, rec_summary): + #get functors + functors = get_functors(MCTRUTH, v2_pvs, rec_summary) + vars_common = functors[0] + vars_composite = functors[1] + var_B = functors[2] + vars_basic = functors[3] + evt_vars = functors[4] + vars_brems = functors[5] + + #variables for Sb field + vars_Bst = FunctorCollection() + B_child = F.CHILD(1, F.FORWARDARG0) + D0_child = F.CHILD(1, F.CHILD(1,F.FORWARDARG0)) + Epi_child = F.CHILD(2, F.FORWARDARG0) + bpv_pi = F.BPV(v2_pvs).bind(Epi_child) + #diff in vtx chi2 with and without extra particle + vars_Bst['DELTA_ENDVERTEX_CHI2'] = (F.CHI2 @ F.ENDVERTEX) - (F.CHI2 @ F.ENDVERTEX.bind(B_child)) + #IP and IPChi2 of extra particle wrt to Sb end vertex + vars_Bst['Epi_IP_WRT_SbENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ F.FORWARDARG0 , Epi_child) + vars_Bst['Epi_IPCHI2_WRT_SbENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ F.FORWARDARG0 , Epi_child) + #IP and IPChi2 of extra particle wrt to Lb end vertex + vars_Bst['Epi_IP_WRT_LbENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ B_child , Epi_child) + vars_Bst['Epi_IPCHI2_WRT_LbENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ B_child , Epi_child) + #angle between extra particle and Lb + vars_Bst['Epi_COSANGLE_Lb'] = F.COSANGLE.bind(F.THREEMOMENTUM @ B_child, F.THREEMOMENTUM @ Epi_child) + #diff in fd chi2 with and without extra particle + vars_Bst['Delta_BPV_of_Epi_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi, F.FORWARDARGS) - F.VTX_FDCHI2.bind(bpv_pi, B_child) + vars_Bst['BPV_of_Epi_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi, F.FORWARDARGS) + #IP chi2 of extra particle wrt PV and SV of Sb + vars_Bst['Epi_IP_WRT_SbBPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child) + vars_Bst['Epi_IPCHI2_WRT_SbBPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child) + #IP chi2 of extra particle wrt PV and SV of Bb + vars_Bst['Epi_IP_WRT_LbBPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ B_child, Epi_child) + vars_Bst['Epi_IPCHI2_WRT_LbBPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ B_child, Epi_child) + #DOCA and DOCACHI2 b/w Lb and extra particle + vars_Bst['DOCA12'] = F.DOCA(1, 2) + vars_Bst['DOCA12_CHI2_12'] = F.DOCACHI2(1, 2) + #vars_Bst['SDOCA12'] = F.SDOCA(1, 2) + #vars_Bst['SDOCA_CHI2_12'] = F.SDOCACHI2(1, 2) + #DOCACHI2 of extra particle wrt to mother i.e. Sb + vars_Bst['MTDOCACHI2_1'] = F.MTDOCACHI2(1, v2_pvs) + vars_Bst['MTDOCACHI2_2'] = F.MTDOCACHI2(2, v2_pvs) + #vars_Bst['Dstar_M'] = F.MASS @ ((F.FOURMOMENTUM @ D0_child)+(F.FOURMOMENTUM @ Epi_child)) + #vars_Bst['D0_M'] = F.MASS @ (F.FOURMOMENTUM @ D0_child) + #vars_Bst['test_id'] = F.PARTICLE_ID @ D0_child + vars_Bst['Delta_M'] = F.ABS @ ((F.MASS @ ((F.FOURMOMENTUM @ D0_child)+(F.FOURMOMENTUM @ Epi_child))) - (F.MASS @ D0_child)) + + #define fields + fields = {} + fields['Sb'] = f'[B0 -> (B- -> (D0 -> K- pi+) {lepton}-) [pi+]CC]CC' + fields['Lb'] = f'[B0 -> ^(B- -> (D0 -> K- pi+) {lepton}-) [pi+]CC]CC' + fields['Lc'] = f'[B0 -> (B- -> ^(D0 -> K- pi+) {lepton}-) [pi+]CC]CC' + fields['Lep'] = f'[B0 -> (B- -> (D0 -> K- pi+) ^{lepton}-) [pi+]CC]CC' + fields['Epi'] = f'[B0 -> (B- -> (D0 -> K- pi+) {lepton}-) ^[pi+]CC]CC' + fields['Km'] = f'[B0 -> (B- -> (D0 -> ^K- pi+) {lepton}-) [pi+]CC]CC' + fields['pip'] = f'[B0 -> (B- -> (D0 -> K- ^pi+) {lepton}-) [pi+]CC]CC' + + #add variables + variables = {} + variables["ALL"] = vars_common + variables["Sb"] = vars_composite + vars_Bst + variables["Lb"] = vars_composite + var_B + variables["Lc"] = vars_composite + variables["Lep"] = vars_basic + vars_brems + variables["Epi"] = vars_basic + vars_brems + variables["Km"] = vars_basic + vars_brems + variables["pip"] = vars_basic + vars_brems + + #define tuple + my_tuple = Funtuple( + name=f"Tuple_{lepton}", + tuple_name="DecayTree", + fields=fields, + variables=variables, + inputs=Bst) + + return my_tuple + +def get_extra_pions(): + """ + Note this function in DaVinci requires: + https://gitlab.cern.ch/lhcb/Moore/-/merge_requests/3203 + and it's related LHCb, DaVinci and Rec MRs + """ + long_pions = make_has_rich_long_pions() + up_pions = make_has_rich_up_pions() + down_pions = make_has_rich_down_pions() + return ParticleContainersMerger([long_pions, up_pions, down_pions], + name='Pions_combiner') + +#def main(options): +def main(options: Options): + line_name = ['SpruceSLB_BuToD0MuNu_D0ToKPi_FakeMuon','SpruceSLB_BuToD0TauNu_D0ToKPi_FakeMuon'] + + #define filer + my_filter_l = create_lines_filter(name="Filter_l", lines=[line_name[0]]) + my_filter_tau = create_lines_filter(name="Filter_tau", lines=[line_name[1]]) + + #get data and extra particles + lb_l = get_particles(f"/Event/Spruce/{line_name[0]}/Particles") + lb_tau = get_particles(f"/Event/Spruce/{line_name[1]}/Particles") + extra_particles = get_extra_pions() + + #get v2_pvs and rec_summary + v2_pvs = get_pvs() + rec_summary = get_rec_summary() + hadron_candidate_id = 421 + #make sb candidate + Bst_l = make_Bst(lb_l, extra_particles,'mu',hadron_candidate_id,v2_pvs,False) + Bst_tau = make_Bst(lb_tau, extra_particles,'tau', hadron_candidate_id,v2_pvs,False) + #MCTRUTH_Bst = MCTruthAndBkgCat(Bst, name='MCTRUTH_Bst') + + + tuple_file_l = tuple_Bst(Bst_l,'mu', 'None', v2_pvs, rec_summary) + tuple_file_tau = tuple_Bst(Bst_tau,'tau', 'None', v2_pvs, rec_summary) + + #define algorithms + user_algorithms = {} + user_algorithms['Alg_l'] = [my_filter_l, tuple_file_l] + user_algorithms['Alg_tau'] = [my_filter_tau, tuple_file_tau] + + return make_config(options, user_algorithms) -- GitLab From 10755802951f5c45dff96e4ee095791d4fd65604 Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Fri, 24 May 2024 10:06:38 +0200 Subject: [PATCH 30/57] add everything --- SL_l_nu_D0toKpi_Run3_MC/DV.py | 377 ++++++++++++++++++++++++++++++ SL_l_nu_D0toKpi_Run3_MC/Hlt1.py | 26 +++ SL_l_nu_D0toKpi_Run3_MC/Hlt2.py | 129 ++++++++++ SL_l_nu_D0toKpi_Run3_MC/info.yaml | 85 +++++++ 4 files changed, 617 insertions(+) create mode 100644 SL_l_nu_D0toKpi_Run3_MC/DV.py create mode 100644 SL_l_nu_D0toKpi_Run3_MC/Hlt1.py create mode 100644 SL_l_nu_D0toKpi_Run3_MC/Hlt2.py create mode 100644 SL_l_nu_D0toKpi_Run3_MC/info.yaml diff --git a/SL_l_nu_D0toKpi_Run3_MC/DV.py b/SL_l_nu_D0toKpi_Run3_MC/DV.py new file mode 100644 index 0000000000..04f1272761 --- /dev/null +++ b/SL_l_nu_D0toKpi_Run3_MC/DV.py @@ -0,0 +1,377 @@ +import sys,os,math +from PyConf.reading import get_pvs, get_rec_summary, get_particles +import Functors as F +from FunTuple import FunctorCollection +from FunTuple import FunTuple_Particles as Funtuple +from DaVinci.algorithms import create_lines_filter +from DaVinci import Options,make_config +import FunTuple.functorcollections as FC +from DaVinciMCTools import MCTruthAndBkgCat +from Hlt2Conf.algorithms_thor import ParticleCombiner, ParticleFilter +from Hlt2Conf.algorithms_thor import ParticleContainersMerger +from Functors.grammar import Functor +from Hlt2Conf.standard_particles import make_has_rich_long_pions,make_has_rich_up_pions,make_has_rich_down_pions +import numpy as np + +_BPVCORRM = Functor('_BPVCORRM', 'Composite::CorrectedMass','Compute the corrected mass') +_allpv_FDVEC = (F.ENDVERTEX_POS @ F.FORWARDARG1 - F.TOLINALG @ F.POSITION @ F.FORWARDARG0) +_allpv_NORMEDDOT = F.NORMEDDOT.bind(F.THREEMOMENTUM @ F.FORWARDARG1, _allpv_FDVEC) +#ALLPV_CHI2 = lambda Vertices: F.MAP(F.CHI2) @ F.TES(Vertices) +#ALLPV_CHI2DOF = lambda Vertices: F.MAP(F.CHI2DOF) @ F.TES(Vertices) +ALLPV_IPCHI2 = lambda Vertices: F.MAP(F.IPCHI2).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_FDCHI2 = lambda Vertices: F.MAP(F.VTX_FDCHI2).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_DIRA = lambda Vertices: F.MAP(_allpv_NORMEDDOT).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_CORRM = lambda Vertices: F.MAP(_BPVCORRM).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_LTIME = lambda Vertices: F.MAP(F.VTX_LTIME).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_DLS = lambda Vertices: F.MAP(F.VTX_DLS).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_FD_COORDINATE = lambda coordinate, Vertices: F.MAP(coordinate @ _allpv_FDVEC).bind(F.TES(Vertices), F.FORWARDARGS) +#MCNEUTRINO = F.FIND_MCDECAY("[ Lambda_b0 => Lambda_c+ mu- ^nu_mu~ ]CC") + +TRUE_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.PARTICLE_ID) == id) +#MCMOTHER_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.MC_MOTHER(1, F.PARTICLE_ID)) == id) +#GD_MCMOTHER_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.MC_MOTHER(2, F.PARTICLE_ID)) == id) +#GD_GD_MCMOTHER_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.MC_MOTHER(3, F.PARTICLE_ID)) == id) + +def make_Bst(B, pions,lepton, hadron_candidate_id,v2_pvs,do_truth_matching = True): + if do_truth_matching == True : + #filter B keeping only true D0 and true leptons + MCTRUTH_B = MCTruthAndBkgCat(B, name='MCTRUTH_Bu') + Dz_child = F.CHILD(1, F.FORWARDARG0) #get the first child of B*- which is D0 + lep_child = F.CHILD(2, F.FORWARDARG0) #get the second child of B*- which is lepton + Dz_truth_cut = TRUE_ID_IS(hadron_candidate_id, MCTRUTH_B) @ Dz_child #require that D0 is true + lep_truth_cut = F.require_any(TRUE_ID_IS(11, MCTRUTH_B) @ lep_child , TRUE_ID_IS(13, MCTRUTH_B) @ lep_child) #require that lepton is true i.e. electron or muon + cut_b = F.require_all(Dz_truth_cut, lep_truth_cut) #make a cut + signal_B = ParticleFilter(Input=B, Cut=F.FILTER(cut_b), name='signal_Dzmu') #filter the B candidates + else : signal_B = B + + #combine to make [B*0 -> B*- pi+]cc + Bst_1 = ParticleCombiner( + Inputs=[B, pions], + name=f'Bst_1_{lepton}', + DecayDescriptor='[B0 -> B- pi+]cc', + CombinationCut=F.ALL, + CompositeCut=F.ALL, + ParticleCombiner="ParticleVertexFitter", + PrimaryVertices=v2_pvs + #OutputLevel=1 + ) + #combine to make [B*0 -> B*- pi-]cc + Bst_2 = ParticleCombiner( + Inputs=[B, pions], + name=f'Bst_2_{lepton}', + DecayDescriptor='[B0 -> B- pi-]cc', + CombinationCut=F.ALL, + CompositeCut=F.ALL, + ParticleCombiner="ParticleVertexFitter", + PrimaryVertices=v2_pvs + #OutputLevel=1 + ) + #merge the two Bst candidates + Bst = ParticleContainersMerger([Bst_1, Bst_2], name = f'Bst_combiner_{lepton}') + return Bst + +def get_functors(MCTRUTH, v2_pvs, rec_summary): + #define common variables for all fields (composite and basic) + vars_common = FunctorCollection() + #all pvs: ip, ipchi2. The PV positions are stored in event variables + vars_common['ALLPV_IP[pv_indx]'] = F.ALLPV_IP(v2_pvs) + vars_common['ALLPV_IPCHI2[pv_indx]'] = ALLPV_IPCHI2(v2_pvs) + #best pv: x, y, z, ip, ipchi2 + vars_common['BPV_X'] = F.BPVX(v2_pvs) + vars_common['BPV_Y'] = F.BPVY(v2_pvs) + vars_common['BPV_Z'] = F.BPVZ(v2_pvs) + vars_common['BPV_IP'] = F.BPVIP(v2_pvs) + vars_common['BPV_IPCHI2'] = F.BPVIPCHI2(v2_pvs) + vars_common['BPV_CHI2'] = F.CHI2 @ F.BPV(v2_pvs) + vars_common['BPV_CHI2DOF'] = F.CHI2DOF @ F.BPV(v2_pvs) + #particle id, key, truekey. The trueid is stored in MCHierarchy + vars_common['ID'] = F.PARTICLE_ID + vars_common['KEY'] = F.OBJECT_KEY + + #get charge, min ip and min ipchi2 + vars_common['CHARGE'] = F.CHARGE + vars_common['MINIP'] = F.MINIP(v2_pvs) + vars_common['MINIPCHI2'] = F.MINIPCHI2(v2_pvs) + #reco kinematics + vars_common += FC.Kinematics() + vars_common['ETA'] = F.ETA + vars_common['PHI'] = F.PHI + if MCTRUTH != 'None': + #mc vars + vars_common['TRUEKEY'] = F.VALUE_OR(-1) @ MCTRUTH(F.OBJECT_KEY) + vars_common += FC.MCKinematics(mctruth_alg = MCTRUTH) + vars_common['TRUEETA'] = MCTRUTH(F.ETA) + vars_common['TRUEPHI'] = MCTRUTH(F.PHI) + #type of the origin vertex + vars_common['MC_VTX_TYPE'] = MCTRUTH(F.VALUE_OR(-1) @ F.MC_VTX_TYPE @ F.MC_ORIGINVERTEX) + ##mc truth hierarchy (done seperately) + #vars_common += FC.MCHierarchy(mctruth_alg = MCTRUTH) + #make some helper functions + MCMOTHER_ID = lambda n: F.VALUE_OR(0) @ MCTRUTH(F.MC_MOTHER(n, F.PARTICLE_ID)) + MCMOTHER_KEY = lambda n: F.VALUE_OR(-1) @ MCTRUTH(F.MC_MOTHER(n, F.OBJECT_KEY )) + vars_common["TRUEID"] = F.VALUE_OR(0) @ MCTRUTH(F.PARTICLE_ID) + vars_common["MCKEY"] = F.VALUE_OR(0) @ MCTRUTH(F.OBJECT_KEY) + vars_common["MC_MOTHER_ID"] = MCMOTHER_ID(1) + vars_common["MC_MOTHER_KEY"] = MCMOTHER_KEY(1) + for i in range(2,14): + prefix = "MC_GD_MOTHER_{}".format(i) + vars_common[f"{prefix}_ID"] = MCMOTHER_ID(i) + vars_common[f"{prefix}_KEY"] = MCMOTHER_KEY(i) + + #variables for composite particles + vars_composite = FunctorCollection() + #end vertex position and end vertex chi2 + vars_composite['ENDVERTEX_POS_'] = F.ENDVERTEX_POS + vars_composite['ENDVERTEX_CHI2'] = F.CHI2 @ F.ENDVERTEX + vars_composite['ENDVERTEX_CHI2DOF'] = F.CHI2DOF @ F.ENDVERTEX + #all pvs: dira, fd, fdchi2 + vars_composite['ALLPV_DIRA[pv_indx]'] = ALLPV_DIRA(v2_pvs) + vars_composite['ALLPV_FD_X[pv_indx]'] = ALLPV_FD_COORDINATE(F.X_COORDINATE, v2_pvs) + vars_composite['ALLPV_FD_Y[pv_indx]'] = ALLPV_FD_COORDINATE(F.Y_COORDINATE, v2_pvs) + vars_composite['ALLPV_FD_Z[pv_indx]'] = ALLPV_FD_COORDINATE(F.Z_COORDINATE, v2_pvs) + vars_composite['ALLPV_FDCHI2[pv_indx]'] = ALLPV_FDCHI2(v2_pvs) + vars_composite['ALLPV_CORRM[pv_indx]'] = ALLPV_CORRM(v2_pvs) + vars_composite['ALLPV_LTIME[pv_indx]'] = ALLPV_LTIME(v2_pvs) + vars_composite['ALLPV_DLS[pv_indx]'] = ALLPV_DLS(v2_pvs) + #best pv: dira, fd, fdchi2, corrm, ltime, dls + vars_composite['BPV_DIRA'] = F.BPVDIRA(v2_pvs) + vars_composite['BPV_FD_'] = F.BPVFDVEC(v2_pvs) + vars_composite['BPV_FDCHI2'] = F.BPVFDCHI2(v2_pvs) + vars_composite['BPV_CORRM'] = F.BPVCORRM(v2_pvs) + vars_composite['BPV_LTIME'] = F.BPVLTIME(v2_pvs) + vars_composite['BPV_DLS'] = F.BPVDLS(v2_pvs) + #mc composite vertex information + + if MCTRUTH != 'None': vars_composite += FC.MCVertexInfo(mctruth_alg = MCTRUTH) + #Compute maximum DOCA and maximum DOCACHI2. Since there are + # only two daughters of Sb particles, the maximum DOCA/DOCACHI2 is + # the DOCA/DOCACHI2 see below. + vars_composite['MAX_DOCA'] = F.MAXDOCA + vars_composite['MAX_DOCACHI2'] = F.MAXDOCACHI2 + vars_composite['MAX_SDOCA'] = F.MAXSDOCA + vars_composite['MAX_SDOCACHI2'] = F.MAXSDOCACHI2 + + #variables for Lb field + var_B = FunctorCollection() + #var_B['TRUENU_PX'] = MCTRUTH(F.PX @ MCNEUTRINO) + #var_B['TRUENU_PY'] = MCTRUTH(F.PY @ MCNEUTRINO) + #var_B['TRUENU_PZ'] = MCTRUTH(F.PZ @ MCNEUTRINO) + #var_B['TRUENU_ENERGY'] = MCTRUTH(F.ENERGY @ MCNEUTRINO) + ###Bkg category + ##var_B["BKGCAT"] = MCTRUTH.BkgCat + + #variables for basics + vars_basic = FunctorCollection() + vars_basic['TRACKTYPE'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKTYPE @ F.TRACK + vars_basic['TRACKHISTORY'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKHISTORY @ F.TRACK + vars_basic['TRACKFLAG'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKFLAG @ F.TRACK + vars_basic['TRACKNDOF'] = F.VALUE_OR(-1) @ F.NDOF @ F.TRACK + vars_basic['TRACKCHI2'] = F.CHI2 @ F.TRACK + vars_basic['TRACKCHI2DOF'] = F.CHI2DOF @ F.TRACK + vars_basic['GHOSTPROB'] = F.GHOSTPROB + vars_basic['PIDpi'] = F.PID_PI + vars_basic['PIDk'] = F.PID_K + vars_basic['PIDp'] = F.PID_P + vars_basic['PIDe'] = F.PID_E + vars_basic['PIDmu'] = F.PID_MU + vars_basic['PROBNNe'] = F.PROBNN_E + vars_basic['PROBNNpi'] = F.PROBNN_PI + vars_basic['PROBNNk'] = F.PROBNN_K + vars_basic['PROBNNmu'] = F.PROBNN_MU + vars_basic['PROBNNp'] = F.PROBNN_P + vars_basic['PROBNNghost'] = F.PROBNN_GHOST + if MCTRUTH != 'None': + vars_basic['TRUEORIGINVERTEX_X'] = MCTRUTH(F.ORIGIN_VX) + vars_basic['TRUEORIGINVERTEX_Y'] = MCTRUTH(F.ORIGIN_VY) + vars_basic['TRUEORIGINVERTEX_Z'] = MCTRUTH(F.ORIGIN_VZ) + + #variables for event + evt_vars = FunctorCollection() + #evt_vars['ALLPV_X[pv_indx]'] = F.ALLPVX(v2_pvs) + #evt_vars['ALLPV_Y[pv_indx]'] = F.ALLPVY(v2_pvs) + #evt_vars['ALLPV_Z[pv_indx]'] = F.ALLPVZ(v2_pvs) + #evt_vars['ALLPV_CHI2[pv_indx]'] = ALLPV_CHI2(v2_pvs) + #evt_vars['ALLPV_CHI2DOF[pv_indx]']= ALLPV_CHI2DOF(v2_pvs) + evt_vars['nTracks'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nTracks") + evt_vars['nLongTracks'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nLongTracks") + evt_vars['nPVs'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nPVs") + + vars_brems = FunctorCollection({}) + vars_brems.update({"HASBREM": F.HASBREM}) + #vars_brems.update({"HASBREMADDED": F.HASBREMADDED}) + vars_brems.update({"BREMENERGY": F.BREMENERGY}) + vars_brems.update({"BREMBENDCORR": F.BREMBENDCORR}) + vars_brems.update({"BREMPIDE": F.BREMPIDE}) + vars_brems.update({"ECALPIDE": F.ECALPIDE}) + vars_brems.update({"ECALPIDMU": F.ECALPIDMU}) + vars_brems.update({"HCALPIDE": F.HCALPIDE}) + vars_brems.update({"HCALPIDMU": F.HCALPIDMU}) + vars_brems.update({"ELECTRONSHOWEREOP": F.ELECTRONSHOWEREOP}) + vars_brems.update({"ELECTRONSHOWERDLL": F.ELECTRONSHOWERDLL}) + vars_brems.update({"CLUSTERMATCH": F.CLUSTERMATCH_CHI2}) + vars_brems.update({"ELECTRONMATCH": F.ELECTRONMATCH_CHI2}) + vars_brems.update({"BREMHYPOMATCH": F.BREMHYPOMATCH_CHI2}) + vars_brems.update({"ELECTRONENERGY": F.ELECTRONENERGY}) + vars_brems.update({"BREMHYPOENERGY": F.BREMHYPOENERGY}) + vars_brems.update({"BREMHYPODELTAX": F.BREMHYPODELTAX}) + #vars_brems.update({"BREMTRACKBASEDENERGY": F.BREMTRACKBASEDENERGY}) + vars_brems.update({"INBREM": F.INBREM}) + vars_brems.update({"PT_WITH_BREM": F.PT_WITH_BREM}) + vars_brems.update({"P_WITH_BREM": F.P_WITH_BREM}) + + #return all functors + functors = (vars_common, vars_composite, var_B, vars_basic, evt_vars,vars_brems) + return functors + +def get_fitting_variable(v2_pvs,D0,lep): + + B_dis = np.array([F.END_VX-F.BPVX(v2_pvs),F.END_VY-F.BPVY(v2_pvs),F.END_VZ-F.BPVZ(v2_pvs)]) + B_dis_mag = F.SQRT @ (B_dis[0]**2+B_dis[1]**2+B_dis[2]**2) + B_Mod_P = F.ABS @ ((5279.65/F.MASS)*F.PZ/(B_dis[2]/B_dis_mag)) + B_Mod_E = F.SQRT @ (B_Mod_P**2 + 5279.65**2) + B_4P = np.array([B_Mod_P*B_dis[0]/B_dis_mag,B_Mod_P*B_dis[1]/B_dis_mag,B_Mod_P*B_dis[2]/B_dis_mag,B_Mod_E]) + D_4P = np.array([F.PX @ D0,F.PY @ D0,F.PZ @ D0,F.ENERGY @ D0]) + lep_4P = np.array([F.PX @ lep,F.PY @ lep,F.PZ @ lep,F.ENERGY @ lep]) + + vars_fitting = FunctorCollection({}) + vars_fitting["Mod_P"] = B_Mod_P + vars_fitting['missing_m2'] = (B_4P[3]-D_4P[3]-lep_4P[3])**2-(B_4P[0]-D_4P[0]-lep_4P[0])**2-(B_4P[1]-D_4P[1]-lep_4P[1])**2-(B_4P[2]-D_4P[2]-lep_4P[2])**2 + vars_fitting['q2'] = (B_4P[3]-D_4P[3])**2-(B_4P[0]-D_4P[0])**2-(B_4P[1]-D_4P[1])**2-(B_4P[2]-D_4P[2])**2 + B_Beta = B_Mod_P/B_Mod_E + B_gamma = 1/F.SQRT @ (1-B_Beta**2) + + B_Lorentz = [[B_gamma,-1*B_gamma*B_4P[0]/B_4P[3],-1*B_gamma*B_4P[1]/B_4P[3],-1*B_gamma*B_4P[2]/B_4P[3]],[-1*B_gamma*B_4P[0]/B_4P[3],1+(B_gamma-1)*((B_4P[0]/B_4P[3])/B_Beta)*((B_4P[0]/B_4P[3])/B_Beta),(B_gamma-1)*((B_4P[0]/B_4P[3])/B_Beta)*((B_4P[1]/B_4P[3])/B_Beta),(B_gamma-1)*((B_4P[0]/B_4P[3])/B_Beta)*((B_4P[2]/B_4P[3])/B_Beta)],[-1*B_gamma*B_4P[1]/B_4P[3],(B_gamma-1)*((B_4P[0]/B_4P[3])/B_Beta)*((B_4P[1]/B_4P[3])/B_Beta),(B_gamma-1)*((B_4P[1]/B_4P[3])/B_Beta)*((B_4P[1]/B_4P[3])/B_Beta),(B_gamma-1)*((B_4P[1]/B_4P[3])/B_Beta)*((B_4P[2]/B_4P[3])/B_Beta)],[-1*B_gamma*B_4P[2]/B_4P[3],(B_gamma-1)*((B_4P[0]/B_4P[3])/B_Beta)*((B_4P[2]/B_4P[3])/B_Beta),(B_gamma-1)*((B_4P[1]/B_4P[3])/B_Beta)*((B_4P[2]/B_4P[3])/B_Beta),(B_gamma-1)*((B_4P[2]/B_4P[3])/B_Beta)*((B_4P[2]/B_4P[3])/B_Beta)]] + vars_fitting['lep_E_Brest'] = (B_Lorentz[0][0]*lep_4P[3]+B_Lorentz[0][1]*lep_4P[0]+B_Lorentz[0][2]*lep_4P[1]+B_Lorentz[0][3]*lep_4P[2]) + return(vars_fitting) + +def tuple_Bst(Bst,lepton, MCTRUTH, v2_pvs, rec_summary): + #get functors + functors = get_functors(MCTRUTH, v2_pvs, rec_summary) + vars_common = functors[0] + vars_composite = functors[1] + var_B = functors[2] + vars_basic = functors[3] + evt_vars = functors[4] + vars_brems = functors[5] + + #variables for Sb field + vars_Bst = FunctorCollection() + B_child = F.CHILD(1, F.FORWARDARG0) + D0_child = F.CHILD(1, F.CHILD(1,F.FORWARDARG0)) + Lep_child = F.CHILD(1, F.CHILD(2,F.FORWARDARG0)) + Epi_child = F.CHILD(2, F.FORWARDARG0) + bpv_pi = F.BPV(v2_pvs).bind(Epi_child) + #diff in vtx chi2 with and without extra particle + vars_Bst['DELTA_ENDVERTEX_CHI2'] = (F.CHI2 @ F.ENDVERTEX) - (F.CHI2 @ F.ENDVERTEX.bind(B_child)) + #IP and IPChi2 of extra particle wrt to Sb end vertex + vars_Bst['Epi_IP_WRT_SbENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ F.FORWARDARG0 , Epi_child) + vars_Bst['Epi_IPCHI2_WRT_SbENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ F.FORWARDARG0 , Epi_child) + #IP and IPChi2 of extra particle wrt to Lb end vertex + vars_Bst['Epi_IP_WRT_LbENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ B_child , Epi_child) + vars_Bst['Epi_IPCHI2_WRT_LbENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ B_child , Epi_child) + #angle between extra particle and Lb + vars_Bst['Epi_COSANGLE_Lb'] = F.COSANGLE.bind(F.THREEMOMENTUM @ B_child, F.THREEMOMENTUM @ Epi_child) + #diff in fd chi2 with and without extra particle + vars_Bst['Delta_BPV_of_Epi_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi, F.FORWARDARGS) - F.VTX_FDCHI2.bind(bpv_pi, B_child) + vars_Bst['BPV_of_Epi_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi, F.FORWARDARGS) + #IP chi2 of extra particle wrt PV and SV of Sb + vars_Bst['Epi_IP_WRT_SbBPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child) + vars_Bst['Epi_IPCHI2_WRT_SbBPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child) + #IP chi2 of extra particle wrt PV and SV of Bb + vars_Bst['Epi_IP_WRT_LbBPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ B_child, Epi_child) + vars_Bst['Epi_IPCHI2_WRT_LbBPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ B_child, Epi_child) + #DOCA and DOCACHI2 b/w Lb and extra particle + vars_Bst['DOCA12'] = F.DOCA(1, 2) + vars_Bst['DOCA12_CHI2_12'] = F.DOCACHI2(1, 2) + #vars_Bst['SDOCA12'] = F.SDOCA(1, 2) + #vars_Bst['SDOCA_CHI2_12'] = F.SDOCACHI2(1, 2) + #DOCACHI2 of extra particle wrt to mother i.e. Sb + vars_Bst['MTDOCACHI2_1'] = F.MTDOCACHI2(1, v2_pvs) + vars_Bst['MTDOCACHI2_2'] = F.MTDOCACHI2(2, v2_pvs) + vars_Bst['Delta_M'] = F.ABS @ ((F.MASS @ ((F.FOURMOMENTUM @ D0_child)+(F.FOURMOMENTUM @ Epi_child))) - (F.MASS @ D0_child)) + #define fields + fit_vars = get_fitting_variable(v2_pvs,D0_child,Lep_child) + + + #define fields + fields = {} + fields['B0'] = f'[B0 -> (B- -> ([D0 -> K- pi+]CC) {lepton}-) [pi+]CC]CC' + fields['Bm'] = f'[B0 -> ^(B- -> ([D0 -> K- pi+]CC) {lepton}-) [pi+]CC]CC' + fields['D0'] = f'[B0 -> (B- -> ^([D0 -> K- pi+]CC) {lepton}-) [pi+]CC]CC' + fields['Lep'] = f'[B0 -> (B- -> ([D0 -> K- pi+]CC) ^{lepton}-) [pi+]CC]CC' + fields['Epi'] = f'[B0 -> (B- -> ([D0 -> K- pi+]CC) {lepton}-) ^[pi+]CC]CC' + fields['Km'] = f'[B0 -> (B- -> ([D0 -> ^K- pi+]CC) {lepton}-) [pi+]CC]CC' + fields['pip'] = f'[B0 -> (B- -> ([D0 -> K- ^pi+]CC) {lepton}-) [pi+]CC]CC' + + #add variables + variables = {} + variables["ALL"] = vars_common + variables["B0"] = vars_composite + vars_Bst + fit_vars + variables["Bm"] = vars_composite + var_B + variables["D0"] = vars_composite + variables["Lep"] = vars_basic + vars_brems + variables["Epi"] = vars_basic + vars_brems + variables["Km"] = vars_basic + vars_brems + variables["pip"] = vars_basic + vars_brems + + #define tuple + my_tuple = Funtuple( + name=f"Tuple", + tuple_name="DecayTree", + fields=fields, + variables=variables, + inputs=Bst) + + return my_tuple + +def get_extra_pions(): + """ + Note this function in DaVinci requires: + https://gitlab.cern.ch/lhcb/Moore/-/merge_requests/3203 + and it's related LHCb, DaVinci and Rec MRs + """ + long_pions = make_has_rich_long_pions() + up_pions = make_has_rich_up_pions() + down_pions = make_has_rich_down_pions() + return ParticleContainersMerger([long_pions, up_pions, down_pions], + name='Pions_combiner') + +#def main(options): +def main(options: Options,line = '', lep=''): + + #define filer + my_filter = create_lines_filter(name="Filter", lines=[line]) + + #get data and extra particles + lb = get_particles(f"/Event/HLT2/{line}/Particles") + extra_particles = get_extra_pions() + + #get v2_pvs and rec_summary + v2_pvs = get_pvs() + rec_summary = get_rec_summary() + hadron_candidate_id = 421 + #make sb candidate + Bst = make_Bst(lb, extra_particles,lep,hadron_candidate_id,v2_pvs,False) + MCTRUTH_Bst = MCTruthAndBkgCat(Bst, name='MCTRUTH_Bst') + + + tuple_file = tuple_Bst(Bst,lep, MCTRUTH_Bst, v2_pvs, rec_summary) + + #define algorithms + user_algorithms = {} + user_algorithms['Alg'] = [my_filter, tuple_file] + + return make_config(options, user_algorithms) + +def SLB_BuToD0ENu_D0ToKPi(options: Options): + return main(options=options, line='Hlt2SLB_BToDzl',lep='e') + +def SLB_BuToD0MuNu_D0ToKPi(options: Options): + return main(options=options, line='Hlt2SLB_BuToD0MuNu_D0ToKPi',lep='mu') + +def SLB_BuToD0TauNu_D0ToKPi_TauToENuNu(options: Options): + return main(options=options, line='Hlt2SLB_BToDzl',lep='e') + +def SLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu(options: Options): + return main(options=options, line='Hlt2SLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu',lep='mu') + diff --git a/SL_l_nu_D0toKpi_Run3_MC/Hlt1.py b/SL_l_nu_D0toKpi_Run3_MC/Hlt1.py new file mode 100644 index 0000000000..e2d0622696 --- /dev/null +++ b/SL_l_nu_D0toKpi_Run3_MC/Hlt1.py @@ -0,0 +1,26 @@ +############################################################################### +# (c) Copyright 2022 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### +from Moore import Options +from Moore.config import allen_control_flow +from RecoConf.hlt1_allen import allen_gaudi_config, get_allen_line_names +from PyConf.application import configure_input, configure +from RecoConf.muonid import make_muon_hits +#need to bind geometry version to 3 for muon hits +make_muon_hits.global_bind(geometry_version=3) + +def main(options: Options): + config = configure_input(options) + with allen_gaudi_config.bind(sequence="hlt1_pp_matching_no_ut_1000KHz"): + allen_node = allen_control_flow(options) + config.update(configure(options, allen_node)) + return config + + diff --git a/SL_l_nu_D0toKpi_Run3_MC/Hlt2.py b/SL_l_nu_D0toKpi_Run3_MC/Hlt2.py new file mode 100644 index 0000000000..e0d48da235 --- /dev/null +++ b/SL_l_nu_D0toKpi_Run3_MC/Hlt2.py @@ -0,0 +1,129 @@ +############################################################################### +# (c) Copyright 2022 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### +from Moore import Options,options, run_moore, config +from Hlt2Conf.algorithms_thor import ParticleContainersMerger +from Hlt2Conf.lines.semileptonic.builders import sl_line_prefilter +from Hlt2Conf.lines.semileptonic.builders.base_builder import make_candidate +from Hlt2Conf.lines.semileptonic.builders.charm_hadron_builder import make_d0_tokpi +from GaudiKernel.SystemOfUnits import MeV, GeV,mm +from Hlt2Conf.algorithms_thor import ParticleCombiner +from Moore.config import Hlt2Line +from RecoConf.global_tools import stateProvider_with_simplified_geom +from RecoConf.reconstruction_objects import reconstruction,make_pvs +from RecoConf.decoders import default_ft_decoding_version +from Hlt2Conf.standard_particles import ( + make_long_electrons_with_brem, + make_has_rich_long_pions, + make_has_rich_up_pions, + make_has_rich_down_pions) +import Functors as F +from Functors.math import in_range + +#things to control +SUFFIX_NAME = '_BToDzl' +HLT2LINE = f'Hlt2SLB{SUFFIX_NAME}' +CHARM_MASS = 1864.84 #D0 mass +CHARM_BUILDER_NAME = 'Dz2KPi_combiner' +B_BUILDER_NAME = 'BToDzl_combiner' + +def get_charm_cuts(): + #make loose cuts for D0 + delta_mass = 80. #80.0 + make_d0tokpi_cuts = {} + make_d0tokpi_cuts['comb_m_min'] = (CHARM_MASS - delta_mass) * MeV + make_d0tokpi_cuts['comb_m_max'] = (CHARM_MASS + delta_mass) * MeV + make_d0tokpi_cuts['comb_docachi2_max'] = 5. + make_d0tokpi_cuts['vchi2pdof_max'] = 6 #6 (2024) 6/4 (master e/taue) + make_d0tokpi_cuts['bpvfdchi2_min'] = 25 #25 (2024) + make_d0tokpi_cuts['bpvdira_min'] = 0.99 #0.99 (2024) 0.99/0.999 (master e/taue) + make_d0tokpi_cuts['comb_pt_min'] = None #None (2024) None/2000 * MeV (master e/taue) + make_d0tokpi_cuts['comb_pt_any_min'] = None #None (2024) None/800 * MeV (master e/taue) + make_d0tokpi_cuts['comb_pt_sum_min'] = None #None (2024) None/2.5 * GeV (master e/taue) + make_d0tokpi_cuts['comb_doca_max'] = None #None (2024) None/0.1 mm (master e/taue) + make_d0tokpi_cuts['daughter_pt_min'] = 600 * MeV #600 * MeV (2024) 750 * MeV (master) + make_d0tokpi_cuts['daughter_mipchi2_min'] = 9. #10. (2024) 10./9. (master e/taue) + make_d0tokpi_cuts['kaon_pid'] = (F.PID_K > 0.) #(F.PID_K > 0.) (2024) (F.PID_K > 4.) (master) + make_d0tokpi_cuts['pion_pid'] = (F.PID_K < 2.) + return make_d0tokpi_cuts + +def get_electron_cuts(): + #make loose cuts for electron and tauonic muon + make_electron_cuts = {} + make_electron_cuts["p_min"] = 3. * GeV #3. * GeV (2024) 5. *GeV (master) + make_electron_cuts["pt_min"] = 300. * MeV #300. * MeV (2024) 500. * MeV (master) + make_electron_cuts["mipchi2_min"] = 9. #9. (2024) 9./16. (master e/taue) + make_electron_cuts["mip_min"] = None #0. + make_electron_cuts["pid"] = (F.PID_E > 0.0) + make_electron_cuts["make_particles"] = make_long_electrons_with_brem #does not require in calo + return make_electron_cuts + +def make_b(): + make_d0tokpi_cuts = get_charm_cuts() + make_electron_cuts= get_electron_cuts() + pvs = make_pvs() + with make_candidate.bind(p_min=15. * GeV): + dzs = make_d0_tokpi(**make_d0tokpi_cuts, name = CHARM_BUILDER_NAME) + electrons = make_candidate(**make_electron_cuts, name = "Electron_maker") + + cut_vertex = F.require_all(F.CHI2DOF<9,F.BPVDIRA(pvs) >0.999,in_range(0 * MeV, F.MASS, 10000 * MeV)) + + rs_btodze = ParticleCombiner( + Inputs=[dzs, electrons], + name=f'rs_{B_BUILDER_NAME}_e', + DecayDescriptor='[B- -> D0 e-]cc', + CombinationCut=F.ALL, + CompositeCut=cut_vertex, + ParticleCombiner="ParticleVertexFitter") + ws_btodze = ParticleCombiner( + Inputs=[dzs, electrons], + name=f'ws_{B_BUILDER_NAME}_e', + DecayDescriptor='[B+ -> D0 e+]cc', + CombinationCut=F.ALL, + CompositeCut=cut_vertex, + ParticleCombiner="ParticleVertexFitter") + return ParticleContainersMerger([rs_btodze,ws_btodze], name = B_BUILDER_NAME) + +from Hlt2Conf.lines.semileptonic.hlt2_semileptonic import hlt2_butod0munu_d0tokpi_line,hlt2_butod0taunu_d0tokpi_tautomununu_line + +def make_lines_e(): + def hlt2_lines(name=HLT2LINE,prescale=1): + Bcands = make_b() + return Hlt2Line(name=name, prescale=prescale,persistreco=True, algs=sl_line_prefilter() + [Bcands]) + lines = [hlt2_lines()] + return lines + +def make_lines_mu(): + return [hlt2_butod0munu_d0tokpi_line()] + +def make_lines_taumu(): + return [hlt2_butod0taunu_d0tokpi_tautomununu_line()] + +#ft decoding version 6 since MC made after 2019 +default_ft_decoding_version.global_bind(value=6) +def SLB_BuToD0ENu_D0ToKPi(options: Options): + with reconstruction.bind(from_file=False): + config = run_moore(options, make_streams=make_lines_e, public_tools=[stateProvider_with_simplified_geom()]) + return config + +def SLB_BuToD0MuNu_D0ToKPi(options: Options): + with reconstruction.bind(from_file=False): + config = run_moore(options, make_streams=make_lines_mu, public_tools=[stateProvider_with_simplified_geom()]) + return config + +def SLB_BuToD0TauNu_D0ToKPi_TauToENuNu(options: Options): + with reconstruction.bind(from_file=False): + config = run_moore(options, make_streams=make_lines_e, public_tools=[stateProvider_with_simplified_geom()]) + return config + +def SLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu(options: Options): + with reconstruction.bind(from_file=False): + config = run_moore(options, make_streams=make_lines_taumu, public_tools=[stateProvider_with_simplified_geom()]) + return config diff --git a/SL_l_nu_D0toKpi_Run3_MC/info.yaml b/SL_l_nu_D0toKpi_Run3_MC/info.yaml new file mode 100644 index 0000000000..0982bfe288 --- /dev/null +++ b/SL_l_nu_D0toKpi_Run3_MC/info.yaml @@ -0,0 +1,85 @@ +defaults: + inform: + - ching-hua.li@cern.ch + wg: SL + +{%- set evttype_lines_and_leptons = [ + ('11584030','SLB_BuToD0ENu_D0ToKPi','e'), + ('11574020','SLB_BuToD0MuNu_D0ToKPi','muon'), + ('11584010','SLB_BuToD0TauNu_D0ToKPi_TauToENuNu','taue'), + ('11574010','SLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu','taumuon'), +] %} + +{%- set polarity_variables = [ + ('MagDown','sim-20231017-vc-md100'), + ('MagUp','sim-20231017-vc-mu100'), +]%} +{%- for polarity, cond_tag in polarity_variables %} + {%- for evttype, line, lepton in evttype_lines_and_leptons %} +HLT1_b0_dstp_{{lepton}}_{{ polarity }}: + application: "Moore/v55r8@x86_64_v3-el9-gcc13+detdesc-opt+g" + input: + bk_query: "/MC/Dev/Beam6800GeV-expected-2024-{{polarity}}-Nu7.6-25ns-Pythia8/Sim10c/{{evttype}}/DIGI" + dq_flags: + - OK + n_test_lfns: 3 + output: hlt1.dst + options: + entrypoint: SL_l_nu_D0toKpi_Run3_MC.Hlt1:main + extra_options: + input_raw_format: 0.3 + conddb_tag: {{cond_tag}} + dddb_tag: dddb-20231017 + input_type: ROOT + output_type: ROOT + simulation: True + data_type: "Upgrade" + scheduler_legacy_mode: False + compression: + algorithm: ZSTD + level: 1 + max_buffer_size: 1048576 + #evt_max: 1000 + +HLT2_b0_dstp_{{lepton}}_{{ polarity }}: + application: "Moore/v55r8@x86_64_v3-el9-gcc13+detdesc-opt+g" + input: + job_name: HLT1_b0_dstp_{{lepton}}_{{ polarity }} + output: hlt2.dst + options: + entrypoint: SL_l_nu_D0toKpi_Run3_MC.Hlt2:{{line}} + extra_options: + input_raw_format: 0.5 + conddb_tag: {{cond_tag}} + dddb_tag: dddb-20231017 + input_type: ROOT + output_type: ROOT + simulation: True + data_type: "Upgrade" + scheduler_legacy_mode: False + output_manifest_file: "HLT2.tck.json" + compression: + algorithm: ZSTD + level: 1 + max_buffer_size: 1048576 + #evt_max: 1000 +DV_b0_dstp_{{lepton}}_{{ polarity }}: + application: "DaVinci/v64r4@x86_64_v3-el9-gcc13+detdesc-opt+g" + input: + job_name: HLT2_b0_dstp_{{lepton}}_{{ polarity }} + output: NTuple.root + options: + entrypoint: SL_l_nu_D0toKpi_Run3_MC.DV:{{line}} + extra_options: + input_raw_format: 0.5 + conddb_tag: {{cond_tag}} + dddb_tag: dddb-20231017 + input_type: ROOT + simulation: True + data_type: "Upgrade" + input_process: "Hlt2" + input_manifest_file: "HLT2.tck.json" + #evt_max: 1000 + + {%- endfor %} +{%- endfor %} -- GitLab From 4ab068d7f8fe94ef6c5f333a46c61a8df0492c19 Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Fri, 24 May 2024 10:42:53 +0200 Subject: [PATCH 31/57] remove SL_l_nu_D0toKpi_2024_data --- SL_l_nu_D0toKpi_2024_data/info.yaml | 56 ---- SL_l_nu_D0toKpi_2024_data/run_Dzl.py | 389 --------------------------- 2 files changed, 445 deletions(-) delete mode 100644 SL_l_nu_D0toKpi_2024_data/info.yaml delete mode 100644 SL_l_nu_D0toKpi_2024_data/run_Dzl.py diff --git a/SL_l_nu_D0toKpi_2024_data/info.yaml b/SL_l_nu_D0toKpi_2024_data/info.yaml deleted file mode 100644 index 6800bd5c02..0000000000 --- a/SL_l_nu_D0toKpi_2024_data/info.yaml +++ /dev/null @@ -1,56 +0,0 @@ -checks: - hist: - type: range - expression: B0_Delta_M - limits: - min: 130 - max: 200 - n_bins: 70 - -defaults: - inform: - - ching-hua.li@cern.ch - wg: SL - -{%- set lines_and_leptons = [ - ('SpruceSLB_BuToD0ENu_D0ToKPi','e'), - ('SpruceSLB_BuToD0MuNu_D0ToKPi','muon'), - ('SpruceSLB_BuToD0TauNu_D0ToKPi_TauToENuNu','taue'), - ('SpruceSLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu','taumuon'), - ('SpruceSLB_BuToD0ENu_D0ToKPi_FakeElectron','e_fake'), - ('SpruceSLB_BuToD0MuNu_D0ToKPi_FakeMuon','muon_fake'), - ('SpruceSLB_BuToD0TauNu_D0ToKPi_FakeElectron','taue_fake'), - ('SpruceSLB_BuToD0TauNu_D0ToKPi_FakeMuon','taumuon_fake'), -] %} - -{%- set datasets = [ - ('2024Data', 'Down'), -]%} -{%- for evttype, polarity in datasets %} - {%- for spruce_line, leptons in lines_and_leptons %} -b0_dstp_{{leptons}}_{{ evttype }}_{{ polarity }}: - application: "DaVinci/v64r4" - input: - bk_query: "/LHCb/Collision24/Beam6800GeV-VeloClosed-Mag{{ polarity }}-Excl-UT/Real Data/Sprucing24c1/90000000/SL.DST" - dq_flags: - - UNCHECKED - - OK - keep_running: true - n_test_lfns: 1 - output: DATA.ROOT - options: - entrypoint: SL_l_nu_D0toKpi_2024_data.run_Dzl:{{spruce_line}} - extra_options: - input_raw_format: 0.5 - input_type: ROOT # ROOT for SprucingPass, RAW for RAW data (Hlt2 output) - simulation: False - #data_type: "Upgrade" - geometry_version: run3/2024.Q1.2-v00.00 - conditions_version: master - input_process: "Spruce" # Spruce for SprucingPass, "Hlt2" for RAW data (Hlt2 output) - input_stream: "sl" # for streamed data - #evt_max: 1000 - checks: - - hist - {%- endfor %} -{%- endfor %} diff --git a/SL_l_nu_D0toKpi_2024_data/run_Dzl.py b/SL_l_nu_D0toKpi_2024_data/run_Dzl.py deleted file mode 100644 index ed91b7a2a4..0000000000 --- a/SL_l_nu_D0toKpi_2024_data/run_Dzl.py +++ /dev/null @@ -1,389 +0,0 @@ -import sys,os,math -from PyConf.reading import get_pvs, get_rec_summary, get_particles -import Functors as F -from FunTuple import FunctorCollection -from FunTuple import FunTuple_Particles as Funtuple -from DaVinci.algorithms import create_lines_filter -from DaVinci import Options,make_config -import FunTuple.functorcollections as FC -from DaVinciMCTools import MCTruthAndBkgCat -from Hlt2Conf.algorithms_thor import ParticleCombiner, ParticleFilter -from Hlt2Conf.algorithms_thor import ParticleContainersMerger -from Functors.grammar import Functor -from Hlt2Conf.standard_particles import make_has_rich_long_pions,make_has_rich_up_pions,make_has_rich_down_pions -import numpy as np - -_BPVCORRM = Functor('_BPVCORRM', 'Composite::CorrectedMass','Compute the corrected mass') -_allpv_FDVEC = (F.ENDVERTEX_POS @ F.FORWARDARG1 - F.TOLINALG @ F.POSITION @ F.FORWARDARG0) -_allpv_NORMEDDOT = F.NORMEDDOT.bind(F.THREEMOMENTUM @ F.FORWARDARG1, _allpv_FDVEC) -#ALLPV_CHI2 = lambda Vertices: F.MAP(F.CHI2) @ F.TES(Vertices) -#ALLPV_CHI2DOF = lambda Vertices: F.MAP(F.CHI2DOF) @ F.TES(Vertices) -ALLPV_IPCHI2 = lambda Vertices: F.MAP(F.IPCHI2).bind(F.TES(Vertices), F.FORWARDARGS) -ALLPV_FDCHI2 = lambda Vertices: F.MAP(F.VTX_FDCHI2).bind(F.TES(Vertices), F.FORWARDARGS) -ALLPV_DIRA = lambda Vertices: F.MAP(_allpv_NORMEDDOT).bind(F.TES(Vertices), F.FORWARDARGS) -ALLPV_CORRM = lambda Vertices: F.MAP(_BPVCORRM).bind(F.TES(Vertices), F.FORWARDARGS) -ALLPV_LTIME = lambda Vertices: F.MAP(F.VTX_LTIME).bind(F.TES(Vertices), F.FORWARDARGS) -ALLPV_DLS = lambda Vertices: F.MAP(F.VTX_DLS).bind(F.TES(Vertices), F.FORWARDARGS) -ALLPV_FD_COORDINATE = lambda coordinate, Vertices: F.MAP(coordinate @ _allpv_FDVEC).bind(F.TES(Vertices), F.FORWARDARGS) -#MCNEUTRINO = F.FIND_MCDECAY("[ Lambda_b0 => Lambda_c+ mu- ^nu_mu~ ]CC") - -TRUE_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.PARTICLE_ID) == id) -#MCMOTHER_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.MC_MOTHER(1, F.PARTICLE_ID)) == id) -#GD_MCMOTHER_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.MC_MOTHER(2, F.PARTICLE_ID)) == id) -#GD_GD_MCMOTHER_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.MC_MOTHER(3, F.PARTICLE_ID)) == id) - -def make_Bst(B, pions,lepton, hadron_candidate_id,v2_pvs,do_truth_matching = True): - if do_truth_matching == True : - #filter B keeping only true D0 and true leptons - MCTRUTH_B = MCTruthAndBkgCat(B, name='MCTRUTH_Bu') - Dz_child = F.CHILD(1, F.FORWARDARG0) #get the first child of B*- which is D0 - lep_child = F.CHILD(2, F.FORWARDARG0) #get the second child of B*- which is lepton - Dz_truth_cut = TRUE_ID_IS(hadron_candidate_id, MCTRUTH_B) @ Dz_child #require that D0 is true - lep_truth_cut = F.require_any(TRUE_ID_IS(11, MCTRUTH_B) @ lep_child , TRUE_ID_IS(13, MCTRUTH_B) @ lep_child) #require that lepton is true i.e. electron or muon - cut_b = F.require_all(Dz_truth_cut, lep_truth_cut) #make a cut - signal_B = ParticleFilter(Input=B, Cut=F.FILTER(cut_b), name='signal_Dzmu') #filter the B candidates - else : signal_B = B - - #combine to make [B*0 -> B*- pi+]cc - Bst_1 = ParticleCombiner( - Inputs=[B, pions], - name=f'Bst_1_{lepton}', - DecayDescriptor='[B0 -> B- pi+]cc', - CombinationCut=F.ALL, - CompositeCut=F.ALL, - ParticleCombiner="ParticleVertexFitter", - PrimaryVertices=v2_pvs - #OutputLevel=1 - ) - #combine to make [B*0 -> B*- pi-]cc - Bst_2 = ParticleCombiner( - Inputs=[B, pions], - name=f'Bst_2_{lepton}', - DecayDescriptor='[B0 -> B- pi-]cc', - CombinationCut=F.ALL, - CompositeCut=F.ALL, - ParticleCombiner="ParticleVertexFitter", - PrimaryVertices=v2_pvs - #OutputLevel=1 - ) - #merge the two Bst candidates - Bst = ParticleContainersMerger([Bst_1, Bst_2], name = f'Bst_combiner_{lepton}') - return Bst - -def get_functors(MCTRUTH, v2_pvs, rec_summary): - #define common variables for all fields (composite and basic) - vars_common = FunctorCollection() - #all pvs: ip, ipchi2. The PV positions are stored in event variables - vars_common['ALLPV_IP[pv_indx]'] = F.ALLPV_IP(v2_pvs) - vars_common['ALLPV_IPCHI2[pv_indx]'] = ALLPV_IPCHI2(v2_pvs) - #best pv: x, y, z, ip, ipchi2 - vars_common['BPV_X'] = F.BPVX(v2_pvs) - vars_common['BPV_Y'] = F.BPVY(v2_pvs) - vars_common['BPV_Z'] = F.BPVZ(v2_pvs) - vars_common['BPV_IP'] = F.BPVIP(v2_pvs) - vars_common['BPV_IPCHI2'] = F.BPVIPCHI2(v2_pvs) - vars_common['BPV_CHI2'] = F.CHI2 @ F.BPV(v2_pvs) - vars_common['BPV_CHI2DOF'] = F.CHI2DOF @ F.BPV(v2_pvs) - #particle id, key, truekey. The trueid is stored in MCHierarchy - vars_common['ID'] = F.PARTICLE_ID - vars_common['KEY'] = F.OBJECT_KEY - - #get charge, min ip and min ipchi2 - vars_common['CHARGE'] = F.CHARGE - vars_common['MINIP'] = F.MINIP(v2_pvs) - vars_common['MINIPCHI2'] = F.MINIPCHI2(v2_pvs) - #reco kinematics - vars_common += FC.Kinematics() - vars_common['ETA'] = F.ETA - vars_common['PHI'] = F.PHI - if MCTRUTH != 'None': - #mc vars - vars_common['TRUEKEY'] = F.VALUE_OR(-1) @ MCTRUTH(F.OBJECT_KEY) - vars_common += FC.MCKinematics(mctruth_alg = MCTRUTH) - vars_common['TRUEETA'] = MCTRUTH(F.ETA) - vars_common['TRUEPHI'] = MCTRUTH(F.PHI) - #type of the origin vertex - vars_common['MC_VTX_TYPE'] = MCTRUTH(F.VALUE_OR(-1) @ F.MC_VTX_TYPE @ F.MC_ORIGINVERTEX) - ##mc truth hierarchy (done seperately) - #vars_common += FC.MCHierarchy(mctruth_alg = MCTRUTH) - #make some helper functions - MCMOTHER_ID = lambda n: F.VALUE_OR(0) @ MCTRUTH(F.MC_MOTHER(n, F.PARTICLE_ID)) - MCMOTHER_KEY = lambda n: F.VALUE_OR(-1) @ MCTRUTH(F.MC_MOTHER(n, F.OBJECT_KEY )) - vars_common["TRUEID"] = F.VALUE_OR(0) @ MCTRUTH(F.PARTICLE_ID) - vars_common["MCKEY"] = F.VALUE_OR(0) @ MCTRUTH(F.OBJECT_KEY) - vars_common["MC_MOTHER_ID"] = MCMOTHER_ID(1) - vars_common["MC_MOTHER_KEY"] = MCMOTHER_KEY(1) - for i in range(2,14): - prefix = "MC_GD_MOTHER_{}".format(i) - vars_common[f"{prefix}_ID"] = MCMOTHER_ID(i) - vars_common[f"{prefix}_KEY"] = MCMOTHER_KEY(i) - - #variables for composite particles - vars_composite = FunctorCollection() - #end vertex position and end vertex chi2 - vars_composite['ENDVERTEX_POS_'] = F.ENDVERTEX_POS - vars_composite['ENDVERTEX_CHI2'] = F.CHI2 @ F.ENDVERTEX - vars_composite['ENDVERTEX_CHI2DOF'] = F.CHI2DOF @ F.ENDVERTEX - #all pvs: dira, fd, fdchi2 - vars_composite['ALLPV_DIRA[pv_indx]'] = ALLPV_DIRA(v2_pvs) - vars_composite['ALLPV_FD_X[pv_indx]'] = ALLPV_FD_COORDINATE(F.X_COORDINATE, v2_pvs) - vars_composite['ALLPV_FD_Y[pv_indx]'] = ALLPV_FD_COORDINATE(F.Y_COORDINATE, v2_pvs) - vars_composite['ALLPV_FD_Z[pv_indx]'] = ALLPV_FD_COORDINATE(F.Z_COORDINATE, v2_pvs) - vars_composite['ALLPV_FDCHI2[pv_indx]'] = ALLPV_FDCHI2(v2_pvs) - vars_composite['ALLPV_CORRM[pv_indx]'] = ALLPV_CORRM(v2_pvs) - vars_composite['ALLPV_LTIME[pv_indx]'] = ALLPV_LTIME(v2_pvs) - vars_composite['ALLPV_DLS[pv_indx]'] = ALLPV_DLS(v2_pvs) - #best pv: dira, fd, fdchi2, corrm, ltime, dls - vars_composite['BPV_DIRA'] = F.BPVDIRA(v2_pvs) - vars_composite['BPV_FD_'] = F.BPVFDVEC(v2_pvs) - vars_composite['BPV_FDCHI2'] = F.BPVFDCHI2(v2_pvs) - vars_composite['BPV_CORRM'] = F.BPVCORRM(v2_pvs) - vars_composite['BPV_LTIME'] = F.BPVLTIME(v2_pvs) - vars_composite['BPV_DLS'] = F.BPVDLS(v2_pvs) - #mc composite vertex information - - if MCTRUTH != 'None': vars_composite += FC.MCVertexInfo(mctruth_alg = MCTRUTH) - #Compute maximum DOCA and maximum DOCACHI2. Since there are - # only two daughters of Sb particles, the maximum DOCA/DOCACHI2 is - # the DOCA/DOCACHI2 see below. - vars_composite['MAX_DOCA'] = F.MAXDOCA - vars_composite['MAX_DOCACHI2'] = F.MAXDOCACHI2 - vars_composite['MAX_SDOCA'] = F.MAXSDOCA - vars_composite['MAX_SDOCACHI2'] = F.MAXSDOCACHI2 - - #variables for Lb field - var_B = FunctorCollection() - #var_B['TRUENU_PX'] = MCTRUTH(F.PX @ MCNEUTRINO) - #var_B['TRUENU_PY'] = MCTRUTH(F.PY @ MCNEUTRINO) - #var_B['TRUENU_PZ'] = MCTRUTH(F.PZ @ MCNEUTRINO) - #var_B['TRUENU_ENERGY'] = MCTRUTH(F.ENERGY @ MCNEUTRINO) - ###Bkg category - ##var_B["BKGCAT"] = MCTRUTH.BkgCat - - #variables for basics - vars_basic = FunctorCollection() - vars_basic['TRACKTYPE'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKTYPE @ F.TRACK - vars_basic['TRACKHISTORY'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKHISTORY @ F.TRACK - vars_basic['TRACKFLAG'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKFLAG @ F.TRACK - vars_basic['TRACKNDOF'] = F.VALUE_OR(-1) @ F.NDOF @ F.TRACK - vars_basic['TRACKCHI2'] = F.CHI2 @ F.TRACK - vars_basic['TRACKCHI2DOF'] = F.CHI2DOF @ F.TRACK - vars_basic['GHOSTPROB'] = F.GHOSTPROB - vars_basic['PIDpi'] = F.PID_PI - vars_basic['PIDk'] = F.PID_K - vars_basic['PIDp'] = F.PID_P - vars_basic['PIDe'] = F.PID_E - vars_basic['PIDmu'] = F.PID_MU - vars_basic['PROBNNe'] = F.PROBNN_E - vars_basic['PROBNNpi'] = F.PROBNN_PI - vars_basic['PROBNNk'] = F.PROBNN_K - vars_basic['PROBNNmu'] = F.PROBNN_MU - vars_basic['PROBNNp'] = F.PROBNN_P - vars_basic['PROBNNghost'] = F.PROBNN_GHOST - if MCTRUTH != 'None': - vars_basic['TRUEORIGINVERTEX_X'] = MCTRUTH(F.ORIGIN_VX) - vars_basic['TRUEORIGINVERTEX_Y'] = MCTRUTH(F.ORIGIN_VY) - vars_basic['TRUEORIGINVERTEX_Z'] = MCTRUTH(F.ORIGIN_VZ) - - #variables for event - evt_vars = FunctorCollection() - #evt_vars['ALLPV_X[pv_indx]'] = F.ALLPVX(v2_pvs) - #evt_vars['ALLPV_Y[pv_indx]'] = F.ALLPVY(v2_pvs) - #evt_vars['ALLPV_Z[pv_indx]'] = F.ALLPVZ(v2_pvs) - #evt_vars['ALLPV_CHI2[pv_indx]'] = ALLPV_CHI2(v2_pvs) - #evt_vars['ALLPV_CHI2DOF[pv_indx]']= ALLPV_CHI2DOF(v2_pvs) - evt_vars['nTracks'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nTracks") - evt_vars['nLongTracks'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nLongTracks") - evt_vars['nPVs'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nPVs") - - vars_brems = FunctorCollection({}) - vars_brems.update({"HASBREM": F.HASBREM}) - #vars_brems.update({"HASBREMADDED": F.HASBREMADDED}) - vars_brems.update({"BREMENERGY": F.BREMENERGY}) - vars_brems.update({"BREMBENDCORR": F.BREMBENDCORR}) - vars_brems.update({"BREMPIDE": F.BREMPIDE}) - vars_brems.update({"ECALPIDE": F.ECALPIDE}) - vars_brems.update({"ECALPIDMU": F.ECALPIDMU}) - vars_brems.update({"HCALPIDE": F.HCALPIDE}) - vars_brems.update({"HCALPIDMU": F.HCALPIDMU}) - vars_brems.update({"ELECTRONSHOWEREOP": F.ELECTRONSHOWEREOP}) - vars_brems.update({"ELECTRONSHOWERDLL": F.ELECTRONSHOWERDLL}) - vars_brems.update({"CLUSTERMATCH": F.CLUSTERMATCH_CHI2}) - vars_brems.update({"ELECTRONMATCH": F.ELECTRONMATCH_CHI2}) - vars_brems.update({"BREMHYPOMATCH": F.BREMHYPOMATCH_CHI2}) - vars_brems.update({"ELECTRONENERGY": F.ELECTRONENERGY}) - vars_brems.update({"BREMHYPOENERGY": F.BREMHYPOENERGY}) - vars_brems.update({"BREMHYPODELTAX": F.BREMHYPODELTAX}) - #vars_brems.update({"BREMTRACKBASEDENERGY": F.BREMTRACKBASEDENERGY}) - vars_brems.update({"INBREM": F.INBREM}) - vars_brems.update({"PT_WITH_BREM": F.PT_WITH_BREM}) - vars_brems.update({"P_WITH_BREM": F.P_WITH_BREM}) - - #return all functors - functors = (vars_common, vars_composite, var_B, vars_basic, evt_vars,vars_brems) - return functors - -def get_fitting_variable(v2_pvs,D0,lep): - - B_dis = np.array([F.END_VX-F.BPVX(v2_pvs),F.END_VY-F.BPVY(v2_pvs),F.END_VZ-F.BPVZ(v2_pvs)]) - B_dis_mag = F.SQRT @ (B_dis[0]**2+B_dis[1]**2+B_dis[2]**2) - B_Mod_P = F.ABS @ ((5279.65/F.MASS)*F.PZ/(B_dis[2]/B_dis_mag)) - B_Mod_E = F.SQRT @ (B_Mod_P**2 + 5279.65**2) - B_4P = np.array([B_Mod_P*B_dis[0]/B_dis_mag,B_Mod_P*B_dis[1]/B_dis_mag,B_Mod_P*B_dis[2]/B_dis_mag,B_Mod_E]) - D_4P = np.array([F.PX @ D0,F.PY @ D0,F.PZ @ D0,F.ENERGY @ D0]) - lep_4P = np.array([F.PX @ lep,F.PY @ lep,F.PZ @ lep,F.ENERGY @ lep]) - - vars_fitting = FunctorCollection({}) - vars_fitting["Mod_P"] = B_Mod_P - vars_fitting['missing_m2'] = (B_4P[3]-D_4P[3]-lep_4P[3])**2-(B_4P[0]-D_4P[0]-lep_4P[0])**2-(B_4P[1]-D_4P[1]-lep_4P[1])**2-(B_4P[2]-D_4P[2]-lep_4P[2])**2 - vars_fitting['q2'] = (B_4P[3]-D_4P[3])**2-(B_4P[0]-D_4P[0])**2-(B_4P[1]-D_4P[1])**2-(B_4P[2]-D_4P[2])**2 - B_Beta = B_Mod_P/B_Mod_E - B_gamma = 1/F.SQRT @ (1-B_Beta**2) - - B_Lorentz = [[B_gamma,-1*B_gamma*B_4P[0]/B_4P[3],-1*B_gamma*B_4P[1]/B_4P[3],-1*B_gamma*B_4P[2]/B_4P[3]],[-1*B_gamma*B_4P[0]/B_4P[3],1+(B_gamma-1)*((B_4P[0]/B_4P[3])/B_Beta)*((B_4P[0]/B_4P[3])/B_Beta),(B_gamma-1)*((B_4P[0]/B_4P[3])/B_Beta)*((B_4P[1]/B_4P[3])/B_Beta),(B_gamma-1)*((B_4P[0]/B_4P[3])/B_Beta)*((B_4P[2]/B_4P[3])/B_Beta)],[-1*B_gamma*B_4P[1]/B_4P[3],(B_gamma-1)*((B_4P[0]/B_4P[3])/B_Beta)*((B_4P[1]/B_4P[3])/B_Beta),(B_gamma-1)*((B_4P[1]/B_4P[3])/B_Beta)*((B_4P[1]/B_4P[3])/B_Beta),(B_gamma-1)*((B_4P[1]/B_4P[3])/B_Beta)*((B_4P[2]/B_4P[3])/B_Beta)],[-1*B_gamma*B_4P[2]/B_4P[3],(B_gamma-1)*((B_4P[0]/B_4P[3])/B_Beta)*((B_4P[2]/B_4P[3])/B_Beta),(B_gamma-1)*((B_4P[1]/B_4P[3])/B_Beta)*((B_4P[2]/B_4P[3])/B_Beta),(B_gamma-1)*((B_4P[2]/B_4P[3])/B_Beta)*((B_4P[2]/B_4P[3])/B_Beta)]] - vars_fitting['lep_E_Brest'] = (B_Lorentz[0][0]*lep_4P[3]+B_Lorentz[0][1]*lep_4P[0]+B_Lorentz[0][2]*lep_4P[1]+B_Lorentz[0][3]*lep_4P[2]) - return(vars_fitting) - -def tuple_Bst(Bst,lepton, MCTRUTH, v2_pvs, rec_summary): - #get functors - functors = get_functors(MCTRUTH, v2_pvs, rec_summary) - vars_common = functors[0] - vars_composite = functors[1] - var_B = functors[2] - vars_basic = functors[3] - evt_vars = functors[4] - vars_brems = functors[5] - - #variables for Sb field - vars_Bst = FunctorCollection() - B_child = F.CHILD(1, F.FORWARDARG0) - D0_child = F.CHILD(1, F.CHILD(1,F.FORWARDARG0)) - Lep_child = F.CHILD(1, F.CHILD(2,F.FORWARDARG0)) - Epi_child = F.CHILD(2, F.FORWARDARG0) - bpv_pi = F.BPV(v2_pvs).bind(Epi_child) - #diff in vtx chi2 with and without extra particle - vars_Bst['DELTA_ENDVERTEX_CHI2'] = (F.CHI2 @ F.ENDVERTEX) - (F.CHI2 @ F.ENDVERTEX.bind(B_child)) - #IP and IPChi2 of extra particle wrt to Sb end vertex - vars_Bst['Epi_IP_WRT_SbENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ F.FORWARDARG0 , Epi_child) - vars_Bst['Epi_IPCHI2_WRT_SbENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ F.FORWARDARG0 , Epi_child) - #IP and IPChi2 of extra particle wrt to Lb end vertex - vars_Bst['Epi_IP_WRT_LbENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ B_child , Epi_child) - vars_Bst['Epi_IPCHI2_WRT_LbENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ B_child , Epi_child) - #angle between extra particle and Lb - vars_Bst['Epi_COSANGLE_Lb'] = F.COSANGLE.bind(F.THREEMOMENTUM @ B_child, F.THREEMOMENTUM @ Epi_child) - #diff in fd chi2 with and without extra particle - vars_Bst['Delta_BPV_of_Epi_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi, F.FORWARDARGS) - F.VTX_FDCHI2.bind(bpv_pi, B_child) - vars_Bst['BPV_of_Epi_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi, F.FORWARDARGS) - #IP chi2 of extra particle wrt PV and SV of Sb - vars_Bst['Epi_IP_WRT_SbBPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child) - vars_Bst['Epi_IPCHI2_WRT_SbBPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child) - #IP chi2 of extra particle wrt PV and SV of Bb - vars_Bst['Epi_IP_WRT_LbBPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ B_child, Epi_child) - vars_Bst['Epi_IPCHI2_WRT_LbBPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ B_child, Epi_child) - #DOCA and DOCACHI2 b/w Lb and extra particle - vars_Bst['DOCA12'] = F.DOCA(1, 2) - vars_Bst['DOCA12_CHI2_12'] = F.DOCACHI2(1, 2) - #vars_Bst['SDOCA12'] = F.SDOCA(1, 2) - #vars_Bst['SDOCA_CHI2_12'] = F.SDOCACHI2(1, 2) - #DOCACHI2 of extra particle wrt to mother i.e. Sb - vars_Bst['MTDOCACHI2_1'] = F.MTDOCACHI2(1, v2_pvs) - vars_Bst['MTDOCACHI2_2'] = F.MTDOCACHI2(2, v2_pvs) - vars_Bst['Delta_M'] = F.ABS @ ((F.MASS @ ((F.FOURMOMENTUM @ D0_child)+(F.FOURMOMENTUM @ Epi_child))) - (F.MASS @ D0_child)) - #define fields - fit_vars = get_fitting_variable(v2_pvs,D0_child,Lep_child) - - - #define fields - fields = {} - fields['B0'] = f'[B0 -> (B- -> (D0 -> K- pi+) [{lepton}-]CC) [pi+]CC]CC' - fields['Bm'] = f'[B0 -> ^(B- -> (D0 -> K- pi+) [{lepton}-]CC) [pi+]CC]CC' - fields['D0'] = f'[B0 -> (B- -> ^(D0 -> K- pi+) [{lepton}-]CC) [pi+]CC]CC' - fields['Lep'] = f'[B0 -> (B- -> (D0 -> K- pi+) ^[{lepton}-]CC) [pi+]CC]CC' - fields['Epi'] = f'[B0 -> (B- -> (D0 -> K- pi+) [{lepton}-]CC) ^[pi+]CC]CC' - fields['Km'] = f'[B0 -> (B- -> (D0 -> ^K- pi+) [{lepton}-]CC) [pi+]CC]CC' - fields['pip'] = f'[B0 -> (B- -> (D0 -> K- ^pi+) [{lepton}-]CC) [pi+]CC]CC' - - #add variables - variables = {} - variables["ALL"] = vars_common - variables["B0"] = vars_composite + vars_Bst + fit_vars - variables["Bm"] = vars_composite + var_B - variables["D0"] = vars_composite - variables["Lep"] = vars_basic + vars_brems - variables["Epi"] = vars_basic + vars_brems - variables["Km"] = vars_basic + vars_brems - variables["pip"] = vars_basic + vars_brems - - #define tuple - my_tuple = Funtuple( - name=f"Tuple", - tuple_name="DecayTree", - fields=fields, - variables=variables, - inputs=Bst) - - return my_tuple - -def get_extra_pions(): - """ - Note this function in DaVinci requires: - https://gitlab.cern.ch/lhcb/Moore/-/merge_requests/3203 - and it's related LHCb, DaVinci and Rec MRs - """ - long_pions = make_has_rich_long_pions() - up_pions = make_has_rich_up_pions() - down_pions = make_has_rich_down_pions() - return ParticleContainersMerger([long_pions, up_pions, down_pions], - name='Pions_combiner') - -#def main(options): -def main(options: Options,line = '', lep=''): - - #define filer - my_filter = create_lines_filter(name="Filter", lines=[line]) - - #get data and extra particles - lb = get_particles(f"/Event/Spruce/{line}/Particles") - extra_particles = get_extra_pions() - - #get v2_pvs and rec_summary - v2_pvs = get_pvs() - rec_summary = get_rec_summary() - hadron_candidate_id = 421 - #make sb candidate - Bst = make_Bst(lb, extra_particles,lep,hadron_candidate_id,v2_pvs,False) - #MCTRUTH_Bst = MCTruthAndBkgCat(Bst, name='MCTRUTH_Bst') - - - tuple_file = tuple_Bst(Bst,lep, 'None', v2_pvs, rec_summary) - - #define algorithms - user_algorithms = {} - user_algorithms['Alg'] = [my_filter, tuple_file] - - return make_config(options, user_algorithms) - -def SpruceSLB_BuToD0ENu_D0ToKPi(options: Options): - return main(options=options, line='SpruceSLB_BuToD0ENu_D0ToKPi',lep='e') - -def SpruceSLB_BuToD0MuNu_D0ToKPi(options: Options): - return main(options=options, line='SpruceSLB_BuToD0MuNu_D0ToKPi',lep='mu') - -def SpruceSLB_BuToD0TauNu_D0ToKPi_TauToENuNu(options: Options): - return main(options=options, line='SpruceSLB_BuToD0TauNu_D0ToKPi_TauToENuNu',lep='e') - -def SpruceSLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu(options: Options): - return main(options=options, line='SpruceSLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu',lep='mu') - -def SpruceSLB_BuToD0ENu_D0ToKPi_FakeElectron(options: Options): - return main(options=options, line='SpruceSLB_BuToD0ENu_D0ToKPi_FakeElectron',lep='e') - -def SpruceSLB_BuToD0MuNu_D0ToKPi_FakeMuon(options: Options): - return main(options=options, line='SpruceSLB_BuToD0MuNu_D0ToKPi_FakeMuon',lep='mu') - -def SpruceSLB_BuToD0TauNu_D0ToKPi_FakeElectron(options: Options): - return main(options=options, line='SpruceSLB_BuToD0TauNu_D0ToKPi_FakeElectron',lep='e') - -def SpruceSLB_BuToD0TauNu_D0ToKPi_FakeMuon(options: Options): - return main(options=options, line='SpruceSLB_BuToD0TauNu_D0ToKPi_FakeMuon',lep='mu') - -- GitLab From 5951888c2ec0a3892dd2aa08f378131f0711fd94 Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Mon, 27 May 2024 12:08:47 +0200 Subject: [PATCH 32/57] Remove ft decoding version. Add spruce, totCandidate vars, BKGcat, isolation mva and delta D* mass pre-cut --- SL_l_nu_D0toKpi_Run3_MC/DV.py | 49 ++++++++++------------ SL_l_nu_D0toKpi_Run3_MC/Hlt2.py | 2 - SL_l_nu_D0toKpi_Run3_MC/Spruce.py | 70 +++++++++++++++++++++++++++++++ SL_l_nu_D0toKpi_Run3_MC/info.yaml | 34 ++++++++++++--- 4 files changed, 120 insertions(+), 35 deletions(-) create mode 100644 SL_l_nu_D0toKpi_Run3_MC/Spruce.py diff --git a/SL_l_nu_D0toKpi_Run3_MC/DV.py b/SL_l_nu_D0toKpi_Run3_MC/DV.py index 04f1272761..11d4c83109 100644 --- a/SL_l_nu_D0toKpi_Run3_MC/DV.py +++ b/SL_l_nu_D0toKpi_Run3_MC/DV.py @@ -12,6 +12,7 @@ from Hlt2Conf.algorithms_thor import ParticleContainersMerger from Functors.grammar import Functor from Hlt2Conf.standard_particles import make_has_rich_long_pions,make_has_rich_up_pions,make_has_rich_down_pions import numpy as np +from Hlt2Conf.lines.semileptonic.isolationMVA import mva_functor_e_inclusive,mva_functor_mu_inclusive _BPVCORRM = Functor('_BPVCORRM', 'Composite::CorrectedMass','Compute the corrected mass') _allpv_FDVEC = (F.ENDVERTEX_POS @ F.FORWARDARG1 - F.TOLINALG @ F.POSITION @ F.FORWARDARG0) @@ -25,12 +26,8 @@ ALLPV_CORRM = lambda Vertices: F.MAP(_BPVCORRM).bind(F.TES(Vertices), F.FORW ALLPV_LTIME = lambda Vertices: F.MAP(F.VTX_LTIME).bind(F.TES(Vertices), F.FORWARDARGS) ALLPV_DLS = lambda Vertices: F.MAP(F.VTX_DLS).bind(F.TES(Vertices), F.FORWARDARGS) ALLPV_FD_COORDINATE = lambda coordinate, Vertices: F.MAP(coordinate @ _allpv_FDVEC).bind(F.TES(Vertices), F.FORWARDARGS) -#MCNEUTRINO = F.FIND_MCDECAY("[ Lambda_b0 => Lambda_c+ mu- ^nu_mu~ ]CC") TRUE_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.PARTICLE_ID) == id) -#MCMOTHER_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.MC_MOTHER(1, F.PARTICLE_ID)) == id) -#GD_MCMOTHER_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.MC_MOTHER(2, F.PARTICLE_ID)) == id) -#GD_GD_MCMOTHER_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.MC_MOTHER(3, F.PARTICLE_ID)) == id) def make_Bst(B, pions,lepton, hadron_candidate_id,v2_pvs,do_truth_matching = True): if do_truth_matching == True : @@ -44,12 +41,17 @@ def make_Bst(B, pions,lepton, hadron_candidate_id,v2_pvs,do_truth_matching = Tru signal_B = ParticleFilter(Input=B, Cut=F.FILTER(cut_b), name='signal_Dzmu') #filter the B candidates else : signal_B = B + D0_child = F.CHILD(1, F.CHILD(1,F.FORWARDARG0)) + Epi_child = F.CHILD(2, F.FORWARDARG0) + #D* mass - D0 mass cut + cut_combine = F.require_all(((F.MASS @ ((F.FOURMOMENTUM @ D0_child)+(F.FOURMOMENTUM @ Epi_child))) - (F.MASS @ D0_child))<200) + #combine to make [B*0 -> B*- pi+]cc Bst_1 = ParticleCombiner( Inputs=[B, pions], name=f'Bst_1_{lepton}', DecayDescriptor='[B0 -> B- pi+]cc', - CombinationCut=F.ALL, + CombinationCut=cut_combine, CompositeCut=F.ALL, ParticleCombiner="ParticleVertexFitter", PrimaryVertices=v2_pvs @@ -60,7 +62,7 @@ def make_Bst(B, pions,lepton, hadron_candidate_id,v2_pvs,do_truth_matching = Tru Inputs=[B, pions], name=f'Bst_2_{lepton}', DecayDescriptor='[B0 -> B- pi-]cc', - CombinationCut=F.ALL, + CombinationCut=cut_combine, CompositeCut=F.ALL, ParticleCombiner="ParticleVertexFitter", PrimaryVertices=v2_pvs @@ -98,14 +100,13 @@ def get_functors(MCTRUTH, v2_pvs, rec_summary): vars_common['PHI'] = F.PHI if MCTRUTH != 'None': #mc vars + vars_common['BKGCAT'] = MCTRUTH.BkgCat vars_common['TRUEKEY'] = F.VALUE_OR(-1) @ MCTRUTH(F.OBJECT_KEY) vars_common += FC.MCKinematics(mctruth_alg = MCTRUTH) vars_common['TRUEETA'] = MCTRUTH(F.ETA) vars_common['TRUEPHI'] = MCTRUTH(F.PHI) #type of the origin vertex vars_common['MC_VTX_TYPE'] = MCTRUTH(F.VALUE_OR(-1) @ F.MC_VTX_TYPE @ F.MC_ORIGINVERTEX) - ##mc truth hierarchy (done seperately) - #vars_common += FC.MCHierarchy(mctruth_alg = MCTRUTH) #make some helper functions MCMOTHER_ID = lambda n: F.VALUE_OR(0) @ MCTRUTH(F.MC_MOTHER(n, F.PARTICLE_ID)) MCMOTHER_KEY = lambda n: F.VALUE_OR(-1) @ MCTRUTH(F.MC_MOTHER(n, F.OBJECT_KEY )) @@ -151,15 +152,6 @@ def get_functors(MCTRUTH, v2_pvs, rec_summary): vars_composite['MAX_SDOCA'] = F.MAXSDOCA vars_composite['MAX_SDOCACHI2'] = F.MAXSDOCACHI2 - #variables for Lb field - var_B = FunctorCollection() - #var_B['TRUENU_PX'] = MCTRUTH(F.PX @ MCNEUTRINO) - #var_B['TRUENU_PY'] = MCTRUTH(F.PY @ MCNEUTRINO) - #var_B['TRUENU_PZ'] = MCTRUTH(F.PZ @ MCNEUTRINO) - #var_B['TRUENU_ENERGY'] = MCTRUTH(F.ENERGY @ MCNEUTRINO) - ###Bkg category - ##var_B["BKGCAT"] = MCTRUTH.BkgCat - #variables for basics vars_basic = FunctorCollection() vars_basic['TRACKTYPE'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKTYPE @ F.TRACK @@ -220,7 +212,7 @@ def get_functors(MCTRUTH, v2_pvs, rec_summary): vars_brems.update({"P_WITH_BREM": F.P_WITH_BREM}) #return all functors - functors = (vars_common, vars_composite, var_B, vars_basic, evt_vars,vars_brems) + functors = (vars_common, vars_composite, vars_basic, evt_vars,vars_brems) return functors def get_fitting_variable(v2_pvs,D0,lep): @@ -249,10 +241,9 @@ def tuple_Bst(Bst,lepton, MCTRUTH, v2_pvs, rec_summary): functors = get_functors(MCTRUTH, v2_pvs, rec_summary) vars_common = functors[0] vars_composite = functors[1] - var_B = functors[2] - vars_basic = functors[3] - evt_vars = functors[4] - vars_brems = functors[5] + vars_basic = functors[2] + evt_vars = functors[3] + vars_brems = functors[4] #variables for Sb field vars_Bst = FunctorCollection() @@ -289,6 +280,7 @@ def tuple_Bst(Bst,lepton, MCTRUTH, v2_pvs, rec_summary): vars_Bst['MTDOCACHI2_1'] = F.MTDOCACHI2(1, v2_pvs) vars_Bst['MTDOCACHI2_2'] = F.MTDOCACHI2(2, v2_pvs) vars_Bst['Delta_M'] = F.ABS @ ((F.MASS @ ((F.FOURMOMENTUM @ D0_child)+(F.FOURMOMENTUM @ Epi_child))) - (F.MASS @ D0_child)) + vars_Bst['iso_mva'] = mva_functor_e_inclusive(v2_pvs)[0] if lepton == 'e' else mva_functor_mu_inclusive(v2_pvs)[0] #define fields fit_vars = get_fitting_variable(v2_pvs,D0_child,Lep_child) @@ -307,7 +299,7 @@ def tuple_Bst(Bst,lepton, MCTRUTH, v2_pvs, rec_summary): variables = {} variables["ALL"] = vars_common variables["B0"] = vars_composite + vars_Bst + fit_vars - variables["Bm"] = vars_composite + var_B + variables["Bm"] = vars_composite variables["D0"] = vars_composite variables["Lep"] = vars_basic + vars_brems variables["Epi"] = vars_basic + vars_brems @@ -320,6 +312,7 @@ def tuple_Bst(Bst,lepton, MCTRUTH, v2_pvs, rec_summary): tuple_name="DecayTree", fields=fields, variables=variables, + store_multiple_cand_info=True, inputs=Bst) return my_tuple @@ -343,7 +336,7 @@ def main(options: Options,line = '', lep=''): my_filter = create_lines_filter(name="Filter", lines=[line]) #get data and extra particles - lb = get_particles(f"/Event/HLT2/{line}/Particles") + lb = get_particles(f"/Event/Spruce/{line}/Particles") extra_particles = get_extra_pions() #get v2_pvs and rec_summary @@ -364,14 +357,14 @@ def main(options: Options,line = '', lep=''): return make_config(options, user_algorithms) def SLB_BuToD0ENu_D0ToKPi(options: Options): - return main(options=options, line='Hlt2SLB_BToDzl',lep='e') + return main(options=options, line='SpruceSLB_BToDzl',lep='e') def SLB_BuToD0MuNu_D0ToKPi(options: Options): - return main(options=options, line='Hlt2SLB_BuToD0MuNu_D0ToKPi',lep='mu') + return main(options=options, line='SpruceSLB_BuToD0MuNu_D0ToKPi',lep='mu') def SLB_BuToD0TauNu_D0ToKPi_TauToENuNu(options: Options): - return main(options=options, line='Hlt2SLB_BToDzl',lep='e') + return main(options=options, line='SpruceSLB_BToDzl',lep='e') def SLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu(options: Options): - return main(options=options, line='Hlt2SLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu',lep='mu') + return main(options=options, line='SpruceSLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu',lep='mu') diff --git a/SL_l_nu_D0toKpi_Run3_MC/Hlt2.py b/SL_l_nu_D0toKpi_Run3_MC/Hlt2.py index e0d48da235..c7133e1dac 100644 --- a/SL_l_nu_D0toKpi_Run3_MC/Hlt2.py +++ b/SL_l_nu_D0toKpi_Run3_MC/Hlt2.py @@ -106,8 +106,6 @@ def make_lines_mu(): def make_lines_taumu(): return [hlt2_butod0taunu_d0tokpi_tautomununu_line()] -#ft decoding version 6 since MC made after 2019 -default_ft_decoding_version.global_bind(value=6) def SLB_BuToD0ENu_D0ToKPi(options: Options): with reconstruction.bind(from_file=False): config = run_moore(options, make_streams=make_lines_e, public_tools=[stateProvider_with_simplified_geom()]) diff --git a/SL_l_nu_D0toKpi_Run3_MC/Spruce.py b/SL_l_nu_D0toKpi_Run3_MC/Spruce.py new file mode 100644 index 0000000000..7a10321fb5 --- /dev/null +++ b/SL_l_nu_D0toKpi_Run3_MC/Spruce.py @@ -0,0 +1,70 @@ +############################################################################### +# (c) Copyright 2022 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### +#Example follows from hlt2_with_hlt1_decision.py +from Moore import Options,options, run_moore, config +from Hlt2Conf.lines.semileptonic.builders import sl_line_prefilter +from Moore.config import SpruceLine +from .Hlt2 import make_b +from PyConf.application import configure_input, configure, default_raw_event +from RecoConf.global_tools import stateProvider_with_simplified_geom +from RecoConf.reconstruction_objects import reconstruction +from RecoConf.decoders import default_ft_decoding_version +from RecoConf.hlt2_global_reco import reconstruction as hlt2_reconstruction, make_fastest_reconstruction +from Hlt2Conf.lines.semileptonic.spruce_semileptonic import spruce_butod0munu_d0tokpi_line,spruce_butod0taunu_d0tokpi_tautomununu_line +from Hlt2Conf.lines.semileptonic.HbToHcTauNu_TauToLNuNu import make_butod0taunu_d0tokpi_tautolnunu +from Hlt2Conf.lines.semileptonic.HbToHcLNu import make_butod0lnu_d0tokpi + +def make_lines_e(): + def spruce_lines(name='SpruceSLB_BToDzl',prescale=1): + Bcands = make_b() + return SpruceLine(name=name, hlt2_filter_code=[ + f"{name.replace('Spruce','Hlt2')}Decision", + "Hlt2Topo2BodyDecision", "Hlt2Topo3BodyDecision"] + ,prescale=prescale,persistreco=True, algs=sl_line_prefilter() + [Bcands]) + return [spruce_lines()] + +def make_lines_taumu(): + def spruce_lines(name='SpruceSLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu',prescale=1): + line_alg = make_butod0taunu_d0tokpi_tautolnunu(process='spruce', lepton="mu") + return SpruceLine(name=name, hlt2_filter_code=[ + f"{name.replace('Spruce','Hlt2')}Decision", + "Hlt2Topo2BodyDecision", "Hlt2Topo3BodyDecision"] + ,prescale=prescale,persistreco=True, algs=sl_line_prefilter() + [line_alg]) + return [spruce_lines()] + +def make_lines_mu(): + def spruce_lines(name="SpruceSLB_BuToD0MuNu_D0ToKPi",prescale=1): + line_alg = make_butod0lnu_d0tokpi(process='spruce', lepton="mu") + return SpruceLine(name=name, hlt2_filter_code=[ + f"{name.replace('Spruce','Hlt2')}Decision", + "Hlt2Topo2BodyDecision", "Hlt2Topo3BodyDecision"] + ,prescale=prescale,persistreco=True, algs=sl_line_prefilter() + [line_alg]) + return [spruce_lines()] + +def SLB_BuToD0ENu_D0ToKPi(options: Options): + with reconstruction.bind(from_file=True, spruce=True): + config = run_moore(options, make_streams=make_lines_e, public_tools=[stateProvider_with_simplified_geom()]) + return config + +def SLB_BuToD0MuNu_D0ToKPi(options: Options): + with reconstruction.bind(from_file=True, spruce=True): + config = run_moore(options, make_streams=make_lines_mu, public_tools=[stateProvider_with_simplified_geom()]) + return config + +def SLB_BuToD0TauNu_D0ToKPi_TauToENuNu(options: Options): + with reconstruction.bind(from_file=True, spruce=True): + config = run_moore(options, make_streams=make_lines_e, public_tools=[stateProvider_with_simplified_geom()]) + return config + +def SLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu(options: Options): + with reconstruction.bind(from_file=True, spruce=True): + config = run_moore(options, make_streams=make_lines_taumu, public_tools=[stateProvider_with_simplified_geom()]) + return config diff --git a/SL_l_nu_D0toKpi_Run3_MC/info.yaml b/SL_l_nu_D0toKpi_Run3_MC/info.yaml index 0982bfe288..4cff9509f0 100644 --- a/SL_l_nu_D0toKpi_Run3_MC/info.yaml +++ b/SL_l_nu_D0toKpi_Run3_MC/info.yaml @@ -22,7 +22,7 @@ HLT1_b0_dstp_{{lepton}}_{{ polarity }}: bk_query: "/MC/Dev/Beam6800GeV-expected-2024-{{polarity}}-Nu7.6-25ns-Pythia8/Sim10c/{{evttype}}/DIGI" dq_flags: - OK - n_test_lfns: 3 + n_test_lfns: 2 output: hlt1.dst options: entrypoint: SL_l_nu_D0toKpi_Run3_MC.Hlt1:main @@ -63,22 +63,46 @@ HLT2_b0_dstp_{{lepton}}_{{ polarity }}: level: 1 max_buffer_size: 1048576 #evt_max: 1000 -DV_b0_dstp_{{lepton}}_{{ polarity }}: - application: "DaVinci/v64r4@x86_64_v3-el9-gcc13+detdesc-opt+g" +SPRUCE_b0_dstp_{{lepton}}_{{ polarity }}: + application: "Moore/v55r8@x86_64_v3-el9-gcc13+detdesc-opt+g" input: job_name: HLT2_b0_dstp_{{lepton}}_{{ polarity }} - output: NTuple.root + output: spruce.dst options: - entrypoint: SL_l_nu_D0toKpi_Run3_MC.DV:{{line}} + entrypoint: SL_l_nu_D0toKpi_Run3_MC.Spruce:{{line}} extra_options: input_raw_format: 0.5 conddb_tag: {{cond_tag}} dddb_tag: dddb-20231017 input_type: ROOT + output_type: ROOT simulation: True data_type: "Upgrade" + scheduler_legacy_mode: False input_process: "Hlt2" input_manifest_file: "HLT2.tck.json" + output_manifest_file: "SPRUCE.tck.json" + compression: + algorithm: ZSTD + level: 1 + max_buffer_size: 1048576 + #evt_max: 1000 +DV_b0_dstp_{{lepton}}_{{ polarity }}: + application: "DaVinci/v64r5@x86_64_v3-el9-gcc13+detdesc-opt+g" + input: + job_name: SPRUCE_b0_dstp_{{lepton}}_{{ polarity }} + output: NTuple.root + options: + entrypoint: SL_l_nu_D0toKpi_Run3_MC.DV:{{line}} + extra_options: + input_raw_format: 0.5 + conddb_tag: {{cond_tag}} + dddb_tag: dddb-20231017 + input_type: ROOT + simulation: True + data_type: "Upgrade" + input_process: "Spruce" + input_manifest_file: "SPRUCE.tck.json" #evt_max: 1000 {%- endfor %} -- GitLab From 9bb431a5a86d05bf6a96a67337b4843d08c53100 Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Thu, 30 May 2024 15:13:26 +0200 Subject: [PATCH 33/57] Add variables and new MC sample --- SL_l_nu_D0toKpi_Run3_MC/DV.py | 116 ++++++++++++++++++-------- SL_l_nu_D0toKpi_Run3_MC/Hlt2.py | 20 +++++ SL_l_nu_D0toKpi_Run3_MC/MC_Matcher.py | 26 ++++++ SL_l_nu_D0toKpi_Run3_MC/Spruce.py | 36 ++++---- SL_l_nu_D0toKpi_Run3_MC/info.yaml | 34 ++++---- 5 files changed, 168 insertions(+), 64 deletions(-) create mode 100644 SL_l_nu_D0toKpi_Run3_MC/MC_Matcher.py diff --git a/SL_l_nu_D0toKpi_Run3_MC/DV.py b/SL_l_nu_D0toKpi_Run3_MC/DV.py index 11d4c83109..19a333dfa6 100644 --- a/SL_l_nu_D0toKpi_Run3_MC/DV.py +++ b/SL_l_nu_D0toKpi_Run3_MC/DV.py @@ -13,12 +13,13 @@ from Functors.grammar import Functor from Hlt2Conf.standard_particles import make_has_rich_long_pions,make_has_rich_up_pions,make_has_rich_down_pions import numpy as np from Hlt2Conf.lines.semileptonic.isolationMVA import mva_functor_e_inclusive,mva_functor_mu_inclusive +from .MC_Matcher import trail_seeker _BPVCORRM = Functor('_BPVCORRM', 'Composite::CorrectedMass','Compute the corrected mass') _allpv_FDVEC = (F.ENDVERTEX_POS @ F.FORWARDARG1 - F.TOLINALG @ F.POSITION @ F.FORWARDARG0) _allpv_NORMEDDOT = F.NORMEDDOT.bind(F.THREEMOMENTUM @ F.FORWARDARG1, _allpv_FDVEC) -#ALLPV_CHI2 = lambda Vertices: F.MAP(F.CHI2) @ F.TES(Vertices) -#ALLPV_CHI2DOF = lambda Vertices: F.MAP(F.CHI2DOF) @ F.TES(Vertices) +ALLPV_CHI2 = lambda Vertices: F.MAP(F.CHI2) @ F.TES(Vertices) +ALLPV_CHI2DOF = lambda Vertices: F.MAP(F.CHI2DOF) @ F.TES(Vertices) ALLPV_IPCHI2 = lambda Vertices: F.MAP(F.IPCHI2).bind(F.TES(Vertices), F.FORWARDARGS) ALLPV_FDCHI2 = lambda Vertices: F.MAP(F.VTX_FDCHI2).bind(F.TES(Vertices), F.FORWARDARGS) ALLPV_DIRA = lambda Vertices: F.MAP(_allpv_NORMEDDOT).bind(F.TES(Vertices), F.FORWARDARGS) @@ -43,6 +44,7 @@ def make_Bst(B, pions,lepton, hadron_candidate_id,v2_pvs,do_truth_matching = Tru D0_child = F.CHILD(1, F.CHILD(1,F.FORWARDARG0)) Epi_child = F.CHILD(2, F.FORWARDARG0) + #D* mass - D0 mass cut cut_combine = F.require_all(((F.MASS @ ((F.FOURMOMENTUM @ D0_child)+(F.FOURMOMENTUM @ Epi_child))) - (F.MASS @ D0_child))<200) @@ -72,7 +74,7 @@ def make_Bst(B, pions,lepton, hadron_candidate_id,v2_pvs,do_truth_matching = Tru Bst = ParticleContainersMerger([Bst_1, Bst_2], name = f'Bst_combiner_{lepton}') return Bst -def get_functors(MCTRUTH, v2_pvs, rec_summary): +def get_functors(MCTRUTH, v2_pvs, rec_summary,line): #define common variables for all fields (composite and basic) vars_common = FunctorCollection() #all pvs: ip, ipchi2. The PV positions are stored in event variables @@ -141,8 +143,8 @@ def get_functors(MCTRUTH, v2_pvs, rec_summary): vars_composite['BPV_CORRM'] = F.BPVCORRM(v2_pvs) vars_composite['BPV_LTIME'] = F.BPVLTIME(v2_pvs) vars_composite['BPV_DLS'] = F.BPVDLS(v2_pvs) - #mc composite vertex information + #mc composite vertex information if MCTRUTH != 'None': vars_composite += FC.MCVertexInfo(mctruth_alg = MCTRUTH) #Compute maximum DOCA and maximum DOCACHI2. Since there are # only two daughters of Sb particles, the maximum DOCA/DOCACHI2 is @@ -161,6 +163,12 @@ def get_functors(MCTRUTH, v2_pvs, rec_summary): vars_basic['TRACKCHI2'] = F.CHI2 @ F.TRACK vars_basic['TRACKCHI2DOF'] = F.CHI2DOF @ F.TRACK vars_basic['GHOSTPROB'] = F.GHOSTPROB + vars_basic['NHITS'] = F.VALUE_OR(-1) @F.NHITS @ F.TRACK + vars_basic['NUTHITS'] = F.VALUE_OR(-1) @F.NUTHITS @ F.TRACK + vars_basic['NVPHITS'] = F.VALUE_OR(-1) @F.NVPHITS @ F.TRACK + vars_basic['NFTHITS'] = F.VALUE_OR(-1) @ F.NFTHITS @ F.TRACK + vars_basic['TRACKHASUT'] = F.VALUE_OR(-1) @ F.TRACKHASUT @ F.TRACK + vars_basic['TRACKHASVELO'] = F.VALUE_OR(-1) @ F.TRACKHASVELO @ F.TRACK vars_basic['PIDpi'] = F.PID_PI vars_basic['PIDk'] = F.PID_K vars_basic['PIDp'] = F.PID_P @@ -172,21 +180,23 @@ def get_functors(MCTRUTH, v2_pvs, rec_summary): vars_basic['PROBNNmu'] = F.PROBNN_MU vars_basic['PROBNNp'] = F.PROBNN_P vars_basic['PROBNNghost'] = F.PROBNN_GHOST - if MCTRUTH != 'None': - vars_basic['TRUEORIGINVERTEX_X'] = MCTRUTH(F.ORIGIN_VX) - vars_basic['TRUEORIGINVERTEX_Y'] = MCTRUTH(F.ORIGIN_VY) - vars_basic['TRUEORIGINVERTEX_Z'] = MCTRUTH(F.ORIGIN_VZ) + if MCTRUTH != 'None': vars_basic += FC.MCVertexInfo(mctruth_alg = MCTRUTH) #variables for event - evt_vars = FunctorCollection() - #evt_vars['ALLPV_X[pv_indx]'] = F.ALLPVX(v2_pvs) - #evt_vars['ALLPV_Y[pv_indx]'] = F.ALLPVY(v2_pvs) - #evt_vars['ALLPV_Z[pv_indx]'] = F.ALLPVZ(v2_pvs) - #evt_vars['ALLPV_CHI2[pv_indx]'] = ALLPV_CHI2(v2_pvs) - #evt_vars['ALLPV_CHI2DOF[pv_indx]']= ALLPV_CHI2DOF(v2_pvs) - evt_vars['nTracks'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nTracks") - evt_vars['nLongTracks'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nLongTracks") - evt_vars['nPVs'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nPVs") + #Collection includes tis_tos, nPVs,nHits/clusters,BUNCHCROSSING and GPS var + evt_collections = [ + FC.EventInfo(), + FC.SelectionInfo(selection_type="Hlt2", trigger_lines=[line.replace("Spruce","HLT2")]), + FC.RecSummary(), + ] + evt_vars = FunctorCollection({}) + evt_vars['ALLPV_X[pv_indx]'] = F.ALLPVX(v2_pvs) + evt_vars['ALLPV_Y[pv_indx]'] = F.ALLPVY(v2_pvs) + evt_vars['ALLPV_Z[pv_indx]'] = F.ALLPVZ(v2_pvs) + evt_vars['ALLPV_CHI2[pv_indx]'] = ALLPV_CHI2(v2_pvs) + evt_vars['ALLPV_CHI2DOF[pv_indx]']= ALLPV_CHI2DOF(v2_pvs) + + for coll in evt_collections:evt_vars += coll vars_brems = FunctorCollection({}) vars_brems.update({"HASBREM": F.HASBREM}) @@ -208,6 +218,7 @@ def get_functors(MCTRUTH, v2_pvs, rec_summary): vars_brems.update({"BREMHYPODELTAX": F.BREMHYPODELTAX}) #vars_brems.update({"BREMTRACKBASEDENERGY": F.BREMTRACKBASEDENERGY}) vars_brems.update({"INBREM": F.INBREM}) + vars_brems.update({"INECAL": F.INECAL}) vars_brems.update({"PT_WITH_BREM": F.PT_WITH_BREM}) vars_brems.update({"P_WITH_BREM": F.P_WITH_BREM}) @@ -236,9 +247,9 @@ def get_fitting_variable(v2_pvs,D0,lep): vars_fitting['lep_E_Brest'] = (B_Lorentz[0][0]*lep_4P[3]+B_Lorentz[0][1]*lep_4P[0]+B_Lorentz[0][2]*lep_4P[1]+B_Lorentz[0][3]*lep_4P[2]) return(vars_fitting) -def tuple_Bst(Bst,lepton, MCTRUTH, v2_pvs, rec_summary): +def tuple_Bst(Bst,lepton,line, MCTRUTH, v2_pvs, rec_summary): #get functors - functors = get_functors(MCTRUTH, v2_pvs, rec_summary) + functors = get_functors(MCTRUTH, v2_pvs, rec_summary,line) vars_common = functors[0] vars_composite = functors[1] vars_basic = functors[2] @@ -254,23 +265,23 @@ def tuple_Bst(Bst,lepton, MCTRUTH, v2_pvs, rec_summary): bpv_pi = F.BPV(v2_pvs).bind(Epi_child) #diff in vtx chi2 with and without extra particle vars_Bst['DELTA_ENDVERTEX_CHI2'] = (F.CHI2 @ F.ENDVERTEX) - (F.CHI2 @ F.ENDVERTEX.bind(B_child)) - #IP and IPChi2 of extra particle wrt to Sb end vertex - vars_Bst['Epi_IP_WRT_SbENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ F.FORWARDARG0 , Epi_child) - vars_Bst['Epi_IPCHI2_WRT_SbENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ F.FORWARDARG0 , Epi_child) - #IP and IPChi2 of extra particle wrt to Lb end vertex - vars_Bst['Epi_IP_WRT_LbENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ B_child , Epi_child) + #IP and IPChi2 of extra particle wrt to B0 end vertex + vars_Bst['Epi_IP_WRT_B0ENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ F.FORWARDARG0 , Epi_child) + vars_Bst['Epi_IPCHI2_WRT_B0ENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ F.FORWARDARG0 , Epi_child) + #IP and IPChi2 of extra particle wrt to Bm end vertex + vars_Bst['Epi_IP_WRT_BmENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ B_child , Epi_child) vars_Bst['Epi_IPCHI2_WRT_LbENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ B_child , Epi_child) - #angle between extra particle and Lb - vars_Bst['Epi_COSANGLE_Lb'] = F.COSANGLE.bind(F.THREEMOMENTUM @ B_child, F.THREEMOMENTUM @ Epi_child) + #angle between extra particle and Bm + vars_Bst['Epi_COSANGLE_Bm'] = F.COSANGLE.bind(F.THREEMOMENTUM @ B_child, F.THREEMOMENTUM @ Epi_child) #diff in fd chi2 with and without extra particle vars_Bst['Delta_BPV_of_Epi_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi, F.FORWARDARGS) - F.VTX_FDCHI2.bind(bpv_pi, B_child) vars_Bst['BPV_of_Epi_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi, F.FORWARDARGS) - #IP chi2 of extra particle wrt PV and SV of Sb - vars_Bst['Epi_IP_WRT_SbBPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child) - vars_Bst['Epi_IPCHI2_WRT_SbBPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child) - #IP chi2 of extra particle wrt PV and SV of Bb - vars_Bst['Epi_IP_WRT_LbBPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ B_child, Epi_child) - vars_Bst['Epi_IPCHI2_WRT_LbBPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ B_child, Epi_child) + #IP chi2 of extra particle wrt PV and SV of B0 + vars_Bst['Epi_IP_WRT_B0BPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child) + vars_Bst['Epi_IPCHI2_WRT_B0BPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child) + #IP chi2 of extra particle wrt PV and SV of Bm + vars_Bst['Epi_IP_WRT_BmBPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ B_child, Epi_child) + vars_Bst['Epi_IPCHI2_WRT_BmBPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ B_child, Epi_child) #DOCA and DOCACHI2 b/w Lb and extra particle vars_Bst['DOCA12'] = F.DOCA(1, 2) vars_Bst['DOCA12_CHI2_12'] = F.DOCACHI2(1, 2) @@ -281,9 +292,28 @@ def tuple_Bst(Bst,lepton, MCTRUTH, v2_pvs, rec_summary): vars_Bst['MTDOCACHI2_2'] = F.MTDOCACHI2(2, v2_pvs) vars_Bst['Delta_M'] = F.ABS @ ((F.MASS @ ((F.FOURMOMENTUM @ D0_child)+(F.FOURMOMENTUM @ Epi_child))) - (F.MASS @ D0_child)) vars_Bst['iso_mva'] = mva_functor_e_inclusive(v2_pvs)[0] if lepton == 'e' else mva_functor_mu_inclusive(v2_pvs)[0] + vars_Bst += trail_seeker(MCTRUTH) + + #define fields fit_vars = get_fitting_variable(v2_pvs,D0_child,Lep_child) - + #TIS and TOS + Hlt1_decisions = ['Hlt1TrackMVA', + 'Hlt1TwoTrackMVA', + 'Hlt1D2KK', + 'Hlt1D2KPi', + 'Hlt1D2PiPi', + 'Hlt1KsToPiPi', + 'Hlt1TrackMuonMVA', + 'Hlt1SingleHighPtMuon', + 'Hlt1TrackElectronMVA', + 'Hlt1SingleHighPtElectron', + 'Hlt1DiElectronDisplaced', + 'Hlt1DiPhotonHighMass', + 'Hlt1Pi02GammaGamma', + 'Hlt1DiElectronHighMass_SS', + 'Hlt1DiElectronHighMass'] + variables_tistos = FC.HltTisTos(selection_type="Hlt1", trigger_lines=Hlt1_decisions, data=Bst) #define fields fields = {} @@ -298,7 +328,7 @@ def tuple_Bst(Bst,lepton, MCTRUTH, v2_pvs, rec_summary): #add variables variables = {} variables["ALL"] = vars_common - variables["B0"] = vars_composite + vars_Bst + fit_vars + variables["B0"] = vars_composite + vars_Bst + fit_vars + variables_tistos variables["Bm"] = vars_composite variables["D0"] = vars_composite variables["Lep"] = vars_basic + vars_brems @@ -312,6 +342,7 @@ def tuple_Bst(Bst,lepton, MCTRUTH, v2_pvs, rec_summary): tuple_name="DecayTree", fields=fields, variables=variables, + event_variables=evt_vars, store_multiple_cand_info=True, inputs=Bst) @@ -348,7 +379,7 @@ def main(options: Options,line = '', lep=''): MCTRUTH_Bst = MCTruthAndBkgCat(Bst, name='MCTRUTH_Bst') - tuple_file = tuple_Bst(Bst,lep, MCTRUTH_Bst, v2_pvs, rec_summary) + tuple_file = tuple_Bst(Bst,lep,line, MCTRUTH_Bst, v2_pvs, rec_summary) #define algorithms user_algorithms = {} @@ -356,15 +387,30 @@ def main(options: Options,line = '', lep=''): return make_config(options, user_algorithms) +def test(options: Options): + return main(options=options, line='Hlt2_Test_line',lep='e') + def SLB_BuToD0ENu_D0ToKPi(options: Options): return main(options=options, line='SpruceSLB_BToDzl',lep='e') +def SLB_BuToDststENu(options: Options): + return main(options=options, line='SpruceSLB_BToDzl',lep='e') + +def SLB_BdToDststENu(options: Options): + return main(options=options, line='SpruceSLB_BToDzl',lep='e') + def SLB_BuToD0MuNu_D0ToKPi(options: Options): return main(options=options, line='SpruceSLB_BuToD0MuNu_D0ToKPi',lep='mu') def SLB_BuToD0TauNu_D0ToKPi_TauToENuNu(options: Options): return main(options=options, line='SpruceSLB_BToDzl',lep='e') +def SLB_BuToDststTauNu_TauToENuNu(options: Options): + return main(options=options, line='SpruceSLB_BToDzl',lep='e') + +def SLB_BdToDststTauNu_TauToENuNu(options: Options): + return main(options=options, line='SpruceSLB_BToDzl',lep='e') + def SLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu(options: Options): return main(options=options, line='SpruceSLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu',lep='mu') diff --git a/SL_l_nu_D0toKpi_Run3_MC/Hlt2.py b/SL_l_nu_D0toKpi_Run3_MC/Hlt2.py index c7133e1dac..8361952e5f 100644 --- a/SL_l_nu_D0toKpi_Run3_MC/Hlt2.py +++ b/SL_l_nu_D0toKpi_Run3_MC/Hlt2.py @@ -111,6 +111,16 @@ def SLB_BuToD0ENu_D0ToKPi(options: Options): config = run_moore(options, make_streams=make_lines_e, public_tools=[stateProvider_with_simplified_geom()]) return config +def SLB_BuToDststENu(options: Options): + with reconstruction.bind(from_file=False): + config = run_moore(options, make_streams=make_lines_e, public_tools=[stateProvider_with_simplified_geom()]) + return config + +def SLB_BdToDststENu(options: Options): + with reconstruction.bind(from_file=False): + config = run_moore(options, make_streams=make_lines_e, public_tools=[stateProvider_with_simplified_geom()]) + return config + def SLB_BuToD0MuNu_D0ToKPi(options: Options): with reconstruction.bind(from_file=False): config = run_moore(options, make_streams=make_lines_mu, public_tools=[stateProvider_with_simplified_geom()]) @@ -121,6 +131,16 @@ def SLB_BuToD0TauNu_D0ToKPi_TauToENuNu(options: Options): config = run_moore(options, make_streams=make_lines_e, public_tools=[stateProvider_with_simplified_geom()]) return config +def SLB_BuToDststTauNu_TauToENuNu(options: Options): + with reconstruction.bind(from_file=False): + config = run_moore(options, make_streams=make_lines_e, public_tools=[stateProvider_with_simplified_geom()]) + return config + +def SLB_BdToDststTauNu_TauToENuNu(options: Options): + with reconstruction.bind(from_file=False): + config = run_moore(options, make_streams=make_lines_e, public_tools=[stateProvider_with_simplified_geom()]) + return config + def SLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu(options: Options): with reconstruction.bind(from_file=False): config = run_moore(options, make_streams=make_lines_taumu, public_tools=[stateProvider_with_simplified_geom()]) diff --git a/SL_l_nu_D0toKpi_Run3_MC/MC_Matcher.py b/SL_l_nu_D0toKpi_Run3_MC/MC_Matcher.py new file mode 100644 index 0000000000..e3b279805b --- /dev/null +++ b/SL_l_nu_D0toKpi_Run3_MC/MC_Matcher.py @@ -0,0 +1,26 @@ +from FunTuple import FunctorCollection +import Functors as F +def trail_seeker(MCTRUTH): + mcMatch = lambda decay_descriptor: (F.HAS_VALUE @ MCTRUTH(F.FIND_MCDECAY(decay_descriptor))) + mcMatch_both = lambda decay_descriptor1,decay_descriptor2: (F.HAS_VALUE @ MCTRUTH(F.FIND_MCDECAY(decay_descriptor1))+F.HAS_VALUE @ MCTRUTH(F.FIND_MCDECAY(decay_descriptor2))) + + variables = FunctorCollection({ + 'IS_Dtaunu':mcMatch_both("[B0 -> D*(2010)- tau+ nu_tau]CC","[B~0 -> D*(2010)- tau+ nu_tau]CC"), + 'IS_Denu':mcMatch_both("[B0 -> D*(2010)- e+ nu_e]CC","[B~0 -> D*(2010)- e+ nu_e]CC"), + 'IS_Dstar_2460enu':mcMatch_both("[B0 -> D*(2640)- e+ nu_e]CC","[B~0 -> D*(2640)- e+ nu_e]CC"), + 'IS_D_2Senu':mcMatch_both("[B0 -> D(2S)- e+ nu_e]CC","[B~0 -> D(2S)- e+ nu_e]CC"), + 'IS_Dstar_2460_2enu':mcMatch_both("[B0 -> D*_2(2460)- e+ nu_e]CC","[B~0 -> D*_2(2460)- e+ nu_e]CC"), + 'IS_D_2460_1enu':mcMatch_both("[B0 -> D_1(2420)- e+ nu_e]CC","[B~0 -> D_1(2420)- e+ nu_e]CC"), + 'IS_Dstar_0taunu':mcMatch_both("[B0 -> D*_0- tau+ nu_tau]CC","[B~0 -> D*_0- tau+ nu_tau]CC"), + 'IS_D_H_1taunu':mcMatch_both("[B0 -> D_1(H)- tau+ nu_tau]CC","[B~0 -> D_1(H)- tau+ nu_tau]CC"), + 'IS_D_2420_1taunu':mcMatch_both("[B0 -> D_1(2420)- tau+ nu_tau]CC","[B~0 -> D_1(2420)- tau+ nu_tau]CC"), + 'IS_Dstar_2460_2taunu':mcMatch_both("[B0 -> D*_2(2460)- tau+ nu_tau]CC","[B~0 -> D*_2(2460)- tau+ nu_tau]CC"), + 'IS_Dstar0_2640enu':mcMatch("[B- -> D*(2640)0 e- nu_e~]CC"), + 'IS_D0_2Senu':mcMatch("[B- -> D(2S)0 e- nu_e~]CC"), + 'IS_Dstar0_2460_2enu':mcMatch("[B- -> D*_2(2460)0 e- nu_e~]CC"), + 'IS_D0_2460_1enu':mcMatch("[B- -> D_1(2420)0 e- nu_e~]CC"), + 'IS_D0_H_1taunu':mcMatch("[B- -> D_1(H)0 tau- nu_tau~]CC"), + 'IS_D0_2420_1taunu':mcMatch("[B- -> D_1(2420)0 tau- nu_tau~]CC"), + 'IS_Dstar0_2460_2taunu':mcMatch("[B- -> D*_2(2460)0 tau- nu_tau~]CC"), + }) + return(variables) diff --git a/SL_l_nu_D0toKpi_Run3_MC/Spruce.py b/SL_l_nu_D0toKpi_Run3_MC/Spruce.py index 7a10321fb5..8e11e66a60 100644 --- a/SL_l_nu_D0toKpi_Run3_MC/Spruce.py +++ b/SL_l_nu_D0toKpi_Run3_MC/Spruce.py @@ -32,28 +32,26 @@ def make_lines_e(): return [spruce_lines()] def make_lines_taumu(): - def spruce_lines(name='SpruceSLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu',prescale=1): - line_alg = make_butod0taunu_d0tokpi_tautolnunu(process='spruce', lepton="mu") - return SpruceLine(name=name, hlt2_filter_code=[ - f"{name.replace('Spruce','Hlt2')}Decision", - "Hlt2Topo2BodyDecision", "Hlt2Topo3BodyDecision"] - ,prescale=prescale,persistreco=True, algs=sl_line_prefilter() + [line_alg]) - return [spruce_lines()] + return [spruce_butod0taunu_d0tokpi_tautomununu_line()] def make_lines_mu(): - def spruce_lines(name="SpruceSLB_BuToD0MuNu_D0ToKPi",prescale=1): - line_alg = make_butod0lnu_d0tokpi(process='spruce', lepton="mu") - return SpruceLine(name=name, hlt2_filter_code=[ - f"{name.replace('Spruce','Hlt2')}Decision", - "Hlt2Topo2BodyDecision", "Hlt2Topo3BodyDecision"] - ,prescale=prescale,persistreco=True, algs=sl_line_prefilter() + [line_alg]) - return [spruce_lines()] + return [spruce_butod0munu_d0tokpi_line()] def SLB_BuToD0ENu_D0ToKPi(options: Options): with reconstruction.bind(from_file=True, spruce=True): config = run_moore(options, make_streams=make_lines_e, public_tools=[stateProvider_with_simplified_geom()]) return config +def SLB_BuToDststENu(options: Options): + with reconstruction.bind(from_file=True, spruce=True): + config = run_moore(options, make_streams=make_lines_e, public_tools=[stateProvider_with_simplified_geom()]) + return config + +def SLB_BdToDststENu(options: Options): + with reconstruction.bind(from_file=True, spruce=True): + config = run_moore(options, make_streams=make_lines_e, public_tools=[stateProvider_with_simplified_geom()]) + return config + def SLB_BuToD0MuNu_D0ToKPi(options: Options): with reconstruction.bind(from_file=True, spruce=True): config = run_moore(options, make_streams=make_lines_mu, public_tools=[stateProvider_with_simplified_geom()]) @@ -64,6 +62,16 @@ def SLB_BuToD0TauNu_D0ToKPi_TauToENuNu(options: Options): config = run_moore(options, make_streams=make_lines_e, public_tools=[stateProvider_with_simplified_geom()]) return config +def SLB_BuToDststTauNu_TauToENuNu(options: Options): + with reconstruction.bind(from_file=True, spruce=True): + config = run_moore(options, make_streams=make_lines_e, public_tools=[stateProvider_with_simplified_geom()]) + return config + +def SLB_BdToDststTauNu_TauToENuNu(options: Options): + with reconstruction.bind(from_file=True, spruce=True): + config = run_moore(options, make_streams=make_lines_e, public_tools=[stateProvider_with_simplified_geom()]) + return config + def SLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu(options: Options): with reconstruction.bind(from_file=True, spruce=True): config = run_moore(options, make_streams=make_lines_taumu, public_tools=[stateProvider_with_simplified_geom()]) diff --git a/SL_l_nu_D0toKpi_Run3_MC/info.yaml b/SL_l_nu_D0toKpi_Run3_MC/info.yaml index 4cff9509f0..8d3007e1f6 100644 --- a/SL_l_nu_D0toKpi_Run3_MC/info.yaml +++ b/SL_l_nu_D0toKpi_Run3_MC/info.yaml @@ -4,10 +4,14 @@ defaults: wg: SL {%- set evttype_lines_and_leptons = [ - ('11584030','SLB_BuToD0ENu_D0ToKPi','e'), - ('11574020','SLB_BuToD0MuNu_D0ToKPi','muon'), - ('11584010','SLB_BuToD0TauNu_D0ToKPi_TauToENuNu','taue'), - ('11574010','SLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu','taumuon'), + ('11584030','SLB_BuToD0ENu_D0ToKPi','b0_dstp_e'), + ('11574020','SLB_BuToD0MuNu_D0ToKPi','b0_dstp_muon'), + ('11584010','SLB_BuToD0TauNu_D0ToKPi_TauToENuNu','b0_dstp_taue'), + ('11574010','SLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu','b0_dstp_taumuon'), + ('12685400','SLB_BuToDststENu','bp_dstst_e'), + ('12883000','SLB_BuToDststTauNu_TauToENuNu','bp_dstst_taue'), + ('11686000','SLB_BdToDststENu','b0_dststp_e'), + ('11883000','SLB_BdToDststTauNu_TauToENuNu','b0_dststp_taue'), ] %} {%- set polarity_variables = [ @@ -15,9 +19,9 @@ defaults: ('MagUp','sim-20231017-vc-mu100'), ]%} {%- for polarity, cond_tag in polarity_variables %} - {%- for evttype, line, lepton in evttype_lines_and_leptons %} -HLT1_b0_dstp_{{lepton}}_{{ polarity }}: - application: "Moore/v55r8@x86_64_v3-el9-gcc13+detdesc-opt+g" + {%- for evttype, line, dk in evttype_lines_and_leptons %} +HLT1_{{dk}}_{{ polarity }}: + application: "Moore/v55r7@x86_64_v3-el9-gcc13+detdesc-opt+g" input: bk_query: "/MC/Dev/Beam6800GeV-expected-2024-{{polarity}}-Nu7.6-25ns-Pythia8/Sim10c/{{evttype}}/DIGI" dq_flags: @@ -41,10 +45,10 @@ HLT1_b0_dstp_{{lepton}}_{{ polarity }}: max_buffer_size: 1048576 #evt_max: 1000 -HLT2_b0_dstp_{{lepton}}_{{ polarity }}: - application: "Moore/v55r8@x86_64_v3-el9-gcc13+detdesc-opt+g" +HLT2_{{dk}}_{{ polarity }}: + application: "Moore/v55r7p3@x86_64_v3-el9-gcc13+detdesc-opt+g" input: - job_name: HLT1_b0_dstp_{{lepton}}_{{ polarity }} + job_name: HLT1_{{dk}}_{{ polarity }} output: hlt2.dst options: entrypoint: SL_l_nu_D0toKpi_Run3_MC.Hlt2:{{line}} @@ -63,10 +67,10 @@ HLT2_b0_dstp_{{lepton}}_{{ polarity }}: level: 1 max_buffer_size: 1048576 #evt_max: 1000 -SPRUCE_b0_dstp_{{lepton}}_{{ polarity }}: - application: "Moore/v55r8@x86_64_v3-el9-gcc13+detdesc-opt+g" +SPRUCE_{{dk}}_{{ polarity }}: + application: "Moore/v55r7p3@x86_64_v3-el9-gcc13+detdesc-opt+g" input: - job_name: HLT2_b0_dstp_{{lepton}}_{{ polarity }} + job_name: HLT2_{{dk}}_{{ polarity }} output: spruce.dst options: entrypoint: SL_l_nu_D0toKpi_Run3_MC.Spruce:{{line}} @@ -87,10 +91,10 @@ SPRUCE_b0_dstp_{{lepton}}_{{ polarity }}: level: 1 max_buffer_size: 1048576 #evt_max: 1000 -DV_b0_dstp_{{lepton}}_{{ polarity }}: +DV_{{dk}}_{{ polarity }}: application: "DaVinci/v64r5@x86_64_v3-el9-gcc13+detdesc-opt+g" input: - job_name: SPRUCE_b0_dstp_{{lepton}}_{{ polarity }} + job_name: SPRUCE_{{dk}}_{{ polarity }} output: NTuple.root options: entrypoint: SL_l_nu_D0toKpi_Run3_MC.DV:{{line}} -- GitLab From 683e06ea4c2821817ab20e7b3ca5c623b59c2a4a Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Fri, 31 May 2024 14:18:18 +0200 Subject: [PATCH 34/57] Use mu iso mva for everything --- SL_l_nu_D0toKpi_Run3_MC/DV.py | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/SL_l_nu_D0toKpi_Run3_MC/DV.py b/SL_l_nu_D0toKpi_Run3_MC/DV.py index 19a333dfa6..7da86855e1 100644 --- a/SL_l_nu_D0toKpi_Run3_MC/DV.py +++ b/SL_l_nu_D0toKpi_Run3_MC/DV.py @@ -74,7 +74,7 @@ def make_Bst(B, pions,lepton, hadron_candidate_id,v2_pvs,do_truth_matching = Tru Bst = ParticleContainersMerger([Bst_1, Bst_2], name = f'Bst_combiner_{lepton}') return Bst -def get_functors(MCTRUTH, v2_pvs, rec_summary,line): +def get_functors(MCTRUTH, v2_pvs, rec_summary): #define common variables for all fields (composite and basic) vars_common = FunctorCollection() #all pvs: ip, ipchi2. The PV positions are stored in event variables @@ -186,7 +186,6 @@ def get_functors(MCTRUTH, v2_pvs, rec_summary,line): #Collection includes tis_tos, nPVs,nHits/clusters,BUNCHCROSSING and GPS var evt_collections = [ FC.EventInfo(), - FC.SelectionInfo(selection_type="Hlt2", trigger_lines=[line.replace("Spruce","HLT2")]), FC.RecSummary(), ] evt_vars = FunctorCollection({}) @@ -249,7 +248,7 @@ def get_fitting_variable(v2_pvs,D0,lep): def tuple_Bst(Bst,lepton,line, MCTRUTH, v2_pvs, rec_summary): #get functors - functors = get_functors(MCTRUTH, v2_pvs, rec_summary,line) + functors = get_functors(MCTRUTH, v2_pvs, rec_summary) vars_common = functors[0] vars_composite = functors[1] vars_basic = functors[2] @@ -291,7 +290,7 @@ def tuple_Bst(Bst,lepton,line, MCTRUTH, v2_pvs, rec_summary): vars_Bst['MTDOCACHI2_1'] = F.MTDOCACHI2(1, v2_pvs) vars_Bst['MTDOCACHI2_2'] = F.MTDOCACHI2(2, v2_pvs) vars_Bst['Delta_M'] = F.ABS @ ((F.MASS @ ((F.FOURMOMENTUM @ D0_child)+(F.FOURMOMENTUM @ Epi_child))) - (F.MASS @ D0_child)) - vars_Bst['iso_mva'] = mva_functor_e_inclusive(v2_pvs)[0] if lepton == 'e' else mva_functor_mu_inclusive(v2_pvs)[0] + vars_Bst['iso_mva'] = mva_functor_mu_inclusive(v2_pvs)[0] vars_Bst += trail_seeker(MCTRUTH) @@ -313,7 +312,14 @@ def tuple_Bst(Bst,lepton,line, MCTRUTH, v2_pvs, rec_summary): 'Hlt1Pi02GammaGamma', 'Hlt1DiElectronHighMass_SS', 'Hlt1DiElectronHighMass'] - variables_tistos = FC.HltTisTos(selection_type="Hlt1", trigger_lines=Hlt1_decisions, data=Bst) + variables_tistos_hlt1 = FC.HltTisTos(selection_type="Hlt1", trigger_lines=Hlt1_decisions, data=Bst) + evt_vars += FC.SelectionInfo(selection_type="Hlt1", trigger_lines=Hlt1_decisions) + + + Hlt2_decisions = ['Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision'] + variables_tistos_hlt2 = FC.HltTisTos(selection_type="Hlt2", trigger_lines=Hlt2_decisions, data=Bst) + evt_vars += FC.SelectionInfo(selection_type="Hlt2", trigger_lines=Hlt2_decisions) + #define fields fields = {} @@ -327,8 +333,8 @@ def tuple_Bst(Bst,lepton,line, MCTRUTH, v2_pvs, rec_summary): #add variables variables = {} - variables["ALL"] = vars_common - variables["B0"] = vars_composite + vars_Bst + fit_vars + variables_tistos + variables["ALL"] = vars_common + variables_tistos_hlt1 + variables_tistos_hlt2 + variables["B0"] = vars_composite + vars_Bst + fit_vars variables["Bm"] = vars_composite variables["D0"] = vars_composite variables["Lep"] = vars_basic + vars_brems @@ -369,6 +375,7 @@ def main(options: Options,line = '', lep=''): #get data and extra particles lb = get_particles(f"/Event/Spruce/{line}/Particles") extra_particles = get_extra_pions() + #extra_particles = get_particles(f"/Event/Spruce/{line}/{line}_extra_tracks/Particles") #get v2_pvs and rec_summary v2_pvs = get_pvs() -- GitLab From af2d722720a9e2b9797d3f100e2d80219d61e21d Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Thu, 6 Jun 2024 11:04:51 +0200 Subject: [PATCH 35/57] Edit comments in Hlt2 cuts --- SL_l_nu_D0toKpi_Run3_MC/Hlt2.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/SL_l_nu_D0toKpi_Run3_MC/Hlt2.py b/SL_l_nu_D0toKpi_Run3_MC/Hlt2.py index 8361952e5f..f2dffdd01d 100644 --- a/SL_l_nu_D0toKpi_Run3_MC/Hlt2.py +++ b/SL_l_nu_D0toKpi_Run3_MC/Hlt2.py @@ -41,25 +41,25 @@ def get_charm_cuts(): make_d0tokpi_cuts['comb_m_min'] = (CHARM_MASS - delta_mass) * MeV make_d0tokpi_cuts['comb_m_max'] = (CHARM_MASS + delta_mass) * MeV make_d0tokpi_cuts['comb_docachi2_max'] = 5. - make_d0tokpi_cuts['vchi2pdof_max'] = 6 #6 (2024) 6/4 (master e/taue) - make_d0tokpi_cuts['bpvfdchi2_min'] = 25 #25 (2024) - make_d0tokpi_cuts['bpvdira_min'] = 0.99 #0.99 (2024) 0.99/0.999 (master e/taue) - make_d0tokpi_cuts['comb_pt_min'] = None #None (2024) None/2000 * MeV (master e/taue) - make_d0tokpi_cuts['comb_pt_any_min'] = None #None (2024) None/800 * MeV (master e/taue) - make_d0tokpi_cuts['comb_pt_sum_min'] = None #None (2024) None/2.5 * GeV (master e/taue) - make_d0tokpi_cuts['comb_doca_max'] = None #None (2024) None/0.1 mm (master e/taue) - make_d0tokpi_cuts['daughter_pt_min'] = 600 * MeV #600 * MeV (2024) 750 * MeV (master) - make_d0tokpi_cuts['daughter_mipchi2_min'] = 9. #10. (2024) 10./9. (master e/taue) - make_d0tokpi_cuts['kaon_pid'] = (F.PID_K > 0.) #(F.PID_K > 0.) (2024) (F.PID_K > 4.) (master) + make_d0tokpi_cuts['vchi2pdof_max'] = 6 #6 (Now) 6/4 (v55r7 e/taue) + make_d0tokpi_cuts['bpvfdchi2_min'] = 25 #25 (Now) + make_d0tokpi_cuts['bpvdira_min'] = 0.99 #0.99 (Now) 0.99/0.999 (v55r7 e/taue) + make_d0tokpi_cuts['comb_pt_min'] = None #None (Now) None/2000 * MeV (v55r7 e/taue) + make_d0tokpi_cuts['comb_pt_any_min'] = None #None (Now) None/800 * MeV (v55r7 e/taue) + make_d0tokpi_cuts['comb_pt_sum_min'] = None #None (Now) None/2.5 * GeV (v55r7 e/taue) + make_d0tokpi_cuts['comb_doca_max'] = None #None (Now) None/0.1 mm (v55r7 e/taue) + make_d0tokpi_cuts['daughter_pt_min'] = 600 * MeV #600 * MeV (Now) 750 * MeV (v55r7) + make_d0tokpi_cuts['daughter_mipchi2_min'] = 9. #10. (Now) 10./9. (v55r7 e/taue) + make_d0tokpi_cuts['kaon_pid'] = (F.PID_K > 0.) #(F.PID_K > 0.) (Now) (F.PID_K > 4.) (v55r7) make_d0tokpi_cuts['pion_pid'] = (F.PID_K < 2.) return make_d0tokpi_cuts def get_electron_cuts(): #make loose cuts for electron and tauonic muon make_electron_cuts = {} - make_electron_cuts["p_min"] = 3. * GeV #3. * GeV (2024) 5. *GeV (master) - make_electron_cuts["pt_min"] = 300. * MeV #300. * MeV (2024) 500. * MeV (master) - make_electron_cuts["mipchi2_min"] = 9. #9. (2024) 9./16. (master e/taue) + make_electron_cuts["p_min"] = 3. * GeV #3. * GeV (Now) 5. *GeV (v55r7) + make_electron_cuts["pt_min"] = 300. * MeV #300. * MeV (Now) 500. * MeV (v55r7) + make_electron_cuts["mipchi2_min"] = 9. #9. (Now) 9./16. (v55r7 e/taue) make_electron_cuts["mip_min"] = None #0. make_electron_cuts["pid"] = (F.PID_E > 0.0) make_electron_cuts["make_particles"] = make_long_electrons_with_brem #does not require in calo -- GitLab From b33f7909f5383c1bb6dca5b5e861cb4047b6b02f Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Thu, 13 Jun 2024 13:44:04 +0200 Subject: [PATCH 36/57] Fix tis_tos issue --- SL_l_nu_D0toKpi_Run3_MC/DV.py | 38 ++++++--- SL_l_nu_D0toKpi_Run3_MC/Hlt1.py | 16 +--- SL_l_nu_D0toKpi_Run3_MC/Hlt2.py | 136 ++++++++++++++++-------------- SL_l_nu_D0toKpi_Run3_MC/Spruce.py | 94 ++++++++------------- SL_l_nu_D0toKpi_Run3_MC/info.yaml | 12 +-- 5 files changed, 144 insertions(+), 152 deletions(-) diff --git a/SL_l_nu_D0toKpi_Run3_MC/DV.py b/SL_l_nu_D0toKpi_Run3_MC/DV.py index 7da86855e1..216f7e7f3d 100644 --- a/SL_l_nu_D0toKpi_Run3_MC/DV.py +++ b/SL_l_nu_D0toKpi_Run3_MC/DV.py @@ -147,7 +147,7 @@ def get_functors(MCTRUTH, v2_pvs, rec_summary): #mc composite vertex information if MCTRUTH != 'None': vars_composite += FC.MCVertexInfo(mctruth_alg = MCTRUTH) #Compute maximum DOCA and maximum DOCACHI2. Since there are - # only two daughters of Sb particles, the maximum DOCA/DOCACHI2 is + # only two daughters of B0 particles, the maximum DOCA/DOCACHI2 is # the DOCA/DOCACHI2 see below. vars_composite['MAX_DOCA'] = F.MAXDOCA vars_composite['MAX_DOCACHI2'] = F.MAXDOCACHI2 @@ -255,7 +255,7 @@ def tuple_Bst(Bst,lepton,line, MCTRUTH, v2_pvs, rec_summary): evt_vars = functors[3] vars_brems = functors[4] - #variables for Sb field + #variables for B0 field vars_Bst = FunctorCollection() B_child = F.CHILD(1, F.FORWARDARG0) D0_child = F.CHILD(1, F.CHILD(1,F.FORWARDARG0)) @@ -286,7 +286,7 @@ def tuple_Bst(Bst,lepton,line, MCTRUTH, v2_pvs, rec_summary): vars_Bst['DOCA12_CHI2_12'] = F.DOCACHI2(1, 2) #vars_Bst['SDOCA12'] = F.SDOCA(1, 2) #vars_Bst['SDOCA_CHI2_12'] = F.SDOCACHI2(1, 2) - #DOCACHI2 of extra particle wrt to mother i.e. Sb + #DOCACHI2 of extra particle wrt to mother i.e. B0 vars_Bst['MTDOCACHI2_1'] = F.MTDOCACHI2(1, v2_pvs) vars_Bst['MTDOCACHI2_2'] = F.MTDOCACHI2(2, v2_pvs) vars_Bst['Delta_M'] = F.ABS @ ((F.MASS @ ((F.FOURMOMENTUM @ D0_child)+(F.FOURMOMENTUM @ Epi_child))) - (F.MASS @ D0_child)) @@ -315,8 +315,20 @@ def tuple_Bst(Bst,lepton,line, MCTRUTH, v2_pvs, rec_summary): variables_tistos_hlt1 = FC.HltTisTos(selection_type="Hlt1", trigger_lines=Hlt1_decisions, data=Bst) evt_vars += FC.SelectionInfo(selection_type="Hlt1", trigger_lines=Hlt1_decisions) + Hlt2_decisions = ['Hlt2SLB_BuToD0MuNu_D0ToKPi', + 'Hlt2SLB_BuToD0MuNu_D0ToKPi_FakeMuon', + 'Hlt2SLB_BuToD0ENu_D0ToKPi', + 'Hlt2SLB_BuToD0ENu_D0ToKPi_FakeElectron', + 'Hlt2SLB_B0ToDpTauNu_DpToKPiPi_TauToENuNu', + 'Hlt2SLB_B0ToDpTauNu_DpToKPiPi_TauToMuNuNu', + 'Hlt2SLB_BuToD0TauNu_D0ToKPi_TauToENuNu', + 'Hlt2SLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu', + 'Hlt2SLB_BuToD0TauNu_D0ToKPi_FakeMuon', + 'Hlt2SLB_BuToD0TauNu_D0ToKPi_FakeElectron', + 'Hlt2SLB_myBuToD0ENu_D0ToKPi', + 'Hlt2Topo2Body', + 'Hlt2Topo3Body'] - Hlt2_decisions = ['Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision'] variables_tistos_hlt2 = FC.HltTisTos(selection_type="Hlt2", trigger_lines=Hlt2_decisions, data=Bst) evt_vars += FC.SelectionInfo(selection_type="Hlt2", trigger_lines=Hlt2_decisions) @@ -373,7 +385,7 @@ def main(options: Options,line = '', lep=''): my_filter = create_lines_filter(name="Filter", lines=[line]) #get data and extra particles - lb = get_particles(f"/Event/Spruce/{line}/Particles") + Bm = get_particles(f"/Event/Spruce/{line}/Particles") extra_particles = get_extra_pions() #extra_particles = get_particles(f"/Event/Spruce/{line}/{line}_extra_tracks/Particles") @@ -381,8 +393,8 @@ def main(options: Options,line = '', lep=''): v2_pvs = get_pvs() rec_summary = get_rec_summary() hadron_candidate_id = 421 - #make sb candidate - Bst = make_Bst(lb, extra_particles,lep,hadron_candidate_id,v2_pvs,False) + #make B0 candidate + Bst = make_Bst(Bm, extra_particles,lep,hadron_candidate_id,v2_pvs,False) MCTRUTH_Bst = MCTruthAndBkgCat(Bst, name='MCTRUTH_Bst') @@ -398,25 +410,25 @@ def test(options: Options): return main(options=options, line='Hlt2_Test_line',lep='e') def SLB_BuToD0ENu_D0ToKPi(options: Options): - return main(options=options, line='SpruceSLB_BToDzl',lep='e') + return main(options=options, line='SpruceSLB_myBuToD0ENu_D0ToKPi',lep='e') def SLB_BuToDststENu(options: Options): - return main(options=options, line='SpruceSLB_BToDzl',lep='e') + return main(options=options, line='SpruceSLB_myBuToD0ENu_D0ToKPi',lep='e') def SLB_BdToDststENu(options: Options): - return main(options=options, line='SpruceSLB_BToDzl',lep='e') + return main(options=options, line='SpruceSLB_myBuToD0ENu_D0ToKPi',lep='e') def SLB_BuToD0MuNu_D0ToKPi(options: Options): return main(options=options, line='SpruceSLB_BuToD0MuNu_D0ToKPi',lep='mu') def SLB_BuToD0TauNu_D0ToKPi_TauToENuNu(options: Options): - return main(options=options, line='SpruceSLB_BToDzl',lep='e') + return main(options=options, line='SpruceSLB_myBuToD0ENu_D0ToKPi',lep='e') def SLB_BuToDststTauNu_TauToENuNu(options: Options): - return main(options=options, line='SpruceSLB_BToDzl',lep='e') + return main(options=options, line='SpruceSLB_myBuToD0ENu_D0ToKPi',lep='e') def SLB_BdToDststTauNu_TauToENuNu(options: Options): - return main(options=options, line='SpruceSLB_BToDzl',lep='e') + return main(options=options, line='SpruceSLB_myBuToD0ENu_D0ToKPi',lep='e') def SLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu(options: Options): return main(options=options, line='SpruceSLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu',lep='mu') diff --git a/SL_l_nu_D0toKpi_Run3_MC/Hlt1.py b/SL_l_nu_D0toKpi_Run3_MC/Hlt1.py index e2d0622696..eeabcc4913 100644 --- a/SL_l_nu_D0toKpi_Run3_MC/Hlt1.py +++ b/SL_l_nu_D0toKpi_Run3_MC/Hlt1.py @@ -9,18 +9,10 @@ # or submit itself to any jurisdiction. # ############################################################################### from Moore import Options -from Moore.config import allen_control_flow -from RecoConf.hlt1_allen import allen_gaudi_config, get_allen_line_names -from PyConf.application import configure_input, configure -from RecoConf.muonid import make_muon_hits -#need to bind geometry version to 3 for muon hits -make_muon_hits.global_bind(geometry_version=3) +from Moore.config import run_allen +from RecoConf.hlt1_allen import allen_gaudi_config as allen_sequence def main(options: Options): - config = configure_input(options) - with allen_gaudi_config.bind(sequence="hlt1_pp_matching_no_ut_1000KHz"): - allen_node = allen_control_flow(options) - config.update(configure(options, allen_node)) - return config - + with allen_sequence.bind(sequence="hlt1_pp_matching_no_ut_1000KHz"): + return run_allen(options) diff --git a/SL_l_nu_D0toKpi_Run3_MC/Hlt2.py b/SL_l_nu_D0toKpi_Run3_MC/Hlt2.py index f2dffdd01d..40ddb823ea 100644 --- a/SL_l_nu_D0toKpi_Run3_MC/Hlt2.py +++ b/SL_l_nu_D0toKpi_Run3_MC/Hlt2.py @@ -8,6 +8,9 @@ # granted to it by virtue of its status as an Intergovernmental Organization # # or submit itself to any jurisdiction. # ############################################################################### +""" +Stolen and adapted from Hlt/Hlt2Conf/options/hlt2_pp_expected_24_without_UT.py from v55r7. +""" from Moore import Options,options, run_moore, config from Hlt2Conf.algorithms_thor import ParticleContainersMerger from Hlt2Conf.lines.semileptonic.builders import sl_line_prefilter @@ -15,10 +18,22 @@ from Hlt2Conf.lines.semileptonic.builders.base_builder import make_candidate from Hlt2Conf.lines.semileptonic.builders.charm_hadron_builder import make_d0_tokpi from GaudiKernel.SystemOfUnits import MeV, GeV,mm from Hlt2Conf.algorithms_thor import ParticleCombiner -from Moore.config import Hlt2Line -from RecoConf.global_tools import stateProvider_with_simplified_geom +from Hlt2Conf.settings.defaults import get_default_hlt1_filter_code_for_hlt2 +from Hlt2Conf.lines.semileptonic import all_lines as slb_lines +from Hlt2Conf.lines.topological_b import all_lines as topo_lines +from Moore.config import Hlt2Line,register_line_builder +from Moore.streams import Stream, Streams, DETECTORS +from RecoConf.event_filters import require_gec +from RecoConf.global_tools import stateProvider_with_simplified_geom, trackMasterExtrapolator_with_simplified_geom +from RecoConf.hlt2_global_reco import reconstruction as hlt2_reconstruction, make_light_reco_pr_kf_without_UT from RecoConf.reconstruction_objects import reconstruction,make_pvs -from RecoConf.decoders import default_ft_decoding_version +from RecoConf.decoders import default_ft_decoding_version,default_VeloCluster_source +from RecoConf.hlt2_tracking import ( + make_TrackBestTrackCreator_tracks, + make_PrKalmanFilter_noUT_tracks, + make_PrKalmanFilter_Velo_tracks, + make_PrKalmanFilter_Seed_tracks, +) from Hlt2Conf.standard_particles import ( make_long_electrons_with_brem, make_has_rich_long_pions, @@ -26,10 +41,11 @@ from Hlt2Conf.standard_particles import ( make_has_rich_down_pions) import Functors as F from Functors.math import in_range +import sys #things to control SUFFIX_NAME = '_BToDzl' -HLT2LINE = f'Hlt2SLB{SUFFIX_NAME}' +HLT2LINE = f'Hlt2SLB_myBuToD0ENu_D0ToKPi' CHARM_MASS = 1864.84 #D0 mass CHARM_BUILDER_NAME = 'Dz2KPi_combiner' B_BUILDER_NAME = 'BToDzl_combiner' @@ -80,68 +96,60 @@ def make_b(): name=f'rs_{B_BUILDER_NAME}_e', DecayDescriptor='[B- -> D0 e-]cc', CombinationCut=F.ALL, - CompositeCut=cut_vertex, - ParticleCombiner="ParticleVertexFitter") + CompositeCut=cut_vertex) + ws_btodze = ParticleCombiner( Inputs=[dzs, electrons], name=f'ws_{B_BUILDER_NAME}_e', DecayDescriptor='[B+ -> D0 e+]cc', CombinationCut=F.ALL, - CompositeCut=cut_vertex, - ParticleCombiner="ParticleVertexFitter") - return ParticleContainersMerger([rs_btodze,ws_btodze], name = B_BUILDER_NAME) - -from Hlt2Conf.lines.semileptonic.hlt2_semileptonic import hlt2_butod0munu_d0tokpi_line,hlt2_butod0taunu_d0tokpi_tautomununu_line - -def make_lines_e(): - def hlt2_lines(name=HLT2LINE,prescale=1): - Bcands = make_b() - return Hlt2Line(name=name, prescale=prescale,persistreco=True, algs=sl_line_prefilter() + [Bcands]) - lines = [hlt2_lines()] - return lines - -def make_lines_mu(): - return [hlt2_butod0munu_d0tokpi_line()] - -def make_lines_taumu(): - return [hlt2_butod0taunu_d0tokpi_tautomununu_line()] - -def SLB_BuToD0ENu_D0ToKPi(options: Options): - with reconstruction.bind(from_file=False): - config = run_moore(options, make_streams=make_lines_e, public_tools=[stateProvider_with_simplified_geom()]) - return config - -def SLB_BuToDststENu(options: Options): - with reconstruction.bind(from_file=False): - config = run_moore(options, make_streams=make_lines_e, public_tools=[stateProvider_with_simplified_geom()]) - return config - -def SLB_BdToDststENu(options: Options): - with reconstruction.bind(from_file=False): - config = run_moore(options, make_streams=make_lines_e, public_tools=[stateProvider_with_simplified_geom()]) - return config - -def SLB_BuToD0MuNu_D0ToKPi(options: Options): - with reconstruction.bind(from_file=False): - config = run_moore(options, make_streams=make_lines_mu, public_tools=[stateProvider_with_simplified_geom()]) - return config - -def SLB_BuToD0TauNu_D0ToKPi_TauToENuNu(options: Options): - with reconstruction.bind(from_file=False): - config = run_moore(options, make_streams=make_lines_e, public_tools=[stateProvider_with_simplified_geom()]) - return config - -def SLB_BuToDststTauNu_TauToENuNu(options: Options): - with reconstruction.bind(from_file=False): - config = run_moore(options, make_streams=make_lines_e, public_tools=[stateProvider_with_simplified_geom()]) - return config - -def SLB_BdToDststTauNu_TauToENuNu(options: Options): - with reconstruction.bind(from_file=False): - config = run_moore(options, make_streams=make_lines_e, public_tools=[stateProvider_with_simplified_geom()]) - return config - -def SLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu(options: Options): - with reconstruction.bind(from_file=False): - config = run_moore(options, make_streams=make_lines_taumu, public_tools=[stateProvider_with_simplified_geom()]) - return config + CompositeCut=cut_vertex) + + return ParticleContainersMerger([rs_btodze,ws_btodze]) + +@register_line_builder(slb_lines) +def hlt2_mybutod0enu_d0tokpi_line(name=HLT2LINE,prescale=1): + Bcands = make_b() + return Hlt2Line(name=name, prescale=prescale,persistreco=True, algs=sl_line_prefilter() + [Bcands]) + +def pass_through_line(name="Hlt2Passthrough"): + """Return a HLT2 line that performs no selection but runs and persists the reconstruction + """ + return Hlt2Line(name=name, prescale=1, algs=[], persistreco=True) + +from Hlt2Conf.lines.topological_b import * + +def _make_lines(): + ret = [] + for line_dict in [slb_lines]: + for line_name, builder in line_dict.items() : + if "D0ToKPi" in line_name and "TauToPiPiPi" not in line_name and "Bc" not in line_name: + print(line_name) + ret.append(builder()) + ret += [twobody_line(),threebody_line(),pass_through_line()] + return ret + +def make_streams(): + streams = [ + Stream(lines=_make_lines(), routing_bit=98, detectors=DETECTORS) + ] + return Streams(streams=streams) + +public_tools = [ + trackMasterExtrapolator_with_simplified_geom(), + stateProvider_with_simplified_geom(), +] + +def main(options: Options): + # NOTE: the TBTC does not apply a chi2 cut because it is applied by the PrKF + with reconstruction.bind(from_file=False),\ + hlt2_reconstruction.bind(make_reconstruction=make_light_reco_pr_kf_without_UT),\ + require_gec.bind(skipUT=True),\ + default_VeloCluster_source.bind(bank_type="VPRetinaCluster"),\ + make_TrackBestTrackCreator_tracks.bind(max_ghost_prob=0.7, max_chi2ndof=sys.float_info.max),\ + make_PrKalmanFilter_Velo_tracks.bind(max_chi2ndof=5.),\ + make_PrKalmanFilter_noUT_tracks.bind(max_chi2ndof=4.),\ + make_PrKalmanFilter_Seed_tracks.bind(max_chi2ndof=6.),\ + get_default_hlt1_filter_code_for_hlt2.bind(code=r"Hlt1(?!PassthroughLargeEvent).*Decision"): + return run_moore(options, make_streams, public_tools=[]) + diff --git a/SL_l_nu_D0toKpi_Run3_MC/Spruce.py b/SL_l_nu_D0toKpi_Run3_MC/Spruce.py index 8e11e66a60..964714aba8 100644 --- a/SL_l_nu_D0toKpi_Run3_MC/Spruce.py +++ b/SL_l_nu_D0toKpi_Run3_MC/Spruce.py @@ -11,68 +11,48 @@ #Example follows from hlt2_with_hlt1_decision.py from Moore import Options,options, run_moore, config from Hlt2Conf.lines.semileptonic.builders import sl_line_prefilter -from Moore.config import SpruceLine +from Moore.config import SpruceLine,register_line_builder from .Hlt2 import make_b +from Moore.streams import DETECTORS, Stream, Streams from PyConf.application import configure_input, configure, default_raw_event from RecoConf.global_tools import stateProvider_with_simplified_geom from RecoConf.reconstruction_objects import reconstruction +from PyConf.reading import reconstruction as reco_spruce, upfront_reconstruction as upfront_spruce from RecoConf.decoders import default_ft_decoding_version -from RecoConf.hlt2_global_reco import reconstruction as hlt2_reconstruction, make_fastest_reconstruction from Hlt2Conf.lines.semileptonic.spruce_semileptonic import spruce_butod0munu_d0tokpi_line,spruce_butod0taunu_d0tokpi_tautomununu_line from Hlt2Conf.lines.semileptonic.HbToHcTauNu_TauToLNuNu import make_butod0taunu_d0tokpi_tautolnunu from Hlt2Conf.lines.semileptonic.HbToHcLNu import make_butod0lnu_d0tokpi - -def make_lines_e(): - def spruce_lines(name='SpruceSLB_BToDzl',prescale=1): - Bcands = make_b() - return SpruceLine(name=name, hlt2_filter_code=[ - f"{name.replace('Spruce','Hlt2')}Decision", - "Hlt2Topo2BodyDecision", "Hlt2Topo3BodyDecision"] - ,prescale=prescale,persistreco=True, algs=sl_line_prefilter() + [Bcands]) - return [spruce_lines()] - -def make_lines_taumu(): - return [spruce_butod0taunu_d0tokpi_tautomununu_line()] - -def make_lines_mu(): - return [spruce_butod0munu_d0tokpi_line()] - -def SLB_BuToD0ENu_D0ToKPi(options: Options): - with reconstruction.bind(from_file=True, spruce=True): - config = run_moore(options, make_streams=make_lines_e, public_tools=[stateProvider_with_simplified_geom()]) - return config - -def SLB_BuToDststENu(options: Options): - with reconstruction.bind(from_file=True, spruce=True): - config = run_moore(options, make_streams=make_lines_e, public_tools=[stateProvider_with_simplified_geom()]) - return config - -def SLB_BdToDststENu(options: Options): - with reconstruction.bind(from_file=True, spruce=True): - config = run_moore(options, make_streams=make_lines_e, public_tools=[stateProvider_with_simplified_geom()]) - return config - -def SLB_BuToD0MuNu_D0ToKPi(options: Options): - with reconstruction.bind(from_file=True, spruce=True): - config = run_moore(options, make_streams=make_lines_mu, public_tools=[stateProvider_with_simplified_geom()]) - return config - -def SLB_BuToD0TauNu_D0ToKPi_TauToENuNu(options: Options): - with reconstruction.bind(from_file=True, spruce=True): - config = run_moore(options, make_streams=make_lines_e, public_tools=[stateProvider_with_simplified_geom()]) - return config - -def SLB_BuToDststTauNu_TauToENuNu(options: Options): - with reconstruction.bind(from_file=True, spruce=True): - config = run_moore(options, make_streams=make_lines_e, public_tools=[stateProvider_with_simplified_geom()]) - return config - -def SLB_BdToDststTauNu_TauToENuNu(options: Options): - with reconstruction.bind(from_file=True, spruce=True): - config = run_moore(options, make_streams=make_lines_e, public_tools=[stateProvider_with_simplified_geom()]) - return config - -def SLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu(options: Options): - with reconstruction.bind(from_file=True, spruce=True): - config = run_moore(options, make_streams=make_lines_taumu, public_tools=[stateProvider_with_simplified_geom()]) - return config +from Moore.persistence.hlt2_tistos import list_of_full_stream_lines +from Hlt2Conf.lines.semileptonic import all_lines as slb_lines +from Hlt2Conf.lines.topological_b import all_lines as topo_lines +from Hlt2Conf.lines.semileptonic import sprucing_lines as slb_sprucing_lines +def lines_for_tistos(): + """ + Nikole Comment : + This TISTOS part is only needed for exclusive Sprucing + and it saves the candidates of the FULL HLT2 lines that fired for each event. + You need to make sure its only FULL HLT2 lines in the lines_for_tistos + and they are the ones you care about ie. RD inclusive lines + """ + return [linename for line_dict in [slb_lines,topo_lines] for linename in line_dict.keys()] + +@register_line_builder(slb_sprucing_lines) +def spruce_mybutod0enu_d0tokpi_line(name='SpruceSLB_myBuToD0ENu_D0ToKPi',prescale=1): + Bcands = make_b() + return SpruceLine(name=name, hlt2_filter_code=[ + f"{name.replace('Spruce','Hlt2')}Decision", + "Hlt2Topo2BodyDecision", "Hlt2Topo3BodyDecision"] + ,prescale=prescale,persistreco=True, algs=sl_line_prefilter() + [Bcands]) + +def make_full_streams(): + lines = [builder() for builder in slb_sprucing_lines.values()] + streams = [Stream(lines=lines, detectors=[])] + return Streams(streams=streams) + +def main(options: Options): + public_tools = [stateProvider_with_simplified_geom()] + with reconstruction.bind(from_file=True, spruce=True),\ + reco_spruce.bind(simulation=True),\ + upfront_spruce.bind(simulation=True),\ + list_of_full_stream_lines.bind(lines=lines_for_tistos()): + return run_moore(options, make_full_streams, public_tools=public_tools) diff --git a/SL_l_nu_D0toKpi_Run3_MC/info.yaml b/SL_l_nu_D0toKpi_Run3_MC/info.yaml index 8d3007e1f6..7e1d75701c 100644 --- a/SL_l_nu_D0toKpi_Run3_MC/info.yaml +++ b/SL_l_nu_D0toKpi_Run3_MC/info.yaml @@ -26,7 +26,7 @@ HLT1_{{dk}}_{{ polarity }}: bk_query: "/MC/Dev/Beam6800GeV-expected-2024-{{polarity}}-Nu7.6-25ns-Pythia8/Sim10c/{{evttype}}/DIGI" dq_flags: - OK - n_test_lfns: 2 + n_test_lfns: 3 output: hlt1.dst options: entrypoint: SL_l_nu_D0toKpi_Run3_MC.Hlt1:main @@ -43,15 +43,15 @@ HLT1_{{dk}}_{{ polarity }}: algorithm: ZSTD level: 1 max_buffer_size: 1048576 - #evt_max: 1000 + #evt_max: 1000 HLT2_{{dk}}_{{ polarity }}: - application: "Moore/v55r7p3@x86_64_v3-el9-gcc13+detdesc-opt+g" + application: "Moore/v55r7@x86_64_v3-el9-gcc13+detdesc-opt+g" input: job_name: HLT1_{{dk}}_{{ polarity }} output: hlt2.dst options: - entrypoint: SL_l_nu_D0toKpi_Run3_MC.Hlt2:{{line}} + entrypoint: SL_l_nu_D0toKpi_Run3_MC.Hlt2:main extra_options: input_raw_format: 0.5 conddb_tag: {{cond_tag}} @@ -68,12 +68,12 @@ HLT2_{{dk}}_{{ polarity }}: max_buffer_size: 1048576 #evt_max: 1000 SPRUCE_{{dk}}_{{ polarity }}: - application: "Moore/v55r7p3@x86_64_v3-el9-gcc13+detdesc-opt+g" + application: "Moore/v55r7@x86_64_v3-el9-gcc13+detdesc-opt+g" input: job_name: HLT2_{{dk}}_{{ polarity }} output: spruce.dst options: - entrypoint: SL_l_nu_D0toKpi_Run3_MC.Spruce:{{line}} + entrypoint: SL_l_nu_D0toKpi_Run3_MC.Spruce:main extra_options: input_raw_format: 0.5 conddb_tag: {{cond_tag}} -- GitLab From 26f6e9d7c40147d14db89284080ab3c643aadc49 Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Thu, 13 Jun 2024 13:53:37 +0200 Subject: [PATCH 37/57] Fix Moore version --- SL_l_nu_D0toKpi_Run3_MC/info.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SL_l_nu_D0toKpi_Run3_MC/info.yaml b/SL_l_nu_D0toKpi_Run3_MC/info.yaml index 7e1d75701c..10fa5c59e4 100644 --- a/SL_l_nu_D0toKpi_Run3_MC/info.yaml +++ b/SL_l_nu_D0toKpi_Run3_MC/info.yaml @@ -46,7 +46,7 @@ HLT1_{{dk}}_{{ polarity }}: #evt_max: 1000 HLT2_{{dk}}_{{ polarity }}: - application: "Moore/v55r7@x86_64_v3-el9-gcc13+detdesc-opt+g" + application: "Moore/v55r7p3@x86_64_v3-el9-gcc13+detdesc-opt+g" input: job_name: HLT1_{{dk}}_{{ polarity }} output: hlt2.dst @@ -68,7 +68,7 @@ HLT2_{{dk}}_{{ polarity }}: max_buffer_size: 1048576 #evt_max: 1000 SPRUCE_{{dk}}_{{ polarity }}: - application: "Moore/v55r7@x86_64_v3-el9-gcc13+detdesc-opt+g" + application: "Moore/v55r7p3@x86_64_v3-el9-gcc13+detdesc-opt+g" input: job_name: HLT2_{{dk}}_{{ polarity }} output: spruce.dst -- GitLab From 81aa30c372c822868cef2255192c59f404a285f5 Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Mon, 17 Jun 2024 12:03:35 +0200 Subject: [PATCH 38/57] Try to reduce memory usage --- SL_l_nu_D0toKpi_Run3_MC/info.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/SL_l_nu_D0toKpi_Run3_MC/info.yaml b/SL_l_nu_D0toKpi_Run3_MC/info.yaml index 10fa5c59e4..a77ff06360 100644 --- a/SL_l_nu_D0toKpi_Run3_MC/info.yaml +++ b/SL_l_nu_D0toKpi_Run3_MC/info.yaml @@ -26,7 +26,7 @@ HLT1_{{dk}}_{{ polarity }}: bk_query: "/MC/Dev/Beam6800GeV-expected-2024-{{polarity}}-Nu7.6-25ns-Pythia8/Sim10c/{{evttype}}/DIGI" dq_flags: - OK - n_test_lfns: 3 + n_test_lfns: 1 output: hlt1.dst options: entrypoint: SL_l_nu_D0toKpi_Run3_MC.Hlt1:main @@ -105,6 +105,7 @@ DV_{{dk}}_{{ polarity }}: input_type: ROOT simulation: True data_type: "Upgrade" + #geometry_version: run3/2024.Q1.2-v00.00 input_process: "Spruce" input_manifest_file: "SPRUCE.tck.json" #evt_max: 1000 -- GitLab From 9df520b577619b70c7b2fd1d209bb026159e4bf6 Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Mon, 24 Jun 2024 03:31:31 +0200 Subject: [PATCH 39/57] add everything --- .../DV.py | 241 +++++++++++------- .../Hlt1.py | 0 .../Hlt2.py | 2 +- .../MC_Matcher.py | 0 .../Spruce.py | 0 .../info.yaml | 51 +++- 6 files changed, 201 insertions(+), 93 deletions(-) rename {SL_l_nu_D0toKpi_Run3_MC => SL_l_nu_D0toKpi_Run3_MC_data}/DV.py (70%) rename {SL_l_nu_D0toKpi_Run3_MC => SL_l_nu_D0toKpi_Run3_MC_data}/Hlt1.py (100%) rename {SL_l_nu_D0toKpi_Run3_MC => SL_l_nu_D0toKpi_Run3_MC_data}/Hlt2.py (99%) rename {SL_l_nu_D0toKpi_Run3_MC => SL_l_nu_D0toKpi_Run3_MC_data}/MC_Matcher.py (100%) rename {SL_l_nu_D0toKpi_Run3_MC => SL_l_nu_D0toKpi_Run3_MC_data}/Spruce.py (100%) rename {SL_l_nu_D0toKpi_Run3_MC => SL_l_nu_D0toKpi_Run3_MC_data}/info.yaml (64%) diff --git a/SL_l_nu_D0toKpi_Run3_MC/DV.py b/SL_l_nu_D0toKpi_Run3_MC_data/DV.py similarity index 70% rename from SL_l_nu_D0toKpi_Run3_MC/DV.py rename to SL_l_nu_D0toKpi_Run3_MC_data/DV.py index 216f7e7f3d..e71c5d49f3 100644 --- a/SL_l_nu_D0toKpi_Run3_MC/DV.py +++ b/SL_l_nu_D0toKpi_Run3_MC_data/DV.py @@ -1,5 +1,6 @@ import sys,os,math from PyConf.reading import get_pvs, get_rec_summary, get_particles +from PyConf.Algorithms import ThOrParticleSelection import Functors as F from FunTuple import FunctorCollection from FunTuple import FunTuple_Particles as Funtuple @@ -31,48 +32,88 @@ ALLPV_FD_COORDINATE = lambda coordinate, Vertices: F.MAP(coordinate @ _allpv_F TRUE_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.PARTICLE_ID) == id) def make_Bst(B, pions,lepton, hadron_candidate_id,v2_pvs,do_truth_matching = True): - if do_truth_matching == True : - #filter B keeping only true D0 and true leptons - MCTRUTH_B = MCTruthAndBkgCat(B, name='MCTRUTH_Bu') - Dz_child = F.CHILD(1, F.FORWARDARG0) #get the first child of B*- which is D0 - lep_child = F.CHILD(2, F.FORWARDARG0) #get the second child of B*- which is lepton - Dz_truth_cut = TRUE_ID_IS(hadron_candidate_id, MCTRUTH_B) @ Dz_child #require that D0 is true - lep_truth_cut = F.require_any(TRUE_ID_IS(11, MCTRUTH_B) @ lep_child , TRUE_ID_IS(13, MCTRUTH_B) @ lep_child) #require that lepton is true i.e. electron or muon - cut_b = F.require_all(Dz_truth_cut, lep_truth_cut) #make a cut - signal_B = ParticleFilter(Input=B, Cut=F.FILTER(cut_b), name='signal_Dzmu') #filter the B candidates - else : signal_B = B - - D0_child = F.CHILD(1, F.CHILD(1,F.FORWARDARG0)) - Epi_child = F.CHILD(2, F.FORWARDARG0) - - #D* mass - D0 mass cut - cut_combine = F.require_all(((F.MASS @ ((F.FOURMOMENTUM @ D0_child)+(F.FOURMOMENTUM @ Epi_child))) - (F.MASS @ D0_child))<200) - - #combine to make [B*0 -> B*- pi+]cc - Bst_1 = ParticleCombiner( - Inputs=[B, pions], - name=f'Bst_1_{lepton}', - DecayDescriptor='[B0 -> B- pi+]cc', - CombinationCut=cut_combine, - CompositeCut=F.ALL, - ParticleCombiner="ParticleVertexFitter", - PrimaryVertices=v2_pvs - #OutputLevel=1 - ) - #combine to make [B*0 -> B*- pi-]cc - Bst_2 = ParticleCombiner( - Inputs=[B, pions], - name=f'Bst_2_{lepton}', - DecayDescriptor='[B0 -> B- pi-]cc', - CombinationCut=cut_combine, - CompositeCut=F.ALL, - ParticleCombiner="ParticleVertexFitter", - PrimaryVertices=v2_pvs - #OutputLevel=1 - ) - #merge the two Bst candidates - Bst = ParticleContainersMerger([Bst_1, Bst_2], name = f'Bst_combiner_{lepton}') - return Bst + if do_truth_matching == True : + #filter B keeping only true D0 and true leptons + MCTRUTH_B = MCTruthAndBkgCat(B, name='MCTRUTH_Bu') + Dz_child = F.CHILD(1, F.FORWARDARG0) #get the first child of B*- which is D0 + lep_child = F.CHILD(2, F.FORWARDARG0) #get the second child of B*- which is lepton + Dz_truth_cut = TRUE_ID_IS(hadron_candidate_id, MCTRUTH_B) @ Dz_child #require that D0 is true + lep_truth_cut = F.require_any(TRUE_ID_IS(11, MCTRUTH_B) @ lep_child , TRUE_ID_IS(13, MCTRUTH_B) @ lep_child) #require that lepton is true i.e. electron or muon + cut_b = F.require_all(Dz_truth_cut, lep_truth_cut) #make a cut + signal_B = ParticleFilter(Input=B, Cut=F.FILTER(cut_b), name='signal_Dzmu') #filter the B candidates + else : signal_B = B + + hadron_cut = F.IS_ABS_ID('D0') # Getting the hadron candidates + + code_hadron = F.FILTER(hadron_cut) @ F.GET_CHILDREN() + hadron_TES = ThOrParticleSelection( + name="hadron_iso", + InputParticles=signal_B, + Functor=code_hadron).OutputSelection + + lepton_cut = F.IS_ABS_ID(f'{lepton}-') + code_lepton = F.FILTER(lepton_cut) @ F.GET_CHILDREN() + lepton_TES = ThOrParticleSelection( + name="lepton_iso", + InputParticles=signal_B, + Functor=code_lepton).OutputSelection + + + #combine to make [B*- -> D0 lep-]cc + Bstm_1 = ParticleCombiner( + Inputs=[hadron_TES, lepton_TES], + name=f'Bstm_1_{lepton}', + DecayDescriptor=f'[B*- -> D0 {lepton}-]cc', + CombinationCut=F.ALL, + CompositeCut=F.ALL, + ParticleCombiner="ParticleVertexFitter", + #PrimaryVertices=v2_pvs + #OutputLevel=1 + ) + #combine to make [B*+ -> D0 lep+]cc + Bstm_2 = ParticleCombiner( + Inputs=[hadron_TES, lepton_TES], + name=f'Bstm_2_{lepton}', + DecayDescriptor=f'[B*+ -> D0 {lepton}+]cc', + CombinationCut=F.ALL, + CompositeCut=F.ALL, + ParticleCombiner="ParticleVertexFitter", + #PrimaryVertices=v2_pvs + #OutputLevel=1 + ) + Bstm = ParticleContainersMerger([Bstm_1, Bstm_2], name = f'Bstm_combiner_{lepton}') + + D0_child = F.CHILD(1, F.CHILD(1,F.FORWARDARG0)) + Epi_child = F.CHILD(2, F.FORWARDARG0) + + #D* mass - D0 mass cut + cut_combine = F.require_all(((F.MASS @ ((F.FOURMOMENTUM @ D0_child)+(F.FOURMOMENTUM @ Epi_child))) - (F.MASS @ D0_child))<200) + + #combine to make [B*0 -> B*- pi+]cc + Bst_1 = ParticleCombiner( + Inputs=[Bstm, pions], + name=f'Bst_1_{lepton}', + DecayDescriptor='[B*0 -> B*- pi+]cc', + CombinationCut=cut_combine, + CompositeCut=F.ALL, + ParticleCombiner="ParticleVertexFitter", + PrimaryVertices=v2_pvs + #OutputLevel=1 + ) + #combine to make [B*0 -> B*- pi-]cc + Bst_2 = ParticleCombiner( + Inputs=[Bstm, pions], + name=f'Bst_2_{lepton}', + DecayDescriptor='[B*0 -> B*- pi-]cc', + CombinationCut=cut_combine, + CompositeCut=F.ALL, + ParticleCombiner="ParticleVertexFitter", + PrimaryVertices=v2_pvs + #OutputLevel=1 + ) + #merge the two Bst candidates + Bst = ParticleContainersMerger([Bst_1, Bst_2], name = f'Bst_combiner_{lepton}') + return Bst def get_functors(MCTRUTH, v2_pvs, rec_summary): #define common variables for all fields (composite and basic) @@ -291,7 +332,7 @@ def tuple_Bst(Bst,lepton,line, MCTRUTH, v2_pvs, rec_summary): vars_Bst['MTDOCACHI2_2'] = F.MTDOCACHI2(2, v2_pvs) vars_Bst['Delta_M'] = F.ABS @ ((F.MASS @ ((F.FOURMOMENTUM @ D0_child)+(F.FOURMOMENTUM @ Epi_child))) - (F.MASS @ D0_child)) vars_Bst['iso_mva'] = mva_functor_mu_inclusive(v2_pvs)[0] - vars_Bst += trail_seeker(MCTRUTH) + if MCTRUTH != 'None': vars_Bst += trail_seeker(MCTRUTH) #define fields @@ -335,13 +376,13 @@ def tuple_Bst(Bst,lepton,line, MCTRUTH, v2_pvs, rec_summary): #define fields fields = {} - fields['B0'] = f'[B0 -> (B- -> ([D0 -> K- pi+]CC) {lepton}-) [pi+]CC]CC' - fields['Bm'] = f'[B0 -> ^(B- -> ([D0 -> K- pi+]CC) {lepton}-) [pi+]CC]CC' - fields['D0'] = f'[B0 -> (B- -> ^([D0 -> K- pi+]CC) {lepton}-) [pi+]CC]CC' - fields['Lep'] = f'[B0 -> (B- -> ([D0 -> K- pi+]CC) ^{lepton}-) [pi+]CC]CC' - fields['Epi'] = f'[B0 -> (B- -> ([D0 -> K- pi+]CC) {lepton}-) ^[pi+]CC]CC' - fields['Km'] = f'[B0 -> (B- -> ([D0 -> ^K- pi+]CC) {lepton}-) [pi+]CC]CC' - fields['pip'] = f'[B0 -> (B- -> ([D0 -> K- ^pi+]CC) {lepton}-) [pi+]CC]CC' + fields['B0'] = f'[B*0 -> (B*- -> ([D0 -> K- pi+]CC) {lepton}-) [pi+]CC]CC' + fields['Bm'] = f'[B*0 -> ^(B*- -> ([D0 -> K- pi+]CC) {lepton}-) [pi+]CC]CC' + fields['D0'] = f'[B*0 -> (B*- -> ^([D0 -> K- pi+]CC) {lepton}-) [pi+]CC]CC' + fields['Lep'] = f'[B*0 -> (B*- -> ([D0 -> K- pi+]CC) ^{lepton}-) [pi+]CC]CC' + fields['Epi'] = f'[B*0 -> (B*- -> ([D0 -> K- pi+]CC) {lepton}-) ^[pi+]CC]CC' + fields['Km'] = f'[B*0 -> (B*- -> ([D0 -> ^K- pi+]CC) {lepton}-) [pi+]CC]CC' + fields['pip'] = f'[B*0 -> (B*- -> ([D0 -> K- ^pi+]CC) {lepton}-) [pi+]CC]CC' #add variables variables = {} @@ -379,57 +420,83 @@ def get_extra_pions(): name='Pions_combiner') #def main(options): -def main(options: Options,line = '', lep=''): +def main(options: Options,line = '', lep='',data_or_mc='mc'): + + #define filer + my_filter = create_lines_filter(name="Filter", lines=[line]) + + #get data and extra particles + Bm = get_particles(f"/Event/Spruce/{line}/Particles") + extra_particles = get_extra_pions() + #extra_particles = get_particles(f"/Event/Spruce/{line}/{line}_extra_tracks/Particles") + + #get v2_pvs and rec_summary + v2_pvs = get_pvs() + rec_summary = get_rec_summary() + hadron_candidate_id = 421 + #make B0 candidate + Bst = make_Bst(Bm, extra_particles,lep,hadron_candidate_id,v2_pvs,False) + + if data_or_mc == 'mc': + MCTRUTH_Bst = MCTruthAndBkgCat(Bst, name='MCTRUTH_Bst') + tuple_file = tuple_Bst(Bst,lep,line, MCTRUTH_Bst, v2_pvs, rec_summary) + elif data_or_mc == 'data': + tuple_file = tuple_Bst(Bst,lep,line, 'None', v2_pvs, rec_summary) + else: + raise ValueError(f"Decay channel {decay_channel} not supported") + #define algorithms + user_algorithms = {} + user_algorithms['Alg'] = [my_filter, tuple_file] + + return make_config(options, user_algorithms) - #define filer - my_filter = create_lines_filter(name="Filter", lines=[line]) +def test(options: Options): + return main(options=options, line='Hlt2_Test_line',lep='e',data_or_mc='data') - #get data and extra particles - Bm = get_particles(f"/Event/Spruce/{line}/Particles") - extra_particles = get_extra_pions() - #extra_particles = get_particles(f"/Event/Spruce/{line}/{line}_extra_tracks/Particles") +def MC_SLB_BuToD0ENu_D0ToKPi(options: Options): + return main(options=options, line='SpruceSLB_myBuToD0ENu_D0ToKPi',lep='e',data_or_mc='mc') - #get v2_pvs and rec_summary - v2_pvs = get_pvs() - rec_summary = get_rec_summary() - hadron_candidate_id = 421 - #make B0 candidate - Bst = make_Bst(Bm, extra_particles,lep,hadron_candidate_id,v2_pvs,False) - MCTRUTH_Bst = MCTruthAndBkgCat(Bst, name='MCTRUTH_Bst') +def MC_SLB_BuToDststENu(options: Options): + return main(options=options, line='SpruceSLB_myBuToD0ENu_D0ToKPi',lep='e',data_or_mc='mc') +def MC_SLB_BdToDststENu(options: Options): + return main(options=options, line='SpruceSLB_myBuToD0ENu_D0ToKPi',lep='e',data_or_mc='mc') - tuple_file = tuple_Bst(Bst,lep,line, MCTRUTH_Bst, v2_pvs, rec_summary) +def MC_SLB_BuToD0MuNu_D0ToKPi(options: Options): + return main(options=options, line='SpruceSLB_BuToD0MuNu_D0ToKPi',lep='mu',data_or_mc='mc') - #define algorithms - user_algorithms = {} - user_algorithms['Alg'] = [my_filter, tuple_file] +def MC_SLB_BuToD0TauNu_D0ToKPi_TauToENuNu(options: Options): + return main(options=options, line='SpruceSLB_myBuToD0ENu_D0ToKPi',lep='e',data_or_mc='mc') - return make_config(options, user_algorithms) +def MC_SLB_BuToDststTauNu_TauToENuNu(options: Options): + return main(options=options, line='SpruceSLB_myBuToD0ENu_D0ToKPi',lep='e',data_or_mc='mc') -def test(options: Options): - return main(options=options, line='Hlt2_Test_line',lep='e') +def MC_SLB_BdToDststTauNu_TauToENuNu(options: Options): + return main(options=options, line='SpruceSLB_myBuToD0ENu_D0ToKPi',lep='e',data_or_mc='mc') -def SLB_BuToD0ENu_D0ToKPi(options: Options): - return main(options=options, line='SpruceSLB_myBuToD0ENu_D0ToKPi',lep='e') +def MC_SLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu(options: Options): + return main(options=options, line='SpruceSLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu',lep='mu',data_or_mc='mc') -def SLB_BuToDststENu(options: Options): - return main(options=options, line='SpruceSLB_myBuToD0ENu_D0ToKPi',lep='e') +def Data_SLB_BuToD0ENu_D0ToKPi(options: Options): + return main(options=options, line='SpruceSLB_BuToD0ENu_D0ToKPi',lep='e',data_or_mc='data') -def SLB_BdToDststENu(options: Options): - return main(options=options, line='SpruceSLB_myBuToD0ENu_D0ToKPi',lep='e') +def Data_SLB_BuToD0MuNu_D0ToKPi(options: Options): + return main(options=options, line='SpruceSLB_BuToD0MuNu_D0ToKPi',lep='mu',data_or_mc='data') -def SLB_BuToD0MuNu_D0ToKPi(options: Options): - return main(options=options, line='SpruceSLB_BuToD0MuNu_D0ToKPi',lep='mu') +def Data_SLB_BuToD0TauNu_D0ToKPi_TauToENuNu(options: Options): + return main(options=options, line='SpruceSLB_BuToD0TauNu_D0ToKPi_TauToENuNu',lep='e',data_or_mc='data') -def SLB_BuToD0TauNu_D0ToKPi_TauToENuNu(options: Options): - return main(options=options, line='SpruceSLB_myBuToD0ENu_D0ToKPi',lep='e') +def Data_SLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu(options: Options): + return main(options=options, line='SpruceSLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu',lep='mu',data_or_mc='data') -def SLB_BuToDststTauNu_TauToENuNu(options: Options): - return main(options=options, line='SpruceSLB_myBuToD0ENu_D0ToKPi',lep='e') +def Data_SLB_BuToD0ENu_D0ToKPi_FakeElectron(options: Options): + return main(options=options, line='SpruceSLB_BuToD0ENu_D0ToKPi_FakeElectron',lep='e',data_or_mc='data') -def SLB_BdToDststTauNu_TauToENuNu(options: Options): - return main(options=options, line='SpruceSLB_myBuToD0ENu_D0ToKPi',lep='e') +def Data_SLB_BuToD0MuNu_D0ToKPi_FakeMuon(options: Options): + return main(options=options, line='SpruceSLB_BuToD0MuNu_D0ToKPi_FakeMuon',lep='mu',data_or_mc='data') -def SLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu(options: Options): - return main(options=options, line='SpruceSLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu',lep='mu') +def Data_SLB_BuToD0TauNu_D0ToKPi_FakeElectron(options: Options): + return main(options=options, line='SpruceSLB_BuToD0TauNu_D0ToKPi_FakeElectron',lep='e',data_or_mc='data') +def Data_SLB_BuToD0TauNu_D0ToKPi_FakeMuon(options: Options): + return main(options=options, line='SpruceSLB_BuToD0TauNu_D0ToKPi_FakeMuon',lep='mu',data_or_mc='data') diff --git a/SL_l_nu_D0toKpi_Run3_MC/Hlt1.py b/SL_l_nu_D0toKpi_Run3_MC_data/Hlt1.py similarity index 100% rename from SL_l_nu_D0toKpi_Run3_MC/Hlt1.py rename to SL_l_nu_D0toKpi_Run3_MC_data/Hlt1.py diff --git a/SL_l_nu_D0toKpi_Run3_MC/Hlt2.py b/SL_l_nu_D0toKpi_Run3_MC_data/Hlt2.py similarity index 99% rename from SL_l_nu_D0toKpi_Run3_MC/Hlt2.py rename to SL_l_nu_D0toKpi_Run3_MC_data/Hlt2.py index 40ddb823ea..be2bda5d70 100644 --- a/SL_l_nu_D0toKpi_Run3_MC/Hlt2.py +++ b/SL_l_nu_D0toKpi_Run3_MC_data/Hlt2.py @@ -77,7 +77,7 @@ def get_electron_cuts(): make_electron_cuts["pt_min"] = 300. * MeV #300. * MeV (Now) 500. * MeV (v55r7) make_electron_cuts["mipchi2_min"] = 9. #9. (Now) 9./16. (v55r7 e/taue) make_electron_cuts["mip_min"] = None #0. - make_electron_cuts["pid"] = (F.PID_E > 0.0) + make_electron_cuts["pid"] = (F.PID_E > 0.) make_electron_cuts["make_particles"] = make_long_electrons_with_brem #does not require in calo return make_electron_cuts diff --git a/SL_l_nu_D0toKpi_Run3_MC/MC_Matcher.py b/SL_l_nu_D0toKpi_Run3_MC_data/MC_Matcher.py similarity index 100% rename from SL_l_nu_D0toKpi_Run3_MC/MC_Matcher.py rename to SL_l_nu_D0toKpi_Run3_MC_data/MC_Matcher.py diff --git a/SL_l_nu_D0toKpi_Run3_MC/Spruce.py b/SL_l_nu_D0toKpi_Run3_MC_data/Spruce.py similarity index 100% rename from SL_l_nu_D0toKpi_Run3_MC/Spruce.py rename to SL_l_nu_D0toKpi_Run3_MC_data/Spruce.py diff --git a/SL_l_nu_D0toKpi_Run3_MC/info.yaml b/SL_l_nu_D0toKpi_Run3_MC_data/info.yaml similarity index 64% rename from SL_l_nu_D0toKpi_Run3_MC/info.yaml rename to SL_l_nu_D0toKpi_Run3_MC_data/info.yaml index a77ff06360..18abc3e05c 100644 --- a/SL_l_nu_D0toKpi_Run3_MC/info.yaml +++ b/SL_l_nu_D0toKpi_Run3_MC_data/info.yaml @@ -22,6 +22,7 @@ defaults: {%- for evttype, line, dk in evttype_lines_and_leptons %} HLT1_{{dk}}_{{ polarity }}: application: "Moore/v55r7@x86_64_v3-el9-gcc13+detdesc-opt+g" + #application: "Moore/v55r8@x86_64_v3-el9-gcc13+detdesc-opt+g" input: bk_query: "/MC/Dev/Beam6800GeV-expected-2024-{{polarity}}-Nu7.6-25ns-Pythia8/Sim10c/{{evttype}}/DIGI" dq_flags: @@ -29,7 +30,7 @@ HLT1_{{dk}}_{{ polarity }}: n_test_lfns: 1 output: hlt1.dst options: - entrypoint: SL_l_nu_D0toKpi_Run3_MC.Hlt1:main + entrypoint: SL_l_nu_D0toKpi_Run3_MC_data.Hlt1:main extra_options: input_raw_format: 0.3 conddb_tag: {{cond_tag}} @@ -43,15 +44,16 @@ HLT1_{{dk}}_{{ polarity }}: algorithm: ZSTD level: 1 max_buffer_size: 1048576 - #evt_max: 1000 + evt_max: 1000 HLT2_{{dk}}_{{ polarity }}: application: "Moore/v55r7p3@x86_64_v3-el9-gcc13+detdesc-opt+g" + #application: "Moore/v55r8@x86_64_v3-el9-gcc13+detdesc-opt+g" input: job_name: HLT1_{{dk}}_{{ polarity }} output: hlt2.dst options: - entrypoint: SL_l_nu_D0toKpi_Run3_MC.Hlt2:main + entrypoint: SL_l_nu_D0toKpi_Run3_MC_data.Hlt2:main extra_options: input_raw_format: 0.5 conddb_tag: {{cond_tag}} @@ -69,11 +71,12 @@ HLT2_{{dk}}_{{ polarity }}: #evt_max: 1000 SPRUCE_{{dk}}_{{ polarity }}: application: "Moore/v55r7p3@x86_64_v3-el9-gcc13+detdesc-opt+g" + #application: "Moore/v55r8@x86_64_v3-el9-gcc13+detdesc-opt+g" input: job_name: HLT2_{{dk}}_{{ polarity }} output: spruce.dst options: - entrypoint: SL_l_nu_D0toKpi_Run3_MC.Spruce:main + entrypoint: SL_l_nu_D0toKpi_Run3_MC_data.Spruce:main extra_options: input_raw_format: 0.5 conddb_tag: {{cond_tag}} @@ -97,7 +100,7 @@ DV_{{dk}}_{{ polarity }}: job_name: SPRUCE_{{dk}}_{{ polarity }} output: NTuple.root options: - entrypoint: SL_l_nu_D0toKpi_Run3_MC.DV:{{line}} + entrypoint: SL_l_nu_D0toKpi_Run3_MC_data.DV:MC_{{line}} extra_options: input_raw_format: 0.5 conddb_tag: {{cond_tag}} @@ -112,3 +115,41 @@ DV_{{dk}}_{{ polarity }}: {%- endfor %} {%- endfor %} + + +{%- set lines_and_decays = [ + ('SLB_BuToD0ENu_D0ToKPi','b0_dstp_e'), + ('SLB_BuToD0MuNu_D0ToKPi','b0_dstp_muon'), + ('SLB_BuToD0TauNu_D0ToKPi_TauToENuNu','b0_dstp_taue'), + ('SLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu','b0_dstp_taumuon'), + ('SLB_BuToD0ENu_D0ToKPi_FakeElectron','b0_dstp_e_fake'), + ('SLB_BuToD0MuNu_D0ToKPi_FakeMuon','b0_dstp_muon_fake'), + ('SLB_BuToD0TauNu_D0ToKPi_FakeElectron','b0_dstp_taue_fake'), + ('SLB_BuToD0TauNu_D0ToKPi_FakeMuon','b0_dstp_taumuon_fake'), +] %} + +{%- for spruce_line, decay in lines_and_decays %} +data_{{decay}}: + application: "DaVinci/v64r5" + input: + bk_query: "/LHCb/Collision24/Beam6800GeV-VeloClosed-MagDown-Excl-UT/Real Data/Sprucing24c1/90000000/SL.DST" + dq_flags: + - UNCHECKED + - OK + keep_running: true + n_test_lfns: 1 + output: DATA.ROOT + options: + entrypoint: SL_l_nu_D0toKpi_Run3_MC_data.DV:Data_{{spruce_line}} + extra_options: + input_raw_format: 0.5 + input_type: ROOT # ROOT for SprucingPass, RAW for RAW data (Hlt2 output) + simulation: False + #data_type: "Upgrade" + geometry_version: run3/2024.Q1.2-v00.00 + conditions_version: master + input_process: "Spruce" # Spruce for SprucingPass, "Hlt2" for RAW data (Hlt2 output) + input_stream: "sl" # for streamed data + #evt_max: 1000 +{%- endfor %} + -- GitLab From ae8154388cf24ef85f32312f2db244e36f1d9ae7 Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Mon, 24 Jun 2024 11:55:12 +0200 Subject: [PATCH 40/57] Fix info.yaml --- SL_l_nu_D0toKpi_Run3_MC_data/info.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SL_l_nu_D0toKpi_Run3_MC_data/info.yaml b/SL_l_nu_D0toKpi_Run3_MC_data/info.yaml index 18abc3e05c..47634c4fa3 100644 --- a/SL_l_nu_D0toKpi_Run3_MC_data/info.yaml +++ b/SL_l_nu_D0toKpi_Run3_MC_data/info.yaml @@ -44,7 +44,7 @@ HLT1_{{dk}}_{{ polarity }}: algorithm: ZSTD level: 1 max_buffer_size: 1048576 - evt_max: 1000 + #evt_max: 1000 HLT2_{{dk}}_{{ polarity }}: application: "Moore/v55r7p3@x86_64_v3-el9-gcc13+detdesc-opt+g" -- GitLab From f2edf471b4f0217afc75bed48a7bab92f3ad9088 Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Mon, 24 Jun 2024 12:48:12 +0200 Subject: [PATCH 41/57] remove brems variables for non-lepton particles --- SL_l_nu_D0toKpi_Run3_MC_data/DV.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SL_l_nu_D0toKpi_Run3_MC_data/DV.py b/SL_l_nu_D0toKpi_Run3_MC_data/DV.py index e71c5d49f3..1bb78a3745 100644 --- a/SL_l_nu_D0toKpi_Run3_MC_data/DV.py +++ b/SL_l_nu_D0toKpi_Run3_MC_data/DV.py @@ -391,9 +391,9 @@ def tuple_Bst(Bst,lepton,line, MCTRUTH, v2_pvs, rec_summary): variables["Bm"] = vars_composite variables["D0"] = vars_composite variables["Lep"] = vars_basic + vars_brems - variables["Epi"] = vars_basic + vars_brems - variables["Km"] = vars_basic + vars_brems - variables["pip"] = vars_basic + vars_brems + variables["Epi"] = vars_basic + variables["Km"] = vars_basic + variables["pip"] = vars_basic #define tuple my_tuple = Funtuple( -- GitLab From 3a000d89fd5c23c21a8e755ea151c90c255c3627 Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Mon, 24 Jun 2024 12:50:08 +0200 Subject: [PATCH 42/57] tighten D* mass cut --- SL_l_nu_D0toKpi_Run3_MC_data/DV.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SL_l_nu_D0toKpi_Run3_MC_data/DV.py b/SL_l_nu_D0toKpi_Run3_MC_data/DV.py index 1bb78a3745..0d0ab03967 100644 --- a/SL_l_nu_D0toKpi_Run3_MC_data/DV.py +++ b/SL_l_nu_D0toKpi_Run3_MC_data/DV.py @@ -87,7 +87,7 @@ def make_Bst(B, pions,lepton, hadron_candidate_id,v2_pvs,do_truth_matching = Tru Epi_child = F.CHILD(2, F.FORWARDARG0) #D* mass - D0 mass cut - cut_combine = F.require_all(((F.MASS @ ((F.FOURMOMENTUM @ D0_child)+(F.FOURMOMENTUM @ Epi_child))) - (F.MASS @ D0_child))<200) + cut_combine = F.require_all(((F.MASS @ ((F.FOURMOMENTUM @ D0_child)+(F.FOURMOMENTUM @ Epi_child))) - (F.MASS @ D0_child))<160) #combine to make [B*0 -> B*- pi+]cc Bst_1 = ParticleCombiner( -- GitLab From 1b98d561e95b11cac8a8a6f25a4b7135a5bc3257 Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Mon, 24 Jun 2024 14:53:40 +0200 Subject: [PATCH 43/57] Try not to include mva in MC --- SL_l_nu_D0toKpi_Run3_MC_data/DV.py | 208 +++++++++++++++-------------- 1 file changed, 105 insertions(+), 103 deletions(-) diff --git a/SL_l_nu_D0toKpi_Run3_MC_data/DV.py b/SL_l_nu_D0toKpi_Run3_MC_data/DV.py index 0d0ab03967..d4ad252f3c 100644 --- a/SL_l_nu_D0toKpi_Run3_MC_data/DV.py +++ b/SL_l_nu_D0toKpi_Run3_MC_data/DV.py @@ -288,75 +288,77 @@ def get_fitting_variable(v2_pvs,D0,lep): return(vars_fitting) def tuple_Bst(Bst,lepton,line, MCTRUTH, v2_pvs, rec_summary): - #get functors - functors = get_functors(MCTRUTH, v2_pvs, rec_summary) - vars_common = functors[0] - vars_composite = functors[1] - vars_basic = functors[2] - evt_vars = functors[3] - vars_brems = functors[4] - - #variables for B0 field - vars_Bst = FunctorCollection() - B_child = F.CHILD(1, F.FORWARDARG0) - D0_child = F.CHILD(1, F.CHILD(1,F.FORWARDARG0)) - Lep_child = F.CHILD(1, F.CHILD(2,F.FORWARDARG0)) - Epi_child = F.CHILD(2, F.FORWARDARG0) - bpv_pi = F.BPV(v2_pvs).bind(Epi_child) - #diff in vtx chi2 with and without extra particle - vars_Bst['DELTA_ENDVERTEX_CHI2'] = (F.CHI2 @ F.ENDVERTEX) - (F.CHI2 @ F.ENDVERTEX.bind(B_child)) - #IP and IPChi2 of extra particle wrt to B0 end vertex - vars_Bst['Epi_IP_WRT_B0ENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ F.FORWARDARG0 , Epi_child) - vars_Bst['Epi_IPCHI2_WRT_B0ENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ F.FORWARDARG0 , Epi_child) - #IP and IPChi2 of extra particle wrt to Bm end vertex - vars_Bst['Epi_IP_WRT_BmENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ B_child , Epi_child) - vars_Bst['Epi_IPCHI2_WRT_LbENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ B_child , Epi_child) - #angle between extra particle and Bm - vars_Bst['Epi_COSANGLE_Bm'] = F.COSANGLE.bind(F.THREEMOMENTUM @ B_child, F.THREEMOMENTUM @ Epi_child) - #diff in fd chi2 with and without extra particle - vars_Bst['Delta_BPV_of_Epi_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi, F.FORWARDARGS) - F.VTX_FDCHI2.bind(bpv_pi, B_child) - vars_Bst['BPV_of_Epi_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi, F.FORWARDARGS) - #IP chi2 of extra particle wrt PV and SV of B0 - vars_Bst['Epi_IP_WRT_B0BPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child) - vars_Bst['Epi_IPCHI2_WRT_B0BPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child) - #IP chi2 of extra particle wrt PV and SV of Bm - vars_Bst['Epi_IP_WRT_BmBPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ B_child, Epi_child) - vars_Bst['Epi_IPCHI2_WRT_BmBPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ B_child, Epi_child) - #DOCA and DOCACHI2 b/w Lb and extra particle - vars_Bst['DOCA12'] = F.DOCA(1, 2) - vars_Bst['DOCA12_CHI2_12'] = F.DOCACHI2(1, 2) - #vars_Bst['SDOCA12'] = F.SDOCA(1, 2) - #vars_Bst['SDOCA_CHI2_12'] = F.SDOCACHI2(1, 2) - #DOCACHI2 of extra particle wrt to mother i.e. B0 - vars_Bst['MTDOCACHI2_1'] = F.MTDOCACHI2(1, v2_pvs) - vars_Bst['MTDOCACHI2_2'] = F.MTDOCACHI2(2, v2_pvs) - vars_Bst['Delta_M'] = F.ABS @ ((F.MASS @ ((F.FOURMOMENTUM @ D0_child)+(F.FOURMOMENTUM @ Epi_child))) - (F.MASS @ D0_child)) - vars_Bst['iso_mva'] = mva_functor_mu_inclusive(v2_pvs)[0] - if MCTRUTH != 'None': vars_Bst += trail_seeker(MCTRUTH) - - - #define fields - fit_vars = get_fitting_variable(v2_pvs,D0_child,Lep_child) - #TIS and TOS - Hlt1_decisions = ['Hlt1TrackMVA', - 'Hlt1TwoTrackMVA', - 'Hlt1D2KK', - 'Hlt1D2KPi', - 'Hlt1D2PiPi', - 'Hlt1KsToPiPi', - 'Hlt1TrackMuonMVA', - 'Hlt1SingleHighPtMuon', - 'Hlt1TrackElectronMVA', - 'Hlt1SingleHighPtElectron', - 'Hlt1DiElectronDisplaced', - 'Hlt1DiPhotonHighMass', - 'Hlt1Pi02GammaGamma', - 'Hlt1DiElectronHighMass_SS', - 'Hlt1DiElectronHighMass'] - variables_tistos_hlt1 = FC.HltTisTos(selection_type="Hlt1", trigger_lines=Hlt1_decisions, data=Bst) - evt_vars += FC.SelectionInfo(selection_type="Hlt1", trigger_lines=Hlt1_decisions) - - Hlt2_decisions = ['Hlt2SLB_BuToD0MuNu_D0ToKPi', + #get functors + functors = get_functors(MCTRUTH, v2_pvs, rec_summary) + vars_common = functors[0] + vars_composite = functors[1] + vars_basic = functors[2] + evt_vars = functors[3] + vars_brems = functors[4] + + #variables for B0 field + vars_Bst = FunctorCollection() + B_child = F.CHILD(1, F.FORWARDARG0) + D0_child = F.CHILD(1, F.CHILD(1,F.FORWARDARG0)) + Lep_child = F.CHILD(1, F.CHILD(2,F.FORWARDARG0)) + Epi_child = F.CHILD(2, F.FORWARDARG0) + bpv_pi = F.BPV(v2_pvs).bind(Epi_child) + #diff in vtx chi2 with and without extra particle + vars_Bst['DELTA_ENDVERTEX_CHI2'] = (F.CHI2 @ F.ENDVERTEX) - (F.CHI2 @ F.ENDVERTEX.bind(B_child)) + #IP and IPChi2 of extra particle wrt to B0 end vertex + vars_Bst['Epi_IP_WRT_B0ENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ F.FORWARDARG0 , Epi_child) + vars_Bst['Epi_IPCHI2_WRT_B0ENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ F.FORWARDARG0 , Epi_child) + #IP and IPChi2 of extra particle wrt to Bm end vertex + vars_Bst['Epi_IP_WRT_BmENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ B_child , Epi_child) + vars_Bst['Epi_IPCHI2_WRT_LbENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ B_child , Epi_child) + #angle between extra particle and Bm + vars_Bst['Epi_COSANGLE_Bm'] = F.COSANGLE.bind(F.THREEMOMENTUM @ B_child, F.THREEMOMENTUM @ Epi_child) + #diff in fd chi2 with and without extra particle + vars_Bst['Delta_BPV_of_Epi_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi, F.FORWARDARGS) - F.VTX_FDCHI2.bind(bpv_pi, B_child) + vars_Bst['BPV_of_Epi_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi, F.FORWARDARGS) + #IP chi2 of extra particle wrt PV and SV of B0 + vars_Bst['Epi_IP_WRT_B0BPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child) + vars_Bst['Epi_IPCHI2_WRT_B0BPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child) + #IP chi2 of extra particle wrt PV and SV of Bm + vars_Bst['Epi_IP_WRT_BmBPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ B_child, Epi_child) + vars_Bst['Epi_IPCHI2_WRT_BmBPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ B_child, Epi_child) + #DOCA and DOCACHI2 b/w Lb and extra particle + vars_Bst['DOCA12'] = F.DOCA(1, 2) + vars_Bst['DOCA12_CHI2_12'] = F.DOCACHI2(1, 2) + #vars_Bst['SDOCA12'] = F.SDOCA(1, 2) + #vars_Bst['SDOCA_CHI2_12'] = F.SDOCACHI2(1, 2) + #DOCACHI2 of extra particle wrt to mother i.e. B0 + vars_Bst['MTDOCACHI2_1'] = F.MTDOCACHI2(1, v2_pvs) + vars_Bst['MTDOCACHI2_2'] = F.MTDOCACHI2(2, v2_pvs) + vars_Bst['Delta_M'] = F.ABS @ ((F.MASS @ ((F.FOURMOMENTUM @ D0_child)+(F.FOURMOMENTUM @ Epi_child))) - (F.MASS @ D0_child)) + #vars_Bst['iso_mva'] = mva_functor_mu_inclusive(v2_pvs)[0] + if MCTRUTH != 'None': + vars_Bst += trail_seeker(MCTRUTH) + elif MCTRUTH == 'None': + vars_Bst['iso_mva'] = mva_functor_mu_inclusive(v2_pvs)[0] + + #define fields + fit_vars = get_fitting_variable(v2_pvs,D0_child,Lep_child) + #TIS and TOS + Hlt1_decisions = ['Hlt1TrackMVA', + 'Hlt1TwoTrackMVA', + 'Hlt1D2KK', + 'Hlt1D2KPi', + 'Hlt1D2PiPi', + 'Hlt1KsToPiPi', + 'Hlt1TrackMuonMVA', + 'Hlt1SingleHighPtMuon', + 'Hlt1TrackElectronMVA', + 'Hlt1SingleHighPtElectron', + 'Hlt1DiElectronDisplaced', + 'Hlt1DiPhotonHighMass', + 'Hlt1Pi02GammaGamma', + 'Hlt1DiElectronHighMass_SS', + 'Hlt1DiElectronHighMass'] + variables_tistos_hlt1 = FC.HltTisTos(selection_type="Hlt1", trigger_lines=Hlt1_decisions, data=Bst) + evt_vars += FC.SelectionInfo(selection_type="Hlt1", trigger_lines=Hlt1_decisions) + + Hlt2_decisions = ['Hlt2SLB_BuToD0MuNu_D0ToKPi', 'Hlt2SLB_BuToD0MuNu_D0ToKPi_FakeMuon', 'Hlt2SLB_BuToD0ENu_D0ToKPi', 'Hlt2SLB_BuToD0ENu_D0ToKPi_FakeElectron', @@ -370,42 +372,42 @@ def tuple_Bst(Bst,lepton,line, MCTRUTH, v2_pvs, rec_summary): 'Hlt2Topo2Body', 'Hlt2Topo3Body'] - variables_tistos_hlt2 = FC.HltTisTos(selection_type="Hlt2", trigger_lines=Hlt2_decisions, data=Bst) - evt_vars += FC.SelectionInfo(selection_type="Hlt2", trigger_lines=Hlt2_decisions) - - - #define fields - fields = {} - fields['B0'] = f'[B*0 -> (B*- -> ([D0 -> K- pi+]CC) {lepton}-) [pi+]CC]CC' - fields['Bm'] = f'[B*0 -> ^(B*- -> ([D0 -> K- pi+]CC) {lepton}-) [pi+]CC]CC' - fields['D0'] = f'[B*0 -> (B*- -> ^([D0 -> K- pi+]CC) {lepton}-) [pi+]CC]CC' - fields['Lep'] = f'[B*0 -> (B*- -> ([D0 -> K- pi+]CC) ^{lepton}-) [pi+]CC]CC' - fields['Epi'] = f'[B*0 -> (B*- -> ([D0 -> K- pi+]CC) {lepton}-) ^[pi+]CC]CC' - fields['Km'] = f'[B*0 -> (B*- -> ([D0 -> ^K- pi+]CC) {lepton}-) [pi+]CC]CC' - fields['pip'] = f'[B*0 -> (B*- -> ([D0 -> K- ^pi+]CC) {lepton}-) [pi+]CC]CC' - - #add variables - variables = {} - variables["ALL"] = vars_common + variables_tistos_hlt1 + variables_tistos_hlt2 - variables["B0"] = vars_composite + vars_Bst + fit_vars - variables["Bm"] = vars_composite - variables["D0"] = vars_composite - variables["Lep"] = vars_basic + vars_brems - variables["Epi"] = vars_basic - variables["Km"] = vars_basic - variables["pip"] = vars_basic - - #define tuple - my_tuple = Funtuple( - name=f"Tuple", - tuple_name="DecayTree", - fields=fields, - variables=variables, - event_variables=evt_vars, + variables_tistos_hlt2 = FC.HltTisTos(selection_type="Hlt2", trigger_lines=Hlt2_decisions, data=Bst) + evt_vars += FC.SelectionInfo(selection_type="Hlt2", trigger_lines=Hlt2_decisions) + + + #define fields + fields = {} + fields['B0'] = f'[B*0 -> (B*- -> ([D0 -> K- pi+]CC) {lepton}-) [pi+]CC]CC' + fields['Bm'] = f'[B*0 -> ^(B*- -> ([D0 -> K- pi+]CC) {lepton}-) [pi+]CC]CC' + fields['D0'] = f'[B*0 -> (B*- -> ^([D0 -> K- pi+]CC) {lepton}-) [pi+]CC]CC' + fields['Lep'] = f'[B*0 -> (B*- -> ([D0 -> K- pi+]CC) ^{lepton}-) [pi+]CC]CC' + fields['Epi'] = f'[B*0 -> (B*- -> ([D0 -> K- pi+]CC) {lepton}-) ^[pi+]CC]CC' + fields['Km'] = f'[B*0 -> (B*- -> ([D0 -> ^K- pi+]CC) {lepton}-) [pi+]CC]CC' + fields['pip'] = f'[B*0 -> (B*- -> ([D0 -> K- ^pi+]CC) {lepton}-) [pi+]CC]CC' + + #add variables + variables = {} + variables["ALL"] = vars_common + variables_tistos_hlt1 + variables_tistos_hlt2 + variables["B0"] = vars_composite + vars_Bst + fit_vars + variables["Bm"] = vars_composite + variables["D0"] = vars_composite + variables["Lep"] = vars_basic + vars_brems + variables["Epi"] = vars_basic + variables["Km"] = vars_basic + variables["pip"] = vars_basic + + #define tuple + my_tuple = Funtuple( + name=f"Tuple", + tuple_name="DecayTree", + fields=fields, + variables=variables, + event_variables=evt_vars, store_multiple_cand_info=True, - inputs=Bst) + inputs=Bst) - return my_tuple + return my_tuple def get_extra_pions(): """ -- GitLab From 644a3835b05ed5dc462aa337646cd10712102a9a Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Wed, 10 Jul 2024 21:31:22 +0200 Subject: [PATCH 44/57] add everything --- SL_l_nu_D0toKpi_Run3_MC_data/DV.py | 504 --------------------- SL_l_nu_D0toKpi_Run3_MC_data/Hlt1.py | 18 - SL_l_nu_D0toKpi_Run3_MC_data/Hlt2.py | 155 ------- SL_l_nu_D0toKpi_Run3_MC_data/MC_Matcher.py | 26 -- SL_l_nu_D0toKpi_Run3_MC_data/Spruce.py | 58 --- SL_l_nu_D0toKpi_Run3_MC_data/info.yaml | 155 ------- lb_lc_mu_2024data/DV.py | 299 ++++++++++++ lb_lc_mu_2024data/info.yaml | 28 ++ 8 files changed, 327 insertions(+), 916 deletions(-) delete mode 100644 SL_l_nu_D0toKpi_Run3_MC_data/DV.py delete mode 100644 SL_l_nu_D0toKpi_Run3_MC_data/Hlt1.py delete mode 100644 SL_l_nu_D0toKpi_Run3_MC_data/Hlt2.py delete mode 100644 SL_l_nu_D0toKpi_Run3_MC_data/MC_Matcher.py delete mode 100644 SL_l_nu_D0toKpi_Run3_MC_data/Spruce.py delete mode 100644 SL_l_nu_D0toKpi_Run3_MC_data/info.yaml create mode 100644 lb_lc_mu_2024data/DV.py create mode 100644 lb_lc_mu_2024data/info.yaml diff --git a/SL_l_nu_D0toKpi_Run3_MC_data/DV.py b/SL_l_nu_D0toKpi_Run3_MC_data/DV.py deleted file mode 100644 index d4ad252f3c..0000000000 --- a/SL_l_nu_D0toKpi_Run3_MC_data/DV.py +++ /dev/null @@ -1,504 +0,0 @@ -import sys,os,math -from PyConf.reading import get_pvs, get_rec_summary, get_particles -from PyConf.Algorithms import ThOrParticleSelection -import Functors as F -from FunTuple import FunctorCollection -from FunTuple import FunTuple_Particles as Funtuple -from DaVinci.algorithms import create_lines_filter -from DaVinci import Options,make_config -import FunTuple.functorcollections as FC -from DaVinciMCTools import MCTruthAndBkgCat -from Hlt2Conf.algorithms_thor import ParticleCombiner, ParticleFilter -from Hlt2Conf.algorithms_thor import ParticleContainersMerger -from Functors.grammar import Functor -from Hlt2Conf.standard_particles import make_has_rich_long_pions,make_has_rich_up_pions,make_has_rich_down_pions -import numpy as np -from Hlt2Conf.lines.semileptonic.isolationMVA import mva_functor_e_inclusive,mva_functor_mu_inclusive -from .MC_Matcher import trail_seeker - -_BPVCORRM = Functor('_BPVCORRM', 'Composite::CorrectedMass','Compute the corrected mass') -_allpv_FDVEC = (F.ENDVERTEX_POS @ F.FORWARDARG1 - F.TOLINALG @ F.POSITION @ F.FORWARDARG0) -_allpv_NORMEDDOT = F.NORMEDDOT.bind(F.THREEMOMENTUM @ F.FORWARDARG1, _allpv_FDVEC) -ALLPV_CHI2 = lambda Vertices: F.MAP(F.CHI2) @ F.TES(Vertices) -ALLPV_CHI2DOF = lambda Vertices: F.MAP(F.CHI2DOF) @ F.TES(Vertices) -ALLPV_IPCHI2 = lambda Vertices: F.MAP(F.IPCHI2).bind(F.TES(Vertices), F.FORWARDARGS) -ALLPV_FDCHI2 = lambda Vertices: F.MAP(F.VTX_FDCHI2).bind(F.TES(Vertices), F.FORWARDARGS) -ALLPV_DIRA = lambda Vertices: F.MAP(_allpv_NORMEDDOT).bind(F.TES(Vertices), F.FORWARDARGS) -ALLPV_CORRM = lambda Vertices: F.MAP(_BPVCORRM).bind(F.TES(Vertices), F.FORWARDARGS) -ALLPV_LTIME = lambda Vertices: F.MAP(F.VTX_LTIME).bind(F.TES(Vertices), F.FORWARDARGS) -ALLPV_DLS = lambda Vertices: F.MAP(F.VTX_DLS).bind(F.TES(Vertices), F.FORWARDARGS) -ALLPV_FD_COORDINATE = lambda coordinate, Vertices: F.MAP(coordinate @ _allpv_FDVEC).bind(F.TES(Vertices), F.FORWARDARGS) - -TRUE_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.PARTICLE_ID) == id) - -def make_Bst(B, pions,lepton, hadron_candidate_id,v2_pvs,do_truth_matching = True): - if do_truth_matching == True : - #filter B keeping only true D0 and true leptons - MCTRUTH_B = MCTruthAndBkgCat(B, name='MCTRUTH_Bu') - Dz_child = F.CHILD(1, F.FORWARDARG0) #get the first child of B*- which is D0 - lep_child = F.CHILD(2, F.FORWARDARG0) #get the second child of B*- which is lepton - Dz_truth_cut = TRUE_ID_IS(hadron_candidate_id, MCTRUTH_B) @ Dz_child #require that D0 is true - lep_truth_cut = F.require_any(TRUE_ID_IS(11, MCTRUTH_B) @ lep_child , TRUE_ID_IS(13, MCTRUTH_B) @ lep_child) #require that lepton is true i.e. electron or muon - cut_b = F.require_all(Dz_truth_cut, lep_truth_cut) #make a cut - signal_B = ParticleFilter(Input=B, Cut=F.FILTER(cut_b), name='signal_Dzmu') #filter the B candidates - else : signal_B = B - - hadron_cut = F.IS_ABS_ID('D0') # Getting the hadron candidates - - code_hadron = F.FILTER(hadron_cut) @ F.GET_CHILDREN() - hadron_TES = ThOrParticleSelection( - name="hadron_iso", - InputParticles=signal_B, - Functor=code_hadron).OutputSelection - - lepton_cut = F.IS_ABS_ID(f'{lepton}-') - code_lepton = F.FILTER(lepton_cut) @ F.GET_CHILDREN() - lepton_TES = ThOrParticleSelection( - name="lepton_iso", - InputParticles=signal_B, - Functor=code_lepton).OutputSelection - - - #combine to make [B*- -> D0 lep-]cc - Bstm_1 = ParticleCombiner( - Inputs=[hadron_TES, lepton_TES], - name=f'Bstm_1_{lepton}', - DecayDescriptor=f'[B*- -> D0 {lepton}-]cc', - CombinationCut=F.ALL, - CompositeCut=F.ALL, - ParticleCombiner="ParticleVertexFitter", - #PrimaryVertices=v2_pvs - #OutputLevel=1 - ) - #combine to make [B*+ -> D0 lep+]cc - Bstm_2 = ParticleCombiner( - Inputs=[hadron_TES, lepton_TES], - name=f'Bstm_2_{lepton}', - DecayDescriptor=f'[B*+ -> D0 {lepton}+]cc', - CombinationCut=F.ALL, - CompositeCut=F.ALL, - ParticleCombiner="ParticleVertexFitter", - #PrimaryVertices=v2_pvs - #OutputLevel=1 - ) - Bstm = ParticleContainersMerger([Bstm_1, Bstm_2], name = f'Bstm_combiner_{lepton}') - - D0_child = F.CHILD(1, F.CHILD(1,F.FORWARDARG0)) - Epi_child = F.CHILD(2, F.FORWARDARG0) - - #D* mass - D0 mass cut - cut_combine = F.require_all(((F.MASS @ ((F.FOURMOMENTUM @ D0_child)+(F.FOURMOMENTUM @ Epi_child))) - (F.MASS @ D0_child))<160) - - #combine to make [B*0 -> B*- pi+]cc - Bst_1 = ParticleCombiner( - Inputs=[Bstm, pions], - name=f'Bst_1_{lepton}', - DecayDescriptor='[B*0 -> B*- pi+]cc', - CombinationCut=cut_combine, - CompositeCut=F.ALL, - ParticleCombiner="ParticleVertexFitter", - PrimaryVertices=v2_pvs - #OutputLevel=1 - ) - #combine to make [B*0 -> B*- pi-]cc - Bst_2 = ParticleCombiner( - Inputs=[Bstm, pions], - name=f'Bst_2_{lepton}', - DecayDescriptor='[B*0 -> B*- pi-]cc', - CombinationCut=cut_combine, - CompositeCut=F.ALL, - ParticleCombiner="ParticleVertexFitter", - PrimaryVertices=v2_pvs - #OutputLevel=1 - ) - #merge the two Bst candidates - Bst = ParticleContainersMerger([Bst_1, Bst_2], name = f'Bst_combiner_{lepton}') - return Bst - -def get_functors(MCTRUTH, v2_pvs, rec_summary): - #define common variables for all fields (composite and basic) - vars_common = FunctorCollection() - #all pvs: ip, ipchi2. The PV positions are stored in event variables - vars_common['ALLPV_IP[pv_indx]'] = F.ALLPV_IP(v2_pvs) - vars_common['ALLPV_IPCHI2[pv_indx]'] = ALLPV_IPCHI2(v2_pvs) - #best pv: x, y, z, ip, ipchi2 - vars_common['BPV_X'] = F.BPVX(v2_pvs) - vars_common['BPV_Y'] = F.BPVY(v2_pvs) - vars_common['BPV_Z'] = F.BPVZ(v2_pvs) - vars_common['BPV_IP'] = F.BPVIP(v2_pvs) - vars_common['BPV_IPCHI2'] = F.BPVIPCHI2(v2_pvs) - vars_common['BPV_CHI2'] = F.CHI2 @ F.BPV(v2_pvs) - vars_common['BPV_CHI2DOF'] = F.CHI2DOF @ F.BPV(v2_pvs) - #particle id, key, truekey. The trueid is stored in MCHierarchy - vars_common['ID'] = F.PARTICLE_ID - vars_common['KEY'] = F.OBJECT_KEY - - #get charge, min ip and min ipchi2 - vars_common['CHARGE'] = F.CHARGE - vars_common['MINIP'] = F.MINIP(v2_pvs) - vars_common['MINIPCHI2'] = F.MINIPCHI2(v2_pvs) - #reco kinematics - vars_common += FC.Kinematics() - vars_common['ETA'] = F.ETA - vars_common['PHI'] = F.PHI - if MCTRUTH != 'None': - #mc vars - vars_common['BKGCAT'] = MCTRUTH.BkgCat - vars_common['TRUEKEY'] = F.VALUE_OR(-1) @ MCTRUTH(F.OBJECT_KEY) - vars_common += FC.MCKinematics(mctruth_alg = MCTRUTH) - vars_common['TRUEETA'] = MCTRUTH(F.ETA) - vars_common['TRUEPHI'] = MCTRUTH(F.PHI) - #type of the origin vertex - vars_common['MC_VTX_TYPE'] = MCTRUTH(F.VALUE_OR(-1) @ F.MC_VTX_TYPE @ F.MC_ORIGINVERTEX) - #make some helper functions - MCMOTHER_ID = lambda n: F.VALUE_OR(0) @ MCTRUTH(F.MC_MOTHER(n, F.PARTICLE_ID)) - MCMOTHER_KEY = lambda n: F.VALUE_OR(-1) @ MCTRUTH(F.MC_MOTHER(n, F.OBJECT_KEY )) - vars_common["TRUEID"] = F.VALUE_OR(0) @ MCTRUTH(F.PARTICLE_ID) - vars_common["MCKEY"] = F.VALUE_OR(0) @ MCTRUTH(F.OBJECT_KEY) - vars_common["MC_MOTHER_ID"] = MCMOTHER_ID(1) - vars_common["MC_MOTHER_KEY"] = MCMOTHER_KEY(1) - for i in range(2,14): - prefix = "MC_GD_MOTHER_{}".format(i) - vars_common[f"{prefix}_ID"] = MCMOTHER_ID(i) - vars_common[f"{prefix}_KEY"] = MCMOTHER_KEY(i) - - #variables for composite particles - vars_composite = FunctorCollection() - #end vertex position and end vertex chi2 - vars_composite['ENDVERTEX_POS_'] = F.ENDVERTEX_POS - vars_composite['ENDVERTEX_CHI2'] = F.CHI2 @ F.ENDVERTEX - vars_composite['ENDVERTEX_CHI2DOF'] = F.CHI2DOF @ F.ENDVERTEX - #all pvs: dira, fd, fdchi2 - vars_composite['ALLPV_DIRA[pv_indx]'] = ALLPV_DIRA(v2_pvs) - vars_composite['ALLPV_FD_X[pv_indx]'] = ALLPV_FD_COORDINATE(F.X_COORDINATE, v2_pvs) - vars_composite['ALLPV_FD_Y[pv_indx]'] = ALLPV_FD_COORDINATE(F.Y_COORDINATE, v2_pvs) - vars_composite['ALLPV_FD_Z[pv_indx]'] = ALLPV_FD_COORDINATE(F.Z_COORDINATE, v2_pvs) - vars_composite['ALLPV_FDCHI2[pv_indx]'] = ALLPV_FDCHI2(v2_pvs) - vars_composite['ALLPV_CORRM[pv_indx]'] = ALLPV_CORRM(v2_pvs) - vars_composite['ALLPV_LTIME[pv_indx]'] = ALLPV_LTIME(v2_pvs) - vars_composite['ALLPV_DLS[pv_indx]'] = ALLPV_DLS(v2_pvs) - #best pv: dira, fd, fdchi2, corrm, ltime, dls - vars_composite['BPV_DIRA'] = F.BPVDIRA(v2_pvs) - vars_composite['BPV_FD_'] = F.BPVFDVEC(v2_pvs) - vars_composite['BPV_FDCHI2'] = F.BPVFDCHI2(v2_pvs) - vars_composite['BPV_CORRM'] = F.BPVCORRM(v2_pvs) - vars_composite['BPV_LTIME'] = F.BPVLTIME(v2_pvs) - vars_composite['BPV_DLS'] = F.BPVDLS(v2_pvs) - - #mc composite vertex information - if MCTRUTH != 'None': vars_composite += FC.MCVertexInfo(mctruth_alg = MCTRUTH) - #Compute maximum DOCA and maximum DOCACHI2. Since there are - # only two daughters of B0 particles, the maximum DOCA/DOCACHI2 is - # the DOCA/DOCACHI2 see below. - vars_composite['MAX_DOCA'] = F.MAXDOCA - vars_composite['MAX_DOCACHI2'] = F.MAXDOCACHI2 - vars_composite['MAX_SDOCA'] = F.MAXSDOCA - vars_composite['MAX_SDOCACHI2'] = F.MAXSDOCACHI2 - - #variables for basics - vars_basic = FunctorCollection() - vars_basic['TRACKTYPE'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKTYPE @ F.TRACK - vars_basic['TRACKHISTORY'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKHISTORY @ F.TRACK - vars_basic['TRACKFLAG'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKFLAG @ F.TRACK - vars_basic['TRACKNDOF'] = F.VALUE_OR(-1) @ F.NDOF @ F.TRACK - vars_basic['TRACKCHI2'] = F.CHI2 @ F.TRACK - vars_basic['TRACKCHI2DOF'] = F.CHI2DOF @ F.TRACK - vars_basic['GHOSTPROB'] = F.GHOSTPROB - vars_basic['NHITS'] = F.VALUE_OR(-1) @F.NHITS @ F.TRACK - vars_basic['NUTHITS'] = F.VALUE_OR(-1) @F.NUTHITS @ F.TRACK - vars_basic['NVPHITS'] = F.VALUE_OR(-1) @F.NVPHITS @ F.TRACK - vars_basic['NFTHITS'] = F.VALUE_OR(-1) @ F.NFTHITS @ F.TRACK - vars_basic['TRACKHASUT'] = F.VALUE_OR(-1) @ F.TRACKHASUT @ F.TRACK - vars_basic['TRACKHASVELO'] = F.VALUE_OR(-1) @ F.TRACKHASVELO @ F.TRACK - vars_basic['PIDpi'] = F.PID_PI - vars_basic['PIDk'] = F.PID_K - vars_basic['PIDp'] = F.PID_P - vars_basic['PIDe'] = F.PID_E - vars_basic['PIDmu'] = F.PID_MU - vars_basic['PROBNNe'] = F.PROBNN_E - vars_basic['PROBNNpi'] = F.PROBNN_PI - vars_basic['PROBNNk'] = F.PROBNN_K - vars_basic['PROBNNmu'] = F.PROBNN_MU - vars_basic['PROBNNp'] = F.PROBNN_P - vars_basic['PROBNNghost'] = F.PROBNN_GHOST - if MCTRUTH != 'None': vars_basic += FC.MCVertexInfo(mctruth_alg = MCTRUTH) - - #variables for event - #Collection includes tis_tos, nPVs,nHits/clusters,BUNCHCROSSING and GPS var - evt_collections = [ - FC.EventInfo(), - FC.RecSummary(), - ] - evt_vars = FunctorCollection({}) - evt_vars['ALLPV_X[pv_indx]'] = F.ALLPVX(v2_pvs) - evt_vars['ALLPV_Y[pv_indx]'] = F.ALLPVY(v2_pvs) - evt_vars['ALLPV_Z[pv_indx]'] = F.ALLPVZ(v2_pvs) - evt_vars['ALLPV_CHI2[pv_indx]'] = ALLPV_CHI2(v2_pvs) - evt_vars['ALLPV_CHI2DOF[pv_indx]']= ALLPV_CHI2DOF(v2_pvs) - - for coll in evt_collections:evt_vars += coll - - vars_brems = FunctorCollection({}) - vars_brems.update({"HASBREM": F.HASBREM}) - #vars_brems.update({"HASBREMADDED": F.HASBREMADDED}) - vars_brems.update({"BREMENERGY": F.BREMENERGY}) - vars_brems.update({"BREMBENDCORR": F.BREMBENDCORR}) - vars_brems.update({"BREMPIDE": F.BREMPIDE}) - vars_brems.update({"ECALPIDE": F.ECALPIDE}) - vars_brems.update({"ECALPIDMU": F.ECALPIDMU}) - vars_brems.update({"HCALPIDE": F.HCALPIDE}) - vars_brems.update({"HCALPIDMU": F.HCALPIDMU}) - vars_brems.update({"ELECTRONSHOWEREOP": F.ELECTRONSHOWEREOP}) - vars_brems.update({"ELECTRONSHOWERDLL": F.ELECTRONSHOWERDLL}) - vars_brems.update({"CLUSTERMATCH": F.CLUSTERMATCH_CHI2}) - vars_brems.update({"ELECTRONMATCH": F.ELECTRONMATCH_CHI2}) - vars_brems.update({"BREMHYPOMATCH": F.BREMHYPOMATCH_CHI2}) - vars_brems.update({"ELECTRONENERGY": F.ELECTRONENERGY}) - vars_brems.update({"BREMHYPOENERGY": F.BREMHYPOENERGY}) - vars_brems.update({"BREMHYPODELTAX": F.BREMHYPODELTAX}) - #vars_brems.update({"BREMTRACKBASEDENERGY": F.BREMTRACKBASEDENERGY}) - vars_brems.update({"INBREM": F.INBREM}) - vars_brems.update({"INECAL": F.INECAL}) - vars_brems.update({"PT_WITH_BREM": F.PT_WITH_BREM}) - vars_brems.update({"P_WITH_BREM": F.P_WITH_BREM}) - - #return all functors - functors = (vars_common, vars_composite, vars_basic, evt_vars,vars_brems) - return functors - -def get_fitting_variable(v2_pvs,D0,lep): - - B_dis = np.array([F.END_VX-F.BPVX(v2_pvs),F.END_VY-F.BPVY(v2_pvs),F.END_VZ-F.BPVZ(v2_pvs)]) - B_dis_mag = F.SQRT @ (B_dis[0]**2+B_dis[1]**2+B_dis[2]**2) - B_Mod_P = F.ABS @ ((5279.65/F.MASS)*F.PZ/(B_dis[2]/B_dis_mag)) - B_Mod_E = F.SQRT @ (B_Mod_P**2 + 5279.65**2) - B_4P = np.array([B_Mod_P*B_dis[0]/B_dis_mag,B_Mod_P*B_dis[1]/B_dis_mag,B_Mod_P*B_dis[2]/B_dis_mag,B_Mod_E]) - D_4P = np.array([F.PX @ D0,F.PY @ D0,F.PZ @ D0,F.ENERGY @ D0]) - lep_4P = np.array([F.PX @ lep,F.PY @ lep,F.PZ @ lep,F.ENERGY @ lep]) - - vars_fitting = FunctorCollection({}) - vars_fitting["Mod_P"] = B_Mod_P - vars_fitting['missing_m2'] = (B_4P[3]-D_4P[3]-lep_4P[3])**2-(B_4P[0]-D_4P[0]-lep_4P[0])**2-(B_4P[1]-D_4P[1]-lep_4P[1])**2-(B_4P[2]-D_4P[2]-lep_4P[2])**2 - vars_fitting['q2'] = (B_4P[3]-D_4P[3])**2-(B_4P[0]-D_4P[0])**2-(B_4P[1]-D_4P[1])**2-(B_4P[2]-D_4P[2])**2 - B_Beta = B_Mod_P/B_Mod_E - B_gamma = 1/F.SQRT @ (1-B_Beta**2) - - B_Lorentz = [[B_gamma,-1*B_gamma*B_4P[0]/B_4P[3],-1*B_gamma*B_4P[1]/B_4P[3],-1*B_gamma*B_4P[2]/B_4P[3]],[-1*B_gamma*B_4P[0]/B_4P[3],1+(B_gamma-1)*((B_4P[0]/B_4P[3])/B_Beta)*((B_4P[0]/B_4P[3])/B_Beta),(B_gamma-1)*((B_4P[0]/B_4P[3])/B_Beta)*((B_4P[1]/B_4P[3])/B_Beta),(B_gamma-1)*((B_4P[0]/B_4P[3])/B_Beta)*((B_4P[2]/B_4P[3])/B_Beta)],[-1*B_gamma*B_4P[1]/B_4P[3],(B_gamma-1)*((B_4P[0]/B_4P[3])/B_Beta)*((B_4P[1]/B_4P[3])/B_Beta),(B_gamma-1)*((B_4P[1]/B_4P[3])/B_Beta)*((B_4P[1]/B_4P[3])/B_Beta),(B_gamma-1)*((B_4P[1]/B_4P[3])/B_Beta)*((B_4P[2]/B_4P[3])/B_Beta)],[-1*B_gamma*B_4P[2]/B_4P[3],(B_gamma-1)*((B_4P[0]/B_4P[3])/B_Beta)*((B_4P[2]/B_4P[3])/B_Beta),(B_gamma-1)*((B_4P[1]/B_4P[3])/B_Beta)*((B_4P[2]/B_4P[3])/B_Beta),(B_gamma-1)*((B_4P[2]/B_4P[3])/B_Beta)*((B_4P[2]/B_4P[3])/B_Beta)]] - vars_fitting['lep_E_Brest'] = (B_Lorentz[0][0]*lep_4P[3]+B_Lorentz[0][1]*lep_4P[0]+B_Lorentz[0][2]*lep_4P[1]+B_Lorentz[0][3]*lep_4P[2]) - return(vars_fitting) - -def tuple_Bst(Bst,lepton,line, MCTRUTH, v2_pvs, rec_summary): - #get functors - functors = get_functors(MCTRUTH, v2_pvs, rec_summary) - vars_common = functors[0] - vars_composite = functors[1] - vars_basic = functors[2] - evt_vars = functors[3] - vars_brems = functors[4] - - #variables for B0 field - vars_Bst = FunctorCollection() - B_child = F.CHILD(1, F.FORWARDARG0) - D0_child = F.CHILD(1, F.CHILD(1,F.FORWARDARG0)) - Lep_child = F.CHILD(1, F.CHILD(2,F.FORWARDARG0)) - Epi_child = F.CHILD(2, F.FORWARDARG0) - bpv_pi = F.BPV(v2_pvs).bind(Epi_child) - #diff in vtx chi2 with and without extra particle - vars_Bst['DELTA_ENDVERTEX_CHI2'] = (F.CHI2 @ F.ENDVERTEX) - (F.CHI2 @ F.ENDVERTEX.bind(B_child)) - #IP and IPChi2 of extra particle wrt to B0 end vertex - vars_Bst['Epi_IP_WRT_B0ENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ F.FORWARDARG0 , Epi_child) - vars_Bst['Epi_IPCHI2_WRT_B0ENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ F.FORWARDARG0 , Epi_child) - #IP and IPChi2 of extra particle wrt to Bm end vertex - vars_Bst['Epi_IP_WRT_BmENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ B_child , Epi_child) - vars_Bst['Epi_IPCHI2_WRT_LbENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ B_child , Epi_child) - #angle between extra particle and Bm - vars_Bst['Epi_COSANGLE_Bm'] = F.COSANGLE.bind(F.THREEMOMENTUM @ B_child, F.THREEMOMENTUM @ Epi_child) - #diff in fd chi2 with and without extra particle - vars_Bst['Delta_BPV_of_Epi_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi, F.FORWARDARGS) - F.VTX_FDCHI2.bind(bpv_pi, B_child) - vars_Bst['BPV_of_Epi_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi, F.FORWARDARGS) - #IP chi2 of extra particle wrt PV and SV of B0 - vars_Bst['Epi_IP_WRT_B0BPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child) - vars_Bst['Epi_IPCHI2_WRT_B0BPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child) - #IP chi2 of extra particle wrt PV and SV of Bm - vars_Bst['Epi_IP_WRT_BmBPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ B_child, Epi_child) - vars_Bst['Epi_IPCHI2_WRT_BmBPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ B_child, Epi_child) - #DOCA and DOCACHI2 b/w Lb and extra particle - vars_Bst['DOCA12'] = F.DOCA(1, 2) - vars_Bst['DOCA12_CHI2_12'] = F.DOCACHI2(1, 2) - #vars_Bst['SDOCA12'] = F.SDOCA(1, 2) - #vars_Bst['SDOCA_CHI2_12'] = F.SDOCACHI2(1, 2) - #DOCACHI2 of extra particle wrt to mother i.e. B0 - vars_Bst['MTDOCACHI2_1'] = F.MTDOCACHI2(1, v2_pvs) - vars_Bst['MTDOCACHI2_2'] = F.MTDOCACHI2(2, v2_pvs) - vars_Bst['Delta_M'] = F.ABS @ ((F.MASS @ ((F.FOURMOMENTUM @ D0_child)+(F.FOURMOMENTUM @ Epi_child))) - (F.MASS @ D0_child)) - #vars_Bst['iso_mva'] = mva_functor_mu_inclusive(v2_pvs)[0] - if MCTRUTH != 'None': - vars_Bst += trail_seeker(MCTRUTH) - elif MCTRUTH == 'None': - vars_Bst['iso_mva'] = mva_functor_mu_inclusive(v2_pvs)[0] - - #define fields - fit_vars = get_fitting_variable(v2_pvs,D0_child,Lep_child) - #TIS and TOS - Hlt1_decisions = ['Hlt1TrackMVA', - 'Hlt1TwoTrackMVA', - 'Hlt1D2KK', - 'Hlt1D2KPi', - 'Hlt1D2PiPi', - 'Hlt1KsToPiPi', - 'Hlt1TrackMuonMVA', - 'Hlt1SingleHighPtMuon', - 'Hlt1TrackElectronMVA', - 'Hlt1SingleHighPtElectron', - 'Hlt1DiElectronDisplaced', - 'Hlt1DiPhotonHighMass', - 'Hlt1Pi02GammaGamma', - 'Hlt1DiElectronHighMass_SS', - 'Hlt1DiElectronHighMass'] - variables_tistos_hlt1 = FC.HltTisTos(selection_type="Hlt1", trigger_lines=Hlt1_decisions, data=Bst) - evt_vars += FC.SelectionInfo(selection_type="Hlt1", trigger_lines=Hlt1_decisions) - - Hlt2_decisions = ['Hlt2SLB_BuToD0MuNu_D0ToKPi', - 'Hlt2SLB_BuToD0MuNu_D0ToKPi_FakeMuon', - 'Hlt2SLB_BuToD0ENu_D0ToKPi', - 'Hlt2SLB_BuToD0ENu_D0ToKPi_FakeElectron', - 'Hlt2SLB_B0ToDpTauNu_DpToKPiPi_TauToENuNu', - 'Hlt2SLB_B0ToDpTauNu_DpToKPiPi_TauToMuNuNu', - 'Hlt2SLB_BuToD0TauNu_D0ToKPi_TauToENuNu', - 'Hlt2SLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu', - 'Hlt2SLB_BuToD0TauNu_D0ToKPi_FakeMuon', - 'Hlt2SLB_BuToD0TauNu_D0ToKPi_FakeElectron', - 'Hlt2SLB_myBuToD0ENu_D0ToKPi', - 'Hlt2Topo2Body', - 'Hlt2Topo3Body'] - - variables_tistos_hlt2 = FC.HltTisTos(selection_type="Hlt2", trigger_lines=Hlt2_decisions, data=Bst) - evt_vars += FC.SelectionInfo(selection_type="Hlt2", trigger_lines=Hlt2_decisions) - - - #define fields - fields = {} - fields['B0'] = f'[B*0 -> (B*- -> ([D0 -> K- pi+]CC) {lepton}-) [pi+]CC]CC' - fields['Bm'] = f'[B*0 -> ^(B*- -> ([D0 -> K- pi+]CC) {lepton}-) [pi+]CC]CC' - fields['D0'] = f'[B*0 -> (B*- -> ^([D0 -> K- pi+]CC) {lepton}-) [pi+]CC]CC' - fields['Lep'] = f'[B*0 -> (B*- -> ([D0 -> K- pi+]CC) ^{lepton}-) [pi+]CC]CC' - fields['Epi'] = f'[B*0 -> (B*- -> ([D0 -> K- pi+]CC) {lepton}-) ^[pi+]CC]CC' - fields['Km'] = f'[B*0 -> (B*- -> ([D0 -> ^K- pi+]CC) {lepton}-) [pi+]CC]CC' - fields['pip'] = f'[B*0 -> (B*- -> ([D0 -> K- ^pi+]CC) {lepton}-) [pi+]CC]CC' - - #add variables - variables = {} - variables["ALL"] = vars_common + variables_tistos_hlt1 + variables_tistos_hlt2 - variables["B0"] = vars_composite + vars_Bst + fit_vars - variables["Bm"] = vars_composite - variables["D0"] = vars_composite - variables["Lep"] = vars_basic + vars_brems - variables["Epi"] = vars_basic - variables["Km"] = vars_basic - variables["pip"] = vars_basic - - #define tuple - my_tuple = Funtuple( - name=f"Tuple", - tuple_name="DecayTree", - fields=fields, - variables=variables, - event_variables=evt_vars, - store_multiple_cand_info=True, - inputs=Bst) - - return my_tuple - -def get_extra_pions(): - """ - Note this function in DaVinci requires: - https://gitlab.cern.ch/lhcb/Moore/-/merge_requests/3203 - and it's related LHCb, DaVinci and Rec MRs - """ - long_pions = make_has_rich_long_pions() - up_pions = make_has_rich_up_pions() - down_pions = make_has_rich_down_pions() - return ParticleContainersMerger([long_pions, up_pions, down_pions], - name='Pions_combiner') - -#def main(options): -def main(options: Options,line = '', lep='',data_or_mc='mc'): - - #define filer - my_filter = create_lines_filter(name="Filter", lines=[line]) - - #get data and extra particles - Bm = get_particles(f"/Event/Spruce/{line}/Particles") - extra_particles = get_extra_pions() - #extra_particles = get_particles(f"/Event/Spruce/{line}/{line}_extra_tracks/Particles") - - #get v2_pvs and rec_summary - v2_pvs = get_pvs() - rec_summary = get_rec_summary() - hadron_candidate_id = 421 - #make B0 candidate - Bst = make_Bst(Bm, extra_particles,lep,hadron_candidate_id,v2_pvs,False) - - if data_or_mc == 'mc': - MCTRUTH_Bst = MCTruthAndBkgCat(Bst, name='MCTRUTH_Bst') - tuple_file = tuple_Bst(Bst,lep,line, MCTRUTH_Bst, v2_pvs, rec_summary) - elif data_or_mc == 'data': - tuple_file = tuple_Bst(Bst,lep,line, 'None', v2_pvs, rec_summary) - else: - raise ValueError(f"Decay channel {decay_channel} not supported") - #define algorithms - user_algorithms = {} - user_algorithms['Alg'] = [my_filter, tuple_file] - - return make_config(options, user_algorithms) - -def test(options: Options): - return main(options=options, line='Hlt2_Test_line',lep='e',data_or_mc='data') - -def MC_SLB_BuToD0ENu_D0ToKPi(options: Options): - return main(options=options, line='SpruceSLB_myBuToD0ENu_D0ToKPi',lep='e',data_or_mc='mc') - -def MC_SLB_BuToDststENu(options: Options): - return main(options=options, line='SpruceSLB_myBuToD0ENu_D0ToKPi',lep='e',data_or_mc='mc') - -def MC_SLB_BdToDststENu(options: Options): - return main(options=options, line='SpruceSLB_myBuToD0ENu_D0ToKPi',lep='e',data_or_mc='mc') - -def MC_SLB_BuToD0MuNu_D0ToKPi(options: Options): - return main(options=options, line='SpruceSLB_BuToD0MuNu_D0ToKPi',lep='mu',data_or_mc='mc') - -def MC_SLB_BuToD0TauNu_D0ToKPi_TauToENuNu(options: Options): - return main(options=options, line='SpruceSLB_myBuToD0ENu_D0ToKPi',lep='e',data_or_mc='mc') - -def MC_SLB_BuToDststTauNu_TauToENuNu(options: Options): - return main(options=options, line='SpruceSLB_myBuToD0ENu_D0ToKPi',lep='e',data_or_mc='mc') - -def MC_SLB_BdToDststTauNu_TauToENuNu(options: Options): - return main(options=options, line='SpruceSLB_myBuToD0ENu_D0ToKPi',lep='e',data_or_mc='mc') - -def MC_SLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu(options: Options): - return main(options=options, line='SpruceSLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu',lep='mu',data_or_mc='mc') - -def Data_SLB_BuToD0ENu_D0ToKPi(options: Options): - return main(options=options, line='SpruceSLB_BuToD0ENu_D0ToKPi',lep='e',data_or_mc='data') - -def Data_SLB_BuToD0MuNu_D0ToKPi(options: Options): - return main(options=options, line='SpruceSLB_BuToD0MuNu_D0ToKPi',lep='mu',data_or_mc='data') - -def Data_SLB_BuToD0TauNu_D0ToKPi_TauToENuNu(options: Options): - return main(options=options, line='SpruceSLB_BuToD0TauNu_D0ToKPi_TauToENuNu',lep='e',data_or_mc='data') - -def Data_SLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu(options: Options): - return main(options=options, line='SpruceSLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu',lep='mu',data_or_mc='data') - -def Data_SLB_BuToD0ENu_D0ToKPi_FakeElectron(options: Options): - return main(options=options, line='SpruceSLB_BuToD0ENu_D0ToKPi_FakeElectron',lep='e',data_or_mc='data') - -def Data_SLB_BuToD0MuNu_D0ToKPi_FakeMuon(options: Options): - return main(options=options, line='SpruceSLB_BuToD0MuNu_D0ToKPi_FakeMuon',lep='mu',data_or_mc='data') - -def Data_SLB_BuToD0TauNu_D0ToKPi_FakeElectron(options: Options): - return main(options=options, line='SpruceSLB_BuToD0TauNu_D0ToKPi_FakeElectron',lep='e',data_or_mc='data') - -def Data_SLB_BuToD0TauNu_D0ToKPi_FakeMuon(options: Options): - return main(options=options, line='SpruceSLB_BuToD0TauNu_D0ToKPi_FakeMuon',lep='mu',data_or_mc='data') diff --git a/SL_l_nu_D0toKpi_Run3_MC_data/Hlt1.py b/SL_l_nu_D0toKpi_Run3_MC_data/Hlt1.py deleted file mode 100644 index eeabcc4913..0000000000 --- a/SL_l_nu_D0toKpi_Run3_MC_data/Hlt1.py +++ /dev/null @@ -1,18 +0,0 @@ -############################################################################### -# (c) Copyright 2022 CERN for the benefit of the LHCb Collaboration # -# # -# This software is distributed under the terms of the GNU General Public # -# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # -# # -# In applying this licence, CERN does not waive the privileges and immunities # -# granted to it by virtue of its status as an Intergovernmental Organization # -# or submit itself to any jurisdiction. # -############################################################################### -from Moore import Options -from Moore.config import run_allen -from RecoConf.hlt1_allen import allen_gaudi_config as allen_sequence - -def main(options: Options): - with allen_sequence.bind(sequence="hlt1_pp_matching_no_ut_1000KHz"): - return run_allen(options) - diff --git a/SL_l_nu_D0toKpi_Run3_MC_data/Hlt2.py b/SL_l_nu_D0toKpi_Run3_MC_data/Hlt2.py deleted file mode 100644 index be2bda5d70..0000000000 --- a/SL_l_nu_D0toKpi_Run3_MC_data/Hlt2.py +++ /dev/null @@ -1,155 +0,0 @@ -############################################################################### -# (c) Copyright 2022 CERN for the benefit of the LHCb Collaboration # -# # -# This software is distributed under the terms of the GNU General Public # -# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # -# # -# In applying this licence, CERN does not waive the privileges and immunities # -# granted to it by virtue of its status as an Intergovernmental Organization # -# or submit itself to any jurisdiction. # -############################################################################### -""" -Stolen and adapted from Hlt/Hlt2Conf/options/hlt2_pp_expected_24_without_UT.py from v55r7. -""" -from Moore import Options,options, run_moore, config -from Hlt2Conf.algorithms_thor import ParticleContainersMerger -from Hlt2Conf.lines.semileptonic.builders import sl_line_prefilter -from Hlt2Conf.lines.semileptonic.builders.base_builder import make_candidate -from Hlt2Conf.lines.semileptonic.builders.charm_hadron_builder import make_d0_tokpi -from GaudiKernel.SystemOfUnits import MeV, GeV,mm -from Hlt2Conf.algorithms_thor import ParticleCombiner -from Hlt2Conf.settings.defaults import get_default_hlt1_filter_code_for_hlt2 -from Hlt2Conf.lines.semileptonic import all_lines as slb_lines -from Hlt2Conf.lines.topological_b import all_lines as topo_lines -from Moore.config import Hlt2Line,register_line_builder -from Moore.streams import Stream, Streams, DETECTORS -from RecoConf.event_filters import require_gec -from RecoConf.global_tools import stateProvider_with_simplified_geom, trackMasterExtrapolator_with_simplified_geom -from RecoConf.hlt2_global_reco import reconstruction as hlt2_reconstruction, make_light_reco_pr_kf_without_UT -from RecoConf.reconstruction_objects import reconstruction,make_pvs -from RecoConf.decoders import default_ft_decoding_version,default_VeloCluster_source -from RecoConf.hlt2_tracking import ( - make_TrackBestTrackCreator_tracks, - make_PrKalmanFilter_noUT_tracks, - make_PrKalmanFilter_Velo_tracks, - make_PrKalmanFilter_Seed_tracks, -) -from Hlt2Conf.standard_particles import ( - make_long_electrons_with_brem, - make_has_rich_long_pions, - make_has_rich_up_pions, - make_has_rich_down_pions) -import Functors as F -from Functors.math import in_range -import sys - -#things to control -SUFFIX_NAME = '_BToDzl' -HLT2LINE = f'Hlt2SLB_myBuToD0ENu_D0ToKPi' -CHARM_MASS = 1864.84 #D0 mass -CHARM_BUILDER_NAME = 'Dz2KPi_combiner' -B_BUILDER_NAME = 'BToDzl_combiner' - -def get_charm_cuts(): - #make loose cuts for D0 - delta_mass = 80. #80.0 - make_d0tokpi_cuts = {} - make_d0tokpi_cuts['comb_m_min'] = (CHARM_MASS - delta_mass) * MeV - make_d0tokpi_cuts['comb_m_max'] = (CHARM_MASS + delta_mass) * MeV - make_d0tokpi_cuts['comb_docachi2_max'] = 5. - make_d0tokpi_cuts['vchi2pdof_max'] = 6 #6 (Now) 6/4 (v55r7 e/taue) - make_d0tokpi_cuts['bpvfdchi2_min'] = 25 #25 (Now) - make_d0tokpi_cuts['bpvdira_min'] = 0.99 #0.99 (Now) 0.99/0.999 (v55r7 e/taue) - make_d0tokpi_cuts['comb_pt_min'] = None #None (Now) None/2000 * MeV (v55r7 e/taue) - make_d0tokpi_cuts['comb_pt_any_min'] = None #None (Now) None/800 * MeV (v55r7 e/taue) - make_d0tokpi_cuts['comb_pt_sum_min'] = None #None (Now) None/2.5 * GeV (v55r7 e/taue) - make_d0tokpi_cuts['comb_doca_max'] = None #None (Now) None/0.1 mm (v55r7 e/taue) - make_d0tokpi_cuts['daughter_pt_min'] = 600 * MeV #600 * MeV (Now) 750 * MeV (v55r7) - make_d0tokpi_cuts['daughter_mipchi2_min'] = 9. #10. (Now) 10./9. (v55r7 e/taue) - make_d0tokpi_cuts['kaon_pid'] = (F.PID_K > 0.) #(F.PID_K > 0.) (Now) (F.PID_K > 4.) (v55r7) - make_d0tokpi_cuts['pion_pid'] = (F.PID_K < 2.) - return make_d0tokpi_cuts - -def get_electron_cuts(): - #make loose cuts for electron and tauonic muon - make_electron_cuts = {} - make_electron_cuts["p_min"] = 3. * GeV #3. * GeV (Now) 5. *GeV (v55r7) - make_electron_cuts["pt_min"] = 300. * MeV #300. * MeV (Now) 500. * MeV (v55r7) - make_electron_cuts["mipchi2_min"] = 9. #9. (Now) 9./16. (v55r7 e/taue) - make_electron_cuts["mip_min"] = None #0. - make_electron_cuts["pid"] = (F.PID_E > 0.) - make_electron_cuts["make_particles"] = make_long_electrons_with_brem #does not require in calo - return make_electron_cuts - -def make_b(): - make_d0tokpi_cuts = get_charm_cuts() - make_electron_cuts= get_electron_cuts() - pvs = make_pvs() - with make_candidate.bind(p_min=15. * GeV): - dzs = make_d0_tokpi(**make_d0tokpi_cuts, name = CHARM_BUILDER_NAME) - electrons = make_candidate(**make_electron_cuts, name = "Electron_maker") - - cut_vertex = F.require_all(F.CHI2DOF<9,F.BPVDIRA(pvs) >0.999,in_range(0 * MeV, F.MASS, 10000 * MeV)) - - rs_btodze = ParticleCombiner( - Inputs=[dzs, electrons], - name=f'rs_{B_BUILDER_NAME}_e', - DecayDescriptor='[B- -> D0 e-]cc', - CombinationCut=F.ALL, - CompositeCut=cut_vertex) - - ws_btodze = ParticleCombiner( - Inputs=[dzs, electrons], - name=f'ws_{B_BUILDER_NAME}_e', - DecayDescriptor='[B+ -> D0 e+]cc', - CombinationCut=F.ALL, - CompositeCut=cut_vertex) - - return ParticleContainersMerger([rs_btodze,ws_btodze]) - -@register_line_builder(slb_lines) -def hlt2_mybutod0enu_d0tokpi_line(name=HLT2LINE,prescale=1): - Bcands = make_b() - return Hlt2Line(name=name, prescale=prescale,persistreco=True, algs=sl_line_prefilter() + [Bcands]) - -def pass_through_line(name="Hlt2Passthrough"): - """Return a HLT2 line that performs no selection but runs and persists the reconstruction - """ - return Hlt2Line(name=name, prescale=1, algs=[], persistreco=True) - -from Hlt2Conf.lines.topological_b import * - -def _make_lines(): - ret = [] - for line_dict in [slb_lines]: - for line_name, builder in line_dict.items() : - if "D0ToKPi" in line_name and "TauToPiPiPi" not in line_name and "Bc" not in line_name: - print(line_name) - ret.append(builder()) - ret += [twobody_line(),threebody_line(),pass_through_line()] - return ret - -def make_streams(): - streams = [ - Stream(lines=_make_lines(), routing_bit=98, detectors=DETECTORS) - ] - return Streams(streams=streams) - -public_tools = [ - trackMasterExtrapolator_with_simplified_geom(), - stateProvider_with_simplified_geom(), -] - -def main(options: Options): - # NOTE: the TBTC does not apply a chi2 cut because it is applied by the PrKF - with reconstruction.bind(from_file=False),\ - hlt2_reconstruction.bind(make_reconstruction=make_light_reco_pr_kf_without_UT),\ - require_gec.bind(skipUT=True),\ - default_VeloCluster_source.bind(bank_type="VPRetinaCluster"),\ - make_TrackBestTrackCreator_tracks.bind(max_ghost_prob=0.7, max_chi2ndof=sys.float_info.max),\ - make_PrKalmanFilter_Velo_tracks.bind(max_chi2ndof=5.),\ - make_PrKalmanFilter_noUT_tracks.bind(max_chi2ndof=4.),\ - make_PrKalmanFilter_Seed_tracks.bind(max_chi2ndof=6.),\ - get_default_hlt1_filter_code_for_hlt2.bind(code=r"Hlt1(?!PassthroughLargeEvent).*Decision"): - return run_moore(options, make_streams, public_tools=[]) - diff --git a/SL_l_nu_D0toKpi_Run3_MC_data/MC_Matcher.py b/SL_l_nu_D0toKpi_Run3_MC_data/MC_Matcher.py deleted file mode 100644 index e3b279805b..0000000000 --- a/SL_l_nu_D0toKpi_Run3_MC_data/MC_Matcher.py +++ /dev/null @@ -1,26 +0,0 @@ -from FunTuple import FunctorCollection -import Functors as F -def trail_seeker(MCTRUTH): - mcMatch = lambda decay_descriptor: (F.HAS_VALUE @ MCTRUTH(F.FIND_MCDECAY(decay_descriptor))) - mcMatch_both = lambda decay_descriptor1,decay_descriptor2: (F.HAS_VALUE @ MCTRUTH(F.FIND_MCDECAY(decay_descriptor1))+F.HAS_VALUE @ MCTRUTH(F.FIND_MCDECAY(decay_descriptor2))) - - variables = FunctorCollection({ - 'IS_Dtaunu':mcMatch_both("[B0 -> D*(2010)- tau+ nu_tau]CC","[B~0 -> D*(2010)- tau+ nu_tau]CC"), - 'IS_Denu':mcMatch_both("[B0 -> D*(2010)- e+ nu_e]CC","[B~0 -> D*(2010)- e+ nu_e]CC"), - 'IS_Dstar_2460enu':mcMatch_both("[B0 -> D*(2640)- e+ nu_e]CC","[B~0 -> D*(2640)- e+ nu_e]CC"), - 'IS_D_2Senu':mcMatch_both("[B0 -> D(2S)- e+ nu_e]CC","[B~0 -> D(2S)- e+ nu_e]CC"), - 'IS_Dstar_2460_2enu':mcMatch_both("[B0 -> D*_2(2460)- e+ nu_e]CC","[B~0 -> D*_2(2460)- e+ nu_e]CC"), - 'IS_D_2460_1enu':mcMatch_both("[B0 -> D_1(2420)- e+ nu_e]CC","[B~0 -> D_1(2420)- e+ nu_e]CC"), - 'IS_Dstar_0taunu':mcMatch_both("[B0 -> D*_0- tau+ nu_tau]CC","[B~0 -> D*_0- tau+ nu_tau]CC"), - 'IS_D_H_1taunu':mcMatch_both("[B0 -> D_1(H)- tau+ nu_tau]CC","[B~0 -> D_1(H)- tau+ nu_tau]CC"), - 'IS_D_2420_1taunu':mcMatch_both("[B0 -> D_1(2420)- tau+ nu_tau]CC","[B~0 -> D_1(2420)- tau+ nu_tau]CC"), - 'IS_Dstar_2460_2taunu':mcMatch_both("[B0 -> D*_2(2460)- tau+ nu_tau]CC","[B~0 -> D*_2(2460)- tau+ nu_tau]CC"), - 'IS_Dstar0_2640enu':mcMatch("[B- -> D*(2640)0 e- nu_e~]CC"), - 'IS_D0_2Senu':mcMatch("[B- -> D(2S)0 e- nu_e~]CC"), - 'IS_Dstar0_2460_2enu':mcMatch("[B- -> D*_2(2460)0 e- nu_e~]CC"), - 'IS_D0_2460_1enu':mcMatch("[B- -> D_1(2420)0 e- nu_e~]CC"), - 'IS_D0_H_1taunu':mcMatch("[B- -> D_1(H)0 tau- nu_tau~]CC"), - 'IS_D0_2420_1taunu':mcMatch("[B- -> D_1(2420)0 tau- nu_tau~]CC"), - 'IS_Dstar0_2460_2taunu':mcMatch("[B- -> D*_2(2460)0 tau- nu_tau~]CC"), - }) - return(variables) diff --git a/SL_l_nu_D0toKpi_Run3_MC_data/Spruce.py b/SL_l_nu_D0toKpi_Run3_MC_data/Spruce.py deleted file mode 100644 index 964714aba8..0000000000 --- a/SL_l_nu_D0toKpi_Run3_MC_data/Spruce.py +++ /dev/null @@ -1,58 +0,0 @@ -############################################################################### -# (c) Copyright 2022 CERN for the benefit of the LHCb Collaboration # -# # -# This software is distributed under the terms of the GNU General Public # -# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # -# # -# In applying this licence, CERN does not waive the privileges and immunities # -# granted to it by virtue of its status as an Intergovernmental Organization # -# or submit itself to any jurisdiction. # -############################################################################### -#Example follows from hlt2_with_hlt1_decision.py -from Moore import Options,options, run_moore, config -from Hlt2Conf.lines.semileptonic.builders import sl_line_prefilter -from Moore.config import SpruceLine,register_line_builder -from .Hlt2 import make_b -from Moore.streams import DETECTORS, Stream, Streams -from PyConf.application import configure_input, configure, default_raw_event -from RecoConf.global_tools import stateProvider_with_simplified_geom -from RecoConf.reconstruction_objects import reconstruction -from PyConf.reading import reconstruction as reco_spruce, upfront_reconstruction as upfront_spruce -from RecoConf.decoders import default_ft_decoding_version -from Hlt2Conf.lines.semileptonic.spruce_semileptonic import spruce_butod0munu_d0tokpi_line,spruce_butod0taunu_d0tokpi_tautomununu_line -from Hlt2Conf.lines.semileptonic.HbToHcTauNu_TauToLNuNu import make_butod0taunu_d0tokpi_tautolnunu -from Hlt2Conf.lines.semileptonic.HbToHcLNu import make_butod0lnu_d0tokpi -from Moore.persistence.hlt2_tistos import list_of_full_stream_lines -from Hlt2Conf.lines.semileptonic import all_lines as slb_lines -from Hlt2Conf.lines.topological_b import all_lines as topo_lines -from Hlt2Conf.lines.semileptonic import sprucing_lines as slb_sprucing_lines -def lines_for_tistos(): - """ - Nikole Comment : - This TISTOS part is only needed for exclusive Sprucing - and it saves the candidates of the FULL HLT2 lines that fired for each event. - You need to make sure its only FULL HLT2 lines in the lines_for_tistos - and they are the ones you care about ie. RD inclusive lines - """ - return [linename for line_dict in [slb_lines,topo_lines] for linename in line_dict.keys()] - -@register_line_builder(slb_sprucing_lines) -def spruce_mybutod0enu_d0tokpi_line(name='SpruceSLB_myBuToD0ENu_D0ToKPi',prescale=1): - Bcands = make_b() - return SpruceLine(name=name, hlt2_filter_code=[ - f"{name.replace('Spruce','Hlt2')}Decision", - "Hlt2Topo2BodyDecision", "Hlt2Topo3BodyDecision"] - ,prescale=prescale,persistreco=True, algs=sl_line_prefilter() + [Bcands]) - -def make_full_streams(): - lines = [builder() for builder in slb_sprucing_lines.values()] - streams = [Stream(lines=lines, detectors=[])] - return Streams(streams=streams) - -def main(options: Options): - public_tools = [stateProvider_with_simplified_geom()] - with reconstruction.bind(from_file=True, spruce=True),\ - reco_spruce.bind(simulation=True),\ - upfront_spruce.bind(simulation=True),\ - list_of_full_stream_lines.bind(lines=lines_for_tistos()): - return run_moore(options, make_full_streams, public_tools=public_tools) diff --git a/SL_l_nu_D0toKpi_Run3_MC_data/info.yaml b/SL_l_nu_D0toKpi_Run3_MC_data/info.yaml deleted file mode 100644 index 47634c4fa3..0000000000 --- a/SL_l_nu_D0toKpi_Run3_MC_data/info.yaml +++ /dev/null @@ -1,155 +0,0 @@ -defaults: - inform: - - ching-hua.li@cern.ch - wg: SL - -{%- set evttype_lines_and_leptons = [ - ('11584030','SLB_BuToD0ENu_D0ToKPi','b0_dstp_e'), - ('11574020','SLB_BuToD0MuNu_D0ToKPi','b0_dstp_muon'), - ('11584010','SLB_BuToD0TauNu_D0ToKPi_TauToENuNu','b0_dstp_taue'), - ('11574010','SLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu','b0_dstp_taumuon'), - ('12685400','SLB_BuToDststENu','bp_dstst_e'), - ('12883000','SLB_BuToDststTauNu_TauToENuNu','bp_dstst_taue'), - ('11686000','SLB_BdToDststENu','b0_dststp_e'), - ('11883000','SLB_BdToDststTauNu_TauToENuNu','b0_dststp_taue'), -] %} - -{%- set polarity_variables = [ - ('MagDown','sim-20231017-vc-md100'), - ('MagUp','sim-20231017-vc-mu100'), -]%} -{%- for polarity, cond_tag in polarity_variables %} - {%- for evttype, line, dk in evttype_lines_and_leptons %} -HLT1_{{dk}}_{{ polarity }}: - application: "Moore/v55r7@x86_64_v3-el9-gcc13+detdesc-opt+g" - #application: "Moore/v55r8@x86_64_v3-el9-gcc13+detdesc-opt+g" - input: - bk_query: "/MC/Dev/Beam6800GeV-expected-2024-{{polarity}}-Nu7.6-25ns-Pythia8/Sim10c/{{evttype}}/DIGI" - dq_flags: - - OK - n_test_lfns: 1 - output: hlt1.dst - options: - entrypoint: SL_l_nu_D0toKpi_Run3_MC_data.Hlt1:main - extra_options: - input_raw_format: 0.3 - conddb_tag: {{cond_tag}} - dddb_tag: dddb-20231017 - input_type: ROOT - output_type: ROOT - simulation: True - data_type: "Upgrade" - scheduler_legacy_mode: False - compression: - algorithm: ZSTD - level: 1 - max_buffer_size: 1048576 - #evt_max: 1000 - -HLT2_{{dk}}_{{ polarity }}: - application: "Moore/v55r7p3@x86_64_v3-el9-gcc13+detdesc-opt+g" - #application: "Moore/v55r8@x86_64_v3-el9-gcc13+detdesc-opt+g" - input: - job_name: HLT1_{{dk}}_{{ polarity }} - output: hlt2.dst - options: - entrypoint: SL_l_nu_D0toKpi_Run3_MC_data.Hlt2:main - extra_options: - input_raw_format: 0.5 - conddb_tag: {{cond_tag}} - dddb_tag: dddb-20231017 - input_type: ROOT - output_type: ROOT - simulation: True - data_type: "Upgrade" - scheduler_legacy_mode: False - output_manifest_file: "HLT2.tck.json" - compression: - algorithm: ZSTD - level: 1 - max_buffer_size: 1048576 - #evt_max: 1000 -SPRUCE_{{dk}}_{{ polarity }}: - application: "Moore/v55r7p3@x86_64_v3-el9-gcc13+detdesc-opt+g" - #application: "Moore/v55r8@x86_64_v3-el9-gcc13+detdesc-opt+g" - input: - job_name: HLT2_{{dk}}_{{ polarity }} - output: spruce.dst - options: - entrypoint: SL_l_nu_D0toKpi_Run3_MC_data.Spruce:main - extra_options: - input_raw_format: 0.5 - conddb_tag: {{cond_tag}} - dddb_tag: dddb-20231017 - input_type: ROOT - output_type: ROOT - simulation: True - data_type: "Upgrade" - scheduler_legacy_mode: False - input_process: "Hlt2" - input_manifest_file: "HLT2.tck.json" - output_manifest_file: "SPRUCE.tck.json" - compression: - algorithm: ZSTD - level: 1 - max_buffer_size: 1048576 - #evt_max: 1000 -DV_{{dk}}_{{ polarity }}: - application: "DaVinci/v64r5@x86_64_v3-el9-gcc13+detdesc-opt+g" - input: - job_name: SPRUCE_{{dk}}_{{ polarity }} - output: NTuple.root - options: - entrypoint: SL_l_nu_D0toKpi_Run3_MC_data.DV:MC_{{line}} - extra_options: - input_raw_format: 0.5 - conddb_tag: {{cond_tag}} - dddb_tag: dddb-20231017 - input_type: ROOT - simulation: True - data_type: "Upgrade" - #geometry_version: run3/2024.Q1.2-v00.00 - input_process: "Spruce" - input_manifest_file: "SPRUCE.tck.json" - #evt_max: 1000 - - {%- endfor %} -{%- endfor %} - - -{%- set lines_and_decays = [ - ('SLB_BuToD0ENu_D0ToKPi','b0_dstp_e'), - ('SLB_BuToD0MuNu_D0ToKPi','b0_dstp_muon'), - ('SLB_BuToD0TauNu_D0ToKPi_TauToENuNu','b0_dstp_taue'), - ('SLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu','b0_dstp_taumuon'), - ('SLB_BuToD0ENu_D0ToKPi_FakeElectron','b0_dstp_e_fake'), - ('SLB_BuToD0MuNu_D0ToKPi_FakeMuon','b0_dstp_muon_fake'), - ('SLB_BuToD0TauNu_D0ToKPi_FakeElectron','b0_dstp_taue_fake'), - ('SLB_BuToD0TauNu_D0ToKPi_FakeMuon','b0_dstp_taumuon_fake'), -] %} - -{%- for spruce_line, decay in lines_and_decays %} -data_{{decay}}: - application: "DaVinci/v64r5" - input: - bk_query: "/LHCb/Collision24/Beam6800GeV-VeloClosed-MagDown-Excl-UT/Real Data/Sprucing24c1/90000000/SL.DST" - dq_flags: - - UNCHECKED - - OK - keep_running: true - n_test_lfns: 1 - output: DATA.ROOT - options: - entrypoint: SL_l_nu_D0toKpi_Run3_MC_data.DV:Data_{{spruce_line}} - extra_options: - input_raw_format: 0.5 - input_type: ROOT # ROOT for SprucingPass, RAW for RAW data (Hlt2 output) - simulation: False - #data_type: "Upgrade" - geometry_version: run3/2024.Q1.2-v00.00 - conditions_version: master - input_process: "Spruce" # Spruce for SprucingPass, "Hlt2" for RAW data (Hlt2 output) - input_stream: "sl" # for streamed data - #evt_max: 1000 -{%- endfor %} - diff --git a/lb_lc_mu_2024data/DV.py b/lb_lc_mu_2024data/DV.py new file mode 100644 index 0000000000..84cf179833 --- /dev/null +++ b/lb_lc_mu_2024data/DV.py @@ -0,0 +1,299 @@ +############################################################################### +# (c) Copyright 2024 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### +import sys +from DaVinci import Options,make_config +from PyConf.reading import get_pvs, get_rec_summary, get_particles +from PyConf.Algorithms import ThOrParticleSelection +import Functors as F +from FunTuple import FunctorCollection +from FunTuple import FunTuple_Particles as Funtuple +from DaVinci.algorithms import create_lines_filter +import FunTuple.functorcollections as FC +from DaVinciMCTools import MCTruthAndBkgCat +from Hlt2Conf.standard_particles import make_has_rich_long_pions,make_has_rich_up_pions,make_has_rich_down_pions +from Hlt2Conf.algorithms_thor import ParticleCombiner, ParticleFilter +from Hlt2Conf.algorithms_thor import ParticleContainersMerger +from Functors.grammar import Functor +from Hlt2Conf.lines.semileptonic.isolationMVA import mva_functor_e_inclusive,mva_functor_mu_inclusive + +_BPVCORRM = Functor('_BPVCORRM', 'Composite::CorrectedMass','Compute the corrected mass') +_allpv_FDVEC = (F.ENDVERTEX_POS @ F.FORWARDARG1 - F.TOLINALG @ F.POSITION @ F.FORWARDARG0) +_allpv_NORMEDDOT = F.NORMEDDOT.bind(F.THREEMOMENTUM @ F.FORWARDARG1, _allpv_FDVEC) +#ALLPV_CHI2 = lambda Vertices: F.MAP(F.CHI2) @ F.TES(Vertices) +#ALLPV_CHI2DOF = lambda Vertices: F.MAP(F.CHI2DOF) @ F.TES(Vertices) +ALLPV_IPCHI2 = lambda Vertices: F.MAP(F.IPCHI2).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_FDCHI2 = lambda Vertices: F.MAP(F.VTX_FDCHI2).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_DIRA = lambda Vertices: F.MAP(_allpv_NORMEDDOT).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_CORRM = lambda Vertices: F.MAP(_BPVCORRM).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_LTIME = lambda Vertices: F.MAP(F.VTX_LTIME).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_DLS = lambda Vertices: F.MAP(F.VTX_DLS).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_FD_COORDINATE = lambda coordinate, Vertices: F.MAP(coordinate @ _allpv_FDVEC).bind(F.TES(Vertices), F.FORWARDARGS) + +TRUE_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.PARTICLE_ID) == id) + +def make_Bst(B, pions): + + + hadron_cut = F.IS_ABS_ID('Lambda_c+') # Getting the hadron candidates + + code_hadron = F.FILTER(hadron_cut) @ F.GET_CHILDREN() + hadron_TES = ThOrParticleSelection( + name="hadron_iso", + InputParticles=B, + Functor=code_hadron).OutputSelection + + lepton_cut = F.IS_ABS_ID('mu-') + code_lepton = F.FILTER(lepton_cut) @ F.GET_CHILDREN() + lepton_TES = ThOrParticleSelection( + name="lepton_iso", + InputParticles=B, + Functor=code_lepton).OutputSelection + + + #combine to make [B*- -> Lambda_c+ mu-]cc + Bstm = ParticleCombiner( + Inputs=[hadron_TES, lepton_TES], + name=f'Bstm_mu', + DecayDescriptor='[B*- -> Lambda_c+ mu-]cc', + CombinationCut=F.ALL, + CompositeCut=F.ALL, + ParticleCombiner="ParticleVertexFitter", + ) + + cut_combination = F.require_all(F.MAXDOCA < 8.0, F.MAXDOCACHI2 < 20) + + #combine to make [B*0 -> B*- pi+]cc + Bst_1 = ParticleCombiner( + Inputs=[Bstm, pions], + name='Bst_1', + DecayDescriptor='[B*0 -> B*- pi+]cc', + CombinationCut=cut_combination, + CompositeCut=F.ALL, + ParticleCombiner="ParticleVertexFitter", #for neutrals need to use different combiner e.g. ParticleAdder + #OutputLevel=1 + ) + #combine to make [B*0 -> B*- pi-]cc + Bst_2 = ParticleCombiner( + Inputs=[Bstm, pions], + name='Bst_2', + DecayDescriptor='[B*0 -> B*- pi-]cc', + CombinationCut=cut_combination, + CompositeCut=F.ALL, + ParticleCombiner="ParticleVertexFitter", #for neutrals need to use different combiner e.g. ParticleAdder + #OutputLevel=1 + ) + #merge the two Bst candidates + Bst = ParticleContainersMerger([Bst_1, Bst_2], name = 'Bst_combiner') + return Bst + +def get_functors(v2_pvs, rec_summary): + #define common variables for all fields (composite and basic) + vars_common = FunctorCollection() + #all pvs: ip, ipchi2. The PV positions are stored in event variables + vars_common['ALLPV_IP[pv_indx]'] = F.ALLPV_IP(v2_pvs) + vars_common['ALLPV_IPCHI2[pv_indx]'] = ALLPV_IPCHI2(v2_pvs) + #best pv: x, y, z, ip, ipchi2 + vars_common['BPV_X'] = F.BPVX(v2_pvs) + vars_common['BPV_Y'] = F.BPVY(v2_pvs) + vars_common['BPV_Z'] = F.BPVZ(v2_pvs) + vars_common['BPV_IP'] = F.BPVIP(v2_pvs) + vars_common['BPV_IPCHI2'] = F.BPVIPCHI2(v2_pvs) + vars_common['BPV_CHI2'] = F.CHI2 @ F.BPV(v2_pvs) + vars_common['BPV_CHI2DOF'] = F.CHI2DOF @ F.BPV(v2_pvs) + #particle id, key, truekey. The trueid is stored in MCHierarchy + vars_common['ID'] = F.PARTICLE_ID + vars_common['KEY'] = F.OBJECT_KEY + #get charge, min ip and min ipchi2 + vars_common['CHARGE'] = F.CHARGE + vars_common['MINIP'] = F.MINIP(v2_pvs) + vars_common['MINIPCHI2'] = F.MINIPCHI2(v2_pvs) + #reco kinematics + vars_common += FC.Kinematics() + vars_common['ETA'] = F.ETA + vars_common['PHI'] = F.PHI + + #variables for composite particles + vars_composite = FunctorCollection() + #end vertex position and end vertex chi2 + vars_composite['ENDVERTEX_POS_'] = F.ENDVERTEX_POS + vars_composite['ENDVERTEX_CHI2'] = F.CHI2 @ F.ENDVERTEX + vars_composite['ENDVERTEX_CHI2DOF'] = F.CHI2DOF @ F.ENDVERTEX + #all pvs: dira, fd, fdchi2 + vars_composite['ALLPV_DIRA[pv_indx]'] = ALLPV_DIRA(v2_pvs) + vars_composite['ALLPV_FD_X[pv_indx]'] = ALLPV_FD_COORDINATE(F.X_COORDINATE, v2_pvs) + vars_composite['ALLPV_FD_Y[pv_indx]'] = ALLPV_FD_COORDINATE(F.Y_COORDINATE, v2_pvs) + vars_composite['ALLPV_FD_Z[pv_indx]'] = ALLPV_FD_COORDINATE(F.Z_COORDINATE, v2_pvs) + vars_composite['ALLPV_FDCHI2[pv_indx]'] = ALLPV_FDCHI2(v2_pvs) + vars_composite['ALLPV_CORRM[pv_indx]'] = ALLPV_CORRM(v2_pvs) + vars_composite['ALLPV_LTIME[pv_indx]'] = ALLPV_LTIME(v2_pvs) + vars_composite['ALLPV_DLS[pv_indx]'] = ALLPV_DLS(v2_pvs) + #best pv: dira, fd, fdchi2, corrm, ltime, dls + vars_composite['BPV_DIRA'] = F.BPVDIRA(v2_pvs) + vars_composite['BPV_FD_'] = F.BPVFDVEC(v2_pvs) + vars_composite['BPV_FDCHI2'] = F.BPVFDCHI2(v2_pvs) + vars_composite['BPV_CORRM'] = F.BPVCORRM(v2_pvs) + vars_composite['BPV_LTIME'] = F.BPVLTIME(v2_pvs) + vars_composite['BPV_DLS'] = F.BPVDLS(v2_pvs) + #Compute maximum DOCA and maximum DOCACHI2. Since there are + # only two daughters of Sb particles, the maximum DOCA/DOCACHI2 is + # the DOCA/DOCACHI2 see below. + vars_composite['MAX_DOCA'] = F.MAXDOCA + vars_composite['MAX_DOCACHI2'] = F.MAXDOCACHI2 + vars_composite['MAX_SDOCA'] = F.MAXSDOCA + vars_composite['MAX_SDOCACHI2'] = F.MAXSDOCACHI2 + + #variables for Lb field + var_B = FunctorCollection() + + #variables for basics + vars_basic = FunctorCollection() + vars_basic['TRACKTYPE'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKTYPE @ F.TRACK + vars_basic['TRACKHISTORY'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKHISTORY @ F.TRACK + vars_basic['TRACKFLAG'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKFLAG @ F.TRACK + vars_basic['TRACKNDOF'] = F.VALUE_OR(-1) @ F.NDOF @ F.TRACK + vars_basic['TRACKCHI2'] = F.CHI2 @ F.TRACK + vars_basic['TRACKCHI2DOF'] = F.CHI2DOF @ F.TRACK + vars_basic['GHOSTPROB'] = F.GHOSTPROB + vars_basic['PIDpi'] = F.PID_PI + vars_basic['PIDk'] = F.PID_K + vars_basic['PIDp'] = F.PID_P + vars_basic['PIDe'] = F.PID_E + vars_basic['PIDmu'] = F.PID_MU + + #variables for event + evt_vars = FunctorCollection() + #evt_vars['ALLPV_X[pv_indx]'] = F.ALLPVX(v2_pvs) + #evt_vars['ALLPV_Y[pv_indx]'] = F.ALLPVY(v2_pvs) + #evt_vars['ALLPV_Z[pv_indx]'] = F.ALLPVZ(v2_pvs) + #evt_vars['ALLPV_CHI2[pv_indx]'] = ALLPV_CHI2(v2_pvs) + #evt_vars['ALLPV_CHI2DOF[pv_indx]']= ALLPV_CHI2DOF(v2_pvs) + evt_vars['nTracks'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nTracks") + evt_vars['nLongTracks'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nLongTracks") + evt_vars['nPVs'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nPVs") + evt_vars['nFTClusters'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nFTClusters") + + #return all functors + functors = (vars_common, vars_composite, var_B, vars_basic, evt_vars) + return functors + +def tuple_Bst(Bst, v2_pvs, rec_summary): + #get functors + functors = get_functors(v2_pvs, rec_summary) + vars_common = functors[0] + vars_composite = functors[1] + var_B = functors[2] + vars_basic = functors[3] + evt_vars = functors[4] + + #variables for Sb field + vars_Bst = FunctorCollection() + B_child = F.CHILD(1, F.FORWARDARG0) + Epi_child = F.CHILD(2, F.FORWARDARG0) + bpv_pi = F.BPV(v2_pvs).bind(Epi_child) + #diff in vtx chi2 with and without extra particle + vars_Bst['DELTA_ENDVERTEX_CHI2'] = (F.CHI2 @ F.ENDVERTEX) - (F.CHI2 @ F.ENDVERTEX.bind(B_child)) + #IP and IPChi2 of extra particle wrt to Sb end vertex + vars_Bst['Epi_IP_WRT_SbENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ F.FORWARDARG0 , Epi_child) + vars_Bst['Epi_IPCHI2_WRT_SbENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ F.FORWARDARG0 , Epi_child) + #IP and IPChi2 of extra particle wrt to Lb end vertex + vars_Bst['Epi_IP_WRT_LbENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ B_child , Epi_child) + vars_Bst['Epi_IPCHI2_WRT_LbENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ B_child , Epi_child) + #angle between extra particle and Lb + vars_Bst['Epi_COSANGLE_Lb'] = F.COSANGLE.bind(F.THREEMOMENTUM @ B_child, F.THREEMOMENTUM @ Epi_child) + #diff in fd chi2 with and without extra particle + vars_Bst['Delta_BPV_of_Epi_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi, F.FORWARDARGS) - F.VTX_FDCHI2.bind(bpv_pi, B_child) + vars_Bst['BPV_of_Epi_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi, F.FORWARDARGS) + #IP chi2 of extra particle wrt PV and SV of Sb + vars_Bst['Epi_IP_WRT_SbBPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child) + vars_Bst['Epi_IPCHI2_WRT_SbBPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child) + #IP chi2 of extra particle wrt PV and SV of Bb + vars_Bst['Epi_IP_WRT_LbBPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ B_child, Epi_child) + vars_Bst['Epi_IPCHI2_WRT_LbBPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ B_child, Epi_child) + #DOCA and DOCACHI2 b/w Lb and extra particle + vars_Bst['DOCA12'] = F.DOCA(1, 2) + vars_Bst['DOCA12_CHI2_12'] = F.DOCACHI2(1, 2) + #vars_Bst['SDOCA12'] = F.SDOCA(1, 2) + #vars_Bst['SDOCA_CHI2_12'] = F.SDOCACHI2(1, 2) + #DOCACHI2 of extra particle wrt to mother i.e. Sb + vars_Bst['MTDOCACHI2_1'] = F.MTDOCACHI2(1, v2_pvs) + vars_Bst['MTDOCACHI2_2'] = F.MTDOCACHI2(2, v2_pvs) + vars_Bst['iso_mva'] = mva_functor_mu_inclusive(v2_pvs)[0] + + #define fields + fields_mu = {} + fields_mu['Sb'] = '[B*0 -> (B*- -> Lambda_c+ mu-) [pi+]CC]CC' + fields_mu['Lb'] = '[B*0 -> ^(B*- -> Lambda_c+ mu-) [pi+]CC]CC' + fields_mu['Lc'] = '[B*0 -> (B*- -> ^Lambda_c+ mu-) [pi+]CC]CC' + fields_mu['Lep'] = '[B*0 -> (B*- -> Lambda_c+ ^mu-) [pi+]CC]CC' + fields_mu['Epi'] = '[B*0 -> (B*- -> Lambda_c+ mu-) ^[pi+]CC]CC' + fields_mu['p'] = '[B*0 -> (B*- -> (Lambda_c+ -> ^p+ K- pi+) mu-) [pi+]CC]CC' + fields_mu['Km'] = '[B*0 -> (B*- -> (Lambda_c+ -> p+ ^K- pi+) mu-) [pi+]CC]CC' + fields_mu['pip'] = '[B*0 -> (B*- -> (Lambda_c+ -> p+ K- ^pi+) mu-) [pi+]CC]CC' + + #add variables + variables = {} + variables["ALL"] = vars_common + variables["Sb"] = vars_composite + vars_Bst + variables["Lb"] = vars_composite + var_B + variables["Lc"] = vars_composite + variables["Lep"] = vars_basic + variables["Epi"] = vars_basic + variables["p"] = vars_basic + variables["Km"] = vars_basic + variables["pip"]= vars_basic + + #define tuple + my_tuple = Funtuple( + name="Tuple", + tuple_name="DecayTree", + fields=fields_mu, + variables=variables, + event_variables=evt_vars, + inputs=Bst) + + return my_tuple + +def get_extra_pions(): + """ + Note this function in DaVinci requires: + https://gitlab.cern.ch/lhcb/Moore/-/merge_requests/3203 + and it's related LHCb, DaVinci and Rec MRs + """ + long_pions = make_has_rich_long_pions() + up_pions = make_has_rich_up_pions() + down_pions = make_has_rich_down_pions() + return ParticleContainersMerger([long_pions, up_pions, down_pions], + name='Pions_combiner') + +def main(options: Options): + + #define filer + my_filter = create_lines_filter(name="Filter", lines=['SpruceSLB_LbToLcMuNu_LcToPKPi']) + + #get data and extra particles + lb = get_particles("/Event/Spruce/SpruceSLB_LbToLcMuNu_LcToPKPi/Particles") + extra_particles = get_extra_pions() + + #get v2_pvs and rec_summary + v2_pvs = get_pvs() + rec_summary = get_rec_summary() + + #make sb candidate + Bst = make_Bst(lb, extra_particles) + #MCTRUTH_Bst = MCTruthAndBkgCat(Bst, name='MCTRUTH_Bst') + + tuple_file = tuple_Bst(Bst, v2_pvs, rec_summary) + + #define algorithms + user_algorithms = {} + user_algorithms['Alg'] = [my_filter, tuple_file] + + return make_config(options, user_algorithms) diff --git a/lb_lc_mu_2024data/info.yaml b/lb_lc_mu_2024data/info.yaml new file mode 100644 index 0000000000..903d0f8a86 --- /dev/null +++ b/lb_lc_mu_2024data/info.yaml @@ -0,0 +1,28 @@ +defaults: + inform: + - ching-hua.li@cern.ch + wg: SL + +data_lb_lc_mu: + application: "DaVinci/v64r5" + input: + bk_query: "/LHCb/Collision24/Beam6800GeV-VeloClosed-MagDown-Excl-UT/Real Data/Sprucing24c1/90000000/SL.DST" + dq_flags: + - UNCHECKED + - OK + keep_running: true + n_test_lfns: 1 + output: DATA.ROOT + options: + entrypoint: lb_lc_mu_2024data.DV:main + extra_options: + input_raw_format: 0.5 + input_type: ROOT # ROOT for SprucingPass, RAW for RAW data (Hlt2 output) + simulation: False + #data_type: "Upgrade" + geometry_version: run3/2024.Q1.2-v00.00 + conditions_version: master + input_process: "Spruce" # Spruce for SprucingPass, "Hlt2" for RAW data (Hlt2 output) + input_stream: "sl" # for streamed data + #evt_max: 1000 + -- GitLab From 33c51739f61a4362ff92682a5b391022dc228ea3 Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Wed, 10 Jul 2024 21:48:08 +0200 Subject: [PATCH 45/57] Fix info.yaml --- lb_lc_mu_2024data/info.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lb_lc_mu_2024data/info.yaml b/lb_lc_mu_2024data/info.yaml index 903d0f8a86..e3ab539a95 100644 --- a/lb_lc_mu_2024data/info.yaml +++ b/lb_lc_mu_2024data/info.yaml @@ -20,7 +20,7 @@ data_lb_lc_mu: input_type: ROOT # ROOT for SprucingPass, RAW for RAW data (Hlt2 output) simulation: False #data_type: "Upgrade" - geometry_version: run3/2024.Q1.2-v00.00 + geometry_version: run3/trunk conditions_version: master input_process: "Spruce" # Spruce for SprucingPass, "Hlt2" for RAW data (Hlt2 output) input_stream: "sl" # for streamed data -- GitLab From 201c10b2729da34f514435abe0d200e26c296a7c Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Thu, 18 Jul 2024 14:28:09 +0200 Subject: [PATCH 46/57] Reconstruct two extra pion --- lb_lc_mu_2024data/DV.py | 66 +++++++++----- lb_lc_mu_2024data/isolationMVA.py | 139 ++++++++++++++++++++++++++++++ 2 files changed, 182 insertions(+), 23 deletions(-) create mode 100644 lb_lc_mu_2024data/isolationMVA.py diff --git a/lb_lc_mu_2024data/DV.py b/lb_lc_mu_2024data/DV.py index 84cf179833..b940627275 100644 --- a/lb_lc_mu_2024data/DV.py +++ b/lb_lc_mu_2024data/DV.py @@ -23,6 +23,8 @@ from Hlt2Conf.algorithms_thor import ParticleCombiner, ParticleFilter from Hlt2Conf.algorithms_thor import ParticleContainersMerger from Functors.grammar import Functor from Hlt2Conf.lines.semileptonic.isolationMVA import mva_functor_e_inclusive,mva_functor_mu_inclusive +from .isolationMVA import mva_transform_output,mva_functor_mu_inclusive + _BPVCORRM = Functor('_BPVCORRM', 'Composite::CorrectedMass','Compute the corrected mass') _allpv_FDVEC = (F.ENDVERTEX_POS @ F.FORWARDARG1 - F.TOLINALG @ F.POSITION @ F.FORWARDARG0) @@ -39,7 +41,7 @@ ALLPV_FD_COORDINATE = lambda coordinate, Vertices: F.MAP(coordinate @ _allpv_F TRUE_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.PARTICLE_ID) == id) -def make_Bst(B, pions): +def make_Bst(B, pions,v2_pvs): hadron_cut = F.IS_ABS_ID('Lambda_c+') # Getting the hadron candidates @@ -68,25 +70,28 @@ def make_Bst(B, pions): ParticleCombiner="ParticleVertexFitter", ) - cut_combination = F.require_all(F.MAXDOCA < 8.0, F.MAXDOCACHI2 < 20) + #cut_combination = F.require_all(F.MAXDOCA < 8.0, F.MAXDOCACHI2 < 20) + + MVA_cut = mva_transform_output(0.05) + cut_composite = F.require_all(mva_functor_mu_inclusive(v2_pvs,2) > MVA_cut,mva_functor_mu_inclusive(v2_pvs,3) > MVA_cut) - #combine to make [B*0 -> B*- pi+]cc + #combine to make [B*0 -> B*- pi+ pi-]cc Bst_1 = ParticleCombiner( - Inputs=[Bstm, pions], + Inputs=[Bstm, pions,pions], name='Bst_1', - DecayDescriptor='[B*0 -> B*- pi+]cc', - CombinationCut=cut_combination, - CompositeCut=F.ALL, + DecayDescriptor='[B*0 -> B*- pi+ pi-]cc', + CombinationCut=F.ALL, + CompositeCut=cut_composite, ParticleCombiner="ParticleVertexFitter", #for neutrals need to use different combiner e.g. ParticleAdder #OutputLevel=1 ) - #combine to make [B*0 -> B*- pi-]cc + #combine to make [B*0 -> B*- pi- pi-]cc Bst_2 = ParticleCombiner( - Inputs=[Bstm, pions], + Inputs=[Bstm, pions,pions], name='Bst_2', - DecayDescriptor='[B*0 -> B*- pi-]cc', - CombinationCut=cut_combination, - CompositeCut=F.ALL, + DecayDescriptor='[B*0 -> B*- pi- pi-]cc', + CombinationCut=F.ALL, + CompositeCut=cut_composite, ParticleCombiner="ParticleVertexFitter", #for neutrals need to use different combiner e.g. ParticleAdder #OutputLevel=1 ) @@ -225,18 +230,32 @@ def tuple_Bst(Bst, v2_pvs, rec_summary): #DOCACHI2 of extra particle wrt to mother i.e. Sb vars_Bst['MTDOCACHI2_1'] = F.MTDOCACHI2(1, v2_pvs) vars_Bst['MTDOCACHI2_2'] = F.MTDOCACHI2(2, v2_pvs) - vars_Bst['iso_mva'] = mva_functor_mu_inclusive(v2_pvs)[0] + #Get mva output for 1st and 2nd pion + #mva_first_pion = mva_functor_mu_inclusive(v2_pvs,2)[0] + vars_Bst['iso_mva_1'] = mva_functor_mu_inclusive(v2_pvs,2) + + #mva_second_pion = mva_functor_mu_inclusive(v2_pvs,3)[0] + vars_Bst['iso_mva_2'] = mva_functor_mu_inclusive(v2_pvs,3) + ''' + MVA_cut = mva_transform_output(0.05) + #MVA_cut_functor = (mva_functor_mu_inclusive(v2_pvs,2) > MVA_cut & mva_functor_mu_inclusive(v2_pvs,3) > MVA_cut) + MVA_cut_functor = F.require_all(mva_functor_mu_inclusive(v2_pvs,2) > MVA_cut,mva_functor_mu_inclusive(v2_pvs,3) > MVA_cut) + Bst_mva_cut = ParticleFilter( + Bst, F.FILTER(MVA_cut_functor), name="filter_isoPions" + ) # B + extra track combos passing the MVA cuts + ''' #define fields fields_mu = {} - fields_mu['Sb'] = '[B*0 -> (B*- -> Lambda_c+ mu-) [pi+]CC]CC' - fields_mu['Lb'] = '[B*0 -> ^(B*- -> Lambda_c+ mu-) [pi+]CC]CC' - fields_mu['Lc'] = '[B*0 -> (B*- -> ^Lambda_c+ mu-) [pi+]CC]CC' - fields_mu['Lep'] = '[B*0 -> (B*- -> Lambda_c+ ^mu-) [pi+]CC]CC' - fields_mu['Epi'] = '[B*0 -> (B*- -> Lambda_c+ mu-) ^[pi+]CC]CC' - fields_mu['p'] = '[B*0 -> (B*- -> (Lambda_c+ -> ^p+ K- pi+) mu-) [pi+]CC]CC' - fields_mu['Km'] = '[B*0 -> (B*- -> (Lambda_c+ -> p+ ^K- pi+) mu-) [pi+]CC]CC' - fields_mu['pip'] = '[B*0 -> (B*- -> (Lambda_c+ -> p+ K- ^pi+) mu-) [pi+]CC]CC' + fields_mu['Sb'] = '[B*0 -> (B*- -> Lambda_c+ mu-) [pi+]CC pi-]CC' + fields_mu['Lb'] = '[B*0 -> ^(B*- -> Lambda_c+ mu-) [pi+]CC pi-]CC' + fields_mu['Lc'] = '[B*0 -> (B*- -> ^Lambda_c+ mu-) [pi+]CC pi-]CC' + fields_mu['Lep'] = '[B*0 -> (B*- -> Lambda_c+ ^mu-) [pi+]CC pi-]CC' + fields_mu['Epi1'] = '[B*0 -> (B*- -> Lambda_c+ mu-) ^[pi+]CC pi-]CC' + fields_mu['Epi2'] = '[B*0 -> (B*- -> Lambda_c+ mu-) [pi+]CC ^pi-]CC' + fields_mu['p'] = '[B*0 -> (B*- -> (Lambda_c+ -> ^p+ K- pi+) mu-) [pi+]CC pi-]CC' + fields_mu['Km'] = '[B*0 -> (B*- -> (Lambda_c+ -> p+ ^K- pi+) mu-) [pi+]CC pi-]CC' + fields_mu['pip'] = '[B*0 -> (B*- -> (Lambda_c+ -> p+ K- ^pi+) mu-) [pi+]CC pi-]CC' #add variables variables = {} @@ -245,7 +264,8 @@ def tuple_Bst(Bst, v2_pvs, rec_summary): variables["Lb"] = vars_composite + var_B variables["Lc"] = vars_composite variables["Lep"] = vars_basic - variables["Epi"] = vars_basic + variables["Epi1"] = vars_basic + variables["Epi2"] = vars_basic variables["p"] = vars_basic variables["Km"] = vars_basic variables["pip"]= vars_basic @@ -287,7 +307,7 @@ def main(options: Options): rec_summary = get_rec_summary() #make sb candidate - Bst = make_Bst(lb, extra_particles) + Bst = make_Bst(lb, extra_particles,v2_pvs) #MCTRUTH_Bst = MCTruthAndBkgCat(Bst, name='MCTRUTH_Bst') tuple_file = tuple_Bst(Bst, v2_pvs, rec_summary) diff --git a/lb_lc_mu_2024data/isolationMVA.py b/lb_lc_mu_2024data/isolationMVA.py new file mode 100644 index 0000000000..92f9ae0700 --- /dev/null +++ b/lb_lc_mu_2024data/isolationMVA.py @@ -0,0 +1,139 @@ +############################################################################### +# (c) Copyright 2024 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### +import Functors as F +from Hlt2Conf.algorithms_thor import ParticleCombiner +from Hlt2Conf.algorithms_thor import ParticleContainersMerger +from Hlt2Conf.algorithms_thor import ParticleFilter +from RecoConf.reconstruction_objects import make_pvs +import Functors.math as fmath +import math +import re +from dataclasses import dataclass +from PyConf.Algorithms import ThOrParticleSelection + +#Multiplying by this number will convert log_e to log_10 +#we multiply by log10(e) rather than dividing by ln(10) +#since multiplication is faster +LOG10_E = math.log10(math.e) +#toggle for printing debug messages +#set to False for proper productions +DEBUG = False + + +@dataclass +class MVAinput: + """Struct for storing MVA input variables""" + name: str # The name of the var (as per the model) + number: int # The number of the var + functor: F.grammar.FunctorBase # The functor to calculate that variable + x_range: (float, float) # axis range for input var monitoring histos + + +def mva_functor_mu_inclusive(v2_pvs, + index_pion, + useNumbers: bool = False): + """ + Compute the output of the MVA classifier (xGBoost) for charged track isolation. + Higher values of MVA classifier output indicate that the charged track is less isolated + and is more likely to be associated to be coming from the same decay vertex as the B0. + For more details: Checkout the presentation https://indico.cern.ch/event/1234758/#sc-1-4-ml-based-charged-isolat + + Args: + v2_pvs (list): TES location of v2 PVs + useNumbers (bool): decision of whether to use the numbers or names of vars in the MVA functor + """ + #get the children of the two-body combination (B0-extraparticle) + Bstar_p_child = F.CHILD(1, F.FORWARDARGS) + ExtraParticle_child = F.CHILD(index_pion, F.FORWARDARGS) + + #define the input variables for mva + mva_input_vars = [] #FunctorCollection() + #define Impact parameter chi2 of the extra particle wrt to the BPV associated to the two-body combination (B0-extraparticle) + mva_input_vars.append( + MVAinput("Epi_BPV_IPCHI2", 0, + F.BPVIPCHI2(v2_pvs).bind(ExtraParticle_child), (0, 20))) # PV + #define PT of two body combination (B0-extraparticle). Here is transformed to be less peaky + mva_input_vars.append( + MVAinput("Epi_PT", 1, + fmath.log(F.PT.bind(ExtraParticle_child)) * LOG10_E, (1, 5))) + #define opening angle between B0 and extra particle. Here is transformed to be less peaky + cos_angle = F.COSANGLE.bind(F.THREEMOMENTUM @ Bstar_p_child, + F.THREEMOMENTUM @ ExtraParticle_child) + mva_input_vars.append( + MVAinput("Sb_Epi_COSANGLE_Lb", 2, 1. - fmath.pow(1. - cos_angle, 0.2), + (0, 1))) + #define DIRA of the two body combination (B0-extraparticle) + mva_input_vars.append( + MVAinput("Sb_BPV_DIRA_TF", 8, fmath.pow(1. - F.BPVDIRA(v2_pvs), 0.2), + (0, 1.2))) + #define magnitude of PV distance i.e. distance between PV and vertex of two-body combination (B0-extraparticle) + # NB: the sign of the magnitude deterimined by the by the difference in z-coordinate of PV and vertex of two-body combination + mva_input_vars.append( + MVAinput("PVdis", 3, + (F.MAGNITUDE @ (F.ENDVERTEX_POS - F.BPV_POS(v2_pvs))) * + fmath.sign(F.END_VZ - F.BPVZ(v2_pvs)), (-50, 100))) + #* F.MAGNITUDE @ (F.ENDVERTEX_POS - F.BPV_POS(v2_pvs)) + #define magnitude of SV distance i.e. distance between two-body combination (B0-extraparticle) vertex and the vertex + # without the extra particle included. The sign of the magnitude is determined by the difference in z-coordinate of both vertices + mva_input_vars.append( + MVAinput("SVdis", 4, + (F.MAGNITUDE + @ (F.ENDVERTEX_POS.bind(Bstar_p_child) - F.ENDVERTEX_POS)) * + fmath.sign(F.END_VZ - F.END_VZ.bind(Bstar_p_child)), + (-50, 50))) + #define DeltaR i.e. the difference in radius of B0 and extra particle in the rapidity-azimuth plane + delta_eta = F.ETA.bind(Bstar_p_child) - F.ETA.bind(ExtraParticle_child) + delta_phi = F.PHI.bind(Bstar_p_child) - F.PHI.bind(ExtraParticle_child) + delta_phi = fmath.where(delta_phi > math.pi, delta_phi - math.pi, + delta_phi) + delta_phi = fmath.where(delta_phi < -math.pi, delta_phi + math.pi, + delta_phi) + mva_input_vars.append( + MVAinput( + "DeltaREpi", 5, + fmath.pow( + fmath.sqrt( + fmath.pow(delta_eta, 2.) + fmath.pow(delta_phi, 2.)), 0.2), + (0, 1.5))) + + mva_input_vars.append( + MVAinput("Sb_MAX_DOCACHI2", 6, + fmath.log(F.SDOCACHI2(1, index_pion)) * LOG10_E, (-2.6, 7.5))) + mva_input_vars.append( + MVAinput( + "Sb_Epi_IPCHI2_WRT_LbENDVERTEX", 7, + fmath.log( + F.IPCHI2.bind(F.ENDVERTEX @ Bstar_p_child, + ExtraParticle_child)) * LOG10_E, (-2, 6))) # SV + + #define the mva classifier + mva = F.MVA( + MVAType='TMVA', + Config={ + 'XMLFile': 'paramfile://data/xgboost_model_cocktail_inclusive.xml', + 'Name': 'BDT', + }, + Inputs={(f"f[{var.number}]" if useNumbers else var.name): var.functor + for var in mva_input_vars}) + return mva + +def mva_transform_output(xgboost_style_input: float) -> float: + """ + We've converted our input from xgboost-style to TMVA-style but this gives a transformation on the cut variables + This function converts from an xgboost-style cut to the corresponding TMVA-style + taken from: https://github.com/jpata/mlglue/blob/master/mlglue/tree.py#L400-L409 + This takes the domain from [0,1] and transforms it from [-1,1] in a strange (nonlinear) way + """ + TMVA_style_output = -math.log(1. / xgboost_style_input - 1.) + TMVA_style_output = 2. / (1. + math.exp(-2. * TMVA_style_output)) - 1. + + return TMVA_style_output + -- GitLab From ab5560ed21f3e6630c4bead1f6f82a4c8cd6b7b1 Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Sat, 20 Jul 2024 22:57:34 +0200 Subject: [PATCH 47/57] Add MC --- lb_lc_mu_2024data/DV.py | 181 +++++++++++++++++++++++++++--------- lb_lc_mu_2024data/Hlt1.py | 18 ++++ lb_lc_mu_2024data/Hlt2.py | 55 +++++++++++ lb_lc_mu_2024data/Spruce.py | 29 ++++++ lb_lc_mu_2024data/info.yaml | 110 +++++++++++++++++++++- 5 files changed, 349 insertions(+), 44 deletions(-) create mode 100644 lb_lc_mu_2024data/Hlt1.py create mode 100644 lb_lc_mu_2024data/Hlt2.py create mode 100644 lb_lc_mu_2024data/Spruce.py diff --git a/lb_lc_mu_2024data/DV.py b/lb_lc_mu_2024data/DV.py index b940627275..ce3f7eef71 100644 --- a/lb_lc_mu_2024data/DV.py +++ b/lb_lc_mu_2024data/DV.py @@ -22,8 +22,8 @@ from Hlt2Conf.standard_particles import make_has_rich_long_pions,make_has_rich_u from Hlt2Conf.algorithms_thor import ParticleCombiner, ParticleFilter from Hlt2Conf.algorithms_thor import ParticleContainersMerger from Functors.grammar import Functor -from Hlt2Conf.lines.semileptonic.isolationMVA import mva_functor_e_inclusive,mva_functor_mu_inclusive -from .isolationMVA import mva_transform_output,mva_functor_mu_inclusive +from Hlt2Conf.lines.semileptonic.isolationMVA import mva_functor_mu_inclusive,mva_transform_output +from .isolationMVA import mva_functor_mu_inclusive as mva_functor_inclusive _BPVCORRM = Functor('_BPVCORRM', 'Composite::CorrectedMass','Compute the corrected mass') @@ -41,8 +41,7 @@ ALLPV_FD_COORDINATE = lambda coordinate, Vertices: F.MAP(coordinate @ _allpv_F TRUE_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.PARTICLE_ID) == id) -def make_Bst(B, pions,v2_pvs): - +def make_Bst_2pi(B, pions,v2_pvs,prepare_pion): hadron_cut = F.IS_ABS_ID('Lambda_c+') # Getting the hadron candidates @@ -72,34 +71,82 @@ def make_Bst(B, pions,v2_pvs): #cut_combination = F.require_all(F.MAXDOCA < 8.0, F.MAXDOCACHI2 < 20) - MVA_cut = mva_transform_output(0.05) - cut_composite = F.require_all(mva_functor_mu_inclusive(v2_pvs,2) > MVA_cut,mva_functor_mu_inclusive(v2_pvs,3) > MVA_cut) - - #combine to make [B*0 -> B*- pi+ pi-]cc - Bst_1 = ParticleCombiner( - Inputs=[Bstm, pions,pions], - name='Bst_1', + if prepare_pion=='True': + MVA_cut = mva_transform_output(0.05) + cut_composite = F.require_all(mva_functor_mu_inclusive(v2_pvs)[0] > MVA_cut) + + #first make [B*0 -> B*- pi+]cc + Bst_1 = ParticleCombiner( + Inputs=[Bstm, pions], + name='Bst_1', + DecayDescriptor='[B*0 -> B*- pi+]cc', + CombinationCut=F.ALL, + CompositeCut=cut_composite, + ParticleCombiner="ParticleVertexFitter", #for neutrals need to use different combiner e.g. ParticleAdder + #OutputLevel=1 + ) + Bst_2 = ParticleCombiner( + Inputs=[Bstm, pions], + name='Bst_2', + DecayDescriptor='[B*0 -> B*- pi-]cc', + CombinationCut=F.ALL, + CompositeCut=cut_composite, + ParticleCombiner="ParticleVertexFitter", #for neutrals need to use different combiner e.g. ParticleAdder + #OutputLevel=1 + ) + #merge the two Bst candidates + Bst = ParticleContainersMerger([Bst_1, Bst_2], name = 'Bst_combiner') + + #prepare filtered pion + pion_cut = F.IS_ABS_ID('pi+') # Getting the filtered pion candidates + + code_pion = F.FILTER(pion_cut) @ F.GET_CHILDREN() + pion_TES = ThOrParticleSelection( + name="pion_iso", + InputParticles=Bst, + Functor=code_pion).OutputSelection + ''' + #prepare filtered Bstm + Bstm_cut = F.IS_ABS_ID('B*+') # Getting the filtered B*+ candidates + + code_Bstm = F.FILTER(Bstm_cut) @ F.GET_CHILDREN() + Bstm_TES = ThOrParticleSelection( + name="Bstm_iso", + InputParticles=Bst, + Functor=code_Bstm).OutputSelection + ''' + else : pion_TES = pions + + #make Lc mu pi pi + Bst_2pi_1 = ParticleCombiner( + Inputs=[Bstm, pion_TES, pion_TES], + name='Bst_2pi_1', DecayDescriptor='[B*0 -> B*- pi+ pi-]cc', CombinationCut=F.ALL, - CompositeCut=cut_composite, + CompositeCut=F.ALL, ParticleCombiner="ParticleVertexFitter", #for neutrals need to use different combiner e.g. ParticleAdder #OutputLevel=1 ) - #combine to make [B*0 -> B*- pi- pi-]cc - Bst_2 = ParticleCombiner( - Inputs=[Bstm, pions,pions], - name='Bst_2', + Bst_2pi_2 = ParticleCombiner( + Inputs=[Bstm, pion_TES, pion_TES], + name='Bst_2pi_2', DecayDescriptor='[B*0 -> B*- pi- pi-]cc', CombinationCut=F.ALL, - CompositeCut=cut_composite, + CompositeCut=F.ALL, ParticleCombiner="ParticleVertexFitter", #for neutrals need to use different combiner e.g. ParticleAdder #OutputLevel=1 ) #merge the two Bst candidates - Bst = ParticleContainersMerger([Bst_1, Bst_2], name = 'Bst_combiner') - return Bst + Bst_2pi = ParticleContainersMerger([Bst_2pi_1, Bst_2pi_2], name = 'Bst_2pi_combiner') + + + return Bst_2pi -def get_functors(v2_pvs, rec_summary): + + + + +def get_functors(MCTRUTH, v2_pvs, rec_summary): #define common variables for all fields (composite and basic) vars_common = FunctorCollection() #all pvs: ip, ipchi2. The PV positions are stored in event variables @@ -124,6 +171,25 @@ def get_functors(v2_pvs, rec_summary): vars_common += FC.Kinematics() vars_common['ETA'] = F.ETA vars_common['PHI'] = F.PHI + if MCTRUTH != 'None': + #mc vars + vars_common['TRUEKEY'] = F.VALUE_OR(-1) @ MCTRUTH(F.OBJECT_KEY) + vars_common += FC.MCKinematics(mctruth_alg = MCTRUTH) + vars_common['TRUEETA'] = MCTRUTH(F.ETA) + vars_common['TRUEPHI'] = MCTRUTH(F.PHI) + #type of the origin vertex + vars_common['MC_VTX_TYPE'] = MCTRUTH(F.VALUE_OR(-1) @ F.MC_VTX_TYPE @ F.MC_ORIGINVERTEX) + #make some helper functions + MCMOTHER_ID = lambda n: F.VALUE_OR(0) @ MCTRUTH(F.MC_MOTHER(n, F.PARTICLE_ID)) + MCMOTHER_KEY = lambda n: F.VALUE_OR(-1) @ MCTRUTH(F.MC_MOTHER(n, F.OBJECT_KEY )) + vars_common["TRUEID"] = F.VALUE_OR(0) @ MCTRUTH(F.PARTICLE_ID) + vars_common["MCKEY"] = F.VALUE_OR(0) @ MCTRUTH(F.OBJECT_KEY) + vars_common["MC_MOTHER_ID"] = MCMOTHER_ID(1) + vars_common["MC_MOTHER_KEY"] = MCMOTHER_KEY(1) + for i in range(2,14): + prefix = "MC_GD_MOTHER_{}".format(i) + vars_common[f"{prefix}_ID"] = MCMOTHER_ID(i) + vars_common[f"{prefix}_KEY"] = MCMOTHER_KEY(i) #variables for composite particles vars_composite = FunctorCollection() @@ -189,9 +255,9 @@ def get_functors(v2_pvs, rec_summary): functors = (vars_common, vars_composite, var_B, vars_basic, evt_vars) return functors -def tuple_Bst(Bst, v2_pvs, rec_summary): +def tuple_Bst(Bst, MCTRUTH,v2_pvs, rec_summary): #get functors - functors = get_functors(v2_pvs, rec_summary) + functors = get_functors(MCTRUTH,v2_pvs, rec_summary) vars_common = functors[0] vars_composite = functors[1] var_B = functors[2] @@ -201,42 +267,59 @@ def tuple_Bst(Bst, v2_pvs, rec_summary): #variables for Sb field vars_Bst = FunctorCollection() B_child = F.CHILD(1, F.FORWARDARG0) - Epi_child = F.CHILD(2, F.FORWARDARG0) - bpv_pi = F.BPV(v2_pvs).bind(Epi_child) + Epi_child1 = F.CHILD(2, F.FORWARDARG0) + Epi_child2 = F.CHILD(3, F.FORWARDARG0) + bpv_pi1 = F.BPV(v2_pvs).bind(Epi_child1) + bpv_pi2 = F.BPV(v2_pvs).bind(Epi_child2) #diff in vtx chi2 with and without extra particle vars_Bst['DELTA_ENDVERTEX_CHI2'] = (F.CHI2 @ F.ENDVERTEX) - (F.CHI2 @ F.ENDVERTEX.bind(B_child)) #IP and IPChi2 of extra particle wrt to Sb end vertex - vars_Bst['Epi_IP_WRT_SbENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ F.FORWARDARG0 , Epi_child) - vars_Bst['Epi_IPCHI2_WRT_SbENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ F.FORWARDARG0 , Epi_child) + vars_Bst['Epi1_IP_WRT_SbENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ F.FORWARDARG0 , Epi_child1) + vars_Bst['Epi1_IPCHI2_WRT_SbENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ F.FORWARDARG0 , Epi_child1) + vars_Bst['Epi2_IP_WRT_SbENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ F.FORWARDARG0 , Epi_child1) + vars_Bst['Epi2_IPCHI2_WRT_SbENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ F.FORWARDARG0 , Epi_child1) #IP and IPChi2 of extra particle wrt to Lb end vertex - vars_Bst['Epi_IP_WRT_LbENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ B_child , Epi_child) - vars_Bst['Epi_IPCHI2_WRT_LbENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ B_child , Epi_child) + vars_Bst['Epi1_IP_WRT_LbENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ B_child , Epi_child1) + vars_Bst['Epi1_IPCHI2_WRT_LbENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ B_child , Epi_child1) + vars_Bst['Epi2_IP_WRT_LbENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ B_child , Epi_child2) + vars_Bst['Epi2_IPCHI2_WRT_LbENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ B_child , Epi_child2) #angle between extra particle and Lb - vars_Bst['Epi_COSANGLE_Lb'] = F.COSANGLE.bind(F.THREEMOMENTUM @ B_child, F.THREEMOMENTUM @ Epi_child) + vars_Bst['Epi1_COSANGLE_Lb'] = F.COSANGLE.bind(F.THREEMOMENTUM @ B_child, F.THREEMOMENTUM @ Epi_child1) + vars_Bst['Epi2_COSANGLE_Lb'] = F.COSANGLE.bind(F.THREEMOMENTUM @ B_child, F.THREEMOMENTUM @ Epi_child2) #diff in fd chi2 with and without extra particle - vars_Bst['Delta_BPV_of_Epi_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi, F.FORWARDARGS) - F.VTX_FDCHI2.bind(bpv_pi, B_child) - vars_Bst['BPV_of_Epi_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi, F.FORWARDARGS) + vars_Bst['Delta_BPV_of_Epi1_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi1, F.FORWARDARGS) - F.VTX_FDCHI2.bind(bpv_pi1, B_child) + vars_Bst['Delta_BPV_of_Epi2_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi2, F.FORWARDARGS) - F.VTX_FDCHI2.bind(bpv_pi1, B_child) + vars_Bst['BPV_of_Epi1_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi1, F.FORWARDARGS) + vars_Bst['BPV_of_Epi2_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi2, F.FORWARDARGS) #IP chi2 of extra particle wrt PV and SV of Sb - vars_Bst['Epi_IP_WRT_SbBPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child) - vars_Bst['Epi_IPCHI2_WRT_SbBPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child) + vars_Bst['Epi1_IP_WRT_SbBPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child1) + vars_Bst['Epi1_IPCHI2_WRT_SbBPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child1) + vars_Bst['Epi2_IP_WRT_SbBPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child2) + vars_Bst['Epi2_IPCHI2_WRT_SbBPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child2) #IP chi2 of extra particle wrt PV and SV of Bb - vars_Bst['Epi_IP_WRT_LbBPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ B_child, Epi_child) - vars_Bst['Epi_IPCHI2_WRT_LbBPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ B_child, Epi_child) + vars_Bst['Epi1_IP_WRT_LbBPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ B_child, Epi_child1) + vars_Bst['Epi1_IPCHI2_WRT_LbBPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ B_child, Epi_child1) + vars_Bst['Epi2_IP_WRT_LbBPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ B_child, Epi_child2) + vars_Bst['Epi2_IPCHI2_WRT_LbBPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ B_child, Epi_child2) #DOCA and DOCACHI2 b/w Lb and extra particle vars_Bst['DOCA12'] = F.DOCA(1, 2) vars_Bst['DOCA12_CHI2_12'] = F.DOCACHI2(1, 2) + vars_Bst['DOCA13'] = F.DOCA(1, 3) + vars_Bst['DOCA12_CHI2_13'] = F.DOCACHI2(1, 3) #vars_Bst['SDOCA12'] = F.SDOCA(1, 2) #vars_Bst['SDOCA_CHI2_12'] = F.SDOCACHI2(1, 2) #DOCACHI2 of extra particle wrt to mother i.e. Sb vars_Bst['MTDOCACHI2_1'] = F.MTDOCACHI2(1, v2_pvs) vars_Bst['MTDOCACHI2_2'] = F.MTDOCACHI2(2, v2_pvs) + vars_Bst['MTDOCACHI2_3'] = F.MTDOCACHI2(3, v2_pvs) #Get mva output for 1st and 2nd pion #mva_first_pion = mva_functor_mu_inclusive(v2_pvs,2)[0] - vars_Bst['iso_mva_1'] = mva_functor_mu_inclusive(v2_pvs,2) + vars_Bst['iso_mva_1'] = mva_functor_inclusive(v2_pvs,2) #mva_second_pion = mva_functor_mu_inclusive(v2_pvs,3)[0] - vars_Bst['iso_mva_2'] = mva_functor_mu_inclusive(v2_pvs,3) + vars_Bst['iso_mva_2'] = mva_functor_inclusive(v2_pvs,3) + ''' MVA_cut = mva_transform_output(0.05) #MVA_cut_functor = (mva_functor_mu_inclusive(v2_pvs,2) > MVA_cut & mva_functor_mu_inclusive(v2_pvs,3) > MVA_cut) @@ -293,27 +376,39 @@ def get_extra_pions(): return ParticleContainersMerger([long_pions, up_pions, down_pions], name='Pions_combiner') -def main(options: Options): +def main(options: Options,data_or_mc='mc'): #define filer my_filter = create_lines_filter(name="Filter", lines=['SpruceSLB_LbToLcMuNu_LcToPKPi']) #get data and extra particles lb = get_particles("/Event/Spruce/SpruceSLB_LbToLcMuNu_LcToPKPi/Particles") - extra_particles = get_extra_pions() #get v2_pvs and rec_summary v2_pvs = get_pvs() rec_summary = get_rec_summary() - #make sb candidate - Bst = make_Bst(lb, extra_particles,v2_pvs) - #MCTRUTH_Bst = MCTruthAndBkgCat(Bst, name='MCTRUTH_Bst') + if data_or_mc == 'mc': + extra_particles = get_particles("/Event/Spruce/SpruceSLB_LbToLcMuNu_LcToPKPi/SpruceSLB_LbToLcMuNu_LcToPKPi_extra_tracks") + #make sb candidate + Bst = make_Bst_2pi(lb, extra_particles,v2_pvs,'False') + MCTRUTH_Bst = MCTruthAndBkgCat(Bst, name='MCTRUTH_Bst') + tuple_file = tuple_Bst(Bst,MCTRUTH_Bst, v2_pvs, rec_summary) - tuple_file = tuple_Bst(Bst, v2_pvs, rec_summary) + elif data_or_mc == 'data': + extra_particles = get_extra_pions() + #make sb candidate + Bst = make_Bst_2pi(lb, extra_particles,v2_pvs,'True') + tuple_file = tuple_Bst(Bst,'None', v2_pvs, rec_summary) #define algorithms user_algorithms = {} user_algorithms['Alg'] = [my_filter, tuple_file] return make_config(options, user_algorithms) + +def MC_SLB_LbToLcMuNu_LcToPKPi(options: Options): + return main(options=options,data_or_mc='mc') + +def Data_SLB_LbToLcMuNu_LcToPKPi(options: Options): + return main(options=options,data_or_mc='data') diff --git a/lb_lc_mu_2024data/Hlt1.py b/lb_lc_mu_2024data/Hlt1.py new file mode 100644 index 0000000000..eeabcc4913 --- /dev/null +++ b/lb_lc_mu_2024data/Hlt1.py @@ -0,0 +1,18 @@ +############################################################################### +# (c) Copyright 2022 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### +from Moore import Options +from Moore.config import run_allen +from RecoConf.hlt1_allen import allen_gaudi_config as allen_sequence + +def main(options: Options): + with allen_sequence.bind(sequence="hlt1_pp_matching_no_ut_1000KHz"): + return run_allen(options) + diff --git a/lb_lc_mu_2024data/Hlt2.py b/lb_lc_mu_2024data/Hlt2.py new file mode 100644 index 0000000000..c9da3abacc --- /dev/null +++ b/lb_lc_mu_2024data/Hlt2.py @@ -0,0 +1,55 @@ +############################################################################### +# (c) Copyright 2022 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### +""" +Stolen and adapted from Hlt/Hlt2Conf/options/hlt2_pp_expected_24_without_UT.py from v55r7. +""" +from Moore import Options,options, run_moore, config +from Hlt2Conf.settings.defaults import get_default_hlt1_filter_code_for_hlt2 +from Hlt2Conf.lines.semileptonic.hlt2_semileptonic import hlt2_lbtolcmunu_lctopkpi_line +from Moore.config import Hlt2Line,register_line_builder +from Moore.streams import Stream, Streams, DETECTORS +from RecoConf.event_filters import require_gec +from RecoConf.global_tools import stateProvider_with_simplified_geom, trackMasterExtrapolator_with_simplified_geom +from RecoConf.hlt2_global_reco import reconstruction as hlt2_reconstruction, make_light_reco_pr_kf_without_UT +from RecoConf.reconstruction_objects import reconstruction,make_pvs +from RecoConf.decoders import default_ft_decoding_version,default_VeloCluster_source +from RecoConf.hlt2_tracking import ( + make_TrackBestTrackCreator_tracks, + make_PrKalmanFilter_noUT_tracks, + make_PrKalmanFilter_Velo_tracks, + make_PrKalmanFilter_Seed_tracks, +) +import Functors as F +from Functors.math import in_range +import sys + +def make_lines(): + lines = [hlt2_lbtolcmunu_lctopkpi_line()] + return lines + +public_tools = [ + trackMasterExtrapolator_with_simplified_geom(), + stateProvider_with_simplified_geom(), +] + +def main(options: Options): + # NOTE: the TBTC does not apply a chi2 cut because it is applied by the PrKF + with reconstruction.bind(from_file=False),\ + hlt2_reconstruction.bind(make_reconstruction=make_light_reco_pr_kf_without_UT),\ + require_gec.bind(skipUT=True),\ + default_VeloCluster_source.bind(bank_type="VPRetinaCluster"),\ + make_TrackBestTrackCreator_tracks.bind(max_ghost_prob=0.7, max_chi2ndof=sys.float_info.max),\ + make_PrKalmanFilter_Velo_tracks.bind(max_chi2ndof=5.),\ + make_PrKalmanFilter_noUT_tracks.bind(max_chi2ndof=4.),\ + make_PrKalmanFilter_Seed_tracks.bind(max_chi2ndof=6.),\ + get_default_hlt1_filter_code_for_hlt2.bind(code=r"Hlt1(?!PassthroughLargeEvent).*Decision"): + return run_moore(options, make_lines, public_tools) + diff --git a/lb_lc_mu_2024data/Spruce.py b/lb_lc_mu_2024data/Spruce.py new file mode 100644 index 0000000000..0905170094 --- /dev/null +++ b/lb_lc_mu_2024data/Spruce.py @@ -0,0 +1,29 @@ +############################################################################### +# (c) Copyright 2022 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### +#Example follows from hlt2_with_hlt1_decision.py +from Moore import Options,options, run_moore, config +from Hlt2Conf.lines.semileptonic.spruce_semileptonic import spruce_lbtolcmunu_lctopkpi_line +from PyConf.application import configure_input, configure, default_raw_event +from RecoConf.global_tools import stateProvider_with_simplified_geom +from RecoConf.reconstruction_objects import reconstruction +from PyConf.reading import reconstruction as reco_spruce, upfront_reconstruction as upfront_spruce +from RecoConf.decoders import default_ft_decoding_version + +def make_lines(): + lines = [spruce_lbtolcmunu_lctopkpi_line()] + return lines + +def main(options: Options): + public_tools = [stateProvider_with_simplified_geom()] + with reconstruction.bind(from_file=True, spruce=True),\ + reco_spruce.bind(simulation=True),\ + upfront_spruce.bind(simulation=True),\ + return run_moore(options, make_lines, public_tools=public_tools) diff --git a/lb_lc_mu_2024data/info.yaml b/lb_lc_mu_2024data/info.yaml index e3ab539a95..b6c0066ad2 100644 --- a/lb_lc_mu_2024data/info.yaml +++ b/lb_lc_mu_2024data/info.yaml @@ -2,6 +2,114 @@ defaults: inform: - ching-hua.li@cern.ch wg: SL +{%- set datasets = [ + ('15576010','lb_lc2593_mu'), + ('15576011','lb_lc2625_mu'), + ('15876031','lb_lc2880_mu'), +] %} + +{%- set polarity_variables = [ + ('MagDown','sim-20231017-vc-md100'), + ('MagUp','sim-20231017-vc-mu100'), +]%} + +{%- for polarity, cond_tag in polarity_variables %} + {%- for evttype, dk in datasets %} +HLT1_{{dk}}_{{ polarity }}: + #application: "Moore/v55r7@x86_64_v3-el9-gcc13+detdesc-opt+g" + application: "Moore/v55r8@x86_64_v3-el9-gcc13+detdesc-opt+g" + input: + bk_query: "/MC/Dev/Beam6800GeV-expected-2024-{{polarity}}-Nu7.6-25ns-Pythia8/Sim10c/{{evttype}}/DIGI" + dq_flags: + - OK + n_test_lfns: 1 + output: hlt1.dst + options: + entrypoint: lb_lc_mu_2024data.Hlt1:main + extra_options: + input_raw_format: 0.3 + conddb_tag: {{cond_tag}} + dddb_tag: dddb-20231017 + input_type: ROOT + output_type: ROOT + simulation: True + data_type: "Upgrade" + scheduler_legacy_mode: False + compression: + algorithm: ZSTD + level: 1 + max_buffer_size: 1048576 + #evt_max: 1000 + +HLT2_{{dk}}_{{ polarity }}: + #application: "Moore/v55r7p3@x86_64_v3-el9-gcc13+detdesc-opt+g" + application: "Moore/v55r8@x86_64_v3-el9-gcc13+detdesc-opt+g" + input: + job_name: HLT1_{{dk}}_{{ polarity }} + output: hlt2.dst + options: + entrypoint: lb_lc_mu_2024data.Hlt2:main + extra_options: + input_raw_format: 0.5 + conddb_tag: {{cond_tag}} + dddb_tag: dddb-20231017 + input_type: ROOT + output_type: ROOT + simulation: True + data_type: "Upgrade" + scheduler_legacy_mode: False + output_manifest_file: "HLT2.tck.json" + compression: + algorithm: ZSTD + level: 1 + max_buffer_size: 1048576 + #evt_max: 1000 +SPRUCE_{{dk}}_{{ polarity }}: + #application: "Moore/v55r7p3@x86_64_v3-el9-gcc13+detdesc-opt+g" + application: "Moore/v55r8@x86_64_v3-el9-gcc13+detdesc-opt+g" + input: + job_name: HLT2_{{dk}}_{{ polarity }} + output: spruce.dst + options: + entrypoint: lb_lc_mu_2024data.Spruce:main + extra_options: + input_raw_format: 0.5 + conddb_tag: {{cond_tag}} + dddb_tag: dddb-20231017 + input_type: ROOT + output_type: ROOT + simulation: True + data_type: "Upgrade" + scheduler_legacy_mode: False + input_process: "Hlt2" + input_manifest_file: "HLT2.tck.json" + output_manifest_file: "SPRUCE.tck.json" + compression: + algorithm: ZSTD + level: 1 + max_buffer_size: 1048576 + #evt_max: 1000 +DV_{{dk}}_{{ polarity }}: + application: "DaVinci/v64r5@x86_64_v2-el9-clang16-opt" + input: + job_name: SPRUCE_{{dk}}_{{ polarity }} + output: NTuple.root + options: + entrypoint: lb_lc_mu_2024data.DV:MC_SLB_LbToLcMuNu_LcToPKPi + extra_options: + input_raw_format: 0.5 + conddb_tag: {{cond_tag}} + dddb_tag: dddb-20231017 + input_type: ROOT + simulation: True + data_type: "Upgrade" + #geometry_version: run3/2024.Q1.2-v00.00 + input_process: "Spruce" + input_manifest_file: "SPRUCE.tck.json" + #evt_max: 1000 + + {%- endfor %} +{%- endfor %} data_lb_lc_mu: application: "DaVinci/v64r5" @@ -14,7 +122,7 @@ data_lb_lc_mu: n_test_lfns: 1 output: DATA.ROOT options: - entrypoint: lb_lc_mu_2024data.DV:main + entrypoint: lb_lc_mu_2024data.DV:Data_SLB_LbToLcMuNu_LcToPKPi extra_options: input_raw_format: 0.5 input_type: ROOT # ROOT for SprucingPass, RAW for RAW data (Hlt2 output) -- GitLab From 811e6c43d450e83e5f17cdff82334a4b589630a3 Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Sat, 20 Jul 2024 23:59:51 +0200 Subject: [PATCH 48/57] Fix bug --- lb_lc_mu_2024data/Spruce.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lb_lc_mu_2024data/Spruce.py b/lb_lc_mu_2024data/Spruce.py index 0905170094..b864401501 100644 --- a/lb_lc_mu_2024data/Spruce.py +++ b/lb_lc_mu_2024data/Spruce.py @@ -25,5 +25,5 @@ def main(options: Options): public_tools = [stateProvider_with_simplified_geom()] with reconstruction.bind(from_file=True, spruce=True),\ reco_spruce.bind(simulation=True),\ - upfront_spruce.bind(simulation=True),\ + upfront_spruce.bind(simulation=True): return run_moore(options, make_lines, public_tools=public_tools) -- GitLab From 281be48d9fb292cc224dc0541c9cd29a8f7ef9e9 Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Tue, 30 Jul 2024 08:51:20 +0200 Subject: [PATCH 49/57] Change DV version --- lb_lc_mu_2024data/info.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lb_lc_mu_2024data/info.yaml b/lb_lc_mu_2024data/info.yaml index b6c0066ad2..94531e876e 100644 --- a/lb_lc_mu_2024data/info.yaml +++ b/lb_lc_mu_2024data/info.yaml @@ -90,7 +90,7 @@ SPRUCE_{{dk}}_{{ polarity }}: max_buffer_size: 1048576 #evt_max: 1000 DV_{{dk}}_{{ polarity }}: - application: "DaVinci/v64r5@x86_64_v2-el9-clang16-opt" + application: "DaVinci/v64r7@x86_64_v2-el9-clang16-opt" input: job_name: SPRUCE_{{dk}}_{{ polarity }} output: NTuple.root @@ -112,7 +112,7 @@ DV_{{dk}}_{{ polarity }}: {%- endfor %} data_lb_lc_mu: - application: "DaVinci/v64r5" + application: "DaVinci/v64r7@x86_64_v2-el9-clang16-opt" input: bk_query: "/LHCb/Collision24/Beam6800GeV-VeloClosed-MagDown-Excl-UT/Real Data/Sprucing24c1/90000000/SL.DST" dq_flags: -- GitLab From b32e3e2269c50268802f68a1299b449ee59f2fe8 Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Wed, 14 Aug 2024 10:36:22 +0200 Subject: [PATCH 50/57] add everything --- lb_lc_mu_2024data/DV.py | 414 ------------------------------ lb_lc_mu_2024data/Hlt1.py | 18 -- lb_lc_mu_2024data/Hlt2.py | 55 ---- lb_lc_mu_2024data/Spruce.py | 29 --- lb_lc_mu_2024data/info.yaml | 136 ---------- lb_lc_mu_2024data/isolationMVA.py | 139 ---------- 6 files changed, 791 deletions(-) delete mode 100644 lb_lc_mu_2024data/DV.py delete mode 100644 lb_lc_mu_2024data/Hlt1.py delete mode 100644 lb_lc_mu_2024data/Hlt2.py delete mode 100644 lb_lc_mu_2024data/Spruce.py delete mode 100644 lb_lc_mu_2024data/info.yaml delete mode 100644 lb_lc_mu_2024data/isolationMVA.py diff --git a/lb_lc_mu_2024data/DV.py b/lb_lc_mu_2024data/DV.py deleted file mode 100644 index ce3f7eef71..0000000000 --- a/lb_lc_mu_2024data/DV.py +++ /dev/null @@ -1,414 +0,0 @@ -############################################################################### -# (c) Copyright 2024 CERN for the benefit of the LHCb Collaboration # -# # -# This software is distributed under the terms of the GNU General Public # -# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # -# # -# In applying this licence, CERN does not waive the privileges and immunities # -# granted to it by virtue of its status as an Intergovernmental Organization # -# or submit itself to any jurisdiction. # -############################################################################### -import sys -from DaVinci import Options,make_config -from PyConf.reading import get_pvs, get_rec_summary, get_particles -from PyConf.Algorithms import ThOrParticleSelection -import Functors as F -from FunTuple import FunctorCollection -from FunTuple import FunTuple_Particles as Funtuple -from DaVinci.algorithms import create_lines_filter -import FunTuple.functorcollections as FC -from DaVinciMCTools import MCTruthAndBkgCat -from Hlt2Conf.standard_particles import make_has_rich_long_pions,make_has_rich_up_pions,make_has_rich_down_pions -from Hlt2Conf.algorithms_thor import ParticleCombiner, ParticleFilter -from Hlt2Conf.algorithms_thor import ParticleContainersMerger -from Functors.grammar import Functor -from Hlt2Conf.lines.semileptonic.isolationMVA import mva_functor_mu_inclusive,mva_transform_output -from .isolationMVA import mva_functor_mu_inclusive as mva_functor_inclusive - - -_BPVCORRM = Functor('_BPVCORRM', 'Composite::CorrectedMass','Compute the corrected mass') -_allpv_FDVEC = (F.ENDVERTEX_POS @ F.FORWARDARG1 - F.TOLINALG @ F.POSITION @ F.FORWARDARG0) -_allpv_NORMEDDOT = F.NORMEDDOT.bind(F.THREEMOMENTUM @ F.FORWARDARG1, _allpv_FDVEC) -#ALLPV_CHI2 = lambda Vertices: F.MAP(F.CHI2) @ F.TES(Vertices) -#ALLPV_CHI2DOF = lambda Vertices: F.MAP(F.CHI2DOF) @ F.TES(Vertices) -ALLPV_IPCHI2 = lambda Vertices: F.MAP(F.IPCHI2).bind(F.TES(Vertices), F.FORWARDARGS) -ALLPV_FDCHI2 = lambda Vertices: F.MAP(F.VTX_FDCHI2).bind(F.TES(Vertices), F.FORWARDARGS) -ALLPV_DIRA = lambda Vertices: F.MAP(_allpv_NORMEDDOT).bind(F.TES(Vertices), F.FORWARDARGS) -ALLPV_CORRM = lambda Vertices: F.MAP(_BPVCORRM).bind(F.TES(Vertices), F.FORWARDARGS) -ALLPV_LTIME = lambda Vertices: F.MAP(F.VTX_LTIME).bind(F.TES(Vertices), F.FORWARDARGS) -ALLPV_DLS = lambda Vertices: F.MAP(F.VTX_DLS).bind(F.TES(Vertices), F.FORWARDARGS) -ALLPV_FD_COORDINATE = lambda coordinate, Vertices: F.MAP(coordinate @ _allpv_FDVEC).bind(F.TES(Vertices), F.FORWARDARGS) - -TRUE_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.PARTICLE_ID) == id) - -def make_Bst_2pi(B, pions,v2_pvs,prepare_pion): - - hadron_cut = F.IS_ABS_ID('Lambda_c+') # Getting the hadron candidates - - code_hadron = F.FILTER(hadron_cut) @ F.GET_CHILDREN() - hadron_TES = ThOrParticleSelection( - name="hadron_iso", - InputParticles=B, - Functor=code_hadron).OutputSelection - - lepton_cut = F.IS_ABS_ID('mu-') - code_lepton = F.FILTER(lepton_cut) @ F.GET_CHILDREN() - lepton_TES = ThOrParticleSelection( - name="lepton_iso", - InputParticles=B, - Functor=code_lepton).OutputSelection - - - #combine to make [B*- -> Lambda_c+ mu-]cc - Bstm = ParticleCombiner( - Inputs=[hadron_TES, lepton_TES], - name=f'Bstm_mu', - DecayDescriptor='[B*- -> Lambda_c+ mu-]cc', - CombinationCut=F.ALL, - CompositeCut=F.ALL, - ParticleCombiner="ParticleVertexFitter", - ) - - #cut_combination = F.require_all(F.MAXDOCA < 8.0, F.MAXDOCACHI2 < 20) - - if prepare_pion=='True': - MVA_cut = mva_transform_output(0.05) - cut_composite = F.require_all(mva_functor_mu_inclusive(v2_pvs)[0] > MVA_cut) - - #first make [B*0 -> B*- pi+]cc - Bst_1 = ParticleCombiner( - Inputs=[Bstm, pions], - name='Bst_1', - DecayDescriptor='[B*0 -> B*- pi+]cc', - CombinationCut=F.ALL, - CompositeCut=cut_composite, - ParticleCombiner="ParticleVertexFitter", #for neutrals need to use different combiner e.g. ParticleAdder - #OutputLevel=1 - ) - Bst_2 = ParticleCombiner( - Inputs=[Bstm, pions], - name='Bst_2', - DecayDescriptor='[B*0 -> B*- pi-]cc', - CombinationCut=F.ALL, - CompositeCut=cut_composite, - ParticleCombiner="ParticleVertexFitter", #for neutrals need to use different combiner e.g. ParticleAdder - #OutputLevel=1 - ) - #merge the two Bst candidates - Bst = ParticleContainersMerger([Bst_1, Bst_2], name = 'Bst_combiner') - - #prepare filtered pion - pion_cut = F.IS_ABS_ID('pi+') # Getting the filtered pion candidates - - code_pion = F.FILTER(pion_cut) @ F.GET_CHILDREN() - pion_TES = ThOrParticleSelection( - name="pion_iso", - InputParticles=Bst, - Functor=code_pion).OutputSelection - ''' - #prepare filtered Bstm - Bstm_cut = F.IS_ABS_ID('B*+') # Getting the filtered B*+ candidates - - code_Bstm = F.FILTER(Bstm_cut) @ F.GET_CHILDREN() - Bstm_TES = ThOrParticleSelection( - name="Bstm_iso", - InputParticles=Bst, - Functor=code_Bstm).OutputSelection - ''' - else : pion_TES = pions - - #make Lc mu pi pi - Bst_2pi_1 = ParticleCombiner( - Inputs=[Bstm, pion_TES, pion_TES], - name='Bst_2pi_1', - DecayDescriptor='[B*0 -> B*- pi+ pi-]cc', - CombinationCut=F.ALL, - CompositeCut=F.ALL, - ParticleCombiner="ParticleVertexFitter", #for neutrals need to use different combiner e.g. ParticleAdder - #OutputLevel=1 - ) - Bst_2pi_2 = ParticleCombiner( - Inputs=[Bstm, pion_TES, pion_TES], - name='Bst_2pi_2', - DecayDescriptor='[B*0 -> B*- pi- pi-]cc', - CombinationCut=F.ALL, - CompositeCut=F.ALL, - ParticleCombiner="ParticleVertexFitter", #for neutrals need to use different combiner e.g. ParticleAdder - #OutputLevel=1 - ) - #merge the two Bst candidates - Bst_2pi = ParticleContainersMerger([Bst_2pi_1, Bst_2pi_2], name = 'Bst_2pi_combiner') - - - return Bst_2pi - - - - - -def get_functors(MCTRUTH, v2_pvs, rec_summary): - #define common variables for all fields (composite and basic) - vars_common = FunctorCollection() - #all pvs: ip, ipchi2. The PV positions are stored in event variables - vars_common['ALLPV_IP[pv_indx]'] = F.ALLPV_IP(v2_pvs) - vars_common['ALLPV_IPCHI2[pv_indx]'] = ALLPV_IPCHI2(v2_pvs) - #best pv: x, y, z, ip, ipchi2 - vars_common['BPV_X'] = F.BPVX(v2_pvs) - vars_common['BPV_Y'] = F.BPVY(v2_pvs) - vars_common['BPV_Z'] = F.BPVZ(v2_pvs) - vars_common['BPV_IP'] = F.BPVIP(v2_pvs) - vars_common['BPV_IPCHI2'] = F.BPVIPCHI2(v2_pvs) - vars_common['BPV_CHI2'] = F.CHI2 @ F.BPV(v2_pvs) - vars_common['BPV_CHI2DOF'] = F.CHI2DOF @ F.BPV(v2_pvs) - #particle id, key, truekey. The trueid is stored in MCHierarchy - vars_common['ID'] = F.PARTICLE_ID - vars_common['KEY'] = F.OBJECT_KEY - #get charge, min ip and min ipchi2 - vars_common['CHARGE'] = F.CHARGE - vars_common['MINIP'] = F.MINIP(v2_pvs) - vars_common['MINIPCHI2'] = F.MINIPCHI2(v2_pvs) - #reco kinematics - vars_common += FC.Kinematics() - vars_common['ETA'] = F.ETA - vars_common['PHI'] = F.PHI - if MCTRUTH != 'None': - #mc vars - vars_common['TRUEKEY'] = F.VALUE_OR(-1) @ MCTRUTH(F.OBJECT_KEY) - vars_common += FC.MCKinematics(mctruth_alg = MCTRUTH) - vars_common['TRUEETA'] = MCTRUTH(F.ETA) - vars_common['TRUEPHI'] = MCTRUTH(F.PHI) - #type of the origin vertex - vars_common['MC_VTX_TYPE'] = MCTRUTH(F.VALUE_OR(-1) @ F.MC_VTX_TYPE @ F.MC_ORIGINVERTEX) - #make some helper functions - MCMOTHER_ID = lambda n: F.VALUE_OR(0) @ MCTRUTH(F.MC_MOTHER(n, F.PARTICLE_ID)) - MCMOTHER_KEY = lambda n: F.VALUE_OR(-1) @ MCTRUTH(F.MC_MOTHER(n, F.OBJECT_KEY )) - vars_common["TRUEID"] = F.VALUE_OR(0) @ MCTRUTH(F.PARTICLE_ID) - vars_common["MCKEY"] = F.VALUE_OR(0) @ MCTRUTH(F.OBJECT_KEY) - vars_common["MC_MOTHER_ID"] = MCMOTHER_ID(1) - vars_common["MC_MOTHER_KEY"] = MCMOTHER_KEY(1) - for i in range(2,14): - prefix = "MC_GD_MOTHER_{}".format(i) - vars_common[f"{prefix}_ID"] = MCMOTHER_ID(i) - vars_common[f"{prefix}_KEY"] = MCMOTHER_KEY(i) - - #variables for composite particles - vars_composite = FunctorCollection() - #end vertex position and end vertex chi2 - vars_composite['ENDVERTEX_POS_'] = F.ENDVERTEX_POS - vars_composite['ENDVERTEX_CHI2'] = F.CHI2 @ F.ENDVERTEX - vars_composite['ENDVERTEX_CHI2DOF'] = F.CHI2DOF @ F.ENDVERTEX - #all pvs: dira, fd, fdchi2 - vars_composite['ALLPV_DIRA[pv_indx]'] = ALLPV_DIRA(v2_pvs) - vars_composite['ALLPV_FD_X[pv_indx]'] = ALLPV_FD_COORDINATE(F.X_COORDINATE, v2_pvs) - vars_composite['ALLPV_FD_Y[pv_indx]'] = ALLPV_FD_COORDINATE(F.Y_COORDINATE, v2_pvs) - vars_composite['ALLPV_FD_Z[pv_indx]'] = ALLPV_FD_COORDINATE(F.Z_COORDINATE, v2_pvs) - vars_composite['ALLPV_FDCHI2[pv_indx]'] = ALLPV_FDCHI2(v2_pvs) - vars_composite['ALLPV_CORRM[pv_indx]'] = ALLPV_CORRM(v2_pvs) - vars_composite['ALLPV_LTIME[pv_indx]'] = ALLPV_LTIME(v2_pvs) - vars_composite['ALLPV_DLS[pv_indx]'] = ALLPV_DLS(v2_pvs) - #best pv: dira, fd, fdchi2, corrm, ltime, dls - vars_composite['BPV_DIRA'] = F.BPVDIRA(v2_pvs) - vars_composite['BPV_FD_'] = F.BPVFDVEC(v2_pvs) - vars_composite['BPV_FDCHI2'] = F.BPVFDCHI2(v2_pvs) - vars_composite['BPV_CORRM'] = F.BPVCORRM(v2_pvs) - vars_composite['BPV_LTIME'] = F.BPVLTIME(v2_pvs) - vars_composite['BPV_DLS'] = F.BPVDLS(v2_pvs) - #Compute maximum DOCA and maximum DOCACHI2. Since there are - # only two daughters of Sb particles, the maximum DOCA/DOCACHI2 is - # the DOCA/DOCACHI2 see below. - vars_composite['MAX_DOCA'] = F.MAXDOCA - vars_composite['MAX_DOCACHI2'] = F.MAXDOCACHI2 - vars_composite['MAX_SDOCA'] = F.MAXSDOCA - vars_composite['MAX_SDOCACHI2'] = F.MAXSDOCACHI2 - - #variables for Lb field - var_B = FunctorCollection() - - #variables for basics - vars_basic = FunctorCollection() - vars_basic['TRACKTYPE'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKTYPE @ F.TRACK - vars_basic['TRACKHISTORY'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKHISTORY @ F.TRACK - vars_basic['TRACKFLAG'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKFLAG @ F.TRACK - vars_basic['TRACKNDOF'] = F.VALUE_OR(-1) @ F.NDOF @ F.TRACK - vars_basic['TRACKCHI2'] = F.CHI2 @ F.TRACK - vars_basic['TRACKCHI2DOF'] = F.CHI2DOF @ F.TRACK - vars_basic['GHOSTPROB'] = F.GHOSTPROB - vars_basic['PIDpi'] = F.PID_PI - vars_basic['PIDk'] = F.PID_K - vars_basic['PIDp'] = F.PID_P - vars_basic['PIDe'] = F.PID_E - vars_basic['PIDmu'] = F.PID_MU - - #variables for event - evt_vars = FunctorCollection() - #evt_vars['ALLPV_X[pv_indx]'] = F.ALLPVX(v2_pvs) - #evt_vars['ALLPV_Y[pv_indx]'] = F.ALLPVY(v2_pvs) - #evt_vars['ALLPV_Z[pv_indx]'] = F.ALLPVZ(v2_pvs) - #evt_vars['ALLPV_CHI2[pv_indx]'] = ALLPV_CHI2(v2_pvs) - #evt_vars['ALLPV_CHI2DOF[pv_indx]']= ALLPV_CHI2DOF(v2_pvs) - evt_vars['nTracks'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nTracks") - evt_vars['nLongTracks'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nLongTracks") - evt_vars['nPVs'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nPVs") - evt_vars['nFTClusters'] = F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nFTClusters") - - #return all functors - functors = (vars_common, vars_composite, var_B, vars_basic, evt_vars) - return functors - -def tuple_Bst(Bst, MCTRUTH,v2_pvs, rec_summary): - #get functors - functors = get_functors(MCTRUTH,v2_pvs, rec_summary) - vars_common = functors[0] - vars_composite = functors[1] - var_B = functors[2] - vars_basic = functors[3] - evt_vars = functors[4] - - #variables for Sb field - vars_Bst = FunctorCollection() - B_child = F.CHILD(1, F.FORWARDARG0) - Epi_child1 = F.CHILD(2, F.FORWARDARG0) - Epi_child2 = F.CHILD(3, F.FORWARDARG0) - bpv_pi1 = F.BPV(v2_pvs).bind(Epi_child1) - bpv_pi2 = F.BPV(v2_pvs).bind(Epi_child2) - #diff in vtx chi2 with and without extra particle - vars_Bst['DELTA_ENDVERTEX_CHI2'] = (F.CHI2 @ F.ENDVERTEX) - (F.CHI2 @ F.ENDVERTEX.bind(B_child)) - #IP and IPChi2 of extra particle wrt to Sb end vertex - vars_Bst['Epi1_IP_WRT_SbENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ F.FORWARDARG0 , Epi_child1) - vars_Bst['Epi1_IPCHI2_WRT_SbENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ F.FORWARDARG0 , Epi_child1) - vars_Bst['Epi2_IP_WRT_SbENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ F.FORWARDARG0 , Epi_child1) - vars_Bst['Epi2_IPCHI2_WRT_SbENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ F.FORWARDARG0 , Epi_child1) - #IP and IPChi2 of extra particle wrt to Lb end vertex - vars_Bst['Epi1_IP_WRT_LbENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ B_child , Epi_child1) - vars_Bst['Epi1_IPCHI2_WRT_LbENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ B_child , Epi_child1) - vars_Bst['Epi2_IP_WRT_LbENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ B_child , Epi_child2) - vars_Bst['Epi2_IPCHI2_WRT_LbENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ B_child , Epi_child2) - #angle between extra particle and Lb - vars_Bst['Epi1_COSANGLE_Lb'] = F.COSANGLE.bind(F.THREEMOMENTUM @ B_child, F.THREEMOMENTUM @ Epi_child1) - vars_Bst['Epi2_COSANGLE_Lb'] = F.COSANGLE.bind(F.THREEMOMENTUM @ B_child, F.THREEMOMENTUM @ Epi_child2) - #diff in fd chi2 with and without extra particle - vars_Bst['Delta_BPV_of_Epi1_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi1, F.FORWARDARGS) - F.VTX_FDCHI2.bind(bpv_pi1, B_child) - vars_Bst['Delta_BPV_of_Epi2_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi2, F.FORWARDARGS) - F.VTX_FDCHI2.bind(bpv_pi1, B_child) - vars_Bst['BPV_of_Epi1_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi1, F.FORWARDARGS) - vars_Bst['BPV_of_Epi2_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi2, F.FORWARDARGS) - #IP chi2 of extra particle wrt PV and SV of Sb - vars_Bst['Epi1_IP_WRT_SbBPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child1) - vars_Bst['Epi1_IPCHI2_WRT_SbBPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child1) - vars_Bst['Epi2_IP_WRT_SbBPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child2) - vars_Bst['Epi2_IPCHI2_WRT_SbBPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child2) - #IP chi2 of extra particle wrt PV and SV of Bb - vars_Bst['Epi1_IP_WRT_LbBPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ B_child, Epi_child1) - vars_Bst['Epi1_IPCHI2_WRT_LbBPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ B_child, Epi_child1) - vars_Bst['Epi2_IP_WRT_LbBPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ B_child, Epi_child2) - vars_Bst['Epi2_IPCHI2_WRT_LbBPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ B_child, Epi_child2) - #DOCA and DOCACHI2 b/w Lb and extra particle - vars_Bst['DOCA12'] = F.DOCA(1, 2) - vars_Bst['DOCA12_CHI2_12'] = F.DOCACHI2(1, 2) - vars_Bst['DOCA13'] = F.DOCA(1, 3) - vars_Bst['DOCA12_CHI2_13'] = F.DOCACHI2(1, 3) - #vars_Bst['SDOCA12'] = F.SDOCA(1, 2) - #vars_Bst['SDOCA_CHI2_12'] = F.SDOCACHI2(1, 2) - #DOCACHI2 of extra particle wrt to mother i.e. Sb - vars_Bst['MTDOCACHI2_1'] = F.MTDOCACHI2(1, v2_pvs) - vars_Bst['MTDOCACHI2_2'] = F.MTDOCACHI2(2, v2_pvs) - vars_Bst['MTDOCACHI2_3'] = F.MTDOCACHI2(3, v2_pvs) - - #Get mva output for 1st and 2nd pion - #mva_first_pion = mva_functor_mu_inclusive(v2_pvs,2)[0] - vars_Bst['iso_mva_1'] = mva_functor_inclusive(v2_pvs,2) - - #mva_second_pion = mva_functor_mu_inclusive(v2_pvs,3)[0] - vars_Bst['iso_mva_2'] = mva_functor_inclusive(v2_pvs,3) - - ''' - MVA_cut = mva_transform_output(0.05) - #MVA_cut_functor = (mva_functor_mu_inclusive(v2_pvs,2) > MVA_cut & mva_functor_mu_inclusive(v2_pvs,3) > MVA_cut) - MVA_cut_functor = F.require_all(mva_functor_mu_inclusive(v2_pvs,2) > MVA_cut,mva_functor_mu_inclusive(v2_pvs,3) > MVA_cut) - Bst_mva_cut = ParticleFilter( - Bst, F.FILTER(MVA_cut_functor), name="filter_isoPions" - ) # B + extra track combos passing the MVA cuts - ''' - #define fields - fields_mu = {} - fields_mu['Sb'] = '[B*0 -> (B*- -> Lambda_c+ mu-) [pi+]CC pi-]CC' - fields_mu['Lb'] = '[B*0 -> ^(B*- -> Lambda_c+ mu-) [pi+]CC pi-]CC' - fields_mu['Lc'] = '[B*0 -> (B*- -> ^Lambda_c+ mu-) [pi+]CC pi-]CC' - fields_mu['Lep'] = '[B*0 -> (B*- -> Lambda_c+ ^mu-) [pi+]CC pi-]CC' - fields_mu['Epi1'] = '[B*0 -> (B*- -> Lambda_c+ mu-) ^[pi+]CC pi-]CC' - fields_mu['Epi2'] = '[B*0 -> (B*- -> Lambda_c+ mu-) [pi+]CC ^pi-]CC' - fields_mu['p'] = '[B*0 -> (B*- -> (Lambda_c+ -> ^p+ K- pi+) mu-) [pi+]CC pi-]CC' - fields_mu['Km'] = '[B*0 -> (B*- -> (Lambda_c+ -> p+ ^K- pi+) mu-) [pi+]CC pi-]CC' - fields_mu['pip'] = '[B*0 -> (B*- -> (Lambda_c+ -> p+ K- ^pi+) mu-) [pi+]CC pi-]CC' - - #add variables - variables = {} - variables["ALL"] = vars_common - variables["Sb"] = vars_composite + vars_Bst - variables["Lb"] = vars_composite + var_B - variables["Lc"] = vars_composite - variables["Lep"] = vars_basic - variables["Epi1"] = vars_basic - variables["Epi2"] = vars_basic - variables["p"] = vars_basic - variables["Km"] = vars_basic - variables["pip"]= vars_basic - - #define tuple - my_tuple = Funtuple( - name="Tuple", - tuple_name="DecayTree", - fields=fields_mu, - variables=variables, - event_variables=evt_vars, - inputs=Bst) - - return my_tuple - -def get_extra_pions(): - """ - Note this function in DaVinci requires: - https://gitlab.cern.ch/lhcb/Moore/-/merge_requests/3203 - and it's related LHCb, DaVinci and Rec MRs - """ - long_pions = make_has_rich_long_pions() - up_pions = make_has_rich_up_pions() - down_pions = make_has_rich_down_pions() - return ParticleContainersMerger([long_pions, up_pions, down_pions], - name='Pions_combiner') - -def main(options: Options,data_or_mc='mc'): - - #define filer - my_filter = create_lines_filter(name="Filter", lines=['SpruceSLB_LbToLcMuNu_LcToPKPi']) - - #get data and extra particles - lb = get_particles("/Event/Spruce/SpruceSLB_LbToLcMuNu_LcToPKPi/Particles") - - #get v2_pvs and rec_summary - v2_pvs = get_pvs() - rec_summary = get_rec_summary() - - if data_or_mc == 'mc': - extra_particles = get_particles("/Event/Spruce/SpruceSLB_LbToLcMuNu_LcToPKPi/SpruceSLB_LbToLcMuNu_LcToPKPi_extra_tracks") - #make sb candidate - Bst = make_Bst_2pi(lb, extra_particles,v2_pvs,'False') - MCTRUTH_Bst = MCTruthAndBkgCat(Bst, name='MCTRUTH_Bst') - tuple_file = tuple_Bst(Bst,MCTRUTH_Bst, v2_pvs, rec_summary) - - elif data_or_mc == 'data': - extra_particles = get_extra_pions() - #make sb candidate - Bst = make_Bst_2pi(lb, extra_particles,v2_pvs,'True') - tuple_file = tuple_Bst(Bst,'None', v2_pvs, rec_summary) - - #define algorithms - user_algorithms = {} - user_algorithms['Alg'] = [my_filter, tuple_file] - - return make_config(options, user_algorithms) - -def MC_SLB_LbToLcMuNu_LcToPKPi(options: Options): - return main(options=options,data_or_mc='mc') - -def Data_SLB_LbToLcMuNu_LcToPKPi(options: Options): - return main(options=options,data_or_mc='data') diff --git a/lb_lc_mu_2024data/Hlt1.py b/lb_lc_mu_2024data/Hlt1.py deleted file mode 100644 index eeabcc4913..0000000000 --- a/lb_lc_mu_2024data/Hlt1.py +++ /dev/null @@ -1,18 +0,0 @@ -############################################################################### -# (c) Copyright 2022 CERN for the benefit of the LHCb Collaboration # -# # -# This software is distributed under the terms of the GNU General Public # -# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # -# # -# In applying this licence, CERN does not waive the privileges and immunities # -# granted to it by virtue of its status as an Intergovernmental Organization # -# or submit itself to any jurisdiction. # -############################################################################### -from Moore import Options -from Moore.config import run_allen -from RecoConf.hlt1_allen import allen_gaudi_config as allen_sequence - -def main(options: Options): - with allen_sequence.bind(sequence="hlt1_pp_matching_no_ut_1000KHz"): - return run_allen(options) - diff --git a/lb_lc_mu_2024data/Hlt2.py b/lb_lc_mu_2024data/Hlt2.py deleted file mode 100644 index c9da3abacc..0000000000 --- a/lb_lc_mu_2024data/Hlt2.py +++ /dev/null @@ -1,55 +0,0 @@ -############################################################################### -# (c) Copyright 2022 CERN for the benefit of the LHCb Collaboration # -# # -# This software is distributed under the terms of the GNU General Public # -# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # -# # -# In applying this licence, CERN does not waive the privileges and immunities # -# granted to it by virtue of its status as an Intergovernmental Organization # -# or submit itself to any jurisdiction. # -############################################################################### -""" -Stolen and adapted from Hlt/Hlt2Conf/options/hlt2_pp_expected_24_without_UT.py from v55r7. -""" -from Moore import Options,options, run_moore, config -from Hlt2Conf.settings.defaults import get_default_hlt1_filter_code_for_hlt2 -from Hlt2Conf.lines.semileptonic.hlt2_semileptonic import hlt2_lbtolcmunu_lctopkpi_line -from Moore.config import Hlt2Line,register_line_builder -from Moore.streams import Stream, Streams, DETECTORS -from RecoConf.event_filters import require_gec -from RecoConf.global_tools import stateProvider_with_simplified_geom, trackMasterExtrapolator_with_simplified_geom -from RecoConf.hlt2_global_reco import reconstruction as hlt2_reconstruction, make_light_reco_pr_kf_without_UT -from RecoConf.reconstruction_objects import reconstruction,make_pvs -from RecoConf.decoders import default_ft_decoding_version,default_VeloCluster_source -from RecoConf.hlt2_tracking import ( - make_TrackBestTrackCreator_tracks, - make_PrKalmanFilter_noUT_tracks, - make_PrKalmanFilter_Velo_tracks, - make_PrKalmanFilter_Seed_tracks, -) -import Functors as F -from Functors.math import in_range -import sys - -def make_lines(): - lines = [hlt2_lbtolcmunu_lctopkpi_line()] - return lines - -public_tools = [ - trackMasterExtrapolator_with_simplified_geom(), - stateProvider_with_simplified_geom(), -] - -def main(options: Options): - # NOTE: the TBTC does not apply a chi2 cut because it is applied by the PrKF - with reconstruction.bind(from_file=False),\ - hlt2_reconstruction.bind(make_reconstruction=make_light_reco_pr_kf_without_UT),\ - require_gec.bind(skipUT=True),\ - default_VeloCluster_source.bind(bank_type="VPRetinaCluster"),\ - make_TrackBestTrackCreator_tracks.bind(max_ghost_prob=0.7, max_chi2ndof=sys.float_info.max),\ - make_PrKalmanFilter_Velo_tracks.bind(max_chi2ndof=5.),\ - make_PrKalmanFilter_noUT_tracks.bind(max_chi2ndof=4.),\ - make_PrKalmanFilter_Seed_tracks.bind(max_chi2ndof=6.),\ - get_default_hlt1_filter_code_for_hlt2.bind(code=r"Hlt1(?!PassthroughLargeEvent).*Decision"): - return run_moore(options, make_lines, public_tools) - diff --git a/lb_lc_mu_2024data/Spruce.py b/lb_lc_mu_2024data/Spruce.py deleted file mode 100644 index b864401501..0000000000 --- a/lb_lc_mu_2024data/Spruce.py +++ /dev/null @@ -1,29 +0,0 @@ -############################################################################### -# (c) Copyright 2022 CERN for the benefit of the LHCb Collaboration # -# # -# This software is distributed under the terms of the GNU General Public # -# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # -# # -# In applying this licence, CERN does not waive the privileges and immunities # -# granted to it by virtue of its status as an Intergovernmental Organization # -# or submit itself to any jurisdiction. # -############################################################################### -#Example follows from hlt2_with_hlt1_decision.py -from Moore import Options,options, run_moore, config -from Hlt2Conf.lines.semileptonic.spruce_semileptonic import spruce_lbtolcmunu_lctopkpi_line -from PyConf.application import configure_input, configure, default_raw_event -from RecoConf.global_tools import stateProvider_with_simplified_geom -from RecoConf.reconstruction_objects import reconstruction -from PyConf.reading import reconstruction as reco_spruce, upfront_reconstruction as upfront_spruce -from RecoConf.decoders import default_ft_decoding_version - -def make_lines(): - lines = [spruce_lbtolcmunu_lctopkpi_line()] - return lines - -def main(options: Options): - public_tools = [stateProvider_with_simplified_geom()] - with reconstruction.bind(from_file=True, spruce=True),\ - reco_spruce.bind(simulation=True),\ - upfront_spruce.bind(simulation=True): - return run_moore(options, make_lines, public_tools=public_tools) diff --git a/lb_lc_mu_2024data/info.yaml b/lb_lc_mu_2024data/info.yaml deleted file mode 100644 index 94531e876e..0000000000 --- a/lb_lc_mu_2024data/info.yaml +++ /dev/null @@ -1,136 +0,0 @@ -defaults: - inform: - - ching-hua.li@cern.ch - wg: SL -{%- set datasets = [ - ('15576010','lb_lc2593_mu'), - ('15576011','lb_lc2625_mu'), - ('15876031','lb_lc2880_mu'), -] %} - -{%- set polarity_variables = [ - ('MagDown','sim-20231017-vc-md100'), - ('MagUp','sim-20231017-vc-mu100'), -]%} - -{%- for polarity, cond_tag in polarity_variables %} - {%- for evttype, dk in datasets %} -HLT1_{{dk}}_{{ polarity }}: - #application: "Moore/v55r7@x86_64_v3-el9-gcc13+detdesc-opt+g" - application: "Moore/v55r8@x86_64_v3-el9-gcc13+detdesc-opt+g" - input: - bk_query: "/MC/Dev/Beam6800GeV-expected-2024-{{polarity}}-Nu7.6-25ns-Pythia8/Sim10c/{{evttype}}/DIGI" - dq_flags: - - OK - n_test_lfns: 1 - output: hlt1.dst - options: - entrypoint: lb_lc_mu_2024data.Hlt1:main - extra_options: - input_raw_format: 0.3 - conddb_tag: {{cond_tag}} - dddb_tag: dddb-20231017 - input_type: ROOT - output_type: ROOT - simulation: True - data_type: "Upgrade" - scheduler_legacy_mode: False - compression: - algorithm: ZSTD - level: 1 - max_buffer_size: 1048576 - #evt_max: 1000 - -HLT2_{{dk}}_{{ polarity }}: - #application: "Moore/v55r7p3@x86_64_v3-el9-gcc13+detdesc-opt+g" - application: "Moore/v55r8@x86_64_v3-el9-gcc13+detdesc-opt+g" - input: - job_name: HLT1_{{dk}}_{{ polarity }} - output: hlt2.dst - options: - entrypoint: lb_lc_mu_2024data.Hlt2:main - extra_options: - input_raw_format: 0.5 - conddb_tag: {{cond_tag}} - dddb_tag: dddb-20231017 - input_type: ROOT - output_type: ROOT - simulation: True - data_type: "Upgrade" - scheduler_legacy_mode: False - output_manifest_file: "HLT2.tck.json" - compression: - algorithm: ZSTD - level: 1 - max_buffer_size: 1048576 - #evt_max: 1000 -SPRUCE_{{dk}}_{{ polarity }}: - #application: "Moore/v55r7p3@x86_64_v3-el9-gcc13+detdesc-opt+g" - application: "Moore/v55r8@x86_64_v3-el9-gcc13+detdesc-opt+g" - input: - job_name: HLT2_{{dk}}_{{ polarity }} - output: spruce.dst - options: - entrypoint: lb_lc_mu_2024data.Spruce:main - extra_options: - input_raw_format: 0.5 - conddb_tag: {{cond_tag}} - dddb_tag: dddb-20231017 - input_type: ROOT - output_type: ROOT - simulation: True - data_type: "Upgrade" - scheduler_legacy_mode: False - input_process: "Hlt2" - input_manifest_file: "HLT2.tck.json" - output_manifest_file: "SPRUCE.tck.json" - compression: - algorithm: ZSTD - level: 1 - max_buffer_size: 1048576 - #evt_max: 1000 -DV_{{dk}}_{{ polarity }}: - application: "DaVinci/v64r7@x86_64_v2-el9-clang16-opt" - input: - job_name: SPRUCE_{{dk}}_{{ polarity }} - output: NTuple.root - options: - entrypoint: lb_lc_mu_2024data.DV:MC_SLB_LbToLcMuNu_LcToPKPi - extra_options: - input_raw_format: 0.5 - conddb_tag: {{cond_tag}} - dddb_tag: dddb-20231017 - input_type: ROOT - simulation: True - data_type: "Upgrade" - #geometry_version: run3/2024.Q1.2-v00.00 - input_process: "Spruce" - input_manifest_file: "SPRUCE.tck.json" - #evt_max: 1000 - - {%- endfor %} -{%- endfor %} - -data_lb_lc_mu: - application: "DaVinci/v64r7@x86_64_v2-el9-clang16-opt" - input: - bk_query: "/LHCb/Collision24/Beam6800GeV-VeloClosed-MagDown-Excl-UT/Real Data/Sprucing24c1/90000000/SL.DST" - dq_flags: - - UNCHECKED - - OK - keep_running: true - n_test_lfns: 1 - output: DATA.ROOT - options: - entrypoint: lb_lc_mu_2024data.DV:Data_SLB_LbToLcMuNu_LcToPKPi - extra_options: - input_raw_format: 0.5 - input_type: ROOT # ROOT for SprucingPass, RAW for RAW data (Hlt2 output) - simulation: False - #data_type: "Upgrade" - geometry_version: run3/trunk - conditions_version: master - input_process: "Spruce" # Spruce for SprucingPass, "Hlt2" for RAW data (Hlt2 output) - input_stream: "sl" # for streamed data - #evt_max: 1000 - diff --git a/lb_lc_mu_2024data/isolationMVA.py b/lb_lc_mu_2024data/isolationMVA.py deleted file mode 100644 index 92f9ae0700..0000000000 --- a/lb_lc_mu_2024data/isolationMVA.py +++ /dev/null @@ -1,139 +0,0 @@ -############################################################################### -# (c) Copyright 2024 CERN for the benefit of the LHCb Collaboration # -# # -# This software is distributed under the terms of the GNU General Public # -# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # -# # -# In applying this licence, CERN does not waive the privileges and immunities # -# granted to it by virtue of its status as an Intergovernmental Organization # -# or submit itself to any jurisdiction. # -############################################################################### -import Functors as F -from Hlt2Conf.algorithms_thor import ParticleCombiner -from Hlt2Conf.algorithms_thor import ParticleContainersMerger -from Hlt2Conf.algorithms_thor import ParticleFilter -from RecoConf.reconstruction_objects import make_pvs -import Functors.math as fmath -import math -import re -from dataclasses import dataclass -from PyConf.Algorithms import ThOrParticleSelection - -#Multiplying by this number will convert log_e to log_10 -#we multiply by log10(e) rather than dividing by ln(10) -#since multiplication is faster -LOG10_E = math.log10(math.e) -#toggle for printing debug messages -#set to False for proper productions -DEBUG = False - - -@dataclass -class MVAinput: - """Struct for storing MVA input variables""" - name: str # The name of the var (as per the model) - number: int # The number of the var - functor: F.grammar.FunctorBase # The functor to calculate that variable - x_range: (float, float) # axis range for input var monitoring histos - - -def mva_functor_mu_inclusive(v2_pvs, - index_pion, - useNumbers: bool = False): - """ - Compute the output of the MVA classifier (xGBoost) for charged track isolation. - Higher values of MVA classifier output indicate that the charged track is less isolated - and is more likely to be associated to be coming from the same decay vertex as the B0. - For more details: Checkout the presentation https://indico.cern.ch/event/1234758/#sc-1-4-ml-based-charged-isolat - - Args: - v2_pvs (list): TES location of v2 PVs - useNumbers (bool): decision of whether to use the numbers or names of vars in the MVA functor - """ - #get the children of the two-body combination (B0-extraparticle) - Bstar_p_child = F.CHILD(1, F.FORWARDARGS) - ExtraParticle_child = F.CHILD(index_pion, F.FORWARDARGS) - - #define the input variables for mva - mva_input_vars = [] #FunctorCollection() - #define Impact parameter chi2 of the extra particle wrt to the BPV associated to the two-body combination (B0-extraparticle) - mva_input_vars.append( - MVAinput("Epi_BPV_IPCHI2", 0, - F.BPVIPCHI2(v2_pvs).bind(ExtraParticle_child), (0, 20))) # PV - #define PT of two body combination (B0-extraparticle). Here is transformed to be less peaky - mva_input_vars.append( - MVAinput("Epi_PT", 1, - fmath.log(F.PT.bind(ExtraParticle_child)) * LOG10_E, (1, 5))) - #define opening angle between B0 and extra particle. Here is transformed to be less peaky - cos_angle = F.COSANGLE.bind(F.THREEMOMENTUM @ Bstar_p_child, - F.THREEMOMENTUM @ ExtraParticle_child) - mva_input_vars.append( - MVAinput("Sb_Epi_COSANGLE_Lb", 2, 1. - fmath.pow(1. - cos_angle, 0.2), - (0, 1))) - #define DIRA of the two body combination (B0-extraparticle) - mva_input_vars.append( - MVAinput("Sb_BPV_DIRA_TF", 8, fmath.pow(1. - F.BPVDIRA(v2_pvs), 0.2), - (0, 1.2))) - #define magnitude of PV distance i.e. distance between PV and vertex of two-body combination (B0-extraparticle) - # NB: the sign of the magnitude deterimined by the by the difference in z-coordinate of PV and vertex of two-body combination - mva_input_vars.append( - MVAinput("PVdis", 3, - (F.MAGNITUDE @ (F.ENDVERTEX_POS - F.BPV_POS(v2_pvs))) * - fmath.sign(F.END_VZ - F.BPVZ(v2_pvs)), (-50, 100))) - #* F.MAGNITUDE @ (F.ENDVERTEX_POS - F.BPV_POS(v2_pvs)) - #define magnitude of SV distance i.e. distance between two-body combination (B0-extraparticle) vertex and the vertex - # without the extra particle included. The sign of the magnitude is determined by the difference in z-coordinate of both vertices - mva_input_vars.append( - MVAinput("SVdis", 4, - (F.MAGNITUDE - @ (F.ENDVERTEX_POS.bind(Bstar_p_child) - F.ENDVERTEX_POS)) * - fmath.sign(F.END_VZ - F.END_VZ.bind(Bstar_p_child)), - (-50, 50))) - #define DeltaR i.e. the difference in radius of B0 and extra particle in the rapidity-azimuth plane - delta_eta = F.ETA.bind(Bstar_p_child) - F.ETA.bind(ExtraParticle_child) - delta_phi = F.PHI.bind(Bstar_p_child) - F.PHI.bind(ExtraParticle_child) - delta_phi = fmath.where(delta_phi > math.pi, delta_phi - math.pi, - delta_phi) - delta_phi = fmath.where(delta_phi < -math.pi, delta_phi + math.pi, - delta_phi) - mva_input_vars.append( - MVAinput( - "DeltaREpi", 5, - fmath.pow( - fmath.sqrt( - fmath.pow(delta_eta, 2.) + fmath.pow(delta_phi, 2.)), 0.2), - (0, 1.5))) - - mva_input_vars.append( - MVAinput("Sb_MAX_DOCACHI2", 6, - fmath.log(F.SDOCACHI2(1, index_pion)) * LOG10_E, (-2.6, 7.5))) - mva_input_vars.append( - MVAinput( - "Sb_Epi_IPCHI2_WRT_LbENDVERTEX", 7, - fmath.log( - F.IPCHI2.bind(F.ENDVERTEX @ Bstar_p_child, - ExtraParticle_child)) * LOG10_E, (-2, 6))) # SV - - #define the mva classifier - mva = F.MVA( - MVAType='TMVA', - Config={ - 'XMLFile': 'paramfile://data/xgboost_model_cocktail_inclusive.xml', - 'Name': 'BDT', - }, - Inputs={(f"f[{var.number}]" if useNumbers else var.name): var.functor - for var in mva_input_vars}) - return mva - -def mva_transform_output(xgboost_style_input: float) -> float: - """ - We've converted our input from xgboost-style to TMVA-style but this gives a transformation on the cut variables - This function converts from an xgboost-style cut to the corresponding TMVA-style - taken from: https://github.com/jpata/mlglue/blob/master/mlglue/tree.py#L400-L409 - This takes the domain from [0,1] and transforms it from [-1,1] in a strange (nonlinear) way - """ - TMVA_style_output = -math.log(1. / xgboost_style_input - 1.) - TMVA_style_output = 2. / (1. + math.exp(-2. * TMVA_style_output)) - 1. - - return TMVA_style_output - -- GitLab From afb1c67480f532685529de6fda7712ceabbb6ad4 Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Wed, 14 Aug 2024 10:37:57 +0200 Subject: [PATCH 51/57] add SL_l_nu_D0toKpi_Run3_MC_data_v2 --- SL_l_nu_D0toKpi_Run3_MC_data_v2/DV.py | 503 ++++++++++++++++++ SL_l_nu_D0toKpi_Run3_MC_data_v2/Hlt1.py | 18 + SL_l_nu_D0toKpi_Run3_MC_data_v2/Hlt2.py | 155 ++++++ SL_l_nu_D0toKpi_Run3_MC_data_v2/MC_Matcher.py | 26 + SL_l_nu_D0toKpi_Run3_MC_data_v2/Spruce.py | 58 ++ SL_l_nu_D0toKpi_Run3_MC_data_v2/info.yaml | 156 ++++++ .../isolationMVA.py | 350 ++++++++++++ 7 files changed, 1266 insertions(+) create mode 100644 SL_l_nu_D0toKpi_Run3_MC_data_v2/DV.py create mode 100644 SL_l_nu_D0toKpi_Run3_MC_data_v2/Hlt1.py create mode 100644 SL_l_nu_D0toKpi_Run3_MC_data_v2/Hlt2.py create mode 100644 SL_l_nu_D0toKpi_Run3_MC_data_v2/MC_Matcher.py create mode 100644 SL_l_nu_D0toKpi_Run3_MC_data_v2/Spruce.py create mode 100644 SL_l_nu_D0toKpi_Run3_MC_data_v2/info.yaml create mode 100755 SL_l_nu_D0toKpi_Run3_MC_data_v2/isolationMVA.py diff --git a/SL_l_nu_D0toKpi_Run3_MC_data_v2/DV.py b/SL_l_nu_D0toKpi_Run3_MC_data_v2/DV.py new file mode 100644 index 0000000000..116e9fac67 --- /dev/null +++ b/SL_l_nu_D0toKpi_Run3_MC_data_v2/DV.py @@ -0,0 +1,503 @@ +import sys,os,math +from PyConf.reading import get_pvs, get_rec_summary, get_particles +from PyConf.Algorithms import ThOrParticleSelection +import Functors as F +from FunTuple import FunctorCollection +from FunTuple import FunTuple_Particles as Funtuple +from DaVinci.algorithms import create_lines_filter +from DaVinci import Options,make_config +import FunTuple.functorcollections as FC +from DaVinciMCTools import MCTruthAndBkgCat +from Hlt2Conf.algorithms_thor import ParticleCombiner, ParticleFilter +from Hlt2Conf.algorithms_thor import ParticleContainersMerger +from Functors.grammar import Functor +from Hlt2Conf.standard_particles import make_has_rich_long_pions,make_has_rich_up_pions,make_has_rich_down_pions +import numpy as np +#from Hlt2Conf.lines.semileptonic.isolationMVA import mva_transform_output,mva_functor_mu_inclusive +from .isolationMVA import mva_functor_inclusive,mva_transform_output +from .MC_Matcher import trail_seeker +from DaVinciTools import SubstitutePID +from Gaudi.Configuration import INFO + +_BPVCORRM = Functor('_BPVCORRM', 'Composite::CorrectedMass','Compute the corrected mass') +_allpv_FDVEC = (F.ENDVERTEX_POS @ F.FORWARDARG1 - F.TOLINALG @ F.POSITION @ F.FORWARDARG0) +_allpv_NORMEDDOT = F.NORMEDDOT.bind(F.THREEMOMENTUM @ F.FORWARDARG1, _allpv_FDVEC) +ALLPV_CHI2 = lambda Vertices: F.MAP(F.CHI2) @ F.TES(Vertices) +ALLPV_CHI2DOF = lambda Vertices: F.MAP(F.CHI2DOF) @ F.TES(Vertices) +ALLPV_IPCHI2 = lambda Vertices: F.MAP(F.IPCHI2).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_FDCHI2 = lambda Vertices: F.MAP(F.VTX_FDCHI2).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_DIRA = lambda Vertices: F.MAP(_allpv_NORMEDDOT).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_CORRM = lambda Vertices: F.MAP(_BPVCORRM).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_LTIME = lambda Vertices: F.MAP(F.VTX_LTIME).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_DLS = lambda Vertices: F.MAP(F.VTX_DLS).bind(F.TES(Vertices), F.FORWARDARGS) +ALLPV_FD_COORDINATE = lambda coordinate, Vertices: F.MAP(coordinate @ _allpv_FDVEC).bind(F.TES(Vertices), F.FORWARDARGS) + +TRUE_ID_IS = lambda id, mctruth: (F.VALUE_OR(0) @ mctruth(F.ABS @ F.PARTICLE_ID) == id) + +def make_Bst(B, pions,lepton, hadron_candidate_id,v2_pvs,do_truth_matching = True): + + Bstm = SubstitutePID( + name='PIDSubstitute', + input_particles=B, + substitutions=["B-{{B*-}}","B+{{B*+}}"], + output_level=INFO).Particles + + #combine to make [B*0 -> B*- pi+]cc + Bst_1 = ParticleCombiner( + Inputs=[Bstm, pions], + name=f'Bst_1_{lepton}', + DecayDescriptor='[B*0 -> B*- pi+]cc', + CombinationCut=F.ALL, + CompositeCut=F.ALL, + ParticleCombiner="ParticleVertexFitter", + PrimaryVertices=v2_pvs + #OutputLevel=1 + ) + #combine to make [B*0 -> B*- pi-]cc + Bst_2 = ParticleCombiner( + Inputs=[Bstm, pions], + name=f'Bst_2_{lepton}', + DecayDescriptor='[B*0 -> B*- pi-]cc', + CombinationCut=F.ALL, + CompositeCut=F.ALL, + ParticleCombiner="ParticleVertexFitter", + PrimaryVertices=v2_pvs + #OutputLevel=1 + ) + #merge the two Bst candidates + Bst = ParticleContainersMerger([Bst_1, Bst_2], name = f'Bst_combiner_{lepton}') + return Bst + +def get_functors(MCTRUTH, v2_pvs, rec_summary): + #define common variables for all fields (composite and basic) + vars_common = FunctorCollection() + #all pvs: ip, ipchi2. The PV positions are stored in event variables + vars_common['ALLPV_IP[pv_indx]'] = F.ALLPV_IP(v2_pvs) + vars_common['ALLPV_IPCHI2[pv_indx]'] = ALLPV_IPCHI2(v2_pvs) + #best pv: x, y, z, ip, ipchi2 + vars_common['BPV_X'] = F.BPVX(v2_pvs) + vars_common['BPV_Y'] = F.BPVY(v2_pvs) + vars_common['BPV_Z'] = F.BPVZ(v2_pvs) + vars_common['BPV_IP'] = F.BPVIP(v2_pvs) + vars_common['BPV_IPCHI2'] = F.BPVIPCHI2(v2_pvs) + vars_common['BPV_CHI2'] = F.CHI2 @ F.BPV(v2_pvs) + vars_common['BPV_CHI2DOF'] = F.CHI2DOF @ F.BPV(v2_pvs) + #particle id, key, truekey. The trueid is stored in MCHierarchy + vars_common['ID'] = F.PARTICLE_ID + vars_common['KEY'] = F.OBJECT_KEY + + #get charge, min ip and min ipchi2 + vars_common['CHARGE'] = F.CHARGE + vars_common['MINIP'] = F.MINIP(v2_pvs) + vars_common['MINIPCHI2'] = F.MINIPCHI2(v2_pvs) + #reco kinematics + vars_common += FC.Kinematics() + vars_common['ETA'] = F.ETA + vars_common['PHI'] = F.PHI + if MCTRUTH != 'None': + #mc vars + vars_common['TRUEKEY'] = F.VALUE_OR(-1) @ MCTRUTH(F.OBJECT_KEY) + vars_common += FC.MCKinematics(mctruth_alg = MCTRUTH) + vars_common['TRUEETA'] = MCTRUTH(F.ETA) + vars_common['TRUEPHI'] = MCTRUTH(F.PHI) + #type of the origin vertex + vars_common['MC_VTX_TYPE'] = MCTRUTH(F.VALUE_OR(-1) @ F.MC_VTX_TYPE @ F.MC_ORIGINVERTEX) + #make some helper functions + MCMOTHER_ID = lambda n: F.VALUE_OR(0) @ MCTRUTH(F.MC_MOTHER(n, F.PARTICLE_ID)) + MCMOTHER_KEY = lambda n: F.VALUE_OR(-1) @ MCTRUTH(F.MC_MOTHER(n, F.OBJECT_KEY )) + vars_common["TRUEID"] = F.VALUE_OR(0) @ MCTRUTH(F.PARTICLE_ID) + vars_common["MCKEY"] = F.VALUE_OR(0) @ MCTRUTH(F.OBJECT_KEY) + vars_common["MC_MOTHER_ID"] = MCMOTHER_ID(1) + vars_common["MC_MOTHER_KEY"] = MCMOTHER_KEY(1) + for i in range(2,14): + prefix = "MC_GD_MOTHER_{}".format(i) + vars_common[f"{prefix}_ID"] = MCMOTHER_ID(i) + vars_common[f"{prefix}_KEY"] = MCMOTHER_KEY(i) + + #variables for composite particles + vars_composite = FunctorCollection() + #end vertex position and end vertex chi2 + vars_composite['ENDVERTEX_POS_'] = F.ENDVERTEX_POS + vars_composite['ENDVERTEX_CHI2'] = F.CHI2 @ F.ENDVERTEX + vars_composite['ENDVERTEX_CHI2DOF'] = F.CHI2DOF @ F.ENDVERTEX + #all pvs: dira, fd, fdchi2 + vars_composite['ALLPV_DIRA[pv_indx]'] = ALLPV_DIRA(v2_pvs) + vars_composite['ALLPV_FD_X[pv_indx]'] = ALLPV_FD_COORDINATE(F.X_COORDINATE, v2_pvs) + vars_composite['ALLPV_FD_Y[pv_indx]'] = ALLPV_FD_COORDINATE(F.Y_COORDINATE, v2_pvs) + vars_composite['ALLPV_FD_Z[pv_indx]'] = ALLPV_FD_COORDINATE(F.Z_COORDINATE, v2_pvs) + vars_composite['ALLPV_FDCHI2[pv_indx]'] = ALLPV_FDCHI2(v2_pvs) + vars_composite['ALLPV_CORRM[pv_indx]'] = ALLPV_CORRM(v2_pvs) + vars_composite['ALLPV_LTIME[pv_indx]'] = ALLPV_LTIME(v2_pvs) + vars_composite['ALLPV_DLS[pv_indx]'] = ALLPV_DLS(v2_pvs) + #best pv: dira, fd, fdchi2, corrm, ltime, dls + vars_composite['BPV_DIRA'] = F.BPVDIRA(v2_pvs) + vars_composite['BPV_FD_'] = F.BPVFDVEC(v2_pvs) + vars_composite['BPV_FDCHI2'] = F.BPVFDCHI2(v2_pvs) + vars_composite['BPV_CORRM'] = F.BPVCORRM(v2_pvs) + vars_composite['BPV_LTIME'] = F.BPVLTIME(v2_pvs) + vars_composite['BPV_DLS'] = F.BPVDLS(v2_pvs) + + #mc composite vertex information + if MCTRUTH != 'None': vars_composite += FC.MCVertexInfo(mctruth_alg = MCTRUTH) + #Compute maximum DOCA and maximum DOCACHI2. Since there are + # only two daughters of B0 particles, the maximum DOCA/DOCACHI2 is + # the DOCA/DOCACHI2 see below. + vars_composite['MAX_DOCA'] = F.MAXDOCA + vars_composite['MAX_DOCACHI2'] = F.MAXDOCACHI2 + vars_composite['MAX_SDOCA'] = F.MAXSDOCA + vars_composite['MAX_SDOCACHI2'] = F.MAXSDOCACHI2 + + #variables for basics + vars_basic = FunctorCollection() + vars_basic['TRACKTYPE'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKTYPE @ F.TRACK + vars_basic['TRACKHISTORY'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKHISTORY @ F.TRACK + vars_basic['TRACKFLAG'] = F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.TRACKFLAG @ F.TRACK + vars_basic['TRACKNDOF'] = F.VALUE_OR(-1) @ F.NDOF @ F.TRACK + vars_basic['TRACKCHI2'] = F.CHI2 @ F.TRACK + vars_basic['TRACKCHI2DOF'] = F.CHI2DOF @ F.TRACK + vars_basic['GHOSTPROB'] = F.GHOSTPROB + vars_basic['NHITS'] = F.VALUE_OR(-1) @F.NHITS @ F.TRACK + vars_basic['NUTHITS'] = F.VALUE_OR(-1) @F.NUTHITS @ F.TRACK + vars_basic['NVPHITS'] = F.VALUE_OR(-1) @F.NVPHITS @ F.TRACK + vars_basic['NFTHITS'] = F.VALUE_OR(-1) @ F.NFTHITS @ F.TRACK + vars_basic['TRACKHASUT'] = F.VALUE_OR(-1) @ F.TRACKHASUT @ F.TRACK + vars_basic['TRACKHASVELO'] = F.VALUE_OR(-1) @ F.TRACKHASVELO @ F.TRACK + vars_basic['PIDpi'] = F.PID_PI + vars_basic['PIDk'] = F.PID_K + vars_basic['PIDp'] = F.PID_P + vars_basic['PIDe'] = F.PID_E + vars_basic['PIDmu'] = F.PID_MU + vars_basic['PROBNNe'] = F.PROBNN_E + vars_basic['PROBNNpi'] = F.PROBNN_PI + vars_basic['PROBNNk'] = F.PROBNN_K + vars_basic['PROBNNmu'] = F.PROBNN_MU + vars_basic['PROBNNp'] = F.PROBNN_P + vars_basic['PROBNNghost'] = F.PROBNN_GHOST + if MCTRUTH != 'None': vars_basic += FC.MCVertexInfo(mctruth_alg = MCTRUTH) + + #variables for event + #Collection includes tis_tos, nPVs,nHits/clusters,BUNCHCROSSING and GPS var + evt_collections = [ + FC.EventInfo(), + FC.RecSummary(), + ] + evt_vars = FunctorCollection({}) + evt_vars['ALLPV_X[pv_indx]'] = F.ALLPVX(v2_pvs) + evt_vars['ALLPV_Y[pv_indx]'] = F.ALLPVY(v2_pvs) + evt_vars['ALLPV_Z[pv_indx]'] = F.ALLPVZ(v2_pvs) + evt_vars['ALLPV_CHI2[pv_indx]'] = ALLPV_CHI2(v2_pvs) + evt_vars['ALLPV_CHI2DOF[pv_indx]']= ALLPV_CHI2DOF(v2_pvs) + + for coll in evt_collections:evt_vars += coll + + vars_brems = FunctorCollection({}) + vars_brems.update({"HASBREM": F.HASBREM}) + #vars_brems.update({"HASBREMADDED": F.HASBREMADDED}) + vars_brems.update({"BREMENERGY": F.BREMENERGY}) + vars_brems.update({"BREMBENDCORR": F.BREMBENDCORR}) + vars_brems.update({"BREMPIDE": F.BREMPIDE}) + vars_brems.update({"ECALPIDE": F.ECALPIDE}) + vars_brems.update({"ECALPIDMU": F.ECALPIDMU}) + vars_brems.update({"HCALPIDE": F.HCALPIDE}) + vars_brems.update({"HCALPIDMU": F.HCALPIDMU}) + vars_brems.update({"ELECTRONSHOWEREOP": F.ELECTRONSHOWEREOP}) + vars_brems.update({"ELECTRONSHOWERDLL": F.ELECTRONSHOWERDLL}) + vars_brems.update({"CLUSTERMATCH": F.CLUSTERMATCH_CHI2}) + vars_brems.update({"ELECTRONMATCH": F.ELECTRONMATCH_CHI2}) + vars_brems.update({"BREMHYPOMATCH": F.BREMHYPOMATCH_CHI2}) + vars_brems.update({"ELECTRONENERGY": F.ELECTRONENERGY}) + vars_brems.update({"BREMHYPOENERGY": F.BREMHYPOENERGY}) + vars_brems.update({"BREMHYPODELTAX": F.BREMHYPODELTAX}) + #vars_brems.update({"BREMTRACKBASEDENERGY": F.BREMTRACKBASEDENERGY}) + vars_brems.update({"INBREM": F.INBREM}) + vars_brems.update({"INECAL": F.INECAL}) + vars_brems.update({"PT_WITH_BREM": F.PT_WITH_BREM}) + vars_brems.update({"P_WITH_BREM": F.P_WITH_BREM}) + + #return all functors + functors = (vars_common, vars_composite, vars_basic, evt_vars,vars_brems) + return functors +''' +def get_B_momentum(v2_pvs): + PVIS = F.THREEMOMENTUM + MVIS = F.MASS + EVIS = F.ENERGY + # Get the flight direction of the mother + Fnorm = F.BPVFDIR(v2_pvs) + # Calculate P_vis^perpendicular, as defined in Eq. 5.1 in JHEP(2017)2017:21 + PVIS_PERP = F.MAGNITUDE @ F.CROSS_PRODUCT.bind(PVIS, Fnorm) + # Calculate P_vis^parallel, as defined in Eq. 5.2 in JHEP(2017)2017:21 + PVIS_PARA = F.DOT_PRODUCT.bind(PVIS, Fnorm) + # Extract the known mass of the parent + parent_mass = F.PDG_MASS("B0") + # Calculate parameter a, as defined in Eq. 5.4 in JHEP(2017)2017:21 + a = (PVIS_PARA * (parent_mass**2 - MVIS**2 - 2 * PVIS_PERP**2)) / (2 * (PVIS_PARA**2 - EVIS**2)) + # Calculate r, as defined in Eq. 5.5 in arXiv:1611.08522 + r = EVIS**2 * (parent_mass**2 - MVIS**2 - 2 * PVIS_PERP**2)**2 / (4 * (PVIS_PARA**2 - EVIS**2)**2) + (EVIS * PVIS_PERP)**2 / (PVIS_PARA**2 - EVIS**2) + + return (PVIS_PARA - a + F.SQRT @ r) * Fnorm +''' +def get_fitting_variable(v2_pvs,D0,lep,Epi): + B_mass = F.PDG_MASS("B0") + B_dis = np.array([F.END_VX-F.BPVX(v2_pvs),F.END_VY-F.BPVY(v2_pvs),F.END_VZ-F.BPVZ(v2_pvs)]) + B_dis_mag = F.SQRT @ (B_dis[0]**2+B_dis[1]**2+B_dis[2]**2) + B_Mod_P = F.ABS @ ((B_mass/F.MASS)*F.PZ/(B_dis[2]/B_dis_mag)) + B_Mod_E = F.SQRT @ (B_Mod_P**2 + B_mass**2) + + Dst_PX = F.X_COORDINATE @ ((F.FOURMOMENTUM @ D0)+(F.FOURMOMENTUM @ Epi)) + Dst_PY = F.Y_COORDINATE @ ((F.FOURMOMENTUM @ D0)+(F.FOURMOMENTUM @ Epi)) + Dst_PZ = F.Z_COORDINATE @ ((F.FOURMOMENTUM @ D0)+(F.FOURMOMENTUM @ Epi)) + Dst_E = F.E_COORDINATE @ ((F.FOURMOMENTUM @ D0)+(F.FOURMOMENTUM @ Epi)) + + B_4P = np.array([B_Mod_P*B_dis[0]/B_dis_mag,B_Mod_P*B_dis[1]/B_dis_mag,B_Mod_P*B_dis[2]/B_dis_mag,B_Mod_E]) + D_4P = np.array([Dst_PX,Dst_PY,Dst_PZ,Dst_E]) + lep_4P = np.array([F.PX @ lep,F.PY @ lep,F.PZ @ lep,F.ENERGY @ lep]) + ''' + B_P_mike = get_B_momentum(v2_pvs) + B_Mod_P_mike = F.MAGNITUDE @ B_P_mike + B_E_mike = F.SQRT @ (F.DOT_PRODUCT.bind(B_P_mike, B_P_mike) + F.B_mass**2) + B_4P_mike = np.array([F.X_COORDINATE @ B_P_mike,F.Y_COORDINATE @ B_P_mike,F.Z_COORDINATE @ B_P_mike,B_E_mike]) + ''' + vars_fitting = FunctorCollection({}) + vars_fitting["Mod_P"] = B_Mod_P + #vars_fitting["Mod_P_mike"] = B_Mod_P_mike + vars_fitting['missing_m2'] = (B_4P[3]-D_4P[3]-lep_4P[3])**2-(B_4P[0]-D_4P[0]-lep_4P[0])**2-(B_4P[1]-D_4P[1]-lep_4P[1])**2-(B_4P[2]-D_4P[2]-lep_4P[2])**2 + #vars_fitting['missing_m2_mike'] = (B_4P_mike[3]-D_4P[3]-lep_4P[3])**2-(B_4P_mike[0]-D_4P[0]-lep_4P[0])**2-(B_4P_mike[1]-D_4P[1]-lep_4P[1])**2-(B_4P_mike[2]-D_4P[2]-lep_4P[2])**2 + vars_fitting['q2'] = (B_4P[3]-D_4P[3])**2-(B_4P[0]-D_4P[0])**2-(B_4P[1]-D_4P[1])**2-(B_4P[2]-D_4P[2])**2 + #vars_fitting['q2_mike'] = (B_4P_mike[3]-D_4P[3])**2-(B_4P_mike[0]-D_4P[0])**2-(B_4P_mike[1]-D_4P[1])**2-(B_4P_mike[2]-D_4P[2])**2 + B_Beta = B_Mod_P/B_Mod_E + B_gamma = 1/F.SQRT @ (1-B_Beta**2) + + B_Lorentz = [[B_gamma,-1*B_gamma*B_4P[0]/B_4P[3],-1*B_gamma*B_4P[1]/B_4P[3],-1*B_gamma*B_4P[2]/B_4P[3]],[-1*B_gamma*B_4P[0]/B_4P[3],1+(B_gamma-1)*((B_4P[0]/B_4P[3])/B_Beta)*((B_4P[0]/B_4P[3])/B_Beta),(B_gamma-1)*((B_4P[0]/B_4P[3])/B_Beta)*((B_4P[1]/B_4P[3])/B_Beta),(B_gamma-1)*((B_4P[0]/B_4P[3])/B_Beta)*((B_4P[2]/B_4P[3])/B_Beta)],[-1*B_gamma*B_4P[1]/B_4P[3],(B_gamma-1)*((B_4P[0]/B_4P[3])/B_Beta)*((B_4P[1]/B_4P[3])/B_Beta),(B_gamma-1)*((B_4P[1]/B_4P[3])/B_Beta)*((B_4P[1]/B_4P[3])/B_Beta),(B_gamma-1)*((B_4P[1]/B_4P[3])/B_Beta)*((B_4P[2]/B_4P[3])/B_Beta)],[-1*B_gamma*B_4P[2]/B_4P[3],(B_gamma-1)*((B_4P[0]/B_4P[3])/B_Beta)*((B_4P[2]/B_4P[3])/B_Beta),(B_gamma-1)*((B_4P[1]/B_4P[3])/B_Beta)*((B_4P[2]/B_4P[3])/B_Beta),(B_gamma-1)*((B_4P[2]/B_4P[3])/B_Beta)*((B_4P[2]/B_4P[3])/B_Beta)]] + vars_fitting['lep_E_Brest'] = (B_Lorentz[0][0]*lep_4P[3]+B_Lorentz[0][1]*lep_4P[0]+B_Lorentz[0][2]*lep_4P[1]+B_Lorentz[0][3]*lep_4P[2]) + ''' + B_Beta_mike = B_Mod_P_mike/B_E_mike + B_gamma_mike = 1/F.SQRT @ (1-B_Beta_mike**2) + + B_Lorentz = [[B_gamma_mike,-1*B_gamma_mike*B_4P_mike[0]/B_4P_mike[3],-1*B_gamma_mike*B_4P_mike[1]/B_4P_mike[3],-1*B_gamma_mike*B_4P_mike[2]/B_4P_mike[3]],[-1*B_gamma_mike*B_4P_mike[0]/B_4P_mike[3],1+(B_gamma_mike-1)*((B_4P_mike[0]/B_4P_mike[3])/B_Beta_mike)*((B_4P_mike[0]/B_4P_mike[3])/B_Beta_mike),(B_gamma_mike-1)*((B_4P_mike[0]/B_4P_mike[3])/B_Beta_mike)*((B_4P_mike[1]/B_4P_mike[3])/B_Beta_mike),(B_gamma_mike-1)*((B_4P_mike[0]/B_4P_mike[3])/B_Beta_mike)*((B_4P_mike[2]/B_4P_mike[3])/B_Beta_mike)],[-1*B_gamma_mike*B_4P_mike[1]/B_4P_mike[3],(B_gamma_mike-1)*((B_4P_mike[0]/B_4P_mike[3])/B_Beta_mike)*((B_4P_mike[1]/B_4P_mike[3])/B_Beta_mike),(B_gamma_mike-1)*((B_4P_mike[1]/B_4P_mike[3])/B_Beta_mike)*((B_4P_mike[1]/B_4P_mike[3])/B_Beta_mike),(B_gamma_mike-1)*((B_4P_mike[1]/B_4P_mike[3])/B_Beta_mike)*((B_4P_mike[2]/B_4P_mike[3])/B_Beta_mike)],[-1*B_gamma_mike*B_4P_mike[2]/B_4P_mike[3],(B_gamma_mike-1)*((B_4P_mike[0]/B_4P_mike[3])/B_Beta_mike)*((B_4P_mike[2]/B_4P_mike[3])/B_Beta_mike),(B_gamma_mike-1)*((B_4P_mike[1]/B_4P_mike[3])/B_Beta_mike)*((B_4P_mike[2]/B_4P_mike[3])/B_Beta_mike),(B_gamma_mike-1)*((B_4P_mike[2]/B_4P_mike[3])/B_Beta_mike)*((B_4P_mike[2]/B_4P_mike[3])/B_Beta_mike)]] + vars_fitting['lep_E_Brest_mike'] = (B_Lorentz[0][0]*lep_4P[3]+B_Lorentz[0][1]*lep_4P[0]+B_Lorentz[0][2]*lep_4P[1]+B_Lorentz[0][3]*lep_4P[2]) + ''' + return(vars_fitting) + +def tuple_Bst(Bst,lepton,line, MCTRUTH, v2_pvs, rec_summary): + #get functors + functors = get_functors(MCTRUTH, v2_pvs, rec_summary) + vars_common = functors[0] + vars_composite = functors[1] + vars_basic = functors[2] + evt_vars = functors[3] + vars_brems = functors[4] + + #variables for B0 field + vars_Bst = FunctorCollection() + B_child = F.CHILD(1, F.FORWARDARG0) + D0_child = F.CHILD(1, F.CHILD(1,F.FORWARDARG0)) + Lep_child = F.CHILD(1, F.CHILD(2,F.FORWARDARG0)) + Epi_child = F.CHILD(2, F.FORWARDARG0) + bpv_pi = F.BPV(v2_pvs).bind(Epi_child) + #diff in vtx chi2 with and without extra particle + vars_Bst['DELTA_ENDVERTEX_CHI2'] = (F.CHI2 @ F.ENDVERTEX) - (F.CHI2 @ F.ENDVERTEX.bind(B_child)) + #IP and IPChi2 of extra particle wrt to B0 end vertex + vars_Bst['Epi_IP_WRT_B0ENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ F.FORWARDARG0 , Epi_child) + vars_Bst['Epi_IPCHI2_WRT_B0ENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ F.FORWARDARG0 , Epi_child) + #IP and IPChi2 of extra particle wrt to Bm end vertex + vars_Bst['Epi_IP_WRT_BmENDVERTEX'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.ENDVERTEX @ B_child , Epi_child) + vars_Bst['Epi_IPCHI2_WRT_BmENDVERTEX'] = F.IPCHI2.bind(F.ENDVERTEX @ B_child , Epi_child) + #angle between extra particle and Bm + vars_Bst['Epi_COSANGLE_Bm'] = F.COSANGLE.bind(F.THREEMOMENTUM @ B_child, F.THREEMOMENTUM @ Epi_child) + #diff in fd chi2 with and without extra particle + vars_Bst['Delta_BPV_of_Epi_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi, F.FORWARDARGS) - F.VTX_FDCHI2.bind(bpv_pi, B_child) + vars_Bst['BPV_of_Epi_FDCHI2'] = F.VTX_FDCHI2.bind(bpv_pi, F.FORWARDARGS) + #IP chi2 of extra particle wrt PV and SV of B0 + vars_Bst['Epi_IP_WRT_B0BPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child) + vars_Bst['Epi_IPCHI2_WRT_B0BPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ F.FORWARDARG0, Epi_child) + #IP chi2 of extra particle wrt PV and SV of Bm + vars_Bst['Epi_IP_WRT_BmBPV'] = F.IP.bind(F.TOLINALG @ F.POSITION @ F.BPV(v2_pvs) @ B_child, Epi_child) + vars_Bst['Epi_IPCHI2_WRT_BmBPV'] = F.IPCHI2.bind(F.BPV(v2_pvs) @ B_child, Epi_child) + #DOCA and DOCACHI2 b/w Lb and extra particle + vars_Bst['DOCA12'] = F.DOCA(1, 2) + vars_Bst['DOCA12_CHI2_12'] = F.DOCACHI2(1, 2) + #vars_Bst['SDOCA12'] = F.SDOCA(1, 2) + #vars_Bst['SDOCA_CHI2_12'] = F.SDOCACHI2(1, 2) + #DOCACHI2 of extra particle wrt to mother i.e. B0 + vars_Bst['MTDOCACHI2_1'] = F.MTDOCACHI2(1, v2_pvs) + vars_Bst['MTDOCACHI2_2'] = F.MTDOCACHI2(2, v2_pvs) + vars_Bst['Delta_M'] = F.ABS @ ((F.MASS @ ((F.FOURMOMENTUM @ D0_child)+(F.FOURMOMENTUM @ Epi_child))) - (F.MASS @ D0_child)) + vars_Bst['Dst_M'] = F.MASS @ ((F.FOURMOMENTUM @ D0_child)+(F.FOURMOMENTUM @ Epi_child)) + vars_Bst['Dst_PX'] = F.X_COORDINATE @ ((F.FOURMOMENTUM @ D0_child)+(F.FOURMOMENTUM @ Epi_child)) + vars_Bst['Dst_PY'] = F.Y_COORDINATE @ ((F.FOURMOMENTUM @ D0_child)+(F.FOURMOMENTUM @ Epi_child)) + vars_Bst['Dst_PZ'] = F.Z_COORDINATE @ ((F.FOURMOMENTUM @ D0_child)+(F.FOURMOMENTUM @ Epi_child)) + #vars_Bst['iso_mva'] = mva_functor_mu_inclusive(v2_pvs)[0] + if MCTRUTH != 'None': + vars_Bst += trail_seeker(MCTRUTH) + vars_Bst['iso_mva'] = mva_functor_inclusive(v2_pvs)[0] + + + #define fields + fit_vars = get_fitting_variable(v2_pvs,D0_child,Lep_child,Epi_child) + #TIS and TOS + Hlt1_decisions = ['Hlt1TrackMVA', + 'Hlt1TwoTrackMVA', + 'Hlt1D2KK', + 'Hlt1D2KPi', + 'Hlt1D2PiPi', + 'Hlt1KsToPiPi', + 'Hlt1TrackMuonMVA', + 'Hlt1SingleHighPtMuon', + 'Hlt1TrackElectronMVA', + 'Hlt1SingleHighPtElectron', + 'Hlt1DiElectronDisplaced', + 'Hlt1DiPhotonHighMass', + 'Hlt1Pi02GammaGamma', + 'Hlt1DiElectronHighMass_SS', + 'Hlt1DiElectronHighMass'] + variables_tistos_hlt1 = FC.HltTisTos(selection_type="Hlt1", trigger_lines=Hlt1_decisions, data=Bst) + evt_vars += FC.SelectionInfo(selection_type="Hlt1", trigger_lines=Hlt1_decisions) + + Hlt2_decisions = ['Hlt2SLB_BuToD0MuNu_D0ToKPi', + 'Hlt2SLB_BuToD0MuNu_D0ToKPi_FakeMuon', + 'Hlt2SLB_BuToD0ENu_D0ToKPi', + 'Hlt2SLB_BuToD0ENu_D0ToKPi_FakeElectron', + 'Hlt2SLB_B0ToDpTauNu_DpToKPiPi_TauToENuNu', + 'Hlt2SLB_B0ToDpTauNu_DpToKPiPi_TauToMuNuNu', + 'Hlt2SLB_BuToD0TauNu_D0ToKPi_TauToENuNu', + 'Hlt2SLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu', + 'Hlt2SLB_BuToD0TauNu_D0ToKPi_FakeMuon', + 'Hlt2SLB_BuToD0TauNu_D0ToKPi_FakeElectron', + 'Hlt2SLB_myBuToD0ENu_D0ToKPi', + 'Hlt2Topo2Body', + 'Hlt2Topo3Body'] + + variables_tistos_hlt2 = FC.HltTisTos(selection_type="Hlt2", trigger_lines=Hlt2_decisions, data=Bst) + evt_vars += FC.SelectionInfo(selection_type="Hlt2", trigger_lines=Hlt2_decisions) + + + #define fields + fields = {} + fields['B0'] = f'[B*0 -> (B*- -> ([D0 -> K- pi+]CC) {lepton}-) [pi+]CC]CC' + fields['Bm'] = f'[B*0 -> ^(B*- -> ([D0 -> K- pi+]CC) {lepton}-) [pi+]CC]CC' + fields['D0'] = f'[B*0 -> (B*- -> ^([D0 -> K- pi+]CC) {lepton}-) [pi+]CC]CC' + fields['Lep'] = f'[B*0 -> (B*- -> ([D0 -> K- pi+]CC) ^{lepton}-) [pi+]CC]CC' + fields['Epi'] = f'[B*0 -> (B*- -> ([D0 -> K- pi+]CC) {lepton}-) ^[pi+]CC]CC' + fields['Km'] = f'[B*0 -> (B*- -> ([D0 -> ^K- pi+]CC) {lepton}-) [pi+]CC]CC' + fields['pip'] = f'[B*0 -> (B*- -> ([D0 -> K- ^pi+]CC) {lepton}-) [pi+]CC]CC' + + #add variables + variables = {} + variables["ALL"] = vars_common + variables_tistos_hlt1 + variables_tistos_hlt2 + variables["B0"] = vars_composite + vars_Bst + fit_vars + variables["Bm"] = vars_composite + variables["D0"] = vars_composite + variables["Lep"] = vars_basic + vars_brems + variables["Epi"] = vars_basic + variables["Km"] = vars_basic + variables["pip"] = vars_basic + + #define tuple + my_tuple = Funtuple( + name=f"Tuple", + tuple_name="DecayTree", + fields=fields, + variables=variables, + event_variables=evt_vars, + store_multiple_cand_info=True, + inputs=Bst) + + return my_tuple + +def get_extra_pions(): + """ + Note this function in DaVinci requires: + https://gitlab.cern.ch/lhcb/Moore/-/merge_requests/3203 + and it's related LHCb, DaVinci and Rec MRs + """ + long_pions = make_has_rich_long_pions() + up_pions = make_has_rich_up_pions() + down_pions = make_has_rich_down_pions() + return ParticleContainersMerger([long_pions, up_pions, down_pions], + name='Pions_combiner') + +#def main(options): +def main(options: Options,line = '', lep='',data_or_mc='mc'): + + #define filer + my_filter = create_lines_filter(name="Filter", lines=[line]) + + #get data and extra particles + Bm = get_particles(f"/Event/Spruce/{line}/Particles") + extra_particles = get_extra_pions() + #extra_particles = get_particles(f"/Event/Spruce/{line}/{line}_extra_tracks/Particles") + + #get v2_pvs and rec_summary + v2_pvs = get_pvs() + rec_summary = get_rec_summary() + hadron_candidate_id = 421 + #make B0 candidate + Bst = make_Bst(Bm, extra_particles,lep,hadron_candidate_id,v2_pvs,False) + MVA_cut = mva_transform_output(0.1) + b_cut = F.require_all(mva_functor_inclusive(v2_pvs)[0] > MVA_cut) #make a cut + Bst_after_cut = ParticleFilter(Input=Bst, Cut=F.FILTER(b_cut), name='Bst_after_cut') #filter the B candidates + + if data_or_mc == 'mc': + MCTRUTH_Bst = MCTruthAndBkgCat(Bst_after_cut, name='MCTRUTH_Bst') + tuple_file = tuple_Bst(Bst_after_cut,lep,line, MCTRUTH_Bst, v2_pvs, rec_summary) + elif data_or_mc == 'data': + tuple_file = tuple_Bst(Bst_after_cut,lep,line, 'None', v2_pvs, rec_summary) + else: + raise ValueError(f"Decay channel {decay_channel} not supported") + #define algorithms + user_algorithms = {} + user_algorithms['Alg'] = [my_filter, tuple_file] + + return make_config(options, user_algorithms) + +def test(options: Options): + return main(options=options, line='Hlt2_Test_line',lep='e',data_or_mc='data') + +def MC_SLB_BuToD0ENu_D0ToKPi(options: Options): + return main(options=options, line='SpruceSLB_myBuToD0ENu_D0ToKPi',lep='e',data_or_mc='mc') + +def MC_SLB_BuToDststENu(options: Options): + return main(options=options, line='SpruceSLB_myBuToD0ENu_D0ToKPi',lep='e',data_or_mc='mc') + +def MC_SLB_BdToDststENu(options: Options): + return main(options=options, line='SpruceSLB_myBuToD0ENu_D0ToKPi',lep='e',data_or_mc='mc') + +def MC_SLB_BuToD0MuNu_D0ToKPi(options: Options): + return main(options=options, line='SpruceSLB_BuToD0MuNu_D0ToKPi',lep='mu',data_or_mc='mc') + +def MC_SLB_BuToD0TauNu_D0ToKPi_TauToENuNu(options: Options): + return main(options=options, line='SpruceSLB_myBuToD0ENu_D0ToKPi',lep='e',data_or_mc='mc') + +def MC_SLB_BuToDststTauNu_TauToENuNu(options: Options): + return main(options=options, line='SpruceSLB_myBuToD0ENu_D0ToKPi',lep='e',data_or_mc='mc') + +def MC_SLB_BdToDststTauNu_TauToENuNu(options: Options): + return main(options=options, line='SpruceSLB_myBuToD0ENu_D0ToKPi',lep='e',data_or_mc='mc') + +def MC_SLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu(options: Options): + return main(options=options, line='SpruceSLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu',lep='mu',data_or_mc='mc') + +def Data_SLB_BuToD0ENu_D0ToKPi(options: Options): + return main(options=options, line='SpruceSLB_BuToD0ENu_D0ToKPi',lep='e',data_or_mc='data') + +def Data_SLB_BuToD0MuNu_D0ToKPi(options: Options): + return main(options=options, line='SpruceSLB_BuToD0MuNu_D0ToKPi',lep='mu',data_or_mc='data') + +def Data_SLB_BuToD0TauNu_D0ToKPi_TauToENuNu(options: Options): + return main(options=options, line='SpruceSLB_BuToD0TauNu_D0ToKPi_TauToENuNu',lep='e',data_or_mc='data') + +def Data_SLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu(options: Options): + return main(options=options, line='SpruceSLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu',lep='mu',data_or_mc='data') + +def Data_SLB_BuToD0ENu_D0ToKPi_FakeElectron(options: Options): + return main(options=options, line='SpruceSLB_BuToD0ENu_D0ToKPi_FakeElectron',lep='e',data_or_mc='data') + +def Data_SLB_BuToD0MuNu_D0ToKPi_FakeMuon(options: Options): + return main(options=options, line='SpruceSLB_BuToD0MuNu_D0ToKPi_FakeMuon',lep='mu',data_or_mc='data') + +def Data_SLB_BuToD0TauNu_D0ToKPi_FakeElectron(options: Options): + return main(options=options, line='SpruceSLB_BuToD0TauNu_D0ToKPi_FakeElectron',lep='e',data_or_mc='data') + +def Data_SLB_BuToD0TauNu_D0ToKPi_FakeMuon(options: Options): + return main(options=options, line='SpruceSLB_BuToD0TauNu_D0ToKPi_FakeMuon',lep='mu',data_or_mc='data') diff --git a/SL_l_nu_D0toKpi_Run3_MC_data_v2/Hlt1.py b/SL_l_nu_D0toKpi_Run3_MC_data_v2/Hlt1.py new file mode 100644 index 0000000000..eeabcc4913 --- /dev/null +++ b/SL_l_nu_D0toKpi_Run3_MC_data_v2/Hlt1.py @@ -0,0 +1,18 @@ +############################################################################### +# (c) Copyright 2022 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### +from Moore import Options +from Moore.config import run_allen +from RecoConf.hlt1_allen import allen_gaudi_config as allen_sequence + +def main(options: Options): + with allen_sequence.bind(sequence="hlt1_pp_matching_no_ut_1000KHz"): + return run_allen(options) + diff --git a/SL_l_nu_D0toKpi_Run3_MC_data_v2/Hlt2.py b/SL_l_nu_D0toKpi_Run3_MC_data_v2/Hlt2.py new file mode 100644 index 0000000000..be2bda5d70 --- /dev/null +++ b/SL_l_nu_D0toKpi_Run3_MC_data_v2/Hlt2.py @@ -0,0 +1,155 @@ +############################################################################### +# (c) Copyright 2022 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### +""" +Stolen and adapted from Hlt/Hlt2Conf/options/hlt2_pp_expected_24_without_UT.py from v55r7. +""" +from Moore import Options,options, run_moore, config +from Hlt2Conf.algorithms_thor import ParticleContainersMerger +from Hlt2Conf.lines.semileptonic.builders import sl_line_prefilter +from Hlt2Conf.lines.semileptonic.builders.base_builder import make_candidate +from Hlt2Conf.lines.semileptonic.builders.charm_hadron_builder import make_d0_tokpi +from GaudiKernel.SystemOfUnits import MeV, GeV,mm +from Hlt2Conf.algorithms_thor import ParticleCombiner +from Hlt2Conf.settings.defaults import get_default_hlt1_filter_code_for_hlt2 +from Hlt2Conf.lines.semileptonic import all_lines as slb_lines +from Hlt2Conf.lines.topological_b import all_lines as topo_lines +from Moore.config import Hlt2Line,register_line_builder +from Moore.streams import Stream, Streams, DETECTORS +from RecoConf.event_filters import require_gec +from RecoConf.global_tools import stateProvider_with_simplified_geom, trackMasterExtrapolator_with_simplified_geom +from RecoConf.hlt2_global_reco import reconstruction as hlt2_reconstruction, make_light_reco_pr_kf_without_UT +from RecoConf.reconstruction_objects import reconstruction,make_pvs +from RecoConf.decoders import default_ft_decoding_version,default_VeloCluster_source +from RecoConf.hlt2_tracking import ( + make_TrackBestTrackCreator_tracks, + make_PrKalmanFilter_noUT_tracks, + make_PrKalmanFilter_Velo_tracks, + make_PrKalmanFilter_Seed_tracks, +) +from Hlt2Conf.standard_particles import ( + make_long_electrons_with_brem, + make_has_rich_long_pions, + make_has_rich_up_pions, + make_has_rich_down_pions) +import Functors as F +from Functors.math import in_range +import sys + +#things to control +SUFFIX_NAME = '_BToDzl' +HLT2LINE = f'Hlt2SLB_myBuToD0ENu_D0ToKPi' +CHARM_MASS = 1864.84 #D0 mass +CHARM_BUILDER_NAME = 'Dz2KPi_combiner' +B_BUILDER_NAME = 'BToDzl_combiner' + +def get_charm_cuts(): + #make loose cuts for D0 + delta_mass = 80. #80.0 + make_d0tokpi_cuts = {} + make_d0tokpi_cuts['comb_m_min'] = (CHARM_MASS - delta_mass) * MeV + make_d0tokpi_cuts['comb_m_max'] = (CHARM_MASS + delta_mass) * MeV + make_d0tokpi_cuts['comb_docachi2_max'] = 5. + make_d0tokpi_cuts['vchi2pdof_max'] = 6 #6 (Now) 6/4 (v55r7 e/taue) + make_d0tokpi_cuts['bpvfdchi2_min'] = 25 #25 (Now) + make_d0tokpi_cuts['bpvdira_min'] = 0.99 #0.99 (Now) 0.99/0.999 (v55r7 e/taue) + make_d0tokpi_cuts['comb_pt_min'] = None #None (Now) None/2000 * MeV (v55r7 e/taue) + make_d0tokpi_cuts['comb_pt_any_min'] = None #None (Now) None/800 * MeV (v55r7 e/taue) + make_d0tokpi_cuts['comb_pt_sum_min'] = None #None (Now) None/2.5 * GeV (v55r7 e/taue) + make_d0tokpi_cuts['comb_doca_max'] = None #None (Now) None/0.1 mm (v55r7 e/taue) + make_d0tokpi_cuts['daughter_pt_min'] = 600 * MeV #600 * MeV (Now) 750 * MeV (v55r7) + make_d0tokpi_cuts['daughter_mipchi2_min'] = 9. #10. (Now) 10./9. (v55r7 e/taue) + make_d0tokpi_cuts['kaon_pid'] = (F.PID_K > 0.) #(F.PID_K > 0.) (Now) (F.PID_K > 4.) (v55r7) + make_d0tokpi_cuts['pion_pid'] = (F.PID_K < 2.) + return make_d0tokpi_cuts + +def get_electron_cuts(): + #make loose cuts for electron and tauonic muon + make_electron_cuts = {} + make_electron_cuts["p_min"] = 3. * GeV #3. * GeV (Now) 5. *GeV (v55r7) + make_electron_cuts["pt_min"] = 300. * MeV #300. * MeV (Now) 500. * MeV (v55r7) + make_electron_cuts["mipchi2_min"] = 9. #9. (Now) 9./16. (v55r7 e/taue) + make_electron_cuts["mip_min"] = None #0. + make_electron_cuts["pid"] = (F.PID_E > 0.) + make_electron_cuts["make_particles"] = make_long_electrons_with_brem #does not require in calo + return make_electron_cuts + +def make_b(): + make_d0tokpi_cuts = get_charm_cuts() + make_electron_cuts= get_electron_cuts() + pvs = make_pvs() + with make_candidate.bind(p_min=15. * GeV): + dzs = make_d0_tokpi(**make_d0tokpi_cuts, name = CHARM_BUILDER_NAME) + electrons = make_candidate(**make_electron_cuts, name = "Electron_maker") + + cut_vertex = F.require_all(F.CHI2DOF<9,F.BPVDIRA(pvs) >0.999,in_range(0 * MeV, F.MASS, 10000 * MeV)) + + rs_btodze = ParticleCombiner( + Inputs=[dzs, electrons], + name=f'rs_{B_BUILDER_NAME}_e', + DecayDescriptor='[B- -> D0 e-]cc', + CombinationCut=F.ALL, + CompositeCut=cut_vertex) + + ws_btodze = ParticleCombiner( + Inputs=[dzs, electrons], + name=f'ws_{B_BUILDER_NAME}_e', + DecayDescriptor='[B+ -> D0 e+]cc', + CombinationCut=F.ALL, + CompositeCut=cut_vertex) + + return ParticleContainersMerger([rs_btodze,ws_btodze]) + +@register_line_builder(slb_lines) +def hlt2_mybutod0enu_d0tokpi_line(name=HLT2LINE,prescale=1): + Bcands = make_b() + return Hlt2Line(name=name, prescale=prescale,persistreco=True, algs=sl_line_prefilter() + [Bcands]) + +def pass_through_line(name="Hlt2Passthrough"): + """Return a HLT2 line that performs no selection but runs and persists the reconstruction + """ + return Hlt2Line(name=name, prescale=1, algs=[], persistreco=True) + +from Hlt2Conf.lines.topological_b import * + +def _make_lines(): + ret = [] + for line_dict in [slb_lines]: + for line_name, builder in line_dict.items() : + if "D0ToKPi" in line_name and "TauToPiPiPi" not in line_name and "Bc" not in line_name: + print(line_name) + ret.append(builder()) + ret += [twobody_line(),threebody_line(),pass_through_line()] + return ret + +def make_streams(): + streams = [ + Stream(lines=_make_lines(), routing_bit=98, detectors=DETECTORS) + ] + return Streams(streams=streams) + +public_tools = [ + trackMasterExtrapolator_with_simplified_geom(), + stateProvider_with_simplified_geom(), +] + +def main(options: Options): + # NOTE: the TBTC does not apply a chi2 cut because it is applied by the PrKF + with reconstruction.bind(from_file=False),\ + hlt2_reconstruction.bind(make_reconstruction=make_light_reco_pr_kf_without_UT),\ + require_gec.bind(skipUT=True),\ + default_VeloCluster_source.bind(bank_type="VPRetinaCluster"),\ + make_TrackBestTrackCreator_tracks.bind(max_ghost_prob=0.7, max_chi2ndof=sys.float_info.max),\ + make_PrKalmanFilter_Velo_tracks.bind(max_chi2ndof=5.),\ + make_PrKalmanFilter_noUT_tracks.bind(max_chi2ndof=4.),\ + make_PrKalmanFilter_Seed_tracks.bind(max_chi2ndof=6.),\ + get_default_hlt1_filter_code_for_hlt2.bind(code=r"Hlt1(?!PassthroughLargeEvent).*Decision"): + return run_moore(options, make_streams, public_tools=[]) + diff --git a/SL_l_nu_D0toKpi_Run3_MC_data_v2/MC_Matcher.py b/SL_l_nu_D0toKpi_Run3_MC_data_v2/MC_Matcher.py new file mode 100644 index 0000000000..e3b279805b --- /dev/null +++ b/SL_l_nu_D0toKpi_Run3_MC_data_v2/MC_Matcher.py @@ -0,0 +1,26 @@ +from FunTuple import FunctorCollection +import Functors as F +def trail_seeker(MCTRUTH): + mcMatch = lambda decay_descriptor: (F.HAS_VALUE @ MCTRUTH(F.FIND_MCDECAY(decay_descriptor))) + mcMatch_both = lambda decay_descriptor1,decay_descriptor2: (F.HAS_VALUE @ MCTRUTH(F.FIND_MCDECAY(decay_descriptor1))+F.HAS_VALUE @ MCTRUTH(F.FIND_MCDECAY(decay_descriptor2))) + + variables = FunctorCollection({ + 'IS_Dtaunu':mcMatch_both("[B0 -> D*(2010)- tau+ nu_tau]CC","[B~0 -> D*(2010)- tau+ nu_tau]CC"), + 'IS_Denu':mcMatch_both("[B0 -> D*(2010)- e+ nu_e]CC","[B~0 -> D*(2010)- e+ nu_e]CC"), + 'IS_Dstar_2460enu':mcMatch_both("[B0 -> D*(2640)- e+ nu_e]CC","[B~0 -> D*(2640)- e+ nu_e]CC"), + 'IS_D_2Senu':mcMatch_both("[B0 -> D(2S)- e+ nu_e]CC","[B~0 -> D(2S)- e+ nu_e]CC"), + 'IS_Dstar_2460_2enu':mcMatch_both("[B0 -> D*_2(2460)- e+ nu_e]CC","[B~0 -> D*_2(2460)- e+ nu_e]CC"), + 'IS_D_2460_1enu':mcMatch_both("[B0 -> D_1(2420)- e+ nu_e]CC","[B~0 -> D_1(2420)- e+ nu_e]CC"), + 'IS_Dstar_0taunu':mcMatch_both("[B0 -> D*_0- tau+ nu_tau]CC","[B~0 -> D*_0- tau+ nu_tau]CC"), + 'IS_D_H_1taunu':mcMatch_both("[B0 -> D_1(H)- tau+ nu_tau]CC","[B~0 -> D_1(H)- tau+ nu_tau]CC"), + 'IS_D_2420_1taunu':mcMatch_both("[B0 -> D_1(2420)- tau+ nu_tau]CC","[B~0 -> D_1(2420)- tau+ nu_tau]CC"), + 'IS_Dstar_2460_2taunu':mcMatch_both("[B0 -> D*_2(2460)- tau+ nu_tau]CC","[B~0 -> D*_2(2460)- tau+ nu_tau]CC"), + 'IS_Dstar0_2640enu':mcMatch("[B- -> D*(2640)0 e- nu_e~]CC"), + 'IS_D0_2Senu':mcMatch("[B- -> D(2S)0 e- nu_e~]CC"), + 'IS_Dstar0_2460_2enu':mcMatch("[B- -> D*_2(2460)0 e- nu_e~]CC"), + 'IS_D0_2460_1enu':mcMatch("[B- -> D_1(2420)0 e- nu_e~]CC"), + 'IS_D0_H_1taunu':mcMatch("[B- -> D_1(H)0 tau- nu_tau~]CC"), + 'IS_D0_2420_1taunu':mcMatch("[B- -> D_1(2420)0 tau- nu_tau~]CC"), + 'IS_Dstar0_2460_2taunu':mcMatch("[B- -> D*_2(2460)0 tau- nu_tau~]CC"), + }) + return(variables) diff --git a/SL_l_nu_D0toKpi_Run3_MC_data_v2/Spruce.py b/SL_l_nu_D0toKpi_Run3_MC_data_v2/Spruce.py new file mode 100644 index 0000000000..964714aba8 --- /dev/null +++ b/SL_l_nu_D0toKpi_Run3_MC_data_v2/Spruce.py @@ -0,0 +1,58 @@ +############################################################################### +# (c) Copyright 2022 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### +#Example follows from hlt2_with_hlt1_decision.py +from Moore import Options,options, run_moore, config +from Hlt2Conf.lines.semileptonic.builders import sl_line_prefilter +from Moore.config import SpruceLine,register_line_builder +from .Hlt2 import make_b +from Moore.streams import DETECTORS, Stream, Streams +from PyConf.application import configure_input, configure, default_raw_event +from RecoConf.global_tools import stateProvider_with_simplified_geom +from RecoConf.reconstruction_objects import reconstruction +from PyConf.reading import reconstruction as reco_spruce, upfront_reconstruction as upfront_spruce +from RecoConf.decoders import default_ft_decoding_version +from Hlt2Conf.lines.semileptonic.spruce_semileptonic import spruce_butod0munu_d0tokpi_line,spruce_butod0taunu_d0tokpi_tautomununu_line +from Hlt2Conf.lines.semileptonic.HbToHcTauNu_TauToLNuNu import make_butod0taunu_d0tokpi_tautolnunu +from Hlt2Conf.lines.semileptonic.HbToHcLNu import make_butod0lnu_d0tokpi +from Moore.persistence.hlt2_tistos import list_of_full_stream_lines +from Hlt2Conf.lines.semileptonic import all_lines as slb_lines +from Hlt2Conf.lines.topological_b import all_lines as topo_lines +from Hlt2Conf.lines.semileptonic import sprucing_lines as slb_sprucing_lines +def lines_for_tistos(): + """ + Nikole Comment : + This TISTOS part is only needed for exclusive Sprucing + and it saves the candidates of the FULL HLT2 lines that fired for each event. + You need to make sure its only FULL HLT2 lines in the lines_for_tistos + and they are the ones you care about ie. RD inclusive lines + """ + return [linename for line_dict in [slb_lines,topo_lines] for linename in line_dict.keys()] + +@register_line_builder(slb_sprucing_lines) +def spruce_mybutod0enu_d0tokpi_line(name='SpruceSLB_myBuToD0ENu_D0ToKPi',prescale=1): + Bcands = make_b() + return SpruceLine(name=name, hlt2_filter_code=[ + f"{name.replace('Spruce','Hlt2')}Decision", + "Hlt2Topo2BodyDecision", "Hlt2Topo3BodyDecision"] + ,prescale=prescale,persistreco=True, algs=sl_line_prefilter() + [Bcands]) + +def make_full_streams(): + lines = [builder() for builder in slb_sprucing_lines.values()] + streams = [Stream(lines=lines, detectors=[])] + return Streams(streams=streams) + +def main(options: Options): + public_tools = [stateProvider_with_simplified_geom()] + with reconstruction.bind(from_file=True, spruce=True),\ + reco_spruce.bind(simulation=True),\ + upfront_spruce.bind(simulation=True),\ + list_of_full_stream_lines.bind(lines=lines_for_tistos()): + return run_moore(options, make_full_streams, public_tools=public_tools) diff --git a/SL_l_nu_D0toKpi_Run3_MC_data_v2/info.yaml b/SL_l_nu_D0toKpi_Run3_MC_data_v2/info.yaml new file mode 100644 index 0000000000..7855095923 --- /dev/null +++ b/SL_l_nu_D0toKpi_Run3_MC_data_v2/info.yaml @@ -0,0 +1,156 @@ +defaults: + inform: + - ching-hua.li@cern.ch + wg: SL + +{%- set evttype_lines_and_leptons = [ + ('11584030','SLB_BuToD0ENu_D0ToKPi','b0_dstp_e'), + ('11574020','SLB_BuToD0MuNu_D0ToKPi','b0_dstp_muon'), + ('11584010','SLB_BuToD0TauNu_D0ToKPi_TauToENuNu','b0_dstp_taue'), + ('11574010','SLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu','b0_dstp_taumuon'), + ('12685400','SLB_BuToDststENu','bp_dstst_e'), + ('12883000','SLB_BuToDststTauNu_TauToENuNu','bp_dstst_taue'), + ('11686000','SLB_BdToDststENu','b0_dststp_e'), + ('11883000','SLB_BdToDststTauNu_TauToENuNu','b0_dststp_taue'), +] %} + +{%- set polarity_variables = [ + ('MagDown','sim-20231017-vc-md100'), + ('MagUp','sim-20231017-vc-mu100'), +]%} +{%- for polarity, cond_tag in polarity_variables %} + {%- for evttype, line, dk in evttype_lines_and_leptons %} +HLT1_{{dk}}_{{ polarity }}: + application: "Moore/v55r7@x86_64_v3-el9-gcc13+detdesc-opt+g" + #application: "Moore/v55r8@x86_64_v3-el9-gcc13+detdesc-opt+g" + input: + bk_query: "/MC/Dev/Beam6800GeV-expected-2024-{{polarity}}-Nu7.6-25ns-Pythia8/Sim10c/{{evttype}}/DIGI" + dq_flags: + - OK + n_test_lfns: 1 + output: hlt1.dst + options: + entrypoint: SL_l_nu_D0toKpi_Run3_MC_data_v2.Hlt1:main + extra_options: + input_raw_format: 0.3 + conddb_tag: {{cond_tag}} + dddb_tag: dddb-20231017 + input_type: ROOT + output_type: ROOT + simulation: True + data_type: "Upgrade" + scheduler_legacy_mode: False + compression: + algorithm: ZSTD + level: 1 + max_buffer_size: 1048576 + #evt_max: 1000 + +HLT2_{{dk}}_{{ polarity }}: + application: "Moore/v55r7p3@x86_64_v3-el9-gcc13+detdesc-opt+g" + #application: "Moore/v55r8@x86_64_v3-el9-gcc13+detdesc-opt+g" + input: + job_name: HLT1_{{dk}}_{{ polarity }} + output: hlt2.dst + options: + entrypoint: SL_l_nu_D0toKpi_Run3_MC_data_v2.Hlt2:main + extra_options: + input_raw_format: 0.5 + conddb_tag: {{cond_tag}} + dddb_tag: dddb-20231017 + input_type: ROOT + output_type: ROOT + simulation: True + data_type: "Upgrade" + scheduler_legacy_mode: False + output_manifest_file: "HLT2.tck.json" + compression: + algorithm: ZSTD + level: 1 + max_buffer_size: 1048576 + #evt_max: 1000 +SPRUCE_{{dk}}_{{ polarity }}: + application: "Moore/v55r7p3@x86_64_v3-el9-gcc13+detdesc-opt+g" + #application: "Moore/v55r8@x86_64_v3-el9-gcc13+detdesc-opt+g" + input: + job_name: HLT2_{{dk}}_{{ polarity }} + output: spruce.dst + options: + entrypoint: SL_l_nu_D0toKpi_Run3_MC_data_v2.Spruce:main + extra_options: + input_raw_format: 0.5 + conddb_tag: {{cond_tag}} + dddb_tag: dddb-20231017 + input_type: ROOT + output_type: ROOT + simulation: True + data_type: "Upgrade" + scheduler_legacy_mode: False + input_process: "Hlt2" + input_manifest_file: "HLT2.tck.json" + output_manifest_file: "SPRUCE.tck.json" + compression: + algorithm: ZSTD + level: 1 + max_buffer_size: 1048576 + #evt_max: 1000 +DV_{{dk}}_{{ polarity }}: + application: "DaVinci/v64r8@x86_64_v2-el9-clang16-opt" + input: + job_name: SPRUCE_{{dk}}_{{ polarity }} + output: NTuple.root + options: + entrypoint: SL_l_nu_D0toKpi_Run3_MC_data_v2.DV:MC_{{line}} + extra_options: + input_raw_format: 0.5 + conddb_tag: {{cond_tag}} + dddb_tag: dddb-20231017 + input_type: ROOT + simulation: True + data_type: "Upgrade" + geometry_version: run3/trunk + conditions_version: master + input_process: "Spruce" + input_manifest_file: "SPRUCE.tck.json" + #evt_max: 1000 + + {%- endfor %} +{%- endfor %} + + +{%- set lines_and_decays = [ + ('SLB_BuToD0ENu_D0ToKPi','b0_dstp_e'), + ('SLB_BuToD0MuNu_D0ToKPi','b0_dstp_muon'), + ('SLB_BuToD0TauNu_D0ToKPi_TauToENuNu','b0_dstp_taue'), + ('SLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu','b0_dstp_taumuon'), + ('SLB_BuToD0ENu_D0ToKPi_FakeElectron','b0_dstp_e_fake'), + ('SLB_BuToD0MuNu_D0ToKPi_FakeMuon','b0_dstp_muon_fake'), + ('SLB_BuToD0TauNu_D0ToKPi_FakeElectron','b0_dstp_taue_fake'), + ('SLB_BuToD0TauNu_D0ToKPi_FakeMuon','b0_dstp_taumuon_fake'), +] %} + +{%- for spruce_line, decay in lines_and_decays %} +data_{{decay}}: + application: "DaVinci/v64r5" + input: + bk_query: "/LHCb/Collision24/Beam6800GeV-VeloClosed-MagDown-Excl-UT/Real Data/Sprucing24c1/90000000/SL.DST" + dq_flags: + - UNCHECKED + - OK + keep_running: true + n_test_lfns: 1 + output: DATA.ROOT + options: + entrypoint: SL_l_nu_D0toKpi_Run3_MC_data_v2.DV:Data_{{spruce_line}} + extra_options: + input_raw_format: 0.5 + input_type: ROOT # ROOT for SprucingPass, RAW for RAW data (Hlt2 output) + simulation: False + #data_type: "Upgrade" + geometry_version: run3/2024.Q1.2-v00.00 + conditions_version: master + input_process: "Spruce" # Spruce for SprucingPass, "Hlt2" for RAW data (Hlt2 output) + input_stream: "sl" # for streamed data + #evt_max: 1000 +{%- endfor %} + diff --git a/SL_l_nu_D0toKpi_Run3_MC_data_v2/isolationMVA.py b/SL_l_nu_D0toKpi_Run3_MC_data_v2/isolationMVA.py new file mode 100755 index 0000000000..f075d47825 --- /dev/null +++ b/SL_l_nu_D0toKpi_Run3_MC_data_v2/isolationMVA.py @@ -0,0 +1,350 @@ +############################################################################### +# (c) Copyright 2024 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### +import Functors as F +from Hlt2Conf.algorithms_thor import ParticleCombiner +from Hlt2Conf.algorithms_thor import ParticleContainersMerger +from Hlt2Conf.algorithms_thor import ParticleFilter +from RecoConf.reconstruction_objects import make_pvs +import Functors.math as fmath +import math,re,os +from dataclasses import dataclass +from PyConf.Algorithms import ThOrParticleSelection +from SelAlgorithms.monitoring import monitor, histogram_1d +from Hlt2Conf.standard_particles import make_has_rich_long_pions +from Hlt2Conf.standard_particles import make_has_rich_up_pions +from Hlt2Conf.standard_particles import make_has_rich_down_pions +from DaVinciTools import SubstitutePID + +#Multiplying by this number will convert log_e to log_10 +#we multiply by log10(e) rather than dividing by ln(10) +#since multiplication is faster +LOG10_E = math.log10(math.e) +#toggle for printing debug messages +#set to False for proper productions +DEBUG = False + + +@dataclass +class MVAinput: + """Struct for storing MVA input variables""" + name: str # The name of the var (as per the model) + number: int # The number of the var + functor: F.grammar.FunctorBase # The functor to calculate that variable + x_range: (float, float) # axis range for input var monitoring histos + + +def mva_functor_inclusive(v2_pvs, + make_histos: (bool, str) = (False, ""), + useNumbers: bool = False): + """ + Compute the output of the MVA classifier (xGBoost) for charged track isolation. + Higher values of MVA classifier output indicate that the charged track is less isolated + and is more likely to be associated to be coming from the same decay vertex as the B0. + For more details: Checkout the presentation https://indico.cern.ch/event/1234758/#sc-1-4-ml-based-charged-isolat + + Args: + v2_pvs (list): TES location of v2 PVs + make_histos (tuple): tuple of bool (do you want the input vars to be monitored) and a ParticleContainersMerger (the B*-pion combinations) + useNumbers (bool): decision of whether to use the numbers or names of vars in the MVA functor + """ + #get the children of the two-body combination (B0-extraparticle) + Bstar_p_child = F.CHILD(1, F.FORWARDARGS) + ExtraParticle_child = F.CHILD(2, F.FORWARDARGS) + + #define the input variables for mva + mva_input_vars = [] #FunctorCollection() + #define Impact parameter chi2 of the extra particle wrt to the BPV associated to the two-body combination (B0-extraparticle) + mva_input_vars.append( + MVAinput("Epi_BPV_IPCHI2", 0, + F.BPVIPCHI2(v2_pvs).bind(ExtraParticle_child), (0, 20))) # PV + #define PT of two body combination (B0-extraparticle). Here is transformed to be less peaky + mva_input_vars.append( + MVAinput("Epi_PT", 1, + fmath.log(F.PT.bind(ExtraParticle_child)) * LOG10_E, (1, 5))) + #define opening angle between B0 and extra particle. Here is transformed to be less peaky + cos_angle = F.COSANGLE.bind(F.THREEMOMENTUM @ Bstar_p_child, + F.THREEMOMENTUM @ ExtraParticle_child) + mva_input_vars.append( + MVAinput("Sb_Epi_COSANGLE_Lb", 2, 1. - fmath.pow(1. - cos_angle, 0.2), + (0, 1))) + #define DIRA of the two body combination (B0-extraparticle) + mva_input_vars.append( + MVAinput("Sb_BPV_DIRA_TF", 8, fmath.pow(1. - F.BPVDIRA(v2_pvs), 0.2), + (0, 1.2))) + #define magnitude of PV distance i.e. distance between PV and vertex of two-body combination (B0-extraparticle) + # NB: the sign of the magnitude deterimined by the by the difference in z-coordinate of PV and vertex of two-body combination + mva_input_vars.append( + MVAinput("PVdis", 3, + (F.MAGNITUDE @ (F.ENDVERTEX_POS - F.BPV_POS(v2_pvs))) * + fmath.sign(F.END_VZ - F.BPVZ(v2_pvs)), (-50, 100))) + #* F.MAGNITUDE @ (F.ENDVERTEX_POS - F.BPV_POS(v2_pvs)) + #define magnitude of SV distance i.e. distance between two-body combination (B0-extraparticle) vertex and the vertex + # without the extra particle included. The sign of the magnitude is determined by the difference in z-coordinate of both vertices + mva_input_vars.append( + MVAinput("SVdis", 4, + (F.MAGNITUDE + @ (F.ENDVERTEX_POS.bind(Bstar_p_child) - F.ENDVERTEX_POS)) * + fmath.sign(F.END_VZ - F.END_VZ.bind(Bstar_p_child)), + (-50, 50))) + #define DeltaR i.e. the difference in radius of B0 and extra particle in the rapidity-azimuth plane + delta_eta = F.ETA.bind(Bstar_p_child) - F.ETA.bind(ExtraParticle_child) + delta_phi = F.PHI.bind(Bstar_p_child) - F.PHI.bind(ExtraParticle_child) + delta_phi = fmath.where(delta_phi > math.pi, delta_phi - 2 * math.pi, + delta_phi) + delta_phi = fmath.where(delta_phi < -math.pi, delta_phi + 2 * math.pi, + delta_phi) + mva_input_vars.append( + MVAinput( + "DeltaREpi", 5, + fmath.pow( + fmath.sqrt( + fmath.pow(delta_eta, 2.) + fmath.pow(delta_phi, 2.)), 0.2), + (0, 1.5))) + + mva_input_vars.append( + MVAinput("Sb_MAX_DOCACHI2", 6, + fmath.log(F.MAXSDOCACHI2) * LOG10_E, (-2.6, 7.5))) + mva_input_vars.append( + MVAinput( + "Sb_Epi_IPCHI2_WRT_LbENDVERTEX", 7, + fmath.log( + F.IPCHI2.bind(F.ENDVERTEX @ Bstar_p_child, + ExtraParticle_child)) * LOG10_E, (-2, 6))) # SV + + #define the mva classifier + mva = F.MVA( + MVAType='TMVA', + Config={ + #'XMLFile':'paramfile://data/xgboost_model_cocktail_inclusive_220724.xml', + 'XMLFile': + #f"file://{os.environ['ANALYSIS_PRODUCTIONS_BASE']}/SL_l_nu_D0toKpi_Run3_MC_data_v2/xgboost_model_cocktail_inclusive_220724.xml", + "file:///eos/lhcb/wg/semileptonic/RDst_taue/xgboost_model_cocktail_inclusive_220724.xml", + 'Name':'BDT', + }, + Inputs={(f"f[{var.number}]" if useNumbers else var.name): var.functor + for var in mva_input_vars}) + input_monitoring = make_input_monitoring( + mva_input_vars, make_histos) if make_histos[0] else [] + return (mva, input_monitoring) + + +def make_input_monitoring(mva_input_vars: [MVAinput], + make_histos) -> [histogram_1d]: + input_monitoring = [] + + for var in mva_input_vars: + input_monitoring.append( + histogram_1d( + functor=var.functor, + label=var.name, + name=f"/{make_histos[1]}/iso_{var.name}", + title=f"isolation MVA input: {var.name}", + bins=100, + range=var.x_range)) + + return input_monitoring + + +def mva_transform_output(xgboost_style_input: float) -> float: + """ + We've converted our input from xgboost-style to TMVA-style but this gives a transformation on the cut variables + This function converts from an xgboost-style cut to the corresponding TMVA-style + taken from: https://github.com/jpata/mlglue/blob/master/mlglue/tree.py#L400-L409 + This takes the domain from [0,1] and transforms it from [-1,1] in a strange (nonlinear) way + """ + TMVA_style_output = -math.log(1. / xgboost_style_input - 1.) + TMVA_style_output = 2. / (1. + math.exp(-2. * TMVA_style_output)) - 1. + + return TMVA_style_output + + +def combine_iso_pions(BstarPlus, + extra_particles, + line_name, + v2_pvs, + apply_fiducial_cut: bool = False): + """ + Make two body combination of B0 and extra particles. + + Args: + B0 (list): TES location of B0 particles + extra_particles (list): TES location of extra particles in the event. + Pion id is assigned to the extra particle. + + Returns: + list: TES location of two body combination of B0 and extra_particles + """ + fiducial_cut = F.ALL + if apply_fiducial_cut: + #fiducial cut on pv distance + pv_dist_min = -3. #mm + fiducial_cut_pv_dist = (F.MAGNITUDE @ (F.ENDVERTEX_POS - F.BPV_POS( + v2_pvs))) * fmath.sign(F.END_VZ - F.BPVZ(v2_pvs)) > pv_dist_min + + #fiducial cut on the log IPchi2 w.r.t. SV + #See p11 : https://indico.cern.ch/event/1405184/contributions/5907467/attachments/2835541/4955107/preCuts_11_04_2024.pdf + log_ipchi2_wrtSV_max = 5 + Bstar_p_child = F.CHILD(1, F.FORWARDARGS) + ExtraParticle_child = F.CHILD(2, F.FORWARDARGS) + fiducial_cut_sv_ipchi2 = fmath.log( + F.IPCHI2.bind( + F.ENDVERTEX @ Bstar_p_child, + ExtraParticle_child)) * LOG10_E < log_ipchi2_wrtSV_max + + fiducial_cut = F.require_all(fiducial_cut_pv_dist, + fiducial_cut_sv_ipchi2) + + #first combiner: B0 pi+ + descriptor_1 = "[B*0 -> B*+ pi-]cc" + comb_1 = ParticleCombiner( + Inputs=[BstarPlus, extra_particles], + name=f'SbCombiner_onetrack_1_{line_name}', + DecayDescriptor=descriptor_1, + CombinationCut=F.ALL, + CompositeCut=fiducial_cut, + ParticleCombiner= + "ParticleVertexFitter", #NB: for neutrals need to use different combiner e.g. ParticleAdder + ) + #second combiner: B0 pi- + descriptor_2 = "[B*0 -> B*+ pi+]cc" + comb_2 = ParticleCombiner( + Inputs=[BstarPlus, extra_particles], + name=f'SbCombiner_onetrack_2_{line_name}', + DecayDescriptor=descriptor_2, + CombinationCut=F.ALL, + CompositeCut=fiducial_cut, + ParticleCombiner="ParticleVertexFitter", + ) + #merge two combiners + comb = ParticleContainersMerger([comb_1, comb_2], + name=f'bst_combiner_{line_name}') + return comb + + +def get_extra_pions(): + long_pions = make_has_rich_long_pions() + up_pions = make_has_rich_up_pions() + down_pions = make_has_rich_down_pions() + return ParticleContainersMerger([long_pions, up_pions, down_pions], + name='Pions_combiner') + + +def extract_parent_name(line_name: str) -> (str, str): + #First do some pruning + #e.g. SpruceSLB_BcToJpsiTauNu_JpsiToMuMu_FakeElectron -> JpsiTauNu + parent_string = line_name.split('_')[1].split('To')[0] + #remove any 'Fake' stuff + parent_string = re.sub(r'Fake.*$', '', parent_string) + + #define dicts to convert from our naming convention to + Bcand_dict = { + "Bu": "B+", + "B0": "B0", + "Bs": "B_s0", + "Bc": "B_c+", + "Lb": "Lambda_b0", + "Xib0": "Xi_b0", + "Xibminus": "Xi_b-", + "Omegab": "Omega_b-", + } + anti_Bcand_dict = { + "Bu": "B-", + "B0": "B~0", + "Bs": "B_s~0", + "Bc": "B_c-", + "Lb": "Lambda_b~0", + "Xib0": "Xi_b~0", + "Xibminus": "Xi_b~+", + "Omegab": "Omega_b~+", + } + #throw an error if the parent is not in the dict + if parent_string not in Bcand_dict: + raise ValueError( + f"ERROR: Couldn't automatically determine parent for line: {line_name}" + ) + + return Bcand_dict[parent_string], anti_Bcand_dict[parent_string] + + +def prepare_MVA( + line_name: str, + line_output: ParticleCombiner, + *, #All further options must be given as keyword arguments + mva_min: float = None, + parent: str = "", + anti_parent: str = "", + mva_used: str = "inclusive") -> (ThOrParticleSelection, [monitor]): + + new_parent_name = 'B*+' + anti_new_parent_name = 'B*-' + + if not parent and not anti_parent: + parent_name, anti_parent_name = extract_parent_name(line_name) + else: + parent_name = parent + anti_parent_name = anti_parent + + # Yes, we really do need all those brackets + substitutions = [ + f"{parent_name}{{{{{new_parent_name}}}}}", + f"{anti_parent_name}{{{{{anti_new_parent_name}}}}}" + ] + if DEBUG: print(f"{substitutions = }") + from Gaudi.Configuration import INFO, ALL + output_level = ALL if DEBUG else INFO + Bst_p = SubstitutePID( + name=f'PIDSubstitute_{line_name}', + input_particles=line_output, + substitutions=substitutions, + output_level=output_level).Particles + + v2_pvs = make_pvs() + pions = get_extra_pions() + Bst_z = combine_iso_pions( + Bst_p, pions, line_name, + v2_pvs) # vertex = B + each extra track - vertex 2 + + #Only the inclusive training is being maintained now, no other models are available + if mva_used == "inclusive": + mva_getter = mva_functor_inclusive + if mva_min is None: mva_min = 0.05 # default mu MVA cut + else: + raise ValueError( + f"ERROR: in {__file__}, mva requested must be the inclusive training, no other models are currently maintainted, this has gone wrong for line: {line_name}" + ) + MVA_functor, input_monitoring = mva_getter( + v2_pvs, make_histos=(True, line_name)) + MVA_cut = mva_transform_output(mva_min) + MVA_cut_functor = MVA_functor > MVA_cut + if DEBUG: print(f"for line {line_name : <56}\t MVA cut: {MVA_cut}") + # We'll monitor all the combinations from the MVA, not just those that pass + monitoring_histo = histogram_1d( + functor=MVA_functor, + label="MVA output", + name=f"/{line_name}/iso_MVA", + title=f"isolation MVA (cut at {MVA_cut} in sprucing)", + bins=200, + range=(-1, 1)) + + # However we'll only keep the subset that pass + Bst_z_subset = ParticleFilter( + Bst_z, F.FILTER(MVA_cut_functor), name=f"filter_isoPions_{line_name}" + ) # B + extra track combos passing the MVA cuts + + monitoring_histos = monitor( + data=Bst_z, histograms=input_monitoring + [monitoring_histo]) + + extra_track_cut = (F.IS_ABS_ID('pi+')) + code_extra_track = F.FILTER(extra_track_cut) @ F.GET_CHILDREN() + return (ThOrParticleSelection( + name=f"extra_track_selection_{line_name}", + InputParticles=Bst_z_subset, + Functor=code_extra_track).OutputSelection, [monitoring_histos]) -- GitLab From 7ce8e3044b9d635eec14382d877195184148e2d4 Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Wed, 14 Aug 2024 16:44:46 +0200 Subject: [PATCH 52/57] Try old xml file to estimate the output size --- SL_l_nu_D0toKpi_Run3_MC_data_v2/isolationMVA.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/SL_l_nu_D0toKpi_Run3_MC_data_v2/isolationMVA.py b/SL_l_nu_D0toKpi_Run3_MC_data_v2/isolationMVA.py index f075d47825..32214b9183 100755 --- a/SL_l_nu_D0toKpi_Run3_MC_data_v2/isolationMVA.py +++ b/SL_l_nu_D0toKpi_Run3_MC_data_v2/isolationMVA.py @@ -97,10 +97,16 @@ def mva_functor_inclusive(v2_pvs, #define DeltaR i.e. the difference in radius of B0 and extra particle in the rapidity-azimuth plane delta_eta = F.ETA.bind(Bstar_p_child) - F.ETA.bind(ExtraParticle_child) delta_phi = F.PHI.bind(Bstar_p_child) - F.PHI.bind(ExtraParticle_child) + ''' delta_phi = fmath.where(delta_phi > math.pi, delta_phi - 2 * math.pi, delta_phi) delta_phi = fmath.where(delta_phi < -math.pi, delta_phi + 2 * math.pi, delta_phi) + ''' + delta_phi = fmath.where(delta_phi > math.pi, delta_phi - math.pi, + delta_phi) + delta_phi = fmath.where(delta_phi < -math.pi, delta_phi + math.pi, + delta_phi) mva_input_vars.append( MVAinput( "DeltaREpi", 5, @@ -124,9 +130,10 @@ def mva_functor_inclusive(v2_pvs, MVAType='TMVA', Config={ #'XMLFile':'paramfile://data/xgboost_model_cocktail_inclusive_220724.xml', - 'XMLFile': + #'XMLFile': #f"file://{os.environ['ANALYSIS_PRODUCTIONS_BASE']}/SL_l_nu_D0toKpi_Run3_MC_data_v2/xgboost_model_cocktail_inclusive_220724.xml", - "file:///eos/lhcb/wg/semileptonic/RDst_taue/xgboost_model_cocktail_inclusive_220724.xml", + #"file:///eos/lhcb/wg/semileptonic/RDst_taue/xgboost_model_cocktail_inclusive_220724.xml", + 'XMLFile': 'paramfile://data/xgboost_model_cocktail_inclusive.xml', 'Name':'BDT', }, Inputs={(f"f[{var.number}]" if useNumbers else var.name): var.functor -- GitLab From 57e59c70eaef8e562f6dd0acf2d5b1ee169b6cc2 Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Tue, 20 Aug 2024 11:48:34 +0200 Subject: [PATCH 53/57] 2024 MC data with UT --- SL_l_nu_D0toKpi_Run3_MC_data_v2/DV.py | 17 +-- SL_l_nu_D0toKpi_Run3_MC_data_v2/Hlt1.py | 14 ++- SL_l_nu_D0toKpi_Run3_MC_data_v2/Hlt2.py | 123 +++------------------- SL_l_nu_D0toKpi_Run3_MC_data_v2/Spruce.py | 42 +++++--- SL_l_nu_D0toKpi_Run3_MC_data_v2/info.yaml | 12 +-- 5 files changed, 64 insertions(+), 144 deletions(-) diff --git a/SL_l_nu_D0toKpi_Run3_MC_data_v2/DV.py b/SL_l_nu_D0toKpi_Run3_MC_data_v2/DV.py index 116e9fac67..3ab50fad30 100644 --- a/SL_l_nu_D0toKpi_Run3_MC_data_v2/DV.py +++ b/SL_l_nu_D0toKpi_Run3_MC_data_v2/DV.py @@ -82,6 +82,7 @@ def get_functors(MCTRUTH, v2_pvs, rec_summary): vars_common['BPV_IPCHI2'] = F.BPVIPCHI2(v2_pvs) vars_common['BPV_CHI2'] = F.CHI2 @ F.BPV(v2_pvs) vars_common['BPV_CHI2DOF'] = F.CHI2DOF @ F.BPV(v2_pvs) + vars_common['CHI2DOF'] = F.VALUE_OR(Value=F.NaN) @ F.CHI2DOF #particle id, key, truekey. The trueid is stored in MCHierarchy vars_common['ID'] = F.PARTICLE_ID vars_common['KEY'] = F.OBJECT_KEY @@ -425,8 +426,8 @@ def main(options: Options,line = '', lep='',data_or_mc='mc'): #get data and extra particles Bm = get_particles(f"/Event/Spruce/{line}/Particles") - extra_particles = get_extra_pions() - #extra_particles = get_particles(f"/Event/Spruce/{line}/{line}_extra_tracks/Particles") + #extra_particles = get_extra_pions() + extra_particles = get_particles(f"/Event/Spruce/{line}/{line}_extra_tracks/Particles") #get v2_pvs and rec_summary v2_pvs = get_pvs() @@ -455,25 +456,25 @@ def test(options: Options): return main(options=options, line='Hlt2_Test_line',lep='e',data_or_mc='data') def MC_SLB_BuToD0ENu_D0ToKPi(options: Options): - return main(options=options, line='SpruceSLB_myBuToD0ENu_D0ToKPi',lep='e',data_or_mc='mc') + return main(options=options, line='SpruceSLB_BuToD0ENu_D0ToKPi',lep='e',data_or_mc='mc') def MC_SLB_BuToDststENu(options: Options): - return main(options=options, line='SpruceSLB_myBuToD0ENu_D0ToKPi',lep='e',data_or_mc='mc') + return main(options=options, line='SpruceSLB_BuToD0ENu_D0ToKPi',lep='e',data_or_mc='mc') def MC_SLB_BdToDststENu(options: Options): - return main(options=options, line='SpruceSLB_myBuToD0ENu_D0ToKPi',lep='e',data_or_mc='mc') + return main(options=options, line='SpruceSLB_BuToD0ENu_D0ToKPi',lep='e',data_or_mc='mc') def MC_SLB_BuToD0MuNu_D0ToKPi(options: Options): return main(options=options, line='SpruceSLB_BuToD0MuNu_D0ToKPi',lep='mu',data_or_mc='mc') def MC_SLB_BuToD0TauNu_D0ToKPi_TauToENuNu(options: Options): - return main(options=options, line='SpruceSLB_myBuToD0ENu_D0ToKPi',lep='e',data_or_mc='mc') + return main(options=options, line='SpruceSLB_BuToD0TauNu_D0ToKPi_TauToENuNu',lep='e',data_or_mc='mc') def MC_SLB_BuToDststTauNu_TauToENuNu(options: Options): - return main(options=options, line='SpruceSLB_myBuToD0ENu_D0ToKPi',lep='e',data_or_mc='mc') + return main(options=options, line='SpruceSLB_BuToD0TauNu_D0ToKPi_TauToENuNu',lep='e',data_or_mc='mc') def MC_SLB_BdToDststTauNu_TauToENuNu(options: Options): - return main(options=options, line='SpruceSLB_myBuToD0ENu_D0ToKPi',lep='e',data_or_mc='mc') + return main(options=options, line='SpruceSLB_BuToD0TauNu_D0ToKPi_TauToENuNu',lep='e',data_or_mc='mc') def MC_SLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu(options: Options): return main(options=options, line='SpruceSLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu',lep='mu',data_or_mc='mc') diff --git a/SL_l_nu_D0toKpi_Run3_MC_data_v2/Hlt1.py b/SL_l_nu_D0toKpi_Run3_MC_data_v2/Hlt1.py index eeabcc4913..abab8e2f12 100644 --- a/SL_l_nu_D0toKpi_Run3_MC_data_v2/Hlt1.py +++ b/SL_l_nu_D0toKpi_Run3_MC_data_v2/Hlt1.py @@ -9,10 +9,16 @@ # or submit itself to any jurisdiction. # ############################################################################### from Moore import Options -from Moore.config import run_allen -from RecoConf.hlt1_allen import allen_gaudi_config as allen_sequence +from PyConf.application import configure_input, configure def main(options: Options): - with allen_sequence.bind(sequence="hlt1_pp_matching_no_ut_1000KHz"): - return run_allen(options) + """ + Configures algorithm running of HLT1 via Moore to be passed to Analysis Productions. + """ + config = configure_input(options) + from Moore.production import hlt1 + hlt1(options, "--sequence=hlt1_pp_matching_no_ut_1000KHz", "--flagging") + config["Gaudi::IODataManager/IODataManager"].AgeLimit = 0 + + return config diff --git a/SL_l_nu_D0toKpi_Run3_MC_data_v2/Hlt2.py b/SL_l_nu_D0toKpi_Run3_MC_data_v2/Hlt2.py index be2bda5d70..59510e0eca 100644 --- a/SL_l_nu_D0toKpi_Run3_MC_data_v2/Hlt2.py +++ b/SL_l_nu_D0toKpi_Run3_MC_data_v2/Hlt2.py @@ -12,105 +12,13 @@ Stolen and adapted from Hlt/Hlt2Conf/options/hlt2_pp_expected_24_without_UT.py from v55r7. """ from Moore import Options,options, run_moore, config -from Hlt2Conf.algorithms_thor import ParticleContainersMerger -from Hlt2Conf.lines.semileptonic.builders import sl_line_prefilter -from Hlt2Conf.lines.semileptonic.builders.base_builder import make_candidate -from Hlt2Conf.lines.semileptonic.builders.charm_hadron_builder import make_d0_tokpi -from GaudiKernel.SystemOfUnits import MeV, GeV,mm -from Hlt2Conf.algorithms_thor import ParticleCombiner -from Hlt2Conf.settings.defaults import get_default_hlt1_filter_code_for_hlt2 -from Hlt2Conf.lines.semileptonic import all_lines as slb_lines -from Hlt2Conf.lines.topological_b import all_lines as topo_lines -from Moore.config import Hlt2Line,register_line_builder +from Hlt2Conf.settings.hlt2_binds import config_pp_2024 +from Moore.config import Hlt2Line from Moore.streams import Stream, Streams, DETECTORS -from RecoConf.event_filters import require_gec from RecoConf.global_tools import stateProvider_with_simplified_geom, trackMasterExtrapolator_with_simplified_geom -from RecoConf.hlt2_global_reco import reconstruction as hlt2_reconstruction, make_light_reco_pr_kf_without_UT -from RecoConf.reconstruction_objects import reconstruction,make_pvs -from RecoConf.decoders import default_ft_decoding_version,default_VeloCluster_source -from RecoConf.hlt2_tracking import ( - make_TrackBestTrackCreator_tracks, - make_PrKalmanFilter_noUT_tracks, - make_PrKalmanFilter_Velo_tracks, - make_PrKalmanFilter_Seed_tracks, -) -from Hlt2Conf.standard_particles import ( - make_long_electrons_with_brem, - make_has_rich_long_pions, - make_has_rich_up_pions, - make_has_rich_down_pions) -import Functors as F -from Functors.math import in_range -import sys - -#things to control -SUFFIX_NAME = '_BToDzl' -HLT2LINE = f'Hlt2SLB_myBuToD0ENu_D0ToKPi' -CHARM_MASS = 1864.84 #D0 mass -CHARM_BUILDER_NAME = 'Dz2KPi_combiner' -B_BUILDER_NAME = 'BToDzl_combiner' - -def get_charm_cuts(): - #make loose cuts for D0 - delta_mass = 80. #80.0 - make_d0tokpi_cuts = {} - make_d0tokpi_cuts['comb_m_min'] = (CHARM_MASS - delta_mass) * MeV - make_d0tokpi_cuts['comb_m_max'] = (CHARM_MASS + delta_mass) * MeV - make_d0tokpi_cuts['comb_docachi2_max'] = 5. - make_d0tokpi_cuts['vchi2pdof_max'] = 6 #6 (Now) 6/4 (v55r7 e/taue) - make_d0tokpi_cuts['bpvfdchi2_min'] = 25 #25 (Now) - make_d0tokpi_cuts['bpvdira_min'] = 0.99 #0.99 (Now) 0.99/0.999 (v55r7 e/taue) - make_d0tokpi_cuts['comb_pt_min'] = None #None (Now) None/2000 * MeV (v55r7 e/taue) - make_d0tokpi_cuts['comb_pt_any_min'] = None #None (Now) None/800 * MeV (v55r7 e/taue) - make_d0tokpi_cuts['comb_pt_sum_min'] = None #None (Now) None/2.5 * GeV (v55r7 e/taue) - make_d0tokpi_cuts['comb_doca_max'] = None #None (Now) None/0.1 mm (v55r7 e/taue) - make_d0tokpi_cuts['daughter_pt_min'] = 600 * MeV #600 * MeV (Now) 750 * MeV (v55r7) - make_d0tokpi_cuts['daughter_mipchi2_min'] = 9. #10. (Now) 10./9. (v55r7 e/taue) - make_d0tokpi_cuts['kaon_pid'] = (F.PID_K > 0.) #(F.PID_K > 0.) (Now) (F.PID_K > 4.) (v55r7) - make_d0tokpi_cuts['pion_pid'] = (F.PID_K < 2.) - return make_d0tokpi_cuts - -def get_electron_cuts(): - #make loose cuts for electron and tauonic muon - make_electron_cuts = {} - make_electron_cuts["p_min"] = 3. * GeV #3. * GeV (Now) 5. *GeV (v55r7) - make_electron_cuts["pt_min"] = 300. * MeV #300. * MeV (Now) 500. * MeV (v55r7) - make_electron_cuts["mipchi2_min"] = 9. #9. (Now) 9./16. (v55r7 e/taue) - make_electron_cuts["mip_min"] = None #0. - make_electron_cuts["pid"] = (F.PID_E > 0.) - make_electron_cuts["make_particles"] = make_long_electrons_with_brem #does not require in calo - return make_electron_cuts - -def make_b(): - make_d0tokpi_cuts = get_charm_cuts() - make_electron_cuts= get_electron_cuts() - pvs = make_pvs() - with make_candidate.bind(p_min=15. * GeV): - dzs = make_d0_tokpi(**make_d0tokpi_cuts, name = CHARM_BUILDER_NAME) - electrons = make_candidate(**make_electron_cuts, name = "Electron_maker") - - cut_vertex = F.require_all(F.CHI2DOF<9,F.BPVDIRA(pvs) >0.999,in_range(0 * MeV, F.MASS, 10000 * MeV)) - - rs_btodze = ParticleCombiner( - Inputs=[dzs, electrons], - name=f'rs_{B_BUILDER_NAME}_e', - DecayDescriptor='[B- -> D0 e-]cc', - CombinationCut=F.ALL, - CompositeCut=cut_vertex) - - ws_btodze = ParticleCombiner( - Inputs=[dzs, electrons], - name=f'ws_{B_BUILDER_NAME}_e', - DecayDescriptor='[B+ -> D0 e+]cc', - CombinationCut=F.ALL, - CompositeCut=cut_vertex) - - return ParticleContainersMerger([rs_btodze,ws_btodze]) - -@register_line_builder(slb_lines) -def hlt2_mybutod0enu_d0tokpi_line(name=HLT2LINE,prescale=1): - Bcands = make_b() - return Hlt2Line(name=name, prescale=prescale,persistreco=True, algs=sl_line_prefilter() + [Bcands]) +from RecoConf.reconstruction_objects import reconstruction +from PyConf.Tools import TrackMasterExtrapolator, TrackMasterFitter +from Hlt2Conf.lines.semileptonic import all_lines as slb_lines def pass_through_line(name="Hlt2Passthrough"): """Return a HLT2 line that performs no selection but runs and persists the reconstruction @@ -135,21 +43,18 @@ def make_streams(): ] return Streams(streams=streams) +TrackMasterExtrapolator.global_bind( + ApplyMultScattCorr=False, + ApplyEnergyLossCorr=False, + ApplyElectronEnergyLossCorr=False, +) +TrackMasterFitter.global_bind(ApplyMaterialCorrections=False) + public_tools = [ trackMasterExtrapolator_with_simplified_geom(), stateProvider_with_simplified_geom(), ] def main(options: Options): - # NOTE: the TBTC does not apply a chi2 cut because it is applied by the PrKF - with reconstruction.bind(from_file=False),\ - hlt2_reconstruction.bind(make_reconstruction=make_light_reco_pr_kf_without_UT),\ - require_gec.bind(skipUT=True),\ - default_VeloCluster_source.bind(bank_type="VPRetinaCluster"),\ - make_TrackBestTrackCreator_tracks.bind(max_ghost_prob=0.7, max_chi2ndof=sys.float_info.max),\ - make_PrKalmanFilter_Velo_tracks.bind(max_chi2ndof=5.),\ - make_PrKalmanFilter_noUT_tracks.bind(max_chi2ndof=4.),\ - make_PrKalmanFilter_Seed_tracks.bind(max_chi2ndof=6.),\ - get_default_hlt1_filter_code_for_hlt2.bind(code=r"Hlt1(?!PassthroughLargeEvent).*Decision"): - return run_moore(options, make_streams, public_tools=[]) - + with reconstruction.bind( from_file = False) , config_pp_2024() : + return run_moore(options, make_streams, public_tools=public_tools) diff --git a/SL_l_nu_D0toKpi_Run3_MC_data_v2/Spruce.py b/SL_l_nu_D0toKpi_Run3_MC_data_v2/Spruce.py index 964714aba8..85806e3912 100644 --- a/SL_l_nu_D0toKpi_Run3_MC_data_v2/Spruce.py +++ b/SL_l_nu_D0toKpi_Run3_MC_data_v2/Spruce.py @@ -10,22 +10,21 @@ ############################################################################### #Example follows from hlt2_with_hlt1_decision.py from Moore import Options,options, run_moore, config -from Hlt2Conf.lines.semileptonic.builders import sl_line_prefilter +from Moore.lines import optimize_controlflow from Moore.config import SpruceLine,register_line_builder -from .Hlt2 import make_b from Moore.streams import DETECTORS, Stream, Streams from PyConf.application import configure_input, configure, default_raw_event -from RecoConf.global_tools import stateProvider_with_simplified_geom +from RecoConf.global_tools import stateProvider_with_simplified_geom,trackMasterExtrapolator_with_simplified_geom +from PyConf.Algorithms import VeloRetinaClusterTrackingSIMD from RecoConf.reconstruction_objects import reconstruction +from RecoConf.legacy_rec_hlt1_tracking import (make_VeloClusterTrackingSIMD, make_RetinaClusters) from PyConf.reading import reconstruction as reco_spruce, upfront_reconstruction as upfront_spruce -from RecoConf.decoders import default_ft_decoding_version -from Hlt2Conf.lines.semileptonic.spruce_semileptonic import spruce_butod0munu_d0tokpi_line,spruce_butod0taunu_d0tokpi_tautomununu_line -from Hlt2Conf.lines.semileptonic.HbToHcTauNu_TauToLNuNu import make_butod0taunu_d0tokpi_tautolnunu -from Hlt2Conf.lines.semileptonic.HbToHcLNu import make_butod0lnu_d0tokpi +from RecoConf.decoders import default_ft_decoding_version,default_VeloCluster_source from Moore.persistence.hlt2_tistos import list_of_full_stream_lines from Hlt2Conf.lines.semileptonic import all_lines as slb_lines from Hlt2Conf.lines.topological_b import all_lines as topo_lines from Hlt2Conf.lines.semileptonic import sprucing_lines as slb_sprucing_lines +from Moore.persistence.hlt2_tistos import list_of_full_stream_lines def lines_for_tistos(): """ Nikole Comment : @@ -36,23 +35,32 @@ def lines_for_tistos(): """ return [linename for line_dict in [slb_lines,topo_lines] for linename in line_dict.keys()] -@register_line_builder(slb_sprucing_lines) -def spruce_mybutod0enu_d0tokpi_line(name='SpruceSLB_myBuToD0ENu_D0ToKPi',prescale=1): - Bcands = make_b() - return SpruceLine(name=name, hlt2_filter_code=[ - f"{name.replace('Spruce','Hlt2')}Decision", - "Hlt2Topo2BodyDecision", "Hlt2Topo3BodyDecision"] - ,prescale=prescale,persistreco=True, algs=sl_line_prefilter() + [Bcands]) - def make_full_streams(): + ''' + lines = [] + for line_dict in [slb_sprucing_lines]: + for line_name, builder in line_dict.items() : + if "D0ToKPi" in line_name and "TauToPiPiPi" not in line_name and "Bc" not in line_name: + print(line_name) + lines.append(builder()) + ''' lines = [builder() for builder in slb_sprucing_lines.values()] streams = [Stream(lines=lines, detectors=[])] return Streams(streams=streams) def main(options: Options): - public_tools = [stateProvider_with_simplified_geom()] + default_VeloCluster_source.global_bind(bank_type="VPRetinaCluster") + make_VeloClusterTrackingSIMD.global_bind( + algorithm=VeloRetinaClusterTrackingSIMD) + + public_tools = [ + trackMasterExtrapolator_with_simplified_geom(), + stateProvider_with_simplified_geom() + ] with reconstruction.bind(from_file=True, spruce=True),\ reco_spruce.bind(simulation=True),\ upfront_spruce.bind(simulation=True),\ - list_of_full_stream_lines.bind(lines=lines_for_tistos()): + list_of_full_stream_lines.bind(lines=lines_for_tistos()),\ + optimize_controlflow.bind(optimization="default"): return run_moore(options, make_full_streams, public_tools=public_tools) + diff --git a/SL_l_nu_D0toKpi_Run3_MC_data_v2/info.yaml b/SL_l_nu_D0toKpi_Run3_MC_data_v2/info.yaml index 7855095923..95c0f05c4b 100644 --- a/SL_l_nu_D0toKpi_Run3_MC_data_v2/info.yaml +++ b/SL_l_nu_D0toKpi_Run3_MC_data_v2/info.yaml @@ -21,7 +21,7 @@ defaults: {%- for polarity, cond_tag in polarity_variables %} {%- for evttype, line, dk in evttype_lines_and_leptons %} HLT1_{{dk}}_{{ polarity }}: - application: "Moore/v55r7@x86_64_v3-el9-gcc13+detdesc-opt+g" + application: "Moore/v55r11@x86_64_v3-el9-gcc13+detdesc-opt+g" #application: "Moore/v55r8@x86_64_v3-el9-gcc13+detdesc-opt+g" input: bk_query: "/MC/Dev/Beam6800GeV-expected-2024-{{polarity}}-Nu7.6-25ns-Pythia8/Sim10c/{{evttype}}/DIGI" @@ -44,10 +44,10 @@ HLT1_{{dk}}_{{ polarity }}: algorithm: ZSTD level: 1 max_buffer_size: 1048576 - #evt_max: 1000 + #evt_max: 100 HLT2_{{dk}}_{{ polarity }}: - application: "Moore/v55r7p3@x86_64_v3-el9-gcc13+detdesc-opt+g" + application: "Moore/v55r11@x86_64_v3-el9-gcc13+detdesc-opt+g" #application: "Moore/v55r8@x86_64_v3-el9-gcc13+detdesc-opt+g" input: job_name: HLT1_{{dk}}_{{ polarity }} @@ -70,7 +70,7 @@ HLT2_{{dk}}_{{ polarity }}: max_buffer_size: 1048576 #evt_max: 1000 SPRUCE_{{dk}}_{{ polarity }}: - application: "Moore/v55r7p3@x86_64_v3-el9-gcc13+detdesc-opt+g" + application: "Moore/v55r11@x86_64_v3-el9-gcc13+detdesc-opt+g" #application: "Moore/v55r8@x86_64_v3-el9-gcc13+detdesc-opt+g" input: job_name: HLT2_{{dk}}_{{ polarity }} @@ -131,9 +131,9 @@ DV_{{dk}}_{{ polarity }}: {%- for spruce_line, decay in lines_and_decays %} data_{{decay}}: - application: "DaVinci/v64r5" + application: "DaVinci/v64r8@x86_64_v2-el9-clang16-opt" input: - bk_query: "/LHCb/Collision24/Beam6800GeV-VeloClosed-MagDown-Excl-UT/Real Data/Sprucing24c1/90000000/SL.DST" + bk_query: "/LHCb/Collision24/Beam6800GeV-VeloClosed-MagDown/Real Data/Sprucing24c2/90000000/SL.DST" dq_flags: - UNCHECKED - OK -- GitLab From 6df0886db3e819390bb2d4672ff186d06d245e37 Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Wed, 21 Aug 2024 09:54:38 +0200 Subject: [PATCH 54/57] Update Hlt2.py --- SL_l_nu_D0toKpi_Run3_MC_data_v2/Hlt2.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/SL_l_nu_D0toKpi_Run3_MC_data_v2/Hlt2.py b/SL_l_nu_D0toKpi_Run3_MC_data_v2/Hlt2.py index 59510e0eca..031cb0529e 100644 --- a/SL_l_nu_D0toKpi_Run3_MC_data_v2/Hlt2.py +++ b/SL_l_nu_D0toKpi_Run3_MC_data_v2/Hlt2.py @@ -43,13 +43,6 @@ def make_streams(): ] return Streams(streams=streams) -TrackMasterExtrapolator.global_bind( - ApplyMultScattCorr=False, - ApplyEnergyLossCorr=False, - ApplyElectronEnergyLossCorr=False, -) -TrackMasterFitter.global_bind(ApplyMaterialCorrections=False) - public_tools = [ trackMasterExtrapolator_with_simplified_geom(), stateProvider_with_simplified_geom(), -- GitLab From 34ae8c746385c665d1c4c51d1906c69563d81f76 Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Fri, 23 Aug 2024 12:22:32 +0200 Subject: [PATCH 55/57] Update DV.py --- SL_l_nu_D0toKpi_Run3_MC_data_v2/DV.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/SL_l_nu_D0toKpi_Run3_MC_data_v2/DV.py b/SL_l_nu_D0toKpi_Run3_MC_data_v2/DV.py index 3ab50fad30..86a0588fad 100644 --- a/SL_l_nu_D0toKpi_Run3_MC_data_v2/DV.py +++ b/SL_l_nu_D0toKpi_Run3_MC_data_v2/DV.py @@ -42,13 +42,16 @@ def make_Bst(B, pions,lepton, hadron_candidate_id,v2_pvs,do_truth_matching = Tru substitutions=["B-{{B*-}}","B+{{B*+}}"], output_level=INFO).Particles + MVA_cut = mva_transform_output(0.1) + cut_composite = F.require_all(mva_functor_inclusive(v2_pvs)[0] > MVA_cut) + #combine to make [B*0 -> B*- pi+]cc Bst_1 = ParticleCombiner( Inputs=[Bstm, pions], name=f'Bst_1_{lepton}', DecayDescriptor='[B*0 -> B*- pi+]cc', CombinationCut=F.ALL, - CompositeCut=F.ALL, + CompositeCut=cut_composite, ParticleCombiner="ParticleVertexFitter", PrimaryVertices=v2_pvs #OutputLevel=1 @@ -59,7 +62,7 @@ def make_Bst(B, pions,lepton, hadron_candidate_id,v2_pvs,do_truth_matching = Tru name=f'Bst_2_{lepton}', DecayDescriptor='[B*0 -> B*- pi-]cc', CombinationCut=F.ALL, - CompositeCut=F.ALL, + CompositeCut=cut_composite, ParticleCombiner="ParticleVertexFitter", PrimaryVertices=v2_pvs #OutputLevel=1 @@ -435,15 +438,15 @@ def main(options: Options,line = '', lep='',data_or_mc='mc'): hadron_candidate_id = 421 #make B0 candidate Bst = make_Bst(Bm, extra_particles,lep,hadron_candidate_id,v2_pvs,False) - MVA_cut = mva_transform_output(0.1) - b_cut = F.require_all(mva_functor_inclusive(v2_pvs)[0] > MVA_cut) #make a cut - Bst_after_cut = ParticleFilter(Input=Bst, Cut=F.FILTER(b_cut), name='Bst_after_cut') #filter the B candidates + #MVA_cut = mva_transform_output(0.1) + #b_cut = F.require_all(mva_functor_inclusive(v2_pvs)[0] > MVA_cut) #make a cut + #Bst_after_cut = ParticleFilter(Input=Bst, Cut=F.FILTER(b_cut), name='Bst_after_cut') #filter the B candidates if data_or_mc == 'mc': - MCTRUTH_Bst = MCTruthAndBkgCat(Bst_after_cut, name='MCTRUTH_Bst') - tuple_file = tuple_Bst(Bst_after_cut,lep,line, MCTRUTH_Bst, v2_pvs, rec_summary) + MCTRUTH_Bst = MCTruthAndBkgCat(Bst, name='MCTRUTH_Bst') + tuple_file = tuple_Bst(Bst,lep,line, MCTRUTH_Bst, v2_pvs, rec_summary) elif data_or_mc == 'data': - tuple_file = tuple_Bst(Bst_after_cut,lep,line, 'None', v2_pvs, rec_summary) + tuple_file = tuple_Bst(Bst,lep,line, 'None', v2_pvs, rec_summary) else: raise ValueError(f"Decay channel {decay_channel} not supported") #define algorithms -- GitLab From 29008329a15fab247d7d30606cbba70f9de60627 Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Mon, 26 Aug 2024 00:12:43 +0200 Subject: [PATCH 56/57] Update DV.py --- SL_l_nu_D0toKpi_Run3_MC_data_v2/DV.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/SL_l_nu_D0toKpi_Run3_MC_data_v2/DV.py b/SL_l_nu_D0toKpi_Run3_MC_data_v2/DV.py index 86a0588fad..43b3646deb 100644 --- a/SL_l_nu_D0toKpi_Run3_MC_data_v2/DV.py +++ b/SL_l_nu_D0toKpi_Run3_MC_data_v2/DV.py @@ -13,8 +13,7 @@ from Hlt2Conf.algorithms_thor import ParticleContainersMerger from Functors.grammar import Functor from Hlt2Conf.standard_particles import make_has_rich_long_pions,make_has_rich_up_pions,make_has_rich_down_pions import numpy as np -#from Hlt2Conf.lines.semileptonic.isolationMVA import mva_transform_output,mva_functor_mu_inclusive -from .isolationMVA import mva_functor_inclusive,mva_transform_output +from Hlt2Conf.lines.semileptonic.isolationMVA import mva_functor_inclusive,mva_transform_output from .MC_Matcher import trail_seeker from DaVinciTools import SubstitutePID from Gaudi.Configuration import INFO -- GitLab From 43f58d0cf21c9d30435be7681ee7326c7869c3cc Mon Sep 17 00:00:00 2001 From: Ching-Hua Li <ching-hua.li@cern.ch> Date: Mon, 26 Aug 2024 01:06:47 +0200 Subject: [PATCH 57/57] Update DV.py and isolationMVA.py --- SL_l_nu_D0toKpi_Run3_MC_data_v2/DV.py | 2 +- SL_l_nu_D0toKpi_Run3_MC_data_v2/isolationMVA.py | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/SL_l_nu_D0toKpi_Run3_MC_data_v2/DV.py b/SL_l_nu_D0toKpi_Run3_MC_data_v2/DV.py index 43b3646deb..3caf5c0e4a 100644 --- a/SL_l_nu_D0toKpi_Run3_MC_data_v2/DV.py +++ b/SL_l_nu_D0toKpi_Run3_MC_data_v2/DV.py @@ -13,7 +13,7 @@ from Hlt2Conf.algorithms_thor import ParticleContainersMerger from Functors.grammar import Functor from Hlt2Conf.standard_particles import make_has_rich_long_pions,make_has_rich_up_pions,make_has_rich_down_pions import numpy as np -from Hlt2Conf.lines.semileptonic.isolationMVA import mva_functor_inclusive,mva_transform_output +from .isolationMVA import mva_functor_inclusive,mva_transform_output from .MC_Matcher import trail_seeker from DaVinciTools import SubstitutePID from Gaudi.Configuration import INFO diff --git a/SL_l_nu_D0toKpi_Run3_MC_data_v2/isolationMVA.py b/SL_l_nu_D0toKpi_Run3_MC_data_v2/isolationMVA.py index 32214b9183..87b3f568e9 100755 --- a/SL_l_nu_D0toKpi_Run3_MC_data_v2/isolationMVA.py +++ b/SL_l_nu_D0toKpi_Run3_MC_data_v2/isolationMVA.py @@ -97,7 +97,7 @@ def mva_functor_inclusive(v2_pvs, #define DeltaR i.e. the difference in radius of B0 and extra particle in the rapidity-azimuth plane delta_eta = F.ETA.bind(Bstar_p_child) - F.ETA.bind(ExtraParticle_child) delta_phi = F.PHI.bind(Bstar_p_child) - F.PHI.bind(ExtraParticle_child) - ''' + delta_phi = fmath.where(delta_phi > math.pi, delta_phi - 2 * math.pi, delta_phi) delta_phi = fmath.where(delta_phi < -math.pi, delta_phi + 2 * math.pi, @@ -107,6 +107,7 @@ def mva_functor_inclusive(v2_pvs, delta_phi) delta_phi = fmath.where(delta_phi < -math.pi, delta_phi + math.pi, delta_phi) + ''' mva_input_vars.append( MVAinput( "DeltaREpi", 5, @@ -129,11 +130,11 @@ def mva_functor_inclusive(v2_pvs, mva = F.MVA( MVAType='TMVA', Config={ - #'XMLFile':'paramfile://data/xgboost_model_cocktail_inclusive_220724.xml', + 'XMLFile':'paramfile://data/xgboost_model_cocktail_inclusive_220724.xml', #'XMLFile': #f"file://{os.environ['ANALYSIS_PRODUCTIONS_BASE']}/SL_l_nu_D0toKpi_Run3_MC_data_v2/xgboost_model_cocktail_inclusive_220724.xml", #"file:///eos/lhcb/wg/semileptonic/RDst_taue/xgboost_model_cocktail_inclusive_220724.xml", - 'XMLFile': 'paramfile://data/xgboost_model_cocktail_inclusive.xml', + #'XMLFile': 'paramfile://data/xgboost_model_cocktail_inclusive.xml', 'Name':'BDT', }, Inputs={(f"f[{var.number}]" if useNumbers else var.name): var.functor -- GitLab