diff --git a/bandq_resprucing/B2psiX/dv_data.py b/bandq_resprucing/B2psiX/dv_data.py new file mode 100644 index 0000000000000000000000000000000000000000..1404f2753ea1af7a9b3e9eed2ce49cbad169c17d --- /dev/null +++ b/bandq_resprucing/B2psiX/dv_data.py @@ -0,0 +1,65 @@ +from .template import * + +def Lb2JpsipK(): + algs = template(["Lambda_b0", "J/psi(1S)", "p+", "K-"], True, "B2psiX_Lb2JpsipK") + # return make_config( options, algs ) + return algs + +def Lb2Jpsippi(): + algs = template(["Lambda_b0", "J/psi(1S)", "p+", "pi-"], True, "B2psiX_Lb2Jpsippi") + # return make_config( options, algs ) + return algs + +def B2JpsiKpi(): + algs = template(["B0", "J/psi(1S)", "K+", "pi-"], True, "B2psiX_B2JpsiKpi") + # return make_config( options, algs ) + return algs + +def Bp2JpsiphiK(): + algs = template(["B+", "J/psi(1S)", "phi(1020)", "K+"], True, "B2psiX_Bp2JpsiphiK") +# return make_config( options, algs ) + return algs + +def B2Jpsippbar(): + algs = template(["B_s0", "J/psi(1S)", "p+", "p~-"], False, "B2psiX_B2Jpsippbar") +# return make_config( options, algs ) + return algs + +def Xib2JpsiLambdaK_LL(): + algs = template(["Xi_b-", "J/psi(1S)", "Lambda0", "K-"], True, "B2psiX_Xib2JpsiLambdaK_LL") #LL + return algs + +def Xib2JpsiLambdaK_DD(): + algs = template(["Xi_b-", "J/psi(1S)", "Lambda0_DD", "K-"], True, "B2psiX_Xib2JpsiLambdaK_DD") #DD + return algs + +def Bp2JpsipLambdabar_LL(): + algs = template(["B+", "J/psi(1S)", "p+", "Lambda~0"], True, "B2psiX_Bp2JpsipLambdabar_LL") + return algs + +def Bp2JpsipLambdabar_DD(): + algs = template(["B+", "J/psi(1S)", "p+", "Lambda~0_DD"], True, "B2psiX_Bp2JpsipLambdabar_DD") + return algs + +def Bp2JpsiKS0pi_LL(): + algs = template(["B+", "J/psi(1S)", "KS0", "pi+"], True, "B2psiX_Bp2JpsiKS0pi_LL") + return algs + +def Bp2JpsiKS0pi_DD(): + algs = template(["B+", "J/psi(1S)", "KS0_DD", "pi+"], True, "B2psiX_Bp2JpsiKS0pi_DD") + return algs + +# def entry_point(options: Options): +# algs_merged = Lb2JpsipK() +# algs_merged.update(Lb2Jpsippi()) +# algs_merged.update(B2JpsiKpi()) +# algs_merged.update(Bp2JpsiphiK()) +# algs_merged.update(B2Jpsippbar()) +# algs_merged.update(Xib2JpsiLambdaK_LL()) +# algs_merged.update(Xib2JpsiLambdaK_DD()) +# algs_merged.update(Bp2JpsipLambdabar_LL()) +# algs_merged.update(Bp2JpsipLambdabar_DD()) +# algs_merged.update(Bp2JpsiKS0pi_LL()) +# algs_merged.update(Bp2JpsiKS0pi_DD()) + +# return make_config(options, algs_merged) diff --git a/bandq_resprucing/B2psiX/template.py b/bandq_resprucing/B2psiX/template.py new file mode 100644 index 0000000000000000000000000000000000000000..993c0b94e5b2ee41c8a45e33df12ff17cfdad489 --- /dev/null +++ b/bandq_resprucing/B2psiX/template.py @@ -0,0 +1,167 @@ +from .tools.tupling_maker import * +from .tools.descriptor_writer import * + +from GaudiKernel.SystemOfUnits import GeV, MeV, mm, meter, picosecond + +from RecoConf.reconstruction_objects import make_pvs as _make_pvs + +from Hlt2Conf.standard_particles import make_long_kaons, make_long_protons, make_long_pions, make_LambdaLL, make_long_muons, make_phi2kk, make_down_pions, make_down_protons +from Hlt2Conf.standard_particles import make_LambdaDD, make_KsDD, make_KsLL, _make_particles, _make_V0DD, standard_protoparticle_filter +from Hlt2Conf.algorithms_thor import ParticleFilter + +import Functors as F + +masses = { + 'pi0': 134.9768 * + MeV, # +/- 0.0005 PDG, P.A. Zyla et al. (Particle Data Group), Prog. Theor. Exp. Phys. 2020, 083C01 (2020) and 2021 update. + 'KS0': 497.611 * MeV, # +/- 0.013, PDG, PR D98, 030001 and 2019 update + 'Lambda0': + 1115.683 * MeV, # +/- 0.006, PDG, PR D98, 030001 and 2019 update + 'J/psi(1S)': 3096.900 * + MeV, # +/- 0.006 PDG, P.A. Zyla et al. (Particle Data Group), Prog. Theor. Exp. Phys. 2020, 083C01 (2020) and 2021 update. +} + +def _make_down_for_V0_loose(particles): + code = F.require_all(F.P > 1500 * MeV, F.PT > 50 * MeV) + return ParticleFilter(particles, F.FILTER(code)) + +def make_down_pions_for_V0_loose(): + return _make_down_for_V0_loose(make_down_pions()) + +def make_down_protons_for_V0_loose(): + return _make_down_for_V0_loose(make_down_protons()) + +def make_KsDD_loose(pions_down=None): + if pions_down is None: + pions_down = make_down_pions_for_V0_loose() + descriptors = "KS0 -> pi+ pi-" + return _make_V0DD( + particles=[pions_down,pions_down], + descriptors=descriptors, + pv_maker=_make_pvs, + name='std_make_V0DD_loose_{hash}', + bpvvdz_min=100 * mm) + +def make_LambdaDD_loose(): + pions = make_down_pions_for_V0_loose() + protons = make_down_protons_for_V0_loose() + descriptors = "[Lambda0 -> p+ pi-]cc" + return _make_V0DD( + particles=[protons, pions], + descriptors=descriptors, + pv_maker=_make_pvs, + name='std_make_V0DD_loose_{hash}', + nominal_mass=masses['Lambda0'], + am_dmass=80 * MeV, + m_dmass=24 * MeV, + vchi2pdof_max=30, + bpvvdz_min=100 * mm) + +def template(particles, cc, directory): + + ##### Default inputs + sprucing_line = 'SpruceBandQ_JpsiToMuMuDetached' + Jpsi = get_particles(f"/Event/Spruce/{sprucing_line}/Particles") + + rec_sum = get_rec_summary() + v2_pvs = get_pvs() + odin = get_odin() + decreports = None + + long_pions = make_long_pions() + long_kaons = make_long_kaons() + long_protons = make_long_protons() + + DaughterCutp = "(BPVIPCHI2(get_pvs())>9) & (PT>250*MeV) & (P>10*GeV) & (PID_P>5) & (PID_P-PID_K>5) & (GHOSTPROB<0.5)" + DaughterCutpi = "(BPVIPCHI2(get_pvs())>9) & (PT>250*MeV) & (PID_K<5) & (GHOSTPROB<0.5)" + DaughterCutK = "(BPVIPCHI2(get_pvs())>9) & (PT>250*MeV) & (PID_K>5) & (GHOSTPROB<0.5)" + + protons = ParticleFilter( long_protons, Cut = F.FILTER( convert_cut(DaughterCutp) ) ) + kaons = ParticleFilter( long_kaons, Cut = F.FILTER( convert_cut(DaughterCutK) ) ) + pions = ParticleFilter( long_pions, Cut = F.FILTER( convert_cut(DaughterCutpi) ) ) + muons = make_long_muons() + Lambda = make_LambdaLL() + Lambda_DD = make_LambdaDD_loose() + KS0 = make_KsLL() + KS0_DD = make_KsDD_loose() + phi = make_phi2kk(kaon_pidk_min=5) + + input_dict = {"J/psi(1S)": Jpsi, "phi(1020)": phi, + "Lambda0":Lambda, "Lambda~0":Lambda, + "pi+": pions, "pi-": pions, + "K+": kaons, "K-": kaons, + "p+": protons, "p~-": protons, + "mu+": muons, "mu~-": muons, + "Lambda0_DD":Lambda_DD, "Lambda~0_DD":Lambda_DD, + "KS0":KS0, "KS0_DD":KS0_DD, + } + + data_list = [input_dict[particle] for particle in particles[1:]] + # create particle containers + + for i in range(len(particles)): + if particles[i][-3:] == "_DD": + particles[i] = particles[i][:-3] + #print(particles[i]) + + B2JpsiX = ParticleCombiner( + Inputs = data_list, + DecayDescriptor = descriptor(particles, cc), + name = "JpsiToMuMu_Detached_line_validation_{hash}", + CombinationCut = convert_cut("in_range(4000, MASS, 7000) & (CHILD(2, PT)+CHILD(3, PT)>900*MeV)"), + #CombinationCut = convert_cut("in_range(5200, MASS, 7000)"), + CompositeCut = convert_cut("in_range(4000, MASS, 7000) & CHI2DOF<20 & BPVLTIME(get_pvs())>0.2*picosecond & BPVVDZ(get_pvs())>0.*mm") + ) + + from pprint import pprint + print("++++++++++++++++++++++++++++++++++++") + pprint(descriptor(particles, cc)) + #FunTuple: define branches. + + hlt1_trigger_lines = [ 'Hlt1TrackMVADecision', + 'Hlt1TwoTrackMVADecision', + 'Hlt1D2KKDecision', + 'Hlt1D2KPiDecision', + 'Hlt1D2PiPiDecision', + 'Hlt1DiMuonHighMassDecision', + 'Hlt1DiMuonLowMassDecision', + 'Hlt1DiMuonSoftDecision', + 'Hlt1KsToPiPiDecision', + 'Hlt1LowPtMuonDecision', + 'Hlt1LowPtDiMuonDecision', + 'Hlt1SingleHighPtMuonDecision', + 'Hlt1TrackMuonMVADecision'] + + + line_prefilter = create_lines_filter(name=f"PreFilter_{sprucing_line}_{hash}", lines=[sprucing_line]) + evt_vars = event_variables(v2_pvs, odin, decreports, rec_sum, hlt1_trigger_lines, [sprucing_line]) + candidate_vars = candidate_variables(v2_pvs, particles) + tistos_vars = tistos_variables(hlt1_trigger_lines, ["Hlt2Topo2BodyDecision", "Hlt2Topo3BodyDecision", "Hlt2_JpsiToMuMuDetachedFullDecision", "Hlt2_Psi2SToMuMuDetachedFull"], Jpsi, False) + + composite_particles = [ particle for particle in particles if (particle_df["type"][particle] != "basic") and (particle != "phi(1020)") ] + dtf_vars1 = make_dtf_variables(v2_pvs, B2JpsiX, particles, True, composite_particles, directory) + dtf_vars2 = make_dtf_variables(v2_pvs, B2JpsiX, particles, True, composite_particles[1:], directory) + + for particle in particles: + if particle_df["type"][particle] != "basic": + candidate_vars[particle_df["abbr"][particle]] += tistos_vars + + for key in candidate_vars.keys(): + candidate_vars[key] += dtf_vars1[key] + candidate_vars[key] += dtf_vars2[key] + + B2JpsiX_branches = default_branches(particles, cc) + pprint(B2JpsiX_branches) + + # define tupling algorithms + B2JpsiX_tuple = FunTuple_Particles( name=directory, + inputs=B2JpsiX, + tuple_name="DecayTree", + fields=B2JpsiX_branches, + variables=candidate_vars, + store_multiple_cand_info = True, + event_variables = evt_vars) + + algs = { f"{directory}_tuple":[ B2JpsiX_tuple, line_prefilter ],} + + return algs diff --git a/bandq_resprucing/B2psiX/tools/descriptor_writer.py b/bandq_resprucing/B2psiX/tools/descriptor_writer.py new file mode 100644 index 0000000000000000000000000000000000000000..cfbd2acc901bf5402cc72bd489598872d31e8e80 --- /dev/null +++ b/bandq_resprucing/B2psiX/tools/descriptor_writer.py @@ -0,0 +1,153 @@ +import pandas as pd +import numpy as np +particle_dict = {"Lambda_b0": {"abbr": "Lb", "type": "toplevel", "daughters":[]}, + "Xi_b-": {"abbr": "Xibm", "type": "toplevel", "daughters":[]}, + "Xi_b0": {"abbr": "Xib0", "type": "toplevel", "daughters":[]}, + "B0": {"abbr": "B0", "type": "toplevel", "daughters":[]}, + "B+": {"abbr": "Bp", "type": "toplevel", "daughters":[]}, + "B-": {"abbr": "Bm", "type": "toplevel", "daughters":[]}, + "B_s0": {"abbr": "Bs", "type": "toplevel", "daughters":[]}, + "J/psi(1S)": {"abbr": "Jpsi", "type": "composite", "daughters": ["mu+", "mu-"]}, + "psi(2S)": {"abbr": "psi2S", "type": "composite", "daughters": ["mu+", "mu-"]}, + "phi(1020)": {"abbr": "phi", "type": "composite", "daughters": ["K+", "K-"]}, + "Lambda0": {"abbr": "Lambda", "type": "composite", "daughters": ["p+", "pi-"]}, + "Lambda~0": {"abbr": "Lambda", "type": "composite", "daughters": ["p~-", "pi+"]}, + "KS0": {"abbr": "KS0", "type": "composite", "daughters": ["pi+", "pi-"]}, + "mu+": {"abbr": "mup", "type": "basic", "daughters":[]}, + "mu-": {"abbr": "mum", "type": "basic", "daughters":[]}, + "e+": {"abbr": "ep", "type": "basic", "daughters":[]}, + "e-": {"abbr": "em", "type": "basic", "daughters":[]}, + "pi+": {"abbr": "Pip", "type": "basic", "daughters":[]}, + "pi-": {"abbr": "Pim", "type": "basic", "daughters":[]}, + "K+": {"abbr": "Kp", "type": "basic", "daughters":[]}, + "K-": {"abbr": "Km", "type": "basic", "daughters":[]}, + "p+": {"abbr": "Pp", "type": "basic", "daughters":[]}, + "p~-": {"abbr": "Pm", "type": "basic", "daughters":[]}, + } +particle_df = pd.DataFrame(particle_dict).T + +def descriptor(particles, cc=False): + decay_descriptor = f"{particles[0]} ->" + for particle in particles[1:]: + decay_descriptor += f" {particle}" + if cc: decay_descriptor = f"[{decay_descriptor}]cc" + return decay_descriptor + +def decay_branches(mother, daughters, decay_descriptor): + psi_pos = 0 + phi_pos = 0 + Lambda_pos = 0 + KS0_pos = 0 + Pm_pos = Pp_pos = 0 + Km_pos = Kp_pos = 0 + Pim_pos = Pip_pos = 0 + mum_pos = mup_pos = 0 + em_pos = ep_pos = 0 + + #if decay_descriptor[0] == "[" or decay_descriptor[-3:] == "]cc": + if "cc" in decay_descriptor[-5:]: + branch_descriptor = decay_descriptor[:-2] + "CC" + else: branch_descriptor = decay_descriptor + #if "J/psi(1S)" in decay_descriptor: + # branch_descriptor = branch_descriptor.replace("J/psi(1S)", "(J/psi(1S) -> mu+ mu-)") + #if "psi(2S)" in decay_descriptor: + # branch_descriptor = branch_descriptor.replace("psi(2S)", "(psi(2S) -> mu+ mu-)") + #if "Lambda0" in decay_descriptor: + # branch_descriptor = branch_descriptor.replace("Lambda0", "(Lambda0 -> p+ pi-)") + #if "Lambda~0" in decay_descriptor: + # branch_descriptor = branch_descriptor.replace("Lambda~0", "(Lambda~0 -> p~- pi+)") + for comp_par in particle_df.query("type=='composite'").index: + if comp_par in decay_descriptor: + #branch_descriptor = branch_descriptor.replace(comp_par, comp_par + "->" + " ".join(particle_df["daughters"][comp_par])) + branch_descriptor = branch_descriptor.replace(comp_par, f'({comp_par} -> {" ".join(particle_df["daughters"][comp_par])})') + + branches = {mother: branch_descriptor} + + for daughter in daughters: + if "psi" in daughter: + true_pos = branch_descriptor.rfind("(", 0, branch_descriptor.find("psi", psi_pos)) + branches.update({daughter: branch_descriptor[:true_pos]+"^"+branch_descriptor[true_pos:]}) + psi_pos = branch_descriptor.find("psi", psi_pos) + len("psi(nS)") + if "phi" in daughter: + true_pos = branch_descriptor.rfind("(", 0, branch_descriptor.find("phi", phi_pos)) + branches.update({daughter: branch_descriptor[:true_pos]+"^"+branch_descriptor[true_pos:]}) + phi_pos = branch_descriptor.find("phi", phi_pos) + len("phi(1020)") + if "Lambda" in daughter: + true_pos = branch_descriptor.rfind("(", 0, branch_descriptor.find("Lambda", Lambda_pos)) + branches.update({daughter: branch_descriptor[:true_pos]+"^"+branch_descriptor[true_pos:]}) + Lambda_pos = branch_descriptor.find("Lambda", Lambda_pos) + len("Lambda~0") + if "KS0" in daughter: + true_pos = branch_descriptor.rfind("(", 0, branch_descriptor.find("KS0", KS0_pos)) + branches.update({daughter: branch_descriptor[:true_pos]+"^"+branch_descriptor[true_pos:]}) + KS0_pos = branch_descriptor.find("KS0", KS0_pos) + len("KS0") + if "Pp" in daughter: + true_pos = branch_descriptor.find("p+", Pp_pos) + branches.update({daughter: branch_descriptor[:true_pos]+"^"+branch_descriptor[true_pos:]}) + Pp_pos = true_pos + len("p+") + if "Pm" in daughter: + true_pos = branch_descriptor.find("p~-", Pm_pos) + branches.update({daughter: branch_descriptor[:true_pos]+"^"+branch_descriptor[true_pos:]}) + Pm_pos = true_pos + len("p~-") + if "Kp" in daughter: + true_pos = branch_descriptor.find("K+", Kp_pos) + branches.update({daughter: branch_descriptor[:true_pos]+"^"+branch_descriptor[true_pos:]}) + Kp_pos = true_pos + len("K+") + if "Km" in daughter: + true_pos = branch_descriptor.find("K-", Km_pos) + branches.update({daughter: branch_descriptor[:true_pos]+"^"+branch_descriptor[true_pos:]}) + Km_pos = true_pos + len("K-") + if "Pip" in daughter or "Hp" in daughter: + true_pos = branch_descriptor.find("pi+", Pip_pos) + branches.update({daughter: branch_descriptor[:true_pos]+"^"+branch_descriptor[true_pos:]}) + Pip_pos = true_pos + len("pi+") + if "Pim" in daughter or "Hm" in daughter: + true_pos = branch_descriptor.find("pi-", Pim_pos) + branches.update({daughter: branch_descriptor[:true_pos]+"^"+branch_descriptor[true_pos:]}) + Pim_pos = true_pos + len("pi-") + if "mup" in daughter: + true_pos = branch_descriptor.find("mu+", mup_pos) + branches.update({daughter: branch_descriptor[:true_pos]+"^"+branch_descriptor[true_pos:]}) + mup_pos = true_pos + len("mu+") + if "mum" in daughter: + true_pos = branch_descriptor.find("mu-", mum_pos) + branches.update({daughter: branch_descriptor[:true_pos]+"^"+branch_descriptor[true_pos:]}) + mum_pos = true_pos + len("mu-") + if "ep" in daughter: + true_pos = branch_descriptor.find("e+", ep_pos) + branches.update({daughter: branch_descriptor[:true_pos]+"^"+branch_descriptor[true_pos:]}) + ep_pos = true_pos + len("e+") + if "em" in daughter: + true_pos = branch_descriptor.find("e-", em_pos) + branches.update({daughter: branch_descriptor[:true_pos]+"^"+branch_descriptor[true_pos:]}) + em_pos = true_pos + len("e-") + return branches + +def all_particles(particles): + all_pars = [] + for particle in particles: + all_pars += ( [ particle ] + particle_df["daughters"][particle]) + return all_pars + +#print(all_particles(["B_s0","J/psi(1S)", "p+", "p~-"])) + +def default_names(particles): + names = [] + for particle in particles: + abbr = particle_df["abbr"][ particle ] + names.append( abbr ) + names += [f"{daughter_abbr}_{abbr}" for daughter_abbr in particle_df["abbr"][particle_df["daughters"][particle]]] + return names + +def default_branches(particles, cc=False): + names = default_names(particles) + return decay_branches(names[0], names[1:], descriptor(particles, cc)) + +#from pprint import pprint +#branches = default_branches( ["B+","J/psi(1S)", "KS0", "pi+"], True) +#pprint(branches) + +#branches = decay_branches("Bs", ["Jpsi", "Pp", "Pm", "mup", "mum"], "[B_s0 -> J/psi(1S) p+ p~-]cc") +#print(branches) + +#branches = default_names( ["B_s0","J/psi(1S)", "p+", "p~-"]) +#print(descriptor(["Lambda_b0", "J/psi(1S)", "p+", "K-"], True)) diff --git a/bandq_resprucing/B2psiX/tools/tupling_maker.py b/bandq_resprucing/B2psiX/tools/tupling_maker.py new file mode 100644 index 0000000000000000000000000000000000000000..fb20000bd3a79bd9d2c48eb03317510e3a3d3a9b --- /dev/null +++ b/bandq_resprucing/B2psiX/tools/tupling_maker.py @@ -0,0 +1,387 @@ +from DaVinci import make_config, Options +from DaVinci.algorithms import create_lines_filter + +from PyConf.reading import get_rec_summary, get_pvs +from PyConf.reading import get_particles + +import FunTuple.functorcollections as FC +import Functors as F +from FunTuple import FunctorCollection + +from FunTuple import FunTuple_Event +from FunTuple import FunTuple_Particles +from .descriptor_writer import * + + +#from PyConf.reading import (get_particles, get_charged_protoparticles, get_pvs, get_rec_summary, _get_unpacked) + +from Functors.math import in_range +from Hlt2Conf.algorithms_thor import ParticleCombiner, ParticleFilter + +from RecoConf.event_filters import require_pvs + +from Hlt2Conf.standard_particles import get_long_track_selector, standard_protoparticle_filter +from PyConf.Algorithms import FunctionalParticleMaker +from PyConf.reading import get_charged_protoparticles as _make_charged_protoparticles +from PyConf.reading import get_odin + +from GaudiKernel.SystemOfUnits import MeV, picosecond, mm, GeV +from DecayTreeFitter import DecayTreeFitter + +_basic = "basic" +_composite = "composite" +_toplevel = "toplevel" + +def all_variables(pvs, mctruth, ptype, candidates=None, ftAlg=None): + + if ptype not in [_basic, _composite]: + Exception(f"I want {_basic} or {_composite}. Got {ptype}") + all_vars = FunctorCollection({}) + + comp = _composite == ptype or _toplevel == ptype # is composite + basic = _basic == ptype # is not composite + top = _toplevel == ptype # the B + + all_vars += FC.Kinematics() + if basic: + all_vars += FC.ParticleID(extra_info=True) + + if comp: + all_vars.update({"ALV": F.ALV(Child1=1, Child2=2)}) + + if comp: # all these require a vertex + all_vars.update({"BPVCORRM": F.BPVCORRM(pvs)}) + all_vars.update({"BPVCORRMERR": F.BPVCORRMERR(pvs)}) + all_vars.update({"BPVDIRA": F.BPVDIRA(pvs)}) + all_vars.update({"BPVDLS": F.BPVDLS(pvs)}) + all_vars.update({"BPVETA": F.BPVETA(pvs)}) + all_vars.update({"BPVFD": F.BPVFD(pvs)}) + all_vars.update({"BPVFDCHI2": F.BPVFDCHI2(pvs)}) + all_vars.update({"BPVFDIR": F.BPVFDIR(pvs)}) + all_vars.update({"BPVFDVEC": F.BPVFDVEC(pvs)}) + + all_vars.update({"BPVIP": F.BPVIP(pvs)}) + all_vars.update({"BPVIPCHI2": F.BPVIPCHI2(pvs)}) + all_vars.update({"BPVX": F.BPVX(pvs)}) + all_vars.update({"BPVY": F.BPVY(pvs)}) + all_vars.update({"BPVZ": F.BPVZ(pvs)}) + all_vars.update({"ALLPVX": F.ALLPVX(pvs)}) + all_vars.update({"ALLPVY": F.ALLPVY(pvs)}) + all_vars.update({"ALLPVZ": F.ALLPVZ(pvs)}) + + if comp: # all these require a vertex + all_vars.update({"ALLPV_FD": F.ALLPV_FD(pvs)}) + all_vars.update({"ALLPV_IP": F.ALLPV_IP(pvs)}) + all_vars.update({"BPVLTIME": F.BPVLTIME(pvs)}) + all_vars.update({"BPVVDRHO": F.BPVVDRHO(pvs)}) + all_vars.update({"BPVVDX": F.BPVVDX(pvs)}) + all_vars.update({"BPVVDY": F.BPVVDY(pvs)}) + all_vars.update({"BPVVDZ": F.BPVVDZ(pvs)}) + + all_vars.update({"CHARGE": F.CHARGE}) + all_vars.update({"CHI2": F.CHI2}) + all_vars.update({"CHI2DOF": F.CHI2DOF}) + #if top: # apply this only to B + # all_vars.update({"CHILD1_PT": F.CHILD(1, F.PT)}) # example of CHILD + # all_vars.update({"Ds_END_VZ": F.CHILD(1, F.END_VZ)}) + # all_vars.update({"Delta_END_VZ_DsB0": F.CHILD(1, F.END_VZ) - F.END_VZ}) + + if comp: + #all_vars.update({"DOCA": F.SDOCA(Child1=1, Child2=2)}) + #all_vars.update({"DOCACHI2": F.SDOCACHI2(Child1=1, Child2=2)}) + all_vars.update({"END_VRHO": F.END_VRHO}) + all_vars.update({"END_VX": F.END_VX}) + all_vars.update({"END_VY": F.END_VY}) + all_vars.update({"END_VZ": F.END_VZ}) + + # duplicated from FC all_vars.update({"ENERGY" : F.ENERGY}) + all_vars.update({"ETA": F.ETA}) + all_vars.update({"FOURMOMENTUM": F.FOURMOMENTUM}) + all_vars.update({"ISBASIC": F.ISBASICPARTICLE}) + + if basic: + all_vars.update({"GHOSTPROB": F.GHOSTPROB}) + all_vars.update({"ISMUON": F.ISMUON}) + all_vars.update({"INMUON": F.INMUON}) + all_vars.update({"INECAL": F.INECAL}) + all_vars.update({"INHCAL": F.INHCAL}) + all_vars.update({"HASBREM": F.HASBREM}) + all_vars.update({"BREMENERGY": F.BREMENERGY}) + all_vars.update({"BREMBENDCORR": F.BREMBENDCORR}) + all_vars.update({"BREMPIDE": F.BREMPIDE}) + all_vars.update({"ECALPIDE": F.ECALPIDE}) + all_vars.update({"ECALPIDMU": F.ECALPIDMU}) + all_vars.update({"HCALPIDE": F.HCALPIDE}) + all_vars.update({"HCALPIDMU": F.HCALPIDMU}) + all_vars.update({"ELECTRONSHOWEREOP": F.ELECTRONSHOWEREOP}) + all_vars.update({"CLUSTERMATCH": F.CLUSTERMATCH_CHI2}) + all_vars.update({"ELECTRONMATCH": F.ELECTRONMATCH_CHI2}) + all_vars.update({"BREMHYPOMATCH": F.BREMHYPOMATCH_CHI2}) + all_vars.update({"ELECTRONENERGY": F.ELECTRONENERGY}) + all_vars.update({"BREMHYPOENERGY": F.BREMHYPOENERGY}) + all_vars.update({"BREMHYPODELTAX": F.BREMHYPODELTAX}) + all_vars.update({"ELECTRONID": F.ELECTRONID}) + all_vars.update({"HCALEOP": F.HCALEOP}) + all_vars.update({"TRACK_MOM_": F.TRACK_MOMVEC}) + #all_vars.update({"TRACK_POS_CLOSESTTOBEAM_": F.TRACK_POSVEC_CLOSESTTOBEAM}) + all_vars.update({"IS_ID_pi": F.IS_ID("pi-")}) + all_vars.update({"PDG_MASS_pi": F.PDG_MASS("pi+")}) + all_vars.update({"SIGNED_DELTA_MASS_pi": F.SIGNED_DELTA_MASS("pi+")}) + all_vars.update({"ABS_DELTA_MASS_pi": F.ABS_DELTA_MASS("pi+")}) + all_vars.update({"IS_NOT_H": F.IS_NOT_H}) + all_vars.update({"IS_PHOTON": F.IS_PHOTON}) + + if comp: + all_vars.update({"MAXPT": F.MAX(F.PT)}) + all_vars.update({"MAXDOCA": F.MAXSDOCA}) + all_vars.update({"MAXDOCACHI2": F.MAXSDOCACHI2}) + #all_vars.update({"MINDOCA": F.MINSDOCA}) + #all_vars.update({"MINDOCACHI2": F.MINSDOCACHI2}) + # the above in cut versions. + + # duplicated from FC all_vars.update({ 'MC_MOTHER_ID' : F.VALUE_OR(0) @ mctruth( + # duplicated from FC F.MC_MOTHER(1, F.PARTICLE_ID))}) + + if comp: + all_vars.update({"MINPT": F.MIN(F.PT)}) + all_vars.update({"MINIP": F.MINIP(pvs)}) + all_vars.update({"MINIPCHI2": F.MINIPCHI2(pvs)}) + + if basic: + all_vars.update({"TRACKPT": F.TRACK_PT}) + all_vars.update({"TRACKTYPE": F.VALUE_OR(-1) @ F.TRACKTYPE @ F.TRACK}) + all_vars.update({"TRACKHISTORY": F.VALUE_OR(-1) @ F.TRACKHISTORY @ F.TRACK}) + all_vars.update({"QOVERP": F.QOVERP @ F.TRACK}) + all_vars.update({"NDOF": F.VALUE_OR(-1) @ F.NDOF @ F.TRACK}) + all_vars.update({"NFTHITS": F.VALUE_OR(-1) @ F.NFTHITS @ F.TRACK}) + all_vars.update({"NHITS": F.VALUE_OR(-1) @ F.NHITS @ F.TRACK}) + all_vars.update({"NUTHITS": F.VALUE_OR(-1) @ F.NUTHITS @ F.TRACK}) + all_vars.update({"NVPHITS": F.VALUE_OR(-1) @ F.NVPHITS @ F.TRACK}) + all_vars.update({"TRACKHASVELO": F.VALUE_OR(-1) @ F.TRACKHASVELO @ F.TRACK}) + all_vars.update({"TRACKHASUT": F.VALUE_OR(-1) @ F.TRACKHASUT @ F.TRACK}) + + all_vars.update({"OBJECT_KEY": F.OBJECT_KEY}) + all_vars.update({"PHI": F.PHI}) + + all_vars.update({"ABS_PX": F.ABS @ F.PX}) + + all_vars.update({"REFERENCEPOINT_X": F.REFERENCEPOINT_X}) + all_vars.update({"REFERENCEPOINT_Y": F.REFERENCEPOINT_Y}) + all_vars.update({"REFERENCEPOINT_Z": F.REFERENCEPOINT_Z}) + + if comp: + all_vars.update({"SDOCA12": F.SDOCA(1, 2)}) + all_vars.update({"SDOCA12_CHI2": F.SDOCACHI2(1, 2)}) + if basic: + all_vars.update({"SHOWER_SHAPE": F.CALO_NEUTRAL_SHOWER_SHAPE}) + + if comp: + all_vars.update({"SUBCOMB12_MM": F.SUBCOMB(Functor=F.MASS, Indices=(1, 2))}) + all_vars.update({"SUMPT": F.SUM(F.PT)}) + if top: + all_vars.update({"SDOCA13": F.SDOCA(1, 3)}) + all_vars.update({"SDOCA13_CHI2": F.SDOCACHI2(1, 3)}) + all_vars.update({"SDOCA23": F.SDOCA(2, 3)}) + all_vars.update({"SDOCA23_CHI2": F.SDOCACHI2(2, 3)}) + all_vars.update({"SUBCOMB13_MM": F.SUBCOMB(Functor=F.MASS, Indices=(1, 3))}) + all_vars.update({"SUBCOMB23_MM": F.SUBCOMB(Functor=F.MASS, Indices=(2, 3))}) + + if basic: + all_vars.update({"TX": F.TX}) + all_vars.update({"TY": F.TY}) + + print(f"### For {ptype} returning variables {all_vars.functor_dict.keys()}") + return all_vars + +def tistos_variables(Hlt1_decisions, Hlt2_decisions, data, isturbo): + tistos_vars = FunctorCollection({}) + tistos_vars += FC.HltTisTos( selection_type="Hlt1", trigger_lines=Hlt1_decisions, data=data) + if not isturbo: + tistos_vars += FC.HltTisTos( selection_type="Hlt2", trigger_lines=Hlt2_decisions, data=data) + return tistos_vars + +def event_variables(PVs, ODIN, decreports, rec_sum, hlt1_lines, sprucing_lines): + """ + event variables + """ + + ## Some empty summaries removed + evt_vars = FunctorCollection({ + "nPVs": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nPVs"), + "nTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nTracks"), + "nLongTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nLongTracks"), + "nDownstreamTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nDownstreamTracks"), + "nUpstreamTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nUpstreamTracks"), + "nVeloTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nVeloTracks"), + "nBackTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nBackTracks"), + "nGhosts": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nGhosts"), + "nRich1Hits": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nRich1Hits"), + "nRich2Hits": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nRich2Hits"), + #"nVeloClusters": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nVeloClusters"), + "nVPClusters": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nVPClusters"), + #"nITClusters": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nITClusters"), + #"nTTClusters": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nTTClusters"), + "nUTClusters": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nUTClusters"), + #"nOTClusters": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nOTClusters"), + "nFTClusters": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nFTClusters"), + #"nSPDhits": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nSPDhits"), + "eCalTot": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"eCalTot"), + "hCalTot": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"hCalTot"), + "nEcalClusters": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nEcalClusters"), + #"nMuonCoordsS0": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nMuonCoordsS0"), + #"nMuonCoordsS1": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nMuonCoordsS1"), + #"nMuonCoordsS2": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nMuonCoordsS2"), + #"nMuonCoordsS3": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nMuonCoordsS3"), + #"nMuonCoordsS4": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nMuonCoordsS4"), + #"nMuonTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nMuonTracks"), + "ALLPVX": F.ALLPVX(PVs), + "ALLPVY": F.ALLPVY(PVs), + "ALLPVZ": F.ALLPVZ(PVs), + }) + evt_vars += FC.EventInfo() + + evt_vars += FC.SelectionInfo( selection_type="Hlt1", trigger_lines=hlt1_lines) + evt_vars += FC.SelectionInfo( selection_type="Hlt2", trigger_lines=sprucing_lines) + # duplicated from FC if ODIN: + # duplicated from FC evt_vars.update({ 'BUNCHCROSSING_ID' : F.BUNCHCROSSING_ID(ODIN)}) + # duplicated from FC evt_vars.update({ 'BUNCHCROSSING_TYPE' : F.BUNCHCROSSING_TYPE(ODIN)}) + + if decreports: + evt_vars.update( + { + "DECISIONS": F.DECISIONS( + Lines=[bd2dsk_line + "Decision"], DecReports=decreports + ) + } + ) + evt_vars.update( + { + "DECREPORTS_FILTER": F.DECREPORTS_FILTER( + Lines=[bd2dsk_line + "Decision"], DecReports=decreports + ) + } + ) + + if ODIN: + evt_vars.update({"EVENTTYPE": F.EVENTTYPE(ODIN)}) + + # duplicated from FC evt_vars.update({ 'GPSTIME' : F.GPSTIME(ODIN)}) + # duplicated from FC evt_vars.update({ 'ODINTCK' : F.ODINTCK(ODIN)}) + + evt_vars.update({"PV_SIZE": F.SIZE(PVs)}) + # duplicated from FC evt_vars.update({ 'GPSTIME' : F.GPSTIME(ODIN)}) + # duplicated from FC evt_vars.update({ 'ODINTCK' : F.ODINTCK(ODIN)}) + + if decreports: + evt_vars.update({"TCK": F.TCK(decreports)}) + + print(f"### For event returning variables {evt_vars.functor_dict.keys()}") + return evt_vars + +def candidate_variables(pvs, particles): + abbrs = default_names(particles) + names = all_particles(particles) + variables_B = {abbr: all_variables(pvs, None, particle_df["type"][name]) for abbr, name in zip(abbrs, names)} + return variables_B + +from DecayTreeFitter import DecayTreeFitter +def make_dtf_variables(pvs, data, particles, pv_constraint=False, mass_constraints=[], label_forLLDD=""): + + abbrs = default_names(particles) + names = all_particles(particles) + + if pv_constraint: dtf_name = "DTF_PV_" + else: dtf_name = "DTF_" + dtf_name += "".join(f"{par}_" for par in particle_df["abbr"][mass_constraints]) + my_hash='{hash}' + + DTF = DecayTreeFitter( + name = f"{dtf_name}DecayTreeFitter_{my_hash}", + input_particles = data, + input_pvs = (pv_constraint and pvs), + mass_constraints = mass_constraints, + ) + + dtf_dict = {} + + shared_variables = FunctorCollection( + { "ETA": F.ETA, + "PHI": F.PHI, + "BPVIPCHI2": F.BPVIPCHI2(pvs), + "BPVIP": F.BPVIP(pvs), + "BPVX": F.BPVX(pvs), + "BPVY": F.BPVY(pvs), + "BPVZ": F.BPVZ(pvs), + } + ) + FC.Kinematics() + + dtf_quality_variables = FunctorCollection( { + dtf_name+"_DTFCHI2": DTF.CHI2, + dtf_name+"_DTFNDOF": DTF.NDOF, + dtf_name+"_CTAU": DTF.CTAU, + dtf_name+"_CTAUERR": DTF.CTAUERR, + dtf_name+"_MERR": DTF.MASSERR, + } + ) + + #make branches + for abbr, name in zip(abbrs, names): + is_basic = particle_df["type"][name] + if is_basic: + orig_variables = shared_variables + FunctorCollection( + { "TX" : F.TX, + "TY" : F.TY, + "MINIPCHI2" : F.MINIPCHI2(pvs), + "MINIP" : F.MINIP(pvs), + "KEY" : F.VALUE_OR(-1) @ F.OBJECT_KEY @ F.TRACK, + "TRGHOSTPROB": F.GHOSTPROB, + "TRACKPT": F.TRACK_PT, + "TRACKHISTORY": F.VALUE_OR(-1) @ F.TRACKHISTORY @ F.TRACK, + "QOVERP": F.QOVERP @ F.TRACK, + "TRCHI2DOF": F.CHI2DOF @ F.TRACK, + "NDOF": F.VALUE_OR(-1) @ F.NDOF @ F.TRACK, + } + ) + else: + orig_variables = shared_variables + FunctorCollection( + { "MAXPT": F.MAX(F.PT), + "MINPT": F.MIN(F.PT), + "SUMPT": F.SUM(F.PT), + "MAXP": F.MAX(F.P), + "MINP": F.MIN(F.P), + "BPVDIRA": F.BPVDIRA(pvs), + "CHI2DOF": F.CHI2DOF, #CHI2VXNDOF + "BPVFDCHI2": F.BPVFDCHI2(pvs), + "BPVFD": F.BPVFD(pvs), + "BPVVDRHO": F.BPVVDRHO(pvs), + "BPVVDZ": F.BPVVDZ(pvs), + "BPVLTIME": F.BPVLTIME(pvs), + "END_VX": F.END_VX, #END_ + "END_VY": F.END_VY, + "END_VZ": F.END_VZ, + } + ) + orig_variables += dtf_quality_variables + + dtf_variables = FunctorCollection({ dtf_name + expr: DTF(func) for expr, func in orig_variables.get_thor_functors().items() }) + dtf_dict.update( {abbr: dtf_variables} ) + + return dtf_dict + +import re +def convert_cut(string_cut): + cuts = string_cut.split("&") + paras = ["BPV", "PID_", "MASS", "CHARGE", "CHI2DOF", "END", "IS_ID", "ABS_", "MAX", "SUM", "GHOSTPROB", "CHILD"] + values = [] + for cut in cuts: + value = cut + for para in paras: + if para in cut: + value = value.replace(para, f"F.{para}") + value = re.sub(r"\bPT\b", "F.PT", value) + value = re.sub(r"\bP\b", "F.P", value) + value = re.sub(r"\bCHI2\b", "F.CHI2", value) + values.append(value) + functor_cut = ",".join(values) + return eval(f"F.require_all({functor_cut})") +#return f"F.require_all({functor_cut})" diff --git a/bandq_resprucing/BforSpectroscopy/dv_data.py b/bandq_resprucing/BforSpectroscopy/dv_data.py new file mode 100644 index 0000000000000000000000000000000000000000..554ffb9c8c9136843a13ff24c36f13090acc4bd6 --- /dev/null +++ b/bandq_resprucing/BforSpectroscopy/dv_data.py @@ -0,0 +1,949 @@ +from .tupling_maker import template, line_prefilter +from DaVinci import Options, make_config + +# Bu 7 +# Bd 6 +# Bs 6 +# Bc 3 +# Lb 4 +# Xibm 5-1 +# Xib0 5-1 +# Omegab 6-1 + +HLT2_lines = ["Hlt2Topo2BodyDecision", "Hlt2Topo3BodyDecision", "Hlt2_JpsiToMuMuDetachedFull"] + + +def Bu(): + + # BuToJpsiK = make_BuToJpsiK(process) + # BuToD0Pi = make_BuToD0Pi(process) + # BuToD0PiPiPi = make_BuToD0PiPiPi(process) + # BuToDmPiPi = make_BuToDmPiPi(process) + + decays = [ + # Bu -> J/psi K+ decay + ( + { + "Bu": "[B+ -> (J/psi(1S) -> mu+ mu-) K+]CC", + "Jpsi": "[B+ -> ^(J/psi(1S) -> mu+ mu-) K+]CC", + "Jpsi_mup": "[B+ -> (J/psi(1S) -> ^mu+ mu-) K+]CC", + "Jpsi_mum": "[B+ -> (J/psi(1S) -> mu+ ^mu-) K+]CC", + "Bu_K1": "[B+ -> (J/psi(1S) -> mu+ mu-) ^K+]CC" + }, + ["Bu", "Jpsi"], + ["Jpsi_mup", "Jpsi_mum", "Bu_K1"], + "BforSpectroscopy_BuToJpsiK", + ["J/psi(1S)", "Jpsi"], + ), + + # Bu -> D0 pi+ decay, with D0 -> K- pi+ + ( + { + "Bu": "[B+ -> (D~0 -> K+ pi-) pi+]CC", + "D0": "[B+ -> ^(D~0 -> K+ pi-) pi+]CC", + "D0_K1": "[B+ -> (D~0 -> ^K+ pi-) pi+]CC", + "D0_Pi1": "[B+ -> (D~0 -> K+ ^pi-) pi+]CC", + "Bu_Pi1": "[B+ -> (D~0 -> K+ pi-) ^pi+]CC" + }, + ["Bu", "D0"], + ["D0_K1", "D0_Pi1", "Bu_Pi1"], + "BforSpectroscopy_BuToD0Pi", + ["D~0", "D0"], + ), + + # Bu -> D0 pi+ pi+ pi- decay, with D0 -> K- pi+ + ( + { + "Bu": "[B+ -> (D~0 -> K+ pi-) pi+ pi+ pi-]CC", + "D0": "[B+ -> ^(D~0 -> K+ pi-) pi+ pi+ pi-]CC", + "D0_K1": "[B+ -> (D~0 -> ^K+ pi-) pi+ pi+ pi-]CC", + "D0_Pi1": "[B+ -> (D~0 -> K+ ^pi-) pi+ pi+ pi-]CC", + "Bu_Pi1": "[B+ -> (D~0 -> K+ pi-) ^pi+ pi+ pi-]CC", + "Bu_Pi2": "[B+ -> (D~0 -> K+ pi-) pi+ ^pi+ pi-]CC", + "Bu_Pi3": "[B+ -> (D~0 -> K+ pi-) pi+ pi+ ^pi-]CC" + }, + ["Bu", "D0"], + ["D0_K1", "D0_Pi1", "Bu_Pi1", "Bu_Pi2", "Bu_Pi3"], + "BforSpectroscopy_BuToD0PiPiPi", + ["D~0", "D0"], + ), + + # Bu -> D- pi+ pi+ decay, with D+ -> K- pi+ pi+ + ( + { + "Bu": "[B+ -> (D- -> K+ pi- pi-) pi+ pi+]CC", + "Dm": "[B+ -> ^(D- -> K+ pi- pi-) pi+ pi+]CC", + "Dm_K1": "[B+ -> (D- -> ^K+ pi- pi-) pi+ pi+]CC", + "Dm_Pi1": "[B+ -> (D- -> K+ ^pi- pi-) pi+ pi+]CC", + "Dm_Pi2": "[B+ -> (D- -> K+ pi- ^pi-) pi+ pi+]CC", + "Bu_Pi1": "[B+ -> (D- -> K+ pi- pi-) ^pi+ pi+]CC", + "Bu_Pi2": "[B+ -> (D- -> K+ pi- pi-) pi+ ^pi+]CC" + }, + ["Bu", "Dm"], + ["Dm_K1", "Dm_Pi1", "Dm_Pi2", "Bu_Pi1", "Bu_Pi2"], + "BforSpectroscopy_BuToDmPipPip", + ["D-", "Dm"], + ), + + + # Bu -> D0 pi+ decay, with D0 -> K- pi+ pi- pi+ + ( + { + "Bu": "[B+ -> (D~0 -> K+ pi+ pi- pi-) pi+]CC", + "D0": "[B+ -> ^(D~0 -> K+ pi+ pi- pi-) pi+]CC", + "D0_K1": "[B+ -> (D~0 -> ^K+ pi+ pi- pi-) pi+]CC", + "D0_Pi1": "[B+ -> (D~0 -> K+ ^pi+ pi- pi-) pi+]CC", + "D0_Pi2": "[B+ -> (D~0 -> K+ pi+ ^pi- pi-) pi+]CC", + "D0_Pi3": "[B+ -> (D~0 -> K+ pi+ pi- ^pi-) pi+]CC", + "Bu_Pi1": "[B+ -> (D~0 -> K+ pi+ pi- pi-) ^pi+]CC" + }, + ["Bu", "D0"], + ["D0_K1", "D0_Pi1", "D0_Pi2", "D0_Pi3", "Bu_Pi1"], + "BforSpectroscopy_Bu2D0Pi_K3Pi", + ["D~0", "D0"], + ), + + # Bu -> D0 pi+ pi+ pi- decay, with D0 -> K- pi+ pi- pi+ + ( + { + "Bu": "[B+ -> (D~0 -> K+ pi+ pi- pi-) pi+ pi+ pi-]CC", + "D0": "[B+ -> ^(D~0 -> K+ pi+ pi- pi-) pi+ pi+ pi-]CC", + "D0_K1": "[B+ -> (D~0 -> ^K+ pi+ pi- pi-) pi+ pi+ pi-]CC", + "D0_Pi1": "[B+ -> (D~0 -> K+ ^pi+ pi- pi-) pi+ pi+ pi-]CC", + "D0_Pi2": "[B+ -> (D~0 -> K+ pi+ ^pi- pi-) pi+ pi+ pi-]CC", + "D0_Pi3": "[B+ -> (D~0 -> K+ pi+ pi- ^pi-) pi+ pi+ pi-]CC", + "Bu_Pi1": "[B+ -> (D~0 -> K+ pi+ pi- pi-) ^pi+ pi+ pi-]CC", + "Bu_Pi2": "[B+ -> (D~0 -> K+ pi+ pi- pi-) pi+ ^pi+ pi-]CC", + "Bu_Pi3": "[B+ -> (D~0 -> K+ pi+ pi- pi-) pi+ pi+ ^pi-]CC" + }, + ["Bu", "D0"], + ["D0_K1", "D0_Pi1", "D0_Pi2", "D0_Pi3", "Bu_Pi1", "Bu_Pi2", "Bu_Pi3"], + "BforSpectroscopy_Bu2D0PiPiPi_K3Pi", + ["D~0", "D0"], + ) + ] + + line_name = 'SpruceBandQ_BuForSpectroscopy' + HLT2_decision = line_name.replace("Spruce", "Hlt2") + "FullDecision" + my_filter = line_prefilter(HLT2_decision) + + algs = {} #[my_filter] + + for decay_config in decays: + + decay_descriptor, composite_list, stable_list, decay_name, ParticleToConstrain = decay_config + algs[decay_name] = [my_filter, template(decay_descriptor, line_name, False, HLT2_lines+[HLT2_decision], composite_list, stable_list, decay_name, ParticleToConstrain)] + + return algs + + +def Bd(): + + # BdToJpsiKPi = make_BdToJpsiKPi(process) + # BdToDmPip = make_BdToDmPip(process) + # BdToD0barPiPi = make_BdToD0barPiPi(process) + # BdToDmPipPipPim = make_BdToDmPipPipPim(process) + + decays = [ + # Bd -> J/psi K+ pi- decay + ( + { + "Bd": "[B0 -> (J/psi(1S) -> mu+ mu-) K+ pi-]CC", + "Jpsi": "[B0 -> ^(J/psi(1S) -> mu+ mu-) K+ pi-]CC", + "Jpsi_mup": "[B0 -> (J/psi(1S) -> ^mu+ mu-) K+ pi-]CC", + "Jpsi_mum": "[B0 -> (J/psi(1S) -> mu+ ^mu-) K+ pi-]CC", + "Bd_K1": "[B0 -> (J/psi(1S) -> mu+ mu-) ^K+ pi-]CC", + "Bd_Pi1": "[B0 -> (J/psi(1S) -> mu+ mu-) K+ ^pi-]CC" + }, + ["Bd", "Jpsi"], + ["Jpsi_mup", "Jpsi_mum", "Bd_K1", "Bd_Pi1"], + "BforSpectroscopy_BdToJpsiKPi", + ["J/psi(1S)", "Jpsi"], + ), + + # Bd -> D+ pi- decay, with D+ -> K- pi+ pi+ + ( + { + "Bd": "[B0 -> (D- -> K+ pi- pi-) pi+]CC", + "Dm": "[B0 -> ^(D- -> K+ pi- pi-) pi+]CC", + "Dm_K1": "[B0 -> (D- -> ^K+ pi- pi-) pi+]CC", + "Dm_Pi1": "[B0 -> (D- -> K+ ^pi- pi-) pi+]CC", + "Dm_Pi2": "[B0 -> (D- -> K+ pi- ^pi-) pi+]CC", + "Bd_Pi1": "[B0 -> (D- -> K+ pi- pi-) ^pi+]CC" + }, + ["Bd", "Dm"], + ["Dm_K1", "Dm_Pi1", "Dm_Pi2", "Bd_Pi1"], + "BforSpectroscopy_BdToDmPip", + ["D-", "Dm"], + ), + + # Bd -> D0bar pi+ pi- decay, with D0bar -> K+ pi- + ( + { + "Bd": "[B0 -> (D~0 -> K+ pi-) pi+ pi-]CC", + "D0": "[B0 -> ^(D~0 -> K+ pi-) pi+ pi-]CC", + "D0_K1": "[B0 -> (D~0 -> ^K+ pi-) pi+ pi-]CC", + "D0_Pi1": "[B0 -> (D~0 -> K+ ^pi-) pi+ pi-]CC", + "Bd_Pi1": "[B0 -> (D~0 -> K+ pi-) ^pi+ pi-]CC", + "Bd_Pi2": "[B0 -> (D~0 -> K+ pi-) pi+ ^pi-]CC" + }, + ["Bd", "D0"], + ["D0_K1", "D0_Pi1", "Bd_Pi1", "Bd_Pi2"], + "BforSpectroscopy_BdToD0barPiPi", + ["D~0", "D0"], + ), + + # Bd -> D- pi+ pi+ pi- decay, with D+ -> K- pi+ pi+ + ( + { + "Bd": "[B0 -> (D- -> K+ pi- pi-) pi+ pi+ pi-]CC", + "Dm": "[B0 -> ^(D- -> K+ pi- pi-) pi+ pi+ pi-]CC", + "Dm_K1": "[B0 -> (D- -> ^K+ pi- pi-) pi+ pi+ pi-]CC", + "Dm_Pi1": "[B0 -> (D- -> K+ ^pi- pi-) pi+ pi+ pi-]CC", + "Dm_Pi2": "[B0 -> (D- -> K+ pi- ^pi-) pi+ pi+ pi-]CC", + "Bd_Pi1": "[B0 -> (D- -> K+ pi- pi-) ^pi+ pi+ pi-]CC", + "Bd_Pi2": "[B0 -> (D- -> K+ pi- pi-) pi+ ^pi+ pi-]CC", + "Bd_Pi3": "[B0 -> (D- -> K+ pi- pi-) pi+ pi+ ^pi-]CC" + }, + ["Bd", "Dm"], + ["Dm_K1", "Dm_Pi1", "Dm_Pi2", "Bd_Pi1", "Bd_Pi2", "Bd_Pi3"], + "BforSpectroscopy_BdToDmPipPipPim", + ["D-", "Dm"], + ), + # Bd -> D0bar pi+ pi-, with D0bar -> K+ pi- pi+ pi- + ( + { + "Bd": "[B0 -> (D~0 -> K+ pi- pi+ pi-) pi+ pi-]CC", + "D0": "[B0 -> ^(D~0 -> K+ pi- pi+ pi-) pi+ pi-]CC", + "D0_K1": "[B0 -> (D~0 -> ^K+ pi- pi+ pi-) pi+ pi-]CC", + "D0_Pi1": "[B0 -> (D~0 -> K+ ^pi- pi+ pi-) pi+ pi-]CC", + "D0_Pi2": "[B0 -> (D~0 -> K+ pi- ^pi+ pi-) pi+ pi-]CC", + "D0_Pi3": "[B0 -> (D~0 -> K+ pi- pi+ ^pi-) pi+ pi-]CC", + "Bd_Pi1": "[B0 -> (D~0 -> K+ pi- pi+ pi-) ^pi+ pi-]CC", + "Bd_Pi2": "[B0 -> (D~0 -> K+ pi- pi+ pi-) pi+ ^pi-]CC" + }, + ["Bd", "D0"], + ["D0_K1", "D0_Pi1", "D0_Pi2", "D0_Pi3", "Bd_Pi1", "Bd_Pi2"], + "BforSpectroscopy_BdToD0barPiPi_K3Pi", + ["D~0", "D0"], + ) + ] + + + line_name = 'SpruceBandQ_BdForSpectroscopy' + HLT2_decision = line_name.replace("Spruce", "Hlt2") + "FullDecision" + my_filter = line_prefilter(HLT2_decision) + + + algs = {} #[my_filter] + + for decay_config in decays: + + decay_descriptor, composite_list, stable_list, decay_name, ParticleToConstrain = decay_config + algs[decay_name] = [my_filter, template(decay_descriptor, line_name, False, HLT2_lines+[HLT2_decision], composite_list, stable_list, decay_name, ParticleToConstrain)] + + return algs + + +def Bs(): + + # BsToJpsiKK = make_BsToJpsiKK(process) + # BsToDsmPip = make_BsToDsmPip(process) + # BsToDsmPipPipPim = make_BsToDsmPipPipPim(process) + # BsToD0bKmPip = make_BsToD0bKmPip(process) + + decays = [ + # Bs -> J/psi K+ K- decay + ( + { + "Bs": "[B_s0 -> (J/psi(1S) -> mu+ mu-) K+ K-]CC", + "Jpsi": "[B_s0 -> ^(J/psi(1S) -> mu+ mu-) K+ K-]CC", + "Jpsi_mup": "[B_s0 -> (J/psi(1S) -> ^mu+ mu-) K+ K-]CC", + "Jpsi_mum": "[B_s0 -> (J/psi(1S) -> mu+ ^mu-) K+ K-]CC", + "Bs_K1": "[B_s0 -> (J/psi(1S) -> mu+ mu-) ^K+ K-]CC", + "Bs_K2": "[B_s0 -> (J/psi(1S) -> mu+ mu-) K+ ^K-]CC" + }, + ["Bs", "Jpsi"], + ["Jpsi_mup", "Jpsi_mum", "Bs_K1", "Bs_K2"], + "BforSpectroscopy_BsToJpsiKK", + ["J/psi(1S)", "Jpsi"], + ), + + # Bs -> D_s- pi+ decay (corrected) + ( + { + "Bs": "[B_s0 -> (D_s- -> K- K+ pi-) pi+]CC", + "Ds": "[B_s0 -> ^(D_s- -> K- K+ pi-) pi+]CC", + "Ds_K1": "[B_s0 -> (D_s- -> ^K- K+ pi-) pi+]CC", + "Ds_K2": "[B_s0 -> (D_s- -> K- ^K+ pi-) pi+]CC", + "Ds_Pi1": "[B_s0 -> (D_s- -> K- K+ ^pi-) pi+]CC", + "Bs_Pi1": "[B_s0 -> (D_s- -> K- K+ pi-) ^pi+]CC" + }, + ["Bs", "Ds"], + ["Ds_K1", "Ds_K2", "Ds_Pi1", "Bs_Pi1"], + "BforSpectroscopy_BsToDsmPip", + ["D_s-", "Ds"], + ), + + # Bs -> D_s- pi+ pi+ pi- decay (corrected) + ( + { + "Bs": "[B_s0 -> (D_s- -> K- K+ pi-) pi+ pi+ pi-]CC", + "Ds": "[B_s0 -> ^(D_s- -> K- K+ pi-) pi+ pi+ pi-]CC", + "Ds_K1": "[B_s0 -> (D_s- -> ^K- K+ pi-) pi+ pi+ pi-]CC", + "Ds_K2": "[B_s0 -> (D_s- -> K- ^K+ pi-) pi+ pi+ pi-]CC", + "Ds_Pi1": "[B_s0 -> (D_s- -> K- K+ ^pi-) pi+ pi+ pi-]CC", + "Bs_Pi1": "[B_s0 -> (D_s- -> K- K+ pi-) ^pi+ pi+ pi-]CC", + "Bs_Pi2": "[B_s0 -> (D_s- -> K- K+ pi-) pi+ ^pi+ pi-]CC", + "Bs_Pi3": "[B_s0 -> (D_s- -> K- K+ pi-) pi+ pi+ ^pi-]CC" + }, + ["Bs", "Ds"], + ["Ds_K1", "Ds_K2", "Ds_Pi1", "Bs_Pi1", "Bs_Pi2", "Bs_Pi3"], + "BforSpectroscopy_BsToDsmPipPipPim", + ["D_s-", "Ds"], + ), + + # Bs -> D0bar K- pi+, with D0bar -> K+ pi- pi+ pi- + ( + { + "Bs": "[B_s0 -> (D~0 -> K+ pi- pi+ pi-) K- pi+]CC", + "D0": "[B_s0 -> ^(D~0 -> K+ pi- pi+ pi-) K- pi+]CC", + "D0_K1": "[B_s0 -> (D~0 -> ^K+ pi- pi+ pi-) K- pi+]CC", + "D0_Pi1": "[B_s0 -> (D~0 -> K+ ^pi- pi+ pi-) K- pi+]CC", + "D0_Pi2": "[B_s0 -> (D~0 -> K+ pi- ^pi+ pi-) K- pi+]CC", + "D0_Pi3": "[B_s0 -> (D~0 -> K+ pi- pi+ ^pi-) K- pi+]CC", + "Bs_K1": "[B_s0 -> (D~0 -> K+ pi- pi+ pi-) ^K- pi+]CC", + "Bs_Pi1": "[B_s0 -> (D~0 -> K+ pi- pi+ pi-) K- ^pi+]CC" + }, + ["Bs", "D0"], + ["D0_K1", "D0_Pi1", "D0_Pi2", "D0_Pi3", "Bs_K1", "Bs_Pi1"], + "BforSpectroscopy_BsToD0bKmPip_K3Pi", + ["D~0", "D0"], + ), + + # Bs -> D~0 K- pi+ decay + ( + { + "Bs": "[B_s0 -> (D~0 -> K+ pi-) K- pi+]CC", + "D0": "[B_s0 -> ^(D~0 -> K+ pi-) K- pi+]CC", + "D0_K1": "[B_s0 -> (D~0 -> ^K+ pi-) K- pi+]CC", + "D0_Pi1": "[B_s0 -> (D~0 -> K+ ^pi-) K- pi+]CC", + "Bs_K1": "[B_s0 -> (D~0 -> K+ pi-) ^K- pi+]CC", + "Bs_Pi1": "[B_s0 -> (D~0 -> K+ pi-) K- ^pi+]CC" + }, + ["Bs", "D0"], + ["D0_K1", "D0_Pi1", "Bs_K1", "Bs_Pi1"], + "BforSpectroscopy_BsToD0bKmPip", + ["D~0", "D0"], + ) + ] + + + line_name = 'SpruceBandQ_BsForSpectroscopy' + HLT2_decision = line_name.replace("Spruce", "Hlt2") + "FullDecision" + my_filter = line_prefilter(HLT2_decision) + + algs = {} #[my_filter] + + for decay_config in decays: + + decay_descriptor, composite_list, stable_list, decay_name, ParticleToConstrain = decay_config + algs[decay_name] = [my_filter, template(decay_descriptor, line_name, False, HLT2_lines+[HLT2_decision], composite_list, stable_list, decay_name, ParticleToConstrain)] + + return algs + + +def Bc(): + + # BcToJpsiPi = make_BcToJpsiPi(process) + # BcToJpsiPiPiPi = make_BcToJpsiPiPiPi(process) + + decays = [ + # Bc -> J/psi pi+ decay + ( + { + "Bc": "[B_c+ -> (J/psi(1S) -> mu+ mu-) pi+]CC", + "Jpsi": "[B_c+ -> ^(J/psi(1S) -> mu+ mu-) pi+]CC", + "Jpsi_mup": "[B_c+ -> (J/psi(1S) -> ^mu+ mu-) pi+]CC", + "Jpsi_mum": "[B_c+ -> (J/psi(1S) -> mu+ ^mu-) pi+]CC", + "Bc_Pi1": "[B_c+ -> (J/psi(1S) -> mu+ mu-) ^pi+]CC" + }, + ["Bc", "Jpsi"], + ["Jpsi_mup", "Jpsi_mum", "Bc_Pi1"], + "BforSpectroscopy_BcToJpsiPi", + ["J/psi(1S)", "Jpsi"], + ), + + # Bc -> J/psi pi+ pi+ pi- decay + ( + { + "Bc": "[B_c+ -> (J/psi(1S) -> mu+ mu-) pi+ pi+ pi-]CC", + "Jpsi": "[B_c+ -> ^(J/psi(1S) -> mu+ mu-) pi+ pi+ pi-]CC", + "Jpsi_mup": "[B_c+ -> (J/psi(1S) -> ^mu+ mu-) pi+ pi+ pi-]CC", + "Jpsi_mum": "[B_c+ -> (J/psi(1S) -> mu+ ^mu-) pi+ pi+ pi-]CC", + "Bc_Pi1": "[B_c+ -> (J/psi(1S) -> mu+ mu-) ^pi+ pi+ pi-]CC", + "Bc_Pi2": "[B_c+ -> (J/psi(1S) -> mu+ mu-) pi+ ^pi+ pi-]CC", + "Bc_Pi3": "[B_c+ -> (J/psi(1S) -> mu+ mu-) pi+ pi+ ^pi-]CC" + }, + ["Bc", "Jpsi"], + ["Jpsi_mup", "Jpsi_mum", "Bc_Pi1", "Bc_Pi2", "Bc_Pi3"], + "BforSpectroscopy_BcToJpsiPiPiPi", + ["J/psi(1S)", "Jpsi"], + ) + ] + + + line_name = 'SpruceBandQ_BcForSpectroscopy' + HLT2_decision = line_name.replace("Spruce", "Hlt2") + "FullDecision" + my_filter = line_prefilter(HLT2_decision) + + algs = {} #[my_filter] + + for decay_config in decays: + + decay_descriptor, composite_list, stable_list, decay_name, ParticleToConstrain = decay_config + algs[decay_name] = [my_filter, template(decay_descriptor, line_name, False, HLT2_lines+[HLT2_decision], composite_list, stable_list, decay_name, ParticleToConstrain)] + + return algs + + +def Lb(): + + # LbToJpsiPK = make_LbToJpsiPK(process) + # LbToLcPim = make_LbToLcPim(process) + # LbToLcPipPimPim = make_LbToLcPipPimPim(process) + decays = [ + # Lb -> J/psi p+ K- decay + ( + { + "Lb": "[Lambda_b0 -> (J/psi(1S) -> mu+ mu-) p+ K-]CC", + "Jpsi": "[Lambda_b0 -> ^(J/psi(1S) -> mu+ mu-) p+ K-]CC", + "Jpsi_mup": "[Lambda_b0 -> (J/psi(1S) -> ^mu+ mu-) p+ K-]CC", + "Jpsi_mum": "[Lambda_b0 -> (J/psi(1S) -> mu+ ^mu-) p+ K-]CC", + "Lb_P1": "[Lambda_b0 -> (J/psi(1S) -> mu+ mu-) ^p+ K-]CC", + "Lb_K1": "[Lambda_b0 -> (J/psi(1S) -> mu+ mu-) p+ ^K-]CC" + }, + ["Lb", "Jpsi"], + ["Jpsi_mup", "Jpsi_mum", "Lb_P1", "Lb_K1"], + "BforSpectroscopy_LbToJpsiPK", + ["J/psi(1S)", "Jpsi"], + ), + + # Lb -> Lc+ pi- decay, with Lc+ -> p+ K- pi+ + ( + { + "Lb": "[Lambda_b0 -> (Lambda_c+ -> p+ K- pi+) pi-]CC", + "Lc": "[Lambda_b0 -> ^(Lambda_c+ -> p+ K- pi+) pi-]CC", + "Lc_P1": "[Lambda_b0 -> (Lambda_c+ -> ^p+ K- pi+) pi-]CC", + "Lc_K1": "[Lambda_b0 -> (Lambda_c+ -> p+ ^K- pi+) pi-]CC", + "Lc_Pi1": "[Lambda_b0 -> (Lambda_c+ -> p+ K- ^pi+) pi-]CC", + "Lb_Pi1": "[Lambda_b0 -> (Lambda_c+ -> p+ K- pi+) ^pi-]CC" + }, + ["Lb", "Lc"], + ["Lc_P1", "Lc_K1", "Lc_Pi1", "Lb_Pi1"], + "BforSpectroscopy_LbToLcPim", + ["Lambda_c+", "Lc"], + ), + + # Lb -> Lc+ pi+ pi- pi-, with Lc+ -> p+ K- pi+ + ( + { + "Lb": "[Lambda_b0 -> (Lambda_c+ -> p+ K- pi+) pi+ pi- pi-]CC", + "Lc": "[Lambda_b0 -> ^(Lambda_c+ -> p+ K- pi+) pi+ pi- pi-]CC", + "Lc_P1": "[Lambda_b0 -> (Lambda_c+ -> ^p+ K- pi+) pi+ pi- pi-]CC", + "Lc_K1": "[Lambda_b0 -> (Lambda_c+ -> p+ ^K- pi+) pi+ pi- pi-]CC", + "Lc_Pi1": "[Lambda_b0 -> (Lambda_c+ -> p+ K- ^pi+) pi+ pi- pi-]CC", + "Lb_Pi1": "[Lambda_b0 -> (Lambda_c+ -> p+ K- pi+) ^pi+ pi- pi-]CC", + "Lb_Pi2": "[Lambda_b0 -> (Lambda_c+ -> p+ K- pi+) pi+ ^pi- pi-]CC", + "Lb_Pi3": "[Lambda_b0 -> (Lambda_c+ -> p+ K- pi+) pi+ pi- ^pi-]CC" + }, + ["Lb", "Lc"], + ["Lc_P1", "Lc_K1", "Lc_Pi1", "Lb_Pi1", "Lb_Pi2", "Lb_Pi3"], + "BforSpectroscopy_LbToLcPipPimPim", + ["Lambda_c+", "Lc"], + ) + ] + + line_name = 'SpruceBandQ_LbForSpectroscopy' + HLT2_decision = line_name.replace("Spruce", "Hlt2") + "FullDecision" + my_filter = line_prefilter(HLT2_decision) + + algs = {} #[my_filter] + + for decay_config in decays: + + decay_descriptor, composite_list, stable_list, decay_name, ParticleToConstrain = decay_config + algs[decay_name] = [my_filter, template(decay_descriptor, line_name, False, HLT2_lines+[HLT2_decision], composite_list, stable_list, decay_name, ParticleToConstrain)] + + return algs + + +def Xibm(): + + # XibmToJpsiXi = make_XibmToJpsiXi(process) + # XibmToJpsiPKK = make_XibmToJpsiPKK(process) + + # XibmToXic0Pim = make_XibmToXic0Pim(process) + # XibmToLcKmPim = make_XibmToLcKmPim(process) + + decays = [ + # Xibm -> J/psi Xi-, with Xi- -> Lambda0 pi-, Lambda0 -> p pi- + ( + { + "Xibm": "[Xi_b- -> (J/psi(1S) -> mu+ mu-) (Xi- -> (Lambda0 -> p+ pi-) pi-)]CC", + "Jpsi": "[Xi_b- -> ^(J/psi(1S) -> mu+ mu-) (Xi- -> (Lambda0 -> p+ pi-) pi-)]CC", + "Jpsi_mup": "[Xi_b- -> (J/psi(1S) -> ^mu+ mu-) (Xi- -> (Lambda0 -> p+ pi-) pi-)]CC", + "Jpsi_mum": "[Xi_b- -> (J/psi(1S) -> mu+ ^mu-) (Xi- -> (Lambda0 -> p+ pi-) pi-)]CC", + "Xi": "[Xi_b- -> (J/psi(1S) -> mu+ mu-) ^(Xi- -> (Lambda0 -> p+ pi-) pi-)]CC", + "Lambda": "[Xi_b- -> (J/psi(1S) -> mu+ mu-) (Xi- -> ^(Lambda0 -> p+ pi-) pi-)]CC", + "Lambda_P1": "[Xi_b- -> (J/psi(1S) -> mu+ mu-) (Xi- -> (Lambda0 -> ^p+ pi-) pi-)]CC", + "Lambda_Pi1": "[Xi_b- -> (J/psi(1S) -> mu+ mu-) (Xi- -> (Lambda0 -> p+ ^pi-) pi-)]CC", + "Xi_Pi1": "[Xi_b- -> (J/psi(1S) -> mu+ mu-) (Xi- -> (Lambda0 -> p+ pi-) ^pi-)]CC" + }, + ["Xibm", "Jpsi", "Xi", "Lambda"], + ["Jpsi_mup", "Jpsi_mum", "Lambda_P1", "Lambda_Pi1", "Xi_Pi1"], + "BforSpectroscopy_XibmToJpsiXi", + ["J/psi(1S)", "Jpsi"], + ), + + # Xibm -> J/psi p+ K- K- decay + ( + { + "Xibm": "[Xi_b- -> (J/psi(1S) -> mu+ mu-) p+ K- K-]CC", + "Jpsi": "[Xi_b- -> ^(J/psi(1S) -> mu+ mu-) p+ K- K-]CC", + "Jpsi_mup": "[Xi_b- -> (J/psi(1S) -> ^mu+ mu-) p+ K- K-]CC", + "Jpsi_mum": "[Xi_b- -> (J/psi(1S) -> mu+ ^mu-) p+ K- K-]CC", + "Xibm_P1": "[Xi_b- -> (J/psi(1S) -> mu+ mu-) ^p+ K- K-]CC", + "Xibm_K1": "[Xi_b- -> (J/psi(1S) -> mu+ mu-) p+ ^K- K-]CC", + "Xibm_K2": "[Xi_b- -> (J/psi(1S) -> mu+ mu-) p+ K- ^K-]CC" + }, + ["Xibm", "Jpsi"], + ["Jpsi_mup", "Jpsi_mum", "Xibm_P1", "Xibm_K1", "Xibm_K2"], + "BforSpectroscopy_XibmToJpsiPKK", + ["J/psi(1S)", "Jpsi"], + ), + + # Xibm -> Xic0 pi-, with Xic0 -> p+ K- K- pi+ + ( + { + "Xibm": "[Xi_b- -> (Xi_c0 -> p+ K- K- pi+) pi-]CC", + "Xic0": "[Xi_b- -> ^(Xi_c0 -> p+ K- K- pi+) pi-]CC", + "Xic0_P1": "[Xi_b- -> (Xi_c0 -> ^p+ K- K- pi+) pi-]CC", + "Xic0_K1": "[Xi_b- -> (Xi_c0 -> p+ ^K- K- pi+) pi-]CC", + "Xic0_K2": "[Xi_b- -> (Xi_c0 -> p+ K- ^K- pi+) pi-]CC", + "Xic0_Pi1": "[Xi_b- -> (Xi_c0 -> p+ K- K- ^pi+) pi-]CC", + "Xibm_Pi1": "[Xi_b- -> (Xi_c0 -> p+ K- K- pi+) ^pi-]CC" + }, + ["Xibm", "Xic0"], + ["Xic0_P1", "Xic0_K1", "Xic0_K2", "Xic0_Pi1", "Xibm_Pi1"], + "BforSpectroscopy_XibmToXic0Pim", + ["Xi_c0", "Xic0"], + ), + + # Xibm -> Lambda_c+ K- pi-, with Lambda_c+ -> p+ K- pi+ + ( + { + "Xibm": "[Xi_b- -> (Lambda_c+ -> p+ K- pi+) K- pi-]CC", + "Lc": "[Xi_b- -> ^(Lambda_c+ -> p+ K- pi+) K- pi-]CC", + "Lc_P1": "[Xi_b- -> (Lambda_c+ -> ^p+ K- pi+) K- pi-]CC", + "Lc_K1": "[Xi_b- -> (Lambda_c+ -> p+ ^K- pi+) K- pi-]CC", + "Lc_Pi1": "[Xi_b- -> (Lambda_c+ -> p+ K- ^pi+) K- pi-]CC", + "Xibm_K1": "[Xi_b- -> (Lambda_c+ -> p+ K- pi+) ^K- pi-]CC", + "Xibm_Pi1": "[Xi_b- -> (Lambda_c+ -> p+ K- pi+) K- ^pi-]CC" + }, + ["Xibm", "Lc"], + ["Lc_P1", "Lc_K1", "Lc_Pi1", "Xibm_K1", "Xibm_Pi1"], + "BforSpectroscopy_XibmToLcKmPim", + ["Lambda_c+", "Lc"], + ) + ] + + + line_name = 'SpruceBandQ_XibmForSpectroscopy' + HLT2_decision = line_name.replace("Spruce", "Hlt2") + "FullDecision" + my_filter = line_prefilter(HLT2_decision) + + algs = {} #[my_filter] + + for decay_config in decays: + + decay_descriptor, composite_list, stable_list, decay_name, ParticleToConstrain = decay_config + algs[decay_name] = [my_filter, template(decay_descriptor, line_name, False, HLT2_lines+[HLT2_decision], composite_list, stable_list, decay_name, ParticleToConstrain)] + + return algs + + +def Xib0(): + + # Xib0ToJpsiXiPi = make_Xib0ToJpsiXiPi(process) + # Xib0ToJpsiPKKPi = make_Xib0ToJpsiPKKPi(process) + + # Xib0ToXicpPim = make_Xib0ToXicpPim(process) + # Xib0ToLcKmPipPim = make_Xib0ToLcKmPipPim(process) + + decays = [ + # Xib0 -> J/psi Xi- pi+, with Xi- -> Lambda0 pi-, Lambda0 -> p+ pi- + ( + { + "Xib0": "[Xi_b0 -> (J/psi(1S) -> mu+ mu-) (Xi- -> (Lambda0 -> p+ pi-) pi-) pi+]CC", + "Jpsi": "[Xi_b0 -> ^(J/psi(1S) -> mu+ mu-) (Xi- -> (Lambda0 -> p+ pi-) pi-) pi+]CC", + "Jpsi_mup": "[Xi_b0 -> (J/psi(1S) -> ^mu+ mu-) (Xi- -> (Lambda0 -> p+ pi-) pi-) pi+]CC", + "Jpsi_mum": "[Xi_b0 -> (J/psi(1S) -> mu+ ^mu-) (Xi- -> (Lambda0 -> p+ pi-) pi-) pi+]CC", + "Xi": "[Xi_b0 -> (J/psi(1S) -> mu+ mu-) ^(Xi- -> (Lambda0 -> p+ pi-) pi-) pi+]CC", + "Lambda": "[Xi_b0 -> (J/psi(1S) -> mu+ mu-) (Xi- -> ^(Lambda0 -> p+ pi-) pi-) pi+]CC", + "Lambda_P1": "[Xi_b0 -> (J/psi(1S) -> mu+ mu-) (Xi- -> (Lambda0 -> ^p+ pi-) pi-) pi+]CC", + "Lambda_Pi1": "[Xi_b0 -> (J/psi(1S) -> mu+ mu-) (Xi- -> (Lambda0 -> p+ ^pi-) pi-) pi+]CC", + "Xi_Pi1": "[Xi_b0 -> (J/psi(1S) -> mu+ mu-) (Xi- -> (Lambda0 -> p+ pi-) ^pi-) pi+]CC", + "Xib0_Pi1": "[Xi_b0 -> (J/psi(1S) -> mu+ mu-) (Xi- -> (Lambda0 -> p+ pi-) pi-) ^pi+]CC" + }, + ["Xib0", "Jpsi", "Xi", "Lambda"], + ["Jpsi_mup", "Jpsi_mum", "Lambda_P1", "Lambda_Pi1", "Xi_Pi1", "Xib0_Pi1"], + "BforSpectroscopy_Xib0ToJpsiXiPi", + ["J/psi(1S)", "Jpsi"], + ), + + # Xib0 -> J/psi p+ K- K- pi+ + ( + { + "Xib0": "[Xi_b0 -> (J/psi(1S) -> mu+ mu-) p+ K- K- pi+]CC", + "Jpsi": "[Xi_b0 -> ^(J/psi(1S) -> mu+ mu-) p+ K- K- pi+]CC", + "Jpsi_mup": "[Xi_b0 -> (J/psi(1S) -> ^mu+ mu-) p+ K- K- pi+]CC", + "Jpsi_mum": "[Xi_b0 -> (J/psi(1S) -> mu+ ^mu-) p+ K- K- pi+]CC", + "Xib0_P1": "[Xi_b0 -> (J/psi(1S) -> mu+ mu-) ^p+ K- K- pi+]CC", + "Xib0_K1": "[Xi_b0 -> (J/psi(1S) -> mu+ mu-) p+ ^K- K- pi+]CC", + "Xib0_K2": "[Xi_b0 -> (J/psi(1S) -> mu+ mu-) p+ K- ^K- pi+]CC", + "Xib0_Pi1": "[Xi_b0 -> (J/psi(1S) -> mu+ mu-) p+ K- K- ^pi+]CC" + }, + ["Xib0", "Jpsi"], + ["Jpsi_mup", "Jpsi_mum", "Xib0_P1", "Xib0_K1", "Xib0_K2", "Xib0_Pi1"], + "BforSpectroscopy_Xib0ToJpsiPKKPi", + ["J/psi(1S)", "Jpsi"], + ), + + # Xib0 -> Xic+ pi-, with Xic+ -> p+ K- pi+ + ( + { + "Xib0": "[Xi_b0 -> (Xi_c+ -> p+ K- pi+) pi-]CC", + "Xicp": "[Xi_b0 -> ^(Xi_c+ -> p+ K- pi+) pi-]CC", + "Xicp_P1": "[Xi_b0 -> (Xi_c+ -> ^p+ K- pi+) pi-]CC", + "Xicp_K1": "[Xi_b0 -> (Xi_c+ -> p+ ^K- pi+) pi-]CC", + "Xicp_Pi1": "[Xi_b0 -> (Xi_c+ -> p+ K- ^pi+) pi-]CC", + "Xib0_Pi1": "[Xi_b0 -> (Xi_c+ -> p+ K- pi+) ^pi-]CC" + }, + ["Xib0", "Xicp"], + ["Xicp_P1", "Xicp_K1", "Xicp_Pi1", "Xib0_Pi1"], + "BforSpectroscopy_Xib0ToXicpPim", + ["Xi_c+", "Xicp"], + ), + + # Xib0 -> Lambda_c+ K- pi+ pi-, with Lambda_c+ -> p+ K- pi+ + ( + { + "Xib0": "[Xi_b0 -> (Lambda_c+ -> p+ K- pi+) K- pi+ pi-]CC", + "Lc": "[Xi_b0 -> ^(Lambda_c+ -> p+ K- pi+) K- pi+ pi-]CC", + "Lc_P1": "[Xi_b0 -> (Lambda_c+ -> ^p+ K- pi+) K- pi+ pi-]CC", + "Lc_K1": "[Xi_b0 -> (Lambda_c+ -> p+ ^K- pi+) K- pi+ pi-]CC", + "Lc_Pi1": "[Xi_b0 -> (Lambda_c+ -> p+ K- ^pi+) K- pi+ pi-]CC", + "Xib0_K1": "[Xi_b0 -> (Lambda_c+ -> p+ K- pi+) ^K- pi+ pi-]CC", + "Xib0_Pi1": "[Xi_b0 -> (Lambda_c+ -> p+ K- pi+) K- ^pi+ pi-]CC", + "Xib0_Pi2": "[Xi_b0 -> (Lambda_c+ -> p+ K- pi+) K- pi+ ^pi-]CC" + }, + ["Xib0", "Lc"], + ["Lc_P1", "Lc_K1", "Lc_Pi1", "Xib0_K1", "Xib0_Pi1", "Xib0_Pi2"], + "BforSpectroscopy_Xib0ToLcKmPipPim", + ["Lambda_c+", "Lc"], + ) + ] + + + line_name = 'SpruceBandQ_Xib0ForSpectroscopy' + HLT2_decision = line_name.replace("Spruce", "Hlt2") + "FullDecision" + my_filter = line_prefilter(HLT2_decision) + + algs = {} #[my_filter] + + for decay_config in decays: + + decay_descriptor, composite_list, stable_list, decay_name, ParticleToConstrain = decay_config + algs[decay_name] = [my_filter, template(decay_descriptor, line_name, False, HLT2_lines+[HLT2_decision], composite_list, stable_list, decay_name, ParticleToConstrain )] + + return algs + + +def Omegab(): + + # OmegabToJpsiOmega = make_OmegabToJpsiOmega(process) + # OmegabToJpsiPKKKPi = make_OmegabToJpsiPKKKPi(process) + # OmbToOmcPim = make_OmbToOmcPim(process) + # OmbToXicpKmPim = make_OmbToXicpKmPim(process) + # OmbToLcpKmKmPipPim = make_OmbToLcpKmKmPipPim(process) + + decays = [ + # Omegab -> J/psi Omega-, with Omega- -> (Lambda0 -> p+ pi-) K- + ( + { + "Omegab": "[Omega_b- -> (J/psi(1S) -> mu+ mu-) (Omega- -> (Lambda0 -> p+ pi-) K-)]CC", + "Jpsi": "[Omega_b- -> ^(J/psi(1S) -> mu+ mu-) (Omega- -> (Lambda0 -> p+ pi-) K-)]CC", + "Jpsi_mup": "[Omega_b- -> (J/psi(1S) -> ^mu+ mu-) (Omega- -> (Lambda0 -> p+ pi-) K-)]CC", + "Jpsi_mum": "[Omega_b- -> (J/psi(1S) -> mu+ ^mu-) (Omega- -> (Lambda0 -> p+ pi-) K-)]CC", + "Omega": "[Omega_b- -> (J/psi(1S) -> mu+ mu-) ^(Omega- -> (Lambda0 -> p+ pi-) K-)]CC", + "Lambda": "[Omega_b- -> (J/psi(1S) -> mu+ mu-) (Omega- -> ^(Lambda0 -> p+ pi-) K-)]CC", + "Lambda_P1": "[Omega_b- -> (J/psi(1S) -> mu+ mu-) (Omega- -> (Lambda0 -> ^p+ pi-) K-)]CC", + "Lambda_Pi1": "[Omega_b- -> (J/psi(1S) -> mu+ mu-) (Omega- -> (Lambda0 -> p+ ^pi-) K-)]CC", + "Omega_K1": "[Omega_b- -> (J/psi(1S) -> mu+ mu-) (Omega- -> (Lambda0 -> p+ pi-) ^K-)]CC" + }, + ["Omegab", "Jpsi", "Omega", "Lambda"], + ["Jpsi_mup", "Jpsi_mum", "Lambda_P1", "Lambda_Pi1", "Omega_K1"], + "BforSpectroscopy_OmegabToJpsiOmega", + ["J/psi(1S)", "Jpsi"], + ), + + # Omegab -> J/psi p+ K- K- K- pi+ + ( + { + "Omegab": "[Omega_b- -> (J/psi(1S) -> mu+ mu-) p+ K- K- K- pi+]CC", + "Jpsi": "[Omega_b- -> ^(J/psi(1S) -> mu+ mu-) p+ K- K- K- pi+]CC", + "Jpsi_mup": "[Omega_b- -> (J/psi(1S) -> ^mu+ mu-) p+ K- K- K- pi+]CC", + "Jpsi_mum": "[Omega_b- -> (J/psi(1S) -> mu+ ^mu-) p+ K- K- K- pi+]CC", + "Omegab_P1": "[Omega_b- -> (J/psi(1S) -> mu+ mu-) ^p+ K- K- K- pi+]CC", + "Omegab_K1": "[Omega_b- -> (J/psi(1S) -> mu+ mu-) p+ ^K- K- K- pi+]CC", + "Omegab_K2": "[Omega_b- -> (J/psi(1S) -> mu+ mu-) p+ K- ^K- K- pi+]CC", + "Omegab_K3": "[Omega_b- -> (J/psi(1S) -> mu+ mu-) p+ K- K- ^K- pi+]CC", + "Omegab_Pi1": "[Omega_b- -> (J/psi(1S) -> mu+ mu-) p+ K- K- K- ^pi+]CC" + }, + ["Omegab", "Jpsi"], + ["Jpsi_mup", "Jpsi_mum", "Omegab_P1", "Omegab_K1", "Omegab_K2", "Omegab_K3", "Omegab_Pi1"], + "BforSpectroscopy_OmegabToJpsiPKKKPi", + ["J/psi(1S)", "Jpsi"], + ), + + # Omb -> Omega_c0 pi-, with Omega_c0 -> p+ K- K- pi+ + ( + { + "Omegab": "[Omega_b- -> (Omega_c0 -> p+ K- K- pi+) pi-]CC", + "Omegac": "[Omega_b- -> ^(Omega_c0 -> p+ K- K- pi+) pi-]CC", + "Omegac_P1": "[Omega_b- -> (Omega_c0 -> ^p+ K- K- pi+) pi-]CC", + "Omegac_K1": "[Omega_b- -> (Omega_c0 -> p+ ^K- K- pi+) pi-]CC", + "Omegac_K2": "[Omega_b- -> (Omega_c0 -> p+ K- ^K- pi+) pi-]CC", + "Omegac_Pi1": "[Omega_b- -> (Omega_c0 -> p+ K- K- ^pi+) pi-]CC", + "Omegab_Pi1": "[Omega_b- -> (Omega_c0 -> p+ K- K- pi+) ^pi-]CC" + }, + ["Omegab", "Omegac"], + ["Omegac_P1", "Omegac_K1", "Omegac_K2", "Omegac_Pi1", "Omegab_Pi1"], + "BforSpectroscopy_OmegabToOmcPim", + ["Omega_c0", "Omegac"], + ), + + # Omb -> Xic+ K- pi-, with Xic+ -> p+ K- pi+ + ( + { + "Omegab": "[Omega_b- -> (Xi_c+ -> p+ K- pi+) K- pi-]CC", + "Xic": "[Omega_b- -> ^(Xi_c+ -> p+ K- pi+) K- pi-]CC", + "Xic_P1": "[Omega_b- -> (Xi_c+ -> ^p+ K- pi+) K- pi-]CC", + "Xic_K1": "[Omega_b- -> (Xi_c+ -> p+ ^K- pi+) K- pi-]CC", + "Xic_Pi1": "[Omega_b- -> (Xi_c+ -> p+ K- ^pi+) K- pi-]CC", + "Omegab_K1": "[Omega_b- -> (Xi_c+ -> p+ K- pi+) ^K- pi-]CC", + "Omegab_Pi1": "[Omega_b- -> (Xi_c+ -> p+ K- pi+) K- ^pi-]CC" + }, + ["Omegab", "Xic"], + ["Xic_P1", "Xic_K1", "Xic_Pi1", "Omegab_K1", "Omegab_Pi1"], + "BforSpectroscopy_OmegabToXicpKmPim", + ["Xi_c+", "Xic"], + ), + + # Omb -> Lambda_c+ K- K- pi+ pi-, with Lambda_c+ -> p+ K- pi+ + ( + { + "Omegab": "[Omega_b- -> (Lambda_c+ -> p+ K- pi+) K- K- pi+ pi-]CC", + "Lc": "[Omega_b- -> ^(Lambda_c+ -> p+ K- pi+) K- K- pi+ pi-]CC", + "Lc_P1": "[Omega_b- -> (Lambda_c+ -> ^p+ K- pi+) K- K- pi+ pi-]CC", + "Lc_K1": "[Omega_b- -> (Lambda_c+ -> p+ ^K- pi+) K- K- pi+ pi-]CC", + "Lc_Pi1": "[Omega_b- -> (Lambda_c+ -> p+ K- ^pi+) K- K- pi+ pi-]CC", + "Omegab_K1": "[Omega_b- -> (Lambda_c+ -> p+ K- pi+) ^K- K- pi+ pi-]CC", + "Omegab_K2": "[Omega_b- -> (Lambda_c+ -> p+ K- pi+) K- ^K- pi+ pi-]CC", + "Omegab_Pi1": "[Omega_b- -> (Lambda_c+ -> p+ K- pi+) K- K- ^pi+ pi-]CC", + "Omegab_Pi2": "[Omega_b- -> (Lambda_c+ -> p+ K- pi+) K- K- pi+ ^pi-]CC" + }, + ["Omegab", "Lc"], + ["Lc_P1", "Lc_K1", "Lc_Pi1", "Omegab_K1", "Omegab_K2", "Omegab_Pi1", "Omegab_Pi2"], + "BforSpectroscopy_OmegabToLcpKmKmPipPim", + ["Lambda_c+", "Lc"], + ) + ] + + + line_name = 'SpruceBandQ_OmegabForSpectroscopy' + HLT2_decision = line_name.replace("Spruce", "Hlt2") + "FullDecision" + my_filter = line_prefilter(HLT2_decision) + + algs = {} #[my_filter] + + for decay_config in decays: + + decay_descriptor, composite_list, stable_list, decay_name, ParticleToConstrain = decay_config + algs[decay_name] = [my_filter, template(decay_descriptor, line_name, False, HLT2_lines+[HLT2_decision], composite_list, stable_list, decay_name, ParticleToConstrain)] + + return algs + + +def SL(): + + decays = [ + # Bu -> D0 mu+ decay, with D0 -> K- pi+ + ( + { + "Bu": "[B+ -> (D~0 -> K+ pi-) mu+]CC", + "D0": "[B+ -> ^(D~0 -> K+ pi-) mu+]CC", + "D0_K1": "[B+ -> (D~0 -> ^K+ pi-) mu+]CC", + "D0_Pi1": "[B+ -> (D~0 -> K+ ^pi-) mu+]CC", + "D0_mu1" : "[B+ -> (D~0 -> K+ pi-) ^mu+]CC" + }, + ["Bu", "D0"], + ["D0_K1", "D0_Pi1", "D0_mu1"], + "BforSpectroscopy_BuToD0mu", + ["D~0", "D0"], + ), + # Bd -> D+ mu- decay, with D+ -> K- pi+ pi+ + ( + { + "Bd": "[B0 -> (D- -> K+ pi- pi-) mu+]CC", + "Dm": "[B0 -> ^(D- -> K+ pi- pi-) mu+]CC", + "Dm_K1": "[B0 -> (D- -> ^K+ pi- pi-) mu+]CC", + "Dm_Pi1": "[B0 -> (D- -> K+ ^pi- pi-) mu+]CC", + "Dm_Pi2": "[B0 -> (D- -> K+ pi- ^pi-) mu+]CC", + "Bd_mu1" : "[B0 -> (D- -> K+ pi- pi-) ^mu+]CC" + }, + ["Bd", "Dm"], + ["Dm_K1", "Dm_Pi1", "Dm_Pi2", "Bd_mu1"], + "BforSpectroscopy_BdToDmmu", + ["D-", "Dm"], + ), + # Bs -> D_s- mu+ decay (corrected) + ( + { + "Bs": "[B_s0 -> (D_s- -> K- K+ pi-) mu+]CC", + "Ds": "[B_s0 -> ^(D_s- -> K- K+ pi-) mu+]CC", + "Ds_K1": "[B_s0 -> (D_s- -> ^K- K+ pi-) mu+]CC", + "Ds_K2": "[B_s0 -> (D_s- -> K- ^K+ pi-) mu+]CC", + "Ds_Pi1": "[B_s0 -> (D_s- -> K- K+ ^pi-) mu+]CC", + "Bs_mu1": "[B_s0 -> (D_s- -> K- K+ pi-) ^mu+]CC" + }, + ["Bs", "Ds"], + ["Ds_K1", "Ds_K2", "Ds_Pi1", "Bs_mu1"], + "BforSpectroscopy_BsToDsmmu", + ["D_s-", "Ds"], + ), + # Bc -> J/psi mu+ decay + ( + { + "Bc": "[B_c+ -> (J/psi(1S) -> mu+ mu-) mu+]CC", + "Jpsi": "[B_c+ -> ^(J/psi(1S) -> mu+ mu-) mu+]CC", + "Jpsi_mup": "[B_c+ -> (J/psi(1S) -> ^mu+ mu-) mu+]CC", + "Jpsi_mum": "[B_c+ -> (J/psi(1S) -> mu+ ^mu-) mu+]CC", + "Bc_mu1": "[B_c+ -> (J/psi(1S) -> mu+ mu-) ^mu+]CC" + }, + ["Bc", "Jpsi"], + ["Jpsi_mup", "Jpsi_mum", "Bc_mu1"], + "BforSpectroscopy_BcToJpsimu", + ["J/psi(1S)", "Jpsi"], + ), + # Lb -> Lc+ mu- decay, with Lc+ -> p+ K- pi+ + ( + { + "Lb": "[Lambda_b0 -> (Lambda_c+ -> p+ K- pi+) mu-]CC", + "Lc": "[Lambda_b0 -> ^(Lambda_c+ -> p+ K- pi+) mu-]CC", + "Lc_P1": "[Lambda_b0 -> (Lambda_c+ -> ^p+ K- pi+) mu-]CC", + "Lc_K1": "[Lambda_b0 -> (Lambda_c+ -> p+ ^K- pi+) mu-]CC", + "Lc_Pi1": "[Lambda_b0 -> (Lambda_c+ -> p+ K- ^pi+) mu-]CC", + "Lb_mu1" : "[Lambda_b0 -> (Lambda_c+ -> p+ K- pi+) ^mu-]CC" + }, + ["Lb", "Lc"], + ["Lc_P1", "Lc_K1", "Lc_Pi1", "Lb_mu1"], + "BforSpectroscopy_LbToLcmu", + ["Lambda_c+", "Lc"], + ), + # Xibm -> Xic0 mu-, with Xic0 -> p+ K- K- pi+ + ( + { + "Xibm": "[Xi_b- -> (Xi_c0 -> p+ K- K- pi+) mu-]CC", + "Xic0": "[Xi_b- -> ^(Xi_c0 -> p+ K- K- pi+) mu-]CC", + "Xic0_P1": "[Xi_b- -> (Xi_c0 -> ^p+ K- K- pi+) mu-]CC", + "Xic0_K1": "[Xi_b- -> (Xi_c0 -> p+ ^K- K- pi+) mu-]CC", + "Xic0_K2": "[Xi_b- -> (Xi_c0 -> p+ K- ^K- pi+) mu-]CC", + "Xic0_Pi1": "[Xi_b- -> (Xi_c0 -> p+ K- K- ^pi+) mu-]CC", + "Xibm_mu1" : "[Xi_b- -> (Xi_c0 -> p+ K- K- pi+) ^mu-]CC" + }, + ["Xibm", "Xic0"], + ["Xic0_P1", "Xic0_K1", "Xic0_K2", "Xic0_Pi1", "Xibm_mu1"], + "BforSpectroscopy_XibmToXic0mu", + ["Xi_c0", "Xic0"], + ), + # Xib0 -> Xic+ mu-, with Xic+ -> p+ K- pi+ + ( + { + "Xib0": "[Xi_b0 -> (Xi_c+ -> p+ K- pi+) mu-]CC", + "Xicp": "[Xi_b0 -> ^(Xi_c+ -> p+ K- pi+) mu-]CC", + "Xicp_P1": "[Xi_b0 -> (Xi_c+ -> ^p+ K- pi+) mu-]CC", + "Xicp_K1": "[Xi_b0 -> (Xi_c+ -> p+ ^K- pi+) mu-]CC", + "Xicp_Pi1": "[Xi_b0 -> (Xi_c+ -> p+ K- ^pi+) mu-]CC", + "Xib0_mu1" : "[Xi_b0 -> (Xi_c+ -> p+ K- pi+) ^mu-]CC" + }, + ["Xib0", "Xicp"], + ["Xicp_P1", "Xicp_K1", "Xicp_Pi1", "Xib0_mu1"], + "BforSpectroscopy_Xib0ToXicpmu", + ["Xi_c+", "Xicp"], + ), + # Omb -> Omega_c0 mu-, with Omega_c0 -> p+ K- K- pi+ + ( + { + "Omegab": "[Omega_b- -> (Omega_c0 -> p+ K- K- pi+) mu-]CC", + "Omegac": "[Omega_b- -> ^(Omega_c0 -> p+ K- K- pi+) mu-]CC", + "Omegac_P1": "[Omega_b- -> (Omega_c0 -> ^p+ K- K- pi+) mu-]CC", + "Omegac_K1": "[Omega_b- -> (Omega_c0 -> p+ ^K- K- pi+) mu-]CC", + "Omegac_K2": "[Omega_b- -> (Omega_c0 -> p+ K- ^K- pi+) mu-]CC", + "Omegac_Pi1": "[Omega_b- -> (Omega_c0 -> p+ K- K- ^pi+) mu-]CC", + "Omegab_mu1": "[Omega_b- -> (Omega_c0 -> p+ K- K- pi+) ^mu-]CC" + }, + ["Omegab", "Omegac"], + ["Omegac_P1", "Omegac_K1", "Omegac_K2", "Omegac_Pi1", "Omegab_mu1"], + "BforSpectroscopy_OmegabToOmcmu", + ["Omega_c0", "Omegac"], + ), + ] + + # line_name = 'SpruceBandQ_AllBForSpectroscopySL' + # my_filter = line_prefilter(line_name) + + algs = {} #[my_filter] + + for decay_config in decays: + + decay_descriptor, composite_list, stable_list, decay_name, ParticleToConstrain = decay_config + + _name = composite_list[0] + if _name == "Bu" or _name == "Bd": _name="Bud" + if _name == "Xib0" or _name == "Xibm": _name="Xib" + + line_name = f'SpruceBandQ_{_name}ForSpectroscopySL' + HLT2_decision = line_name.replace("Spruce", "Hlt2") + "FullDecision" + my_filter = line_prefilter(HLT2_decision) + + algs[decay_name] = [my_filter, template(decay_descriptor, line_name, False, HLT2_lines+[HLT2_decision], composite_list, stable_list, decay_name, ParticleToConstrain)] + + return algs + + +# def entry_point(options: Options): + +# algs_dict = Bu() +# algs_dict.update(Bd()) +# algs_dict.update(Bs()) +# algs_dict.update(Bc()) +# algs_dict.update(Lb()) +# algs_dict.update(Xibm()) +# algs_dict.update(Xib0()) +# algs_dict.update(Omegab()) + +# algs_dict.update(SL()) + +# return make_config(options, algs_dict) diff --git a/bandq_resprucing/BforSpectroscopy/make_dtf.py b/bandq_resprucing/BforSpectroscopy/make_dtf.py new file mode 100644 index 0000000000000000000000000000000000000000..16fc87e84f4c565ba69ec8deed1034e648a7f93c --- /dev/null +++ b/bandq_resprucing/BforSpectroscopy/make_dtf.py @@ -0,0 +1,228 @@ +import Functors as F +from Functors.math import log + +from FunTuple import FunctorCollection +from FunTuple.functorcollections import ( + MCHierarchy, + MCPromptDecay, + Kinematics, + SelectionInfo, + HltTisTos, + MCVertexInfo, + MCKinematics, + ParticleID, #wrong variables PID_PI = 0, PROBNN_D = nan + EventInfo, + LHCInfo, + ParticleIsolation, + MCPrimaries, + MCReconstructed, + MCReconstructible, +) + +from DaVinciMCTools import MCTruthAndBkgCat, MCReconstructed, MCReconstructible +from PyConf.Algorithms import ParticleToSubcombinationsAlg +from DecayTreeFitter import DecayTreeFitter + +from DaVinci.algorithms import create_lines_filter +from PyConf.reading import get_particles +from FunTuple import FunTuple_Particles as Funtuple + + + +def make_basic_dtf_variables(pvs, data, DTF=None, pv_constraint=False, mass_constraint=False, particle_name=""): + variables = ( + FunctorCollection( + { + "TRCHI2DOF": F.CHI2DOF @ F.TRACK, + "ETA": F.ETA, + "PHI": F.PHI, + "TRGHOSTPROB": F.GHOSTPROB, + "BPVIPCHI2": F.BPVIPCHI2(pvs), + "BPVIP": F.BPVIP(pvs), + "BPVX": F.BPVX(pvs), + "BPVY": F.BPVY(pvs), + "BPVZ": F.BPVZ(pvs), + "TX" : F.TX, + "TY" : F.TY, + "KEY" : F.VALUE_OR(-1) @ F.OBJECT_KEY @ F.TRACK, +# "CTB" : F.POSITION @ F.CLOSESTTOBEAM @ F.TRACK, + "TRACKPT": F.TRACK_PT, + "TRACKHISTORY": F.VALUE_OR(-1) @ F.TRACKHISTORY @ F.TRACK, + "QOVERP": F.QOVERP @ F.TRACK, + "NDOF": F.VALUE_OR(-1) @ F.NDOF @ F.TRACK, + } + ) + + Kinematics() + ) + + if(mass_constraint): + if(pv_constraint): # MASS + PV + dtf_variables_mass_pv = FunctorCollection({ + 'DTF_PV_M'+ particle_name + '_' + k: DTF(v) + for k, v in variables.get_thor_functors().items() + }) + return dtf_variables_mass_pv + else: # MASS + dtf_variables_mass = FunctorCollection( + {'DTF_M'+ particle_name + '_' + k: DTF(v) + for k, v in variables.get_thor_functors().items()}) + return dtf_variables_mass + + elif(pv_constraint): # PV + dtf_variables_pv = FunctorCollection({ + 'DTF_PV_' + k: DTF(v) + for k, v in variables.get_thor_functors().items() + }) + return dtf_variables_pv + + else: # NO MASS/PV + dtf_variables = FunctorCollection( + {'DTF_' + k: DTF(v) + for k, v in variables.get_thor_functors().items()}) + return dtf_variables + + +def make_composite_dtf_variables(pvs, data, DTF=None, pv_constraint=False, mass_constraint=False, particle_name=""): + variables = ( + FunctorCollection( + { + "BPVDIRA": F.BPVDIRA(pvs), + "VCHI2DOF": F.CHI2DOF, #CHI2VXNDOF + "BPVFDCHI2": F.BPVFDCHI2(pvs), + "BPVFD": F.BPVFD(pvs), + "BPVVDRHO": F.BPVVDRHO(pvs), + "BPVVDZ": F.BPVVDZ(pvs), + "BPVIPCHI2": F.BPVIPCHI2(pvs), + "BPVIP": F.BPVIP(pvs), + "BPVLTIME": F.BPVLTIME(pvs), + "ETA": F.ETA, + "PHI": F.PHI, + "END_VX": F.END_VX, #END_ + "END_VY": F.END_VY, + "END_VZ": F.END_VZ, + "BPVX": F.BPVX(pvs), + "BPVY": F.BPVY(pvs), + "BPVZ": F.BPVZ(pvs), + "ALLPVFD" : F.ALLPV_FD(pvs), + "ALLPVIP" : F.ALLPV_IP(pvs), + + } + ) + + Kinematics() + ) + + addstring = "DTF" + if(pv_constraint): + addstring += '_PV' + if(mass_constraint): + addstring += '_M' + addstring += particle_name + + DTF_chi2ndof = FunctorCollection( + { + addstring+"_DTFCHI2": DTF.CHI2, + addstring+"_DTFNDOF": DTF.NDOF, + addstring+"_CTAU": DTF.CTAU, + addstring+"_CTAUERR": DTF.CTAUERR, + addstring+"_MERR": DTF.MASSERR, + } + ) + + if(mass_constraint): + if(pv_constraint): # MASS + PV + dtf_variables_mass_pv = FunctorCollection({ + 'DTF_PV_M'+ particle_name + '_' + k: DTF(v) + for k, v in variables.get_thor_functors().items() + }) + return dtf_variables_mass_pv+DTF_chi2ndof + else: # MASS + dtf_variables_mass = FunctorCollection( + {'DTF_M'+ particle_name + '_' + k: DTF(v) + for k, v in variables.get_thor_functors().items()}) + return dtf_variables_mass+DTF_chi2ndof + + elif(pv_constraint): # PV + dtf_variables_pv = FunctorCollection({ + 'DTF_PV_' + k: DTF(v) + for k, v in variables.get_thor_functors().items() + }) + return dtf_variables_pv+DTF_chi2ndof + + else: # NO MASS/PV + dtf_variables = FunctorCollection( + {'DTF_' + k: DTF(v) + for k, v in variables.get_thor_functors().items()}) + return dtf_variables+DTF_chi2ndof + + + +def make_dtf_variables(pvs, input_data, ptype, ParticleToConstrain_PDGName, ParticleToConstrain_Name): + + if ptype not in ["basic", "composite"]: + Exception(f"Need \'basic\' or \'composite\'. Got {ptype}") + + from DecayTreeFitter import DecayTreeFitter + +# DTF = DecayTreeFitter( +# name=f'DTF_{{hash}}', +# input_particles=input_data) +# +# DTFvtx = DecayTreeFitter( +# name=f'DTFvtx_{{hash}}', +# input_particles=input_data, +# input_pvs=pvs) + + DTFmassCharm = DecayTreeFitter( + name=f'DTFmassCharm_{{hash}}', + input_particles=input_data, + mass_constraints=[ParticleToConstrain_PDGName]) + +# DTFvtxmassCharm = DecayTreeFitter( +# name=f'DTFvtxmassCharm_{{hash}}', +# input_particles=input_data, +# input_pvs=pvs, +# mass_constraints=["J/psi(1S)"]) + + + + if ptype == "basic": +# dtf_vars = make_basic_dtf_variables(pvs, input_data, +# DTF=DTF, +# pv_constraint=False, +# mass_constraint=False) +# dtf_vars += make_basic_dtf_variables(pvs, input_data, +# DTF=DTFvtx, +# pv_constraint=True, +# mass_constraint=False) + dtf_vars = make_basic_dtf_variables(pvs, input_data, + DTF=DTFmassCharm, + pv_constraint=False, + mass_constraint=True, particle_name=ParticleToConstrain_Name) +# dtf_vars += make_basic_dtf_variables(pvs, input_data, +# DTF=DTFvtxmassCharm, +# pv_constraint=True, +# mass_constraint=True, particle_name="Jpsi") +# + return dtf_vars + + if ptype == "composite": +# dtf_vars = make_composite_dtf_variables(pvs, input_data, +# DTF=DTF, +# pv_constraint=False, +# mass_constraint=False) +# dtf_vars += make_composite_dtf_variables(pvs, input_data, +# DTF=DTFvtx, +# pv_constraint=True, +# mass_constraint=False) + dtf_vars = make_composite_dtf_variables(pvs, input_data, + DTF=DTFmassCharm, + pv_constraint=False, + mass_constraint=True, particle_name=ParticleToConstrain_Name) +# dtf_vars += make_composite_dtf_variables(pvs, input_data, +# DTF=DTFvtxmassCharm, +# pv_constraint=True, +# mass_constraint=True, particle_name="Jpsi") +# + return dtf_vars + + diff --git a/bandq_resprucing/BforSpectroscopy/tupling_maker.py b/bandq_resprucing/BforSpectroscopy/tupling_maker.py new file mode 100644 index 0000000000000000000000000000000000000000..b59ddced97e6327794404a8364bac4ffdcf5dcec --- /dev/null +++ b/bandq_resprucing/BforSpectroscopy/tupling_maker.py @@ -0,0 +1,345 @@ +############################################################################### +# (c) Copyright 2021-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. # +############################################################################### +""" +Read an HLT2 file and create an ntuple with the new DaVinci configuration. +""" +import Functors as F +import FunTuple.functorcollections as FC +from FunTuple import FunctorCollection +from FunTuple import FunTuple_Particles as Funtuple +from PyConf.reading import get_particles, get_pvs, get_rec_summary +from DaVinci.algorithms import create_lines_filter +from DaVinciMCTools import MCTruthAndBkgCat +from FunTuple.functorcollections import MCHierarchy, MCPrimaries, MCPromptDecay, Kinematics, SelectionInfo, HltTisTos, MCVertexInfo, MCKinematics, ParticleID, EventInfo +from PyConf.reading import get_odin # get_decreports, +from DecayTreeFitter import DecayTreeFitter +from Hlt2Conf.algorithms_thor import ParticleFilter + + + +from .make_dtf import make_dtf_variables + + +_basic = "basic" +_composite = "composite" +_toplevel = "toplevel" + +def all_variables(pvs, mctruth, ptype, candidates=None, ftAlg=None): + """ + function that returns dictionary of functors that work. + + functors are listed in order of https://lhcbdoc.web.cern.ch/lhcbdoc/moore/master/selection/thor_functors_reference.html#module-Functo + """ + if ptype not in [_basic, _composite]: + Exception(f"I want {_basic} or {_composite}. Got {ptype}") + all_vars = FunctorCollection({}) + + comp = _composite == ptype or _toplevel == ptype # is composite + basic = _basic == ptype # is not composite + top = _toplevel == ptype # the B + + # First import everything that comes in functorcollections + all_vars += FC.Kinematics() + if basic: + all_vars += FC.ParticleID(extra_info=True) + + # if comp: + # all_vars.update({"ALV": F.ALV(Child1=1, Child2=2)}) + + if comp: # all these require a vertex + all_vars.update({"BPVCORRM": F.BPVCORRM(pvs)}) + all_vars.update({"BPVCORRMERR": F.BPVCORRMERR(pvs)}) + all_vars.update({"BPVDIRA": F.BPVDIRA(pvs)}) + all_vars.update({"BPVDLS": F.BPVDLS(pvs)}) + all_vars.update({"BPVETA": F.BPVETA(pvs)}) + all_vars.update({"BPVFD": F.BPVFD(pvs)}) + all_vars.update({"BPVFDCHI2": F.BPVFDCHI2(pvs)}) + all_vars.update({"BPVFDIR": F.BPVFDIR(pvs)}) + all_vars.update({"BPVFDVEC": F.BPVFDVEC(pvs)}) + + all_vars.update({"BPVIP": F.BPVIP(pvs)}) + all_vars.update({"BPVIPCHI2": F.BPVIPCHI2(pvs)}) + all_vars.update({"BPVX": F.BPVX(pvs)}) + all_vars.update({"BPVY": F.BPVY(pvs)}) + all_vars.update({"BPVZ": F.BPVZ(pvs)}) + + if comp: # all these require a vertex + all_vars.update({"ALLPV_FD": F.ALLPV_FD(pvs)}) + all_vars.update({"ALLPV_IP": F.ALLPV_IP(pvs)}) + all_vars.update({"BPVLTIME": F.BPVLTIME(pvs)}) + all_vars.update({"BPVVDRHO": F.BPVVDRHO(pvs)}) + all_vars.update({"BPVVDX": F.BPVVDX(pvs)}) + all_vars.update({"BPVVDY": F.BPVVDY(pvs)}) + all_vars.update({"BPVVDZ": F.BPVVDZ(pvs)}) + + all_vars.update({"CHARGE": F.CHARGE}) + all_vars.update({"CHI2": F.CHI2}) + all_vars.update({"CHI2DOF": F.CHI2DOF}) + + # if top: # apply this only to B + # all_vars.update({"CHILD1_PT": F.CHILD(1, F.PT)}) # example of CHILD + # all_vars.update({"Ds_END_VZ": F.CHILD(1, F.END_VZ)}) + # all_vars.update({"Delta_END_VZ_DsB0": F.CHILD(1, F.END_VZ) - F.END_VZ}) + + if comp: + # all_vars.update({"DOCA": F.SDOCA(Child1=1, Child2=2)}) + # all_vars.update({"DOCACHI2": F.SDOCACHI2(Child1=1, Child2=2)}) + all_vars.update({"END_VRHO": F.END_VRHO}) + all_vars.update({"END_VX": F.END_VX}) + all_vars.update({"END_VY": F.END_VY}) + all_vars.update({"END_VZ": F.END_VZ}) + + all_vars.update({"ETA": F.ETA}) + all_vars.update({"FOURMOMENTUM": F.FOURMOMENTUM}) + all_vars.update({"ISBASIC": F.ISBASICPARTICLE}) + + if basic: + all_vars.update({"GHOSTPROB": F.GHOSTPROB}) + all_vars.update({"ISMUON": F.ISMUON}) + all_vars.update({"INMUON": F.INMUON}) + all_vars.update({"INECAL": F.INECAL}) + all_vars.update({"INHCAL": F.INHCAL}) + all_vars.update({"HASBREM": F.HASBREM}) + all_vars.update({"BREMENERGY": F.BREMENERGY}) + all_vars.update({"BREMBENDCORR": F.BREMBENDCORR}) + all_vars.update({"BREMPIDE": F.BREMPIDE}) + all_vars.update({"ECALPIDE": F.ECALPIDE}) + all_vars.update({"ECALPIDMU": F.ECALPIDMU}) + all_vars.update({"HCALPIDE": F.HCALPIDE}) + all_vars.update({"HCALPIDMU": F.HCALPIDMU}) + all_vars.update({"ELECTRONSHOWEREOP": F.ELECTRONSHOWEREOP}) + all_vars.update({"CLUSTERMATCH": F.CLUSTERMATCH_CHI2}) + all_vars.update({"ELECTRONMATCH": F.ELECTRONMATCH_CHI2}) + all_vars.update({"BREMHYPOMATCH": F.BREMHYPOMATCH_CHI2}) + all_vars.update({"ELECTRONENERGY": F.ELECTRONENERGY}) + all_vars.update({"BREMHYPOENERGY": F.BREMHYPOENERGY}) + all_vars.update({"BREMHYPODELTAX": F.BREMHYPODELTAX}) + all_vars.update({"ELECTRONID": F.ELECTRONID}) + all_vars.update({"HCALEOP": F.HCALEOP}) + # Note: the observables for the two functors below are (TRACK_MOM_X, TRACK_MOM_Y, TRACK_MOM_Z}) + # and (TRACK_POS_CLOSEST_TO_BEAM_X, TRACK_POS_CLOSEST_TO_BEAM_Y, TRACK_POS_CLOSEST_TO_BEAM_Z), + # which is why the trailing underscore in the name is added i.e. "TRACK_MOM_" and "TRACK_POS_CLOSEST_TO_BEAM_" + all_vars.update({"TRACK_MOM_": F.TRACK_MOMVEC}) +# all_vars.update({"TRACK_POS_CLOSESTTOBEAM_": F.TRACK_POSVEC_CLOSESTTOBEAM}) + + all_vars.update({"IS_ABS_ID_pi": F.IS_ABS_ID("pi+")}) + all_vars.update({"IS_ID_pi": F.IS_ID("pi-")}) + all_vars.update({"PDG_MASS_pi": F.PDG_MASS("pi+")}) + all_vars.update({"SIGNED_DELTA_MASS_pi": F.SIGNED_DELTA_MASS("pi+")}) + all_vars.update({"ABS_DELTA_MASS_pi": F.ABS_DELTA_MASS("pi+")}) + all_vars.update({"IS_NOT_H": F.IS_NOT_H}) + all_vars.update({"IS_PHOTON": F.IS_PHOTON}) + + all_vars.update({"MASS": F.MASS}) + + if comp: + all_vars.update({"MAXPT": F.MAX(F.PT)}) + all_vars.update({"MAXDOCA": F.MAXSDOCA}) + all_vars.update({"MAXDOCACHI2": F.MAXSDOCACHI2}) + # the above in cut versions. + + if comp: + all_vars.update({"MINPT": F.MIN(F.PT)}) + all_vars.update({"MINIP": F.MINIP(pvs)}) + all_vars.update({"MINIPCHI2": F.MINIPCHI2(pvs)}) + + if basic: + all_vars.update({"TRACKPT": F.TRACK_PT}) + all_vars.update({"TRACKHISTORY": F.VALUE_OR(-1) @ F.TRACKHISTORY @ F.TRACK}) + all_vars.update({"QOVERP": F.QOVERP @ F.TRACK}) + all_vars.update({"NDOF": F.VALUE_OR(-1) @ F.NDOF @ F.TRACK}) + all_vars.update({"NFTHITS": F.VALUE_OR(-1) @ F.NFTHITS @ F.TRACK}) + all_vars.update({"NHITS": F.VALUE_OR(-1) @ F.NHITS @ F.TRACK}) + all_vars.update({"NUTHITS": F.VALUE_OR(-1) @ F.NUTHITS @ F.TRACK}) + all_vars.update({"NVPHITS": F.VALUE_OR(-1) @ F.NVPHITS @ F.TRACK}) + all_vars.update({"TRACKHASVELO": F.VALUE_OR(-1) @ F.TRACKHASVELO @ F.TRACK}) + all_vars.update({"TRACKHASUT": F.VALUE_OR(-1) @ F.TRACKHASUT @ F.TRACK}) + + all_vars.update({"OBJECT_KEY": F.OBJECT_KEY}) + + all_vars.update({"PHI": F.PHI}) + + all_vars.update({"ABS_PX": F.ABS @ F.PX}) + + all_vars.update({"REFERENCEPOINT_X": F.REFERENCEPOINT_X}) + all_vars.update({"REFERENCEPOINT_Y": F.REFERENCEPOINT_Y}) + all_vars.update({"REFERENCEPOINT_Z": F.REFERENCEPOINT_Z}) + + if comp: + all_vars.update({"SDOCA": F.SDOCA(1, 2)}) + all_vars.update({"SDOCACHI2": F.SDOCACHI2(1, 2)}) + if basic: + all_vars.update({"SHOWER_SHAPE": F.CALO_NEUTRAL_SHOWER_SHAPE}) + + if comp: + all_vars.update({"SUBCOMB12_MM": F.SUBCOMB(Functor=F.MASS, Indices=(1, 2))}) + all_vars.update({"SUMPT": F.SUM(F.PT)}) + + if basic: + all_vars.update({"TX": F.TX}) + all_vars.update({"TY": F.TY}) + + print(f"### For {ptype} returning variables {all_vars.functor_dict.keys()}") + return all_vars + + +def event_variables(PVs, ODIN, decreports, lines): + """ + event variables + """ + + evt_vars = FunctorCollection({}) + evt_vars += FC.EventInfo() + + evt_vars += FC.SelectionInfo(selection_type="Hlt2", trigger_lines=lines) + + if decreports: + evt_vars.update( + { + "DECISIONS": F.DECISIONS( + Lines=[bd2dsk_line + "Decision"], DecReports=decreports + ) + } + ) + evt_vars.update( + { + "DECREPORTS_FILTER": F.DECREPORTS_FILTER( + Lines=[bd2dsk_line + "Decision"], DecReports=decreports + ) + } + ) + + if ODIN: + evt_vars.update({"EVENTTYPE": F.EVENTTYPE(ODIN)}) + + evt_vars.update({"PV_SIZE": F.SIZE(PVs)}) + + if decreports: + evt_vars.update({"TCK": F.TCK(decreports)}) + + print(f"### For event returning variables {evt_vars.functor_dict.keys()}") + return evt_vars + + +def template(decay_descriptor, line_name, isturbo, Hlt2_decisions, composite_particles, daughter_particles, file_name=None, ParticleToConstrain=["", ""]): + + evtpath_prefix = "/Event/Spruce/" + if isturbo: + evtpath_prefix = "/Event/HLT2/" + + input_data_raw = get_particles(evtpath_prefix + f"{line_name}/Particles") + input_data = ParticleFilter(Input=input_data_raw, Cut = F.FILTER(F.require_all( F.CHILD(1, F.IS_ABS_ID(ParticleToConstrain[0])) ))) + #input_data = ParticleFilter(Input=input_data_raw, Cut = F.FILTER(F.require_all( F.FIND_DECAY( decay_descriptor[composite_particles[0]] )))) + + pvs = get_pvs() + + Hlt1_decisions = [ + 'Hlt1TrackMVADecision', 'Hlt1TwoTrackMVADecision', #'Hlt1D2KKDecision', + #'Hlt1D2KPiDecision', 'Hlt1D2PiPiDecision', + 'Hlt1DiMuonHighMassDecision', #'Hlt1DiMuonLowMassDecision', + #'Hlt1DiMuonSoftDecision', + #'Hlt1KsToPiPiDecision', 'Hlt1LowPtMuonDecision', + 'Hlt1LowPtDiMuonDecision', 'Hlt1SingleHighPtMuonDecision', + 'Hlt1TrackMuonMVADecision', "Hlt1DiMuonNoIP_SSDecision", + #"Hlt1DiMuonDrellYan_VLowMassDecision", + #"Hlt1DiMuonDrellYan_VLowMass_SSDecision", + #"Hlt1DiMuonDrellYanDecision", + #"Hlt1DiMuonDrellYan_SSDecision", + #"Hlt1DetJpsiToMuMuPosTagLineDecision", + #"Hlt1DetJpsiToMuMuNegTagLineDecision", + #"Hlt1TrackElectronMVADecision", + #"Hlt1SingleHighPtElectronDecision", + #"Hlt1DiElectronDisplacedDecision", + #"Hlt1SingleHighEtDecision", + #"Hlt1DiPhotonHighMassDecision", + #"Hlt1Pi02GammaGammaDecision", + #"Hlt1DiElectronHighMass_SSDecision", + #"Hlt1DiElectronHighMassDecision", + "Hlt1DiMuonNoIPDecision", + ] + + composite_variables = FunctorCollection({ + "END_VX_ERR":F.SQRT @ F.CALL(0,0) @ F.POS_COV_MATRIX @ F.ENDVERTEX, + "END_VY_ERR":F.SQRT @ F.CALL(1,1) @ F.POS_COV_MATRIX @ F.ENDVERTEX, + "END_VZ_ERR":F.SQRT @ F.CALL(2,2) @ F.POS_COV_MATRIX @ F.ENDVERTEX, + "BPVX_ERR": F.SQRT @ F.CALL(0,0) @ F.POS_COV_MATRIX @ F.BPV(pvs), + "BPVY_ERR": F.SQRT @ F.CALL(1,1) @ F.POS_COV_MATRIX @ F.BPV(pvs), + "BPVZ_ERR": F.SQRT @ F.CALL(2,2) @ F.POS_COV_MATRIX @ F.BPV(pvs), + "PERR": F.SQRT @ F.PERR2, + "PXERR": F.SQRT @ F.CALL(0,0) @ F.THREE_MOM_COV_MATRIX, + "PYERR": F.SQRT @ F.CALL(1,1) @ F.THREE_MOM_COV_MATRIX, + "PZERR": F.SQRT @ F.CALL(2,2) @ F.THREE_MOM_COV_MATRIX, + }) + + composite_variables += HltTisTos( selection_type="Hlt1", trigger_lines=Hlt1_decisions, data=input_data) + if not isturbo: + composite_variables += HltTisTos( selection_type="Hlt2", trigger_lines=Hlt2_decisions, data=input_data) + + daughter_variables = FunctorCollection({ + "PERR": F.SQRT @ F.PERR2, + "PZERR": F.SQRT @ F.CALL(2,2) @ F.THREE_MOM_COV_MATRIX, + }) + + #define event level variables + odin = get_odin() + decreports = None + rec_sum=get_rec_summary() + event_info = event_variables(pvs, odin, decreports, [line_name]) + FunctorCollection({ + "nPVs": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nPVs"), + "nTTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nTTracks"), + "nLongTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nLongTracks"), + "nDownstreamTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nDownstreamTracks"), + "nUpstreamTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nUpstreamTracks"), + "nVeloTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nVeloTracks"), + "nBackTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nBackTracks"), + "nRich1Hits": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nRich1Hits"), + "nRich2Hits": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nRich2Hits"), + "nVPClusters": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nVPClusters"), + "nFTClusters": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nFTClusters"), + "eCalTot": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"eCalTot"), + "hCalTot": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"hCalTot"), + "nEcalClusters": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nEcalClusters"), + "ALLPVX": F.ALLPVX(pvs), + "ALLPVY": F.ALLPVY(pvs), + "ALLPVZ": F.ALLPVZ(pvs), + }) + + event_info += FC.SelectionInfo( + selection_type="Hlt1", trigger_lines=Hlt1_decisions + ) + + variables = {} + + ParticleToConstrain_PDGName = ParticleToConstrain[0] + ParticleToConstrain_Name = ParticleToConstrain[1] + print("wmz debug", ParticleToConstrain_PDGName, ParticleToConstrain_Name) + + for composite_particle in composite_particles: + variables[composite_particle] = composite_variables + all_variables(pvs, None, _composite) + make_dtf_variables(pvs, input_data, _composite, ParticleToConstrain_PDGName, ParticleToConstrain_Name) + for daughter_particle in daughter_particles: + variables[daughter_particle] = daughter_variables + all_variables(pvs, None, _basic) + make_dtf_variables(pvs, input_data, _basic, ParticleToConstrain_PDGName, ParticleToConstrain_Name) + + #define FunTuple instance + if not file_name: file_name=line_name + my_tuple = Funtuple( + name=file_name, + tuple_name="DecayTree", + fields=decay_descriptor, + variables=variables, + event_variables=event_info, + store_multiple_cand_info = True, + inputs=input_data) + + return my_tuple + + +def line_prefilter(line_name): + return create_lines_filter(name=f"PreFilter_{line_name}", lines=[line_name, "Hlt2Topo2Body", "Hlt2Topo3Body", "Hlt2_JpsiToMuMuDetachedFull"]) diff --git a/bandq_resprucing/double_charm/dv_data_double_charmonia_OS.py b/bandq_resprucing/double_charm/dv_data_double_charmonia_OS.py new file mode 100644 index 0000000000000000000000000000000000000000..a5e0c04f24ba6328c6633a43ceebc94ad1b19fef --- /dev/null +++ b/bandq_resprucing/double_charm/dv_data_double_charmonia_OS.py @@ -0,0 +1,123 @@ +############################################################################### +# (c) Copyright 2021-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. # +############################################################################### +""" +Read an HLT2 file and create an ntuple with the new DaVinci configuration. +""" +import Functors as F +import FunTuple.functorcollections as FC +from FunTuple import FunctorCollection +from FunTuple import FunTuple_Particles as Funtuple +from PyConf.reading import get_particles, get_pvs , get_rec_summary +from DaVinci.algorithms import create_lines_filter +from DaVinci import Options, make_config +from DaVinciTools import SubstitutePID +from FunTuple.functorcollections import SelectionInfo, HltTisTos +from .tupling import * +from Hlt2Conf.algorithms_thor import ParticleFilter + +def Funtuple_with_filter( + line_name, + fields, + variables, + inputs, + name="Tuple", + tuple_name="DecayTree", + event_variables=None, +): + hlt_filter = create_lines_filter( + name ="HDRFilter_{hash}", + lines=[f"{line_name}"]) + + return [ + hlt_filter, + Funtuple( + name=name, + tuple_name=tuple_name, + fields=fields, + variables=variables, + inputs=inputs, + event_variables=event_variables, + ), + ] + +def make_alg_config(Charm1, Charm2, self_conjugate=False, filter=True): + line_name = 'SpruceBandQ_DoubleCharmOppositeSign' + data_raw = get_particles(f"/Event/Spruce/{line_name}/Particles") + data = ParticleFilter( + data_raw, + name="data_filtered_{hash}", + Cut =F.FILTER( + F.require_all( + F.require_any( + F.CHILD(1, F.PARTICLE_ID()==abs(particle_dict[Charm1]["id"])),F.CHILD(1, F.PARTICLE_ID()==-abs(particle_dict[Charm1]["id"])) + ), + F.require_any( + F.CHILD(2, F.PARTICLE_ID()==abs(particle_dict[Charm2]["id"])),F.CHILD(2, F.PARTICLE_ID()==-abs(particle_dict[Charm2]["id"])) + ), + ), + ) + ) + name = "doublecharm_OS_" + Charm1 + Charm2 + fields = make_fields(Charm1, Charm2, self_conjugate) + if filter: + return Funtuple_with_filter( + line_name, + fields, + make_var(data, fields,Charm1,Charm2), + data, + name, + event_variables=make_event_info(), + ) + else: + return [Funtuple( + name=name, + tuple_name="DecayTree", + fields=fields, + variables=make_var(data, fields,Charm1,Charm2), + inputs=data, + event_variables=make_event_info(), + )] + + +def All(): + user_algorithms = {} + decay_ls = [ + ["Db0", "D0", True], + ["Db0", "Dp"], + ["Db0", "Dsp"], + ["Db0", "lcp"], + ["Db0", "xicz"], + ["Db0", "omegacz"], + ["Dm", "Dp", True], + ["Dm", "Dsp"], + ["Dm", "lcp"], + ["Dm", "xicz"], + ["Dm", "omegacz"], + ["Dsm", "Dsp", True], + ["Dsm", "lcp"], + ["Dsm", "xicz"], + ["Dsm", "omegacz"], + ["lcm", "lcp", True], + ["lcm", "xicz"], + ["lcm", "omegacz"], + ["xicbz", "xicz", True], + ["xicbz", "omegacz"], + ["omegacbz", "omegacz", True], + ] + + for decay in decay_ls: + if len(decay) == 3: + user_algorithms[decay[0]+decay[1]] = make_alg_config(decay[0], decay[1], decay[2]) + else: + user_algorithms[decay[0]+decay[1]] = make_alg_config(decay[0], decay[1]) + # config = make_config(options, user_algorithms) + # return config + return user_algorithms \ No newline at end of file diff --git a/bandq_resprucing/double_charm/dv_data_double_charmonia_SS.py b/bandq_resprucing/double_charm/dv_data_double_charmonia_SS.py new file mode 100644 index 0000000000000000000000000000000000000000..ba063bd527bb6788049a2c3447beaa69cebe3d8a --- /dev/null +++ b/bandq_resprucing/double_charm/dv_data_double_charmonia_SS.py @@ -0,0 +1,130 @@ +############################################################################### +# (c) Copyright 2021-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. # +############################################################################### +""" +Read an HLT2 file and create an ntuple with the new DaVinci configuration. +""" +import Functors as F +import FunTuple.functorcollections as FC +from FunTuple import FunctorCollection +from FunTuple import FunTuple_Particles as Funtuple +from PyConf.reading import get_particles, get_pvs , get_rec_summary +from DaVinci.algorithms import create_lines_filter +from DaVinci import make_config +from DaVinciTools import SubstitutePID +from FunTuple.functorcollections import SelectionInfo, HltTisTos +from .tupling import * +from Hlt2Conf.algorithms_thor import ParticleFilter + +def Funtuple_with_filter( + line_name, + fields, + variables, + inputs, + name="Tuple", + tuple_name="DecayTree", + event_variables=None, +): + hlt_filter = create_lines_filter( + name ="HDRFilter_{hash}", + lines=[f"{line_name}"]) + + return [ + hlt_filter, + Funtuple( + name=name, + tuple_name=tuple_name, + fields=fields, + variables=variables, + inputs=inputs, + event_variables=event_variables, + ), + ] + +def make_alg_config(Charm1, Charm2, self_conjugate=False, filter=True): + line_name = 'SpruceBandQ_DoubleCharmSameSign' + data_raw = get_particles(f"/Event/Spruce/{line_name}/Particles") + data = ParticleFilter( + data_raw, + name="data_filtered_{hash}", + Cut =F.FILTER( + F.require_all( + F.require_any( + F.CHILD(1, F.PARTICLE_ID()==abs(particle_dict[Charm1]["id"])),F.CHILD(1, F.PARTICLE_ID()==-abs(particle_dict[Charm1]["id"])) + ), + F.require_any( + F.CHILD(2, F.PARTICLE_ID()==abs(particle_dict[Charm2]["id"])),F.CHILD(2, F.PARTICLE_ID()==-abs(particle_dict[Charm2]["id"])) + ), + ), + ) + ) + name = "doublecharm_SS_" + Charm1 + Charm2 + fields = make_fields(Charm1, Charm2) + if filter: + return Funtuple_with_filter( + line_name, + fields, + make_var(data, fields,Charm1,Charm2), + data, + name, + event_variables=make_event_info(), + ) + else: + return [Funtuple( + name=name, + tuple_name="DecayTree", + fields=fields, + variables=make_var( data, fields,Charm1,Charm2), + inputs=data, + event_variables=make_event_info(), + )] + + +def All(): + user_algorithms = {} + decay_ls = [ + ["D0", "D0"], + ["D0", "Dp"], + ["D0", "Dsp"], + ["D0", "lcp"], + ["D0", "xicz"], + ["D0", "omegacz"], + ["Dp", "Dp"], + ["Dp", "Dsp"], + ["Dp", "lcp"], + ["Dp", "xicz"], + ["Dp", "omegacz"], + ["Dsp", "Dsp"], + ["Dsp", "lcp"], + ["Dsp", "xicz"], + ["Dsp", "omegacz"], + ["lcp", "lcp"], + ["lcp", "xicz"], + ["lcp", "omegacz"], + ["xicz", "xicz"], + ["xicz", "omegacz"], + ["omegacz", "omegacz"], + ["jpsi", "D0"], + ["jpsi", "Dp"], + ["jpsi", "Dsp"], + ["jpsi", "lcp"], + ["jpsi", "xicz"], + ["jpsi", "omegacz"], + ["psi2s", "D0"], + ["psi2s", "Dp"], + ["psi2s", "Dsp"], + ["psi2s", "lcp"], + ["psi2s", "xicz"], + ["psi2s", "omegacz"], + ] + + for decay in decay_ls: + user_algorithms[decay[0]+decay[1]] = make_alg_config(decay[0], decay[1]) + return user_algorithms \ No newline at end of file diff --git a/bandq_resprucing/double_charm/tupling.py b/bandq_resprucing/double_charm/tupling.py new file mode 100644 index 0000000000000000000000000000000000000000..366fc211e1b2e536a8bc189be87c30aa22698aa7 --- /dev/null +++ b/bandq_resprucing/double_charm/tupling.py @@ -0,0 +1,267 @@ +import Functors as F +import FunTuple.functorcollections as FC +from FunTuple import FunctorCollection +from FunTuple import FunTuple_Particles as Funtuple +from PyConf.reading import get_particles, get_pvs , get_rec_summary +from DaVinci.algorithms import create_lines_filter +from DaVinci import make_config +from FunTuple.functorcollections import SelectionInfo, HltTisTos +import pandas as pd + +particle_dict = { + "D0": {"name":"D0", "id":421}, + "Db0": {"name":"D~0", "id":-421}, + "Dp": {"name":"D+", "id":411}, + "Dm": {"name":"D-", "id":-411}, + "Dsp": {"name":"D_s+", "id":431}, + "Dsm": {"name":"D_s-", "id":-431}, + "lcp": {"name":"Lambda_c+", "id":4122}, + "lcm": {"name":"Lambda_c~-", "id":-4122}, + "xicz": {"name":"Xi_c0", "id":4132}, + "xicbz": {"name":"Xi_c~0", "id":-4132}, + "omegacz": {"name":"Omega_c0", "id":4332}, + "omegacbz": {"name":"Omega_c~0", "id":-4332}, + "jpsi": {"name":"J/psi(1S)", "id":443}, + "psi2s": {"name":"psi(2S)", "id":100443}, +} + +Hlt1_decisions = [ + 'Hlt1TrackMVADecision', 'Hlt1TwoTrackMVADecision', 'Hlt1D2KKDecision', + 'Hlt1D2KPiDecision', 'Hlt1D2PiPiDecision', + 'Hlt1DiMuonHighMassDecision', 'Hlt1DiMuonLowMassDecision', + 'Hlt1DiMuonSoftDecision', + 'Hlt1KsToPiPiDecision', 'Hlt1LowPtMuonDecision', + 'Hlt1LowPtDiMuonDecision', 'Hlt1SingleHighPtMuonDecision', + 'Hlt1TrackMuonMVADecision' +] + +def make_composite_variables(): + pvs = get_pvs() + variables = FunctorCollection({ + "ID": F.PARTICLE_ID, + "KEY": F.OBJECT_KEY, + "PT": F.PT, + "PX": F.PX, + "PY": F.PY, + "PZ": F.PZ, + "ENERGY": F.ENERGY, + "P": F.P, + "M": F.MASS, + "ENDVERTEX_CHI2NDOF": F.CHI2DOF, + "FOURMOMENTUM": F.FOURMOMENTUM, + "BPVDIRA": F.BPVDIRA(pvs), + "BPVX": F.BPVX(pvs), + "BPVY": F.BPVY(pvs), + "BPVZ": F.BPVZ(pvs), + "END_VX": F.END_VX, + "END_VY": F.END_VY, + "END_VZ": F.END_VZ, + "END_VZ_ERR":F.SQRT @ F.CALL(2,2) @ F.POS_COV_MATRIX @ F.ENDVERTEX, + "BPVZ_ERR": F.SQRT @ F.CALL(2,2) @ F.POS_COV_MATRIX @ F.BPV(pvs), + "TAU": F.BPVLTIME(pvs), + "BPVFDCHI2": F.BPVFDCHI2(pvs), + "BPVIPCHI2": F.BPVIPCHI2(pvs), + "ETA": F.ETA, + + }) + + return variables + +def make_basic_variables(): + pvs = get_pvs() + variables = FunctorCollection({ + "ID": F.PARTICLE_ID, + "PT": F.PT, + "PX": F.PX, + "PY": F.PY, + "PZ": F.PZ, + "M": F.MASS, + "ENERGY": F.ENERGY, + "P": F.P, + "eta": F.ETA, + "Track_CHI2NDOF": F.CHI2DOF, + "ProbNNK": F.PROBNN_K, + "ProbNNpi": F.PROBNN_PI, + "PIDK": F.PID_K, + "PIDPI": F.PID_PI, + "GhostProb": F.GHOSTPROB, + "FOURMOMENTUM": F.FOURMOMENTUM, + "PERR": F.SQRT @ F.PERR2, + "PZERR": F.SQRT @ F.CALL(2,2) @ F.THREE_MOM_COV_MATRIX, + "BPVIPCHI2": F.BPVIPCHI2(pvs), + "BPVIP": F.BPVIP(pvs), + }) + + return variables + +def make_hlt_variables(data): + return HltTisTos( selection_type="Hlt1", trigger_lines=Hlt1_decisions, data=data) + + +def make_event_info(): + rec_sum=get_rec_summary() + event_info = FC.EventInfo() +FunctorCollection({ + "nPVs": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nPVs"), + "nTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nTracks"), + "nTTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nTTracks"), + "nLongTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nLongTracks"), + "nDownstreamTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nDownstreamTracks"), + "nUpstreamTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nUpstreamTracks"), + "nVeloTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nVeloTracks"), + "nBackTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nBackTracks"), + "nRich1Hits": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nRich1Hits"), + "nRich2Hits": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nRich2Hits"), + "nVPClusters": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nVPClusters"), + "nFTClusters": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nFTClusters"), + "eCalTot": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"eCalTot"), + "hCalTot": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"hCalTot"), + "nEcalClusters": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nEcalClusters"), + }) + return event_info + +from DecayTreeFitter import DecayTreeFitter +def make_dtf_variables(data,Charm1,Charm2, is_basic = False, pv_constraint=True): + pvs = get_pvs() + if pv_constraint: + dtf_name = "DTF_PV_" + else: + dtf_name = "DTF_" + + dtf_name = dtf_name + Charm1 + Charm2 + "_" + ls_mass_constraints = [particle_dict[Charm1]["name"]] + if abs(particle_dict[Charm1]["id"]) != abs(particle_dict[Charm2]["id"]): + ls_mass_constraints.append(particle_dict[Charm2]["name"]) + + DTF = DecayTreeFitter( + name = dtf_name, + input_particles = data, + input_pvs = pvs, + mass_constraints = ls_mass_constraints + #mass_constraints = [particle_dict[Charm1],particle_dict[]], + #mass_constraints = ["D~0"], + ) + + shared_vars = FunctorCollection( + { + "ETA": F.ETA, + "PHI": F.PHI, + "BPVIPCHI2": F.BPVIPCHI2(pvs), + "BPVIP": F.BPVIP(pvs), + "BPVX": F.BPVX(pvs), + "BPVY": F.BPVY(pvs), + "BPVZ": F.BPVZ(pvs), + } + ) + FC.Kinematics() + + dtf_quality_vars = FunctorCollection( + { + dtf_name+"_DTFCHI2": DTF.CHI2, + dtf_name+"_DTFNDOF": DTF.NDOF, + dtf_name+"_CTAU": DTF.CTAU, + dtf_name+"_CTAUERR": DTF.CTAUERR, + dtf_name+"_MERR": DTF.MASSERR, + } + ) + if is_basic: + orig_vars = shared_vars + FunctorCollection( + { + "TX": F.TX, + "TY": F.TY, + "MINIPCHI2": F.MINIPCHI2(pvs), + "MINIP": F.MINIP(pvs), + "KEY": F.VALUE_OR(-1) @ F.OBJECT_KEY @ F.TRACK, + "TRGHOSTPROB": F.GHOSTPROB, + "TRACKPT": F.TRACK_PT, + "TRACKHISTORY": F.VALUE_OR(-1) @ F.TRACKHISTORY @ F.TRACK, + "QOVERP": F.QOVERP @ F.TRACK, + "TRCHI2DOF": F.CHI2DOF @ F.TRACK, + "NDOF": F.VALUE_OR(-1) @ F.NDOF @ F.TRACK, + } + ) + else: + orig_vars = shared_vars + FunctorCollection( + { + "MAXPT": F.MAX(F.PT), + "MINPT": F.MIN(F.PT), + "SUMPT": F.SUM(F.PT), + "MAXP": F.MAX(F.P), + "MINP": F.MIN(F.P), + "BPVDIRA": F.BPVDIRA(pvs), + "CHI2DOF": F.CHI2DOF, #CHI2VXNDOF + "BPVFDCHI2": F.BPVFDCHI2(pvs), + "BPVFD": F.BPVFD(pvs), + "BPVVDRHO": F.BPVVDRHO(pvs), + "BPVVDZ": F.BPVVDZ(pvs), + "BPVLTIME": F.BPVLTIME(pvs), + "END_VX": F.END_VX, #END_ + "END_VY": F.END_VY, + "END_VZ": F.END_VZ, + } + ) + orig_vars += dtf_quality_vars + + dtf_vars = FunctorCollection({ + dtf_name+expr : DTF(func) for expr,func in orig_vars.get_thor_functors().items() + }) + + return dtf_vars + + +def make_var(data, fields,Charm1,Charm2): + var = {} + for key in fields.keys(): + if key == "psi": + var[key] = make_composite_variables()+make_hlt_variables(data)+make_dtf_variables(data,Charm1,Charm2,False,True), + var[key] = var[key][0] + elif key.startswith("Charm"): + var[key] = make_composite_variables() + make_dtf_variables(data, Charm1,Charm2,False,True) + else: + var[key] = make_basic_variables() + make_dtf_variables(data, Charm1,Charm2,True,True) + return var + +def make_fields(Charm1, Charm2, self_conjugate=False): + dec_dict = { + "D0": "(D0 -> K- pi+)", + "Db0": "(D~0 -> K+ pi-)", + "Dp": "(D+ -> K- pi+ pi+)", + "Dm": "(D- -> K+ pi- pi-)", + "Dsp": "(D_s+ -> K- K+ pi+)", + "Dsm": "(D_s- -> K+ K- pi-)", + "lcp": "(Lambda_c+ -> p+ K- pi+)", + "lcm": "(Lambda_c~- -> p~- K+ pi-)", + "xicz": "(Xi_c0 -> p+ K- K- pi+)", + "xicbz": "(Xi_c~0 -> p~- K+ K+ pi-)", + "omegacz": "(Omega_c0 -> p+ K- K- pi+)", + "omegacbz": "(Omega_c~0 -> p~- K+ K+ pi-)", + "jpsi": "(J/psi(1S) -> mu- mu+)", + "psi2s": "(psi(2S) -> mu- mu+)", + } + # Ensure Charm1 and Charm2 are valid keys in dec_dict + if Charm1 not in dec_dict or Charm2 not in dec_dict: + raise ValueError("Invalid Charm1 or Charm2 provided.") + fields = {} + + # Creat the decay descriptor for Charms. + fields["psi"] = "[psi(3770) -> " + dec_dict[Charm1] + " " + dec_dict[Charm2] + "]CC" + fields["Charm1"] = "[psi(3770) -> ^" + dec_dict[Charm1] + " " + dec_dict[Charm2] + "]CC" + fields["Charm2"] = "[psi(3770) -> " + dec_dict[Charm1] + " ^" + dec_dict[Charm2] + "]CC" + + # Creat the decay descriptor for final kaons and pions. + Charm1_split = dec_dict[Charm1].split(" ") + N_final_state1 = len(Charm1_split) - 2 + Charm2_split = dec_dict[Charm2].split(" ") + N_final_state2 = len(Charm2_split) - 2 + for i in range(N_final_state1): + string = Charm1_split[:2+i] + ['^'] + Charm1_split[2+i:] + subdecay = ' '.join(string) + fields["h1"+str(i+1)] = "[psi(3770) -> " + subdecay.replace("^ ", "^") + " " + dec_dict[Charm2] + "]CC" + for i in range(N_final_state2): + string = Charm2_split[:2+i] + ['^'] + Charm2_split[2+i:] + subdecay = ' '.join(string) + fields["h2"+str(i+1)] = "[psi(3770) -> " + dec_dict[Charm1] + " " + subdecay.replace("^ ", "^") + "]CC" + + # Removing 'CC' to avoid double counting. Seems not working. + if self_conjugate: + for key, values in fields.items(): + fields[key] = values[1:-3] + return fields \ No newline at end of file diff --git a/bandq_resprucing/info.yaml b/bandq_resprucing/info.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1f89ab00572995ce029fd6be83da9415b6671f2e --- /dev/null +++ b/bandq_resprucing/info.yaml @@ -0,0 +1,34 @@ +defaults: + application: "DaVinci/v64r13@x86_64_v2-el9-clang16-opt" + output: DATA.ROOT + inform: + - yajing.wei@cern.ch + - mengzhen.wang@cern.ch + wg: BandQ + +{%- set datasets = [ + ('Sprucing24r1', '-Excl-UT', 'Down'), + ('Sprucing24r1', '-Excl-UT', 'Up'), + ('Sprucing24r1', '', 'Down'), + ('Sprucing24r1', '', 'Up'), +]%} +{%- for version, condition, polarity in datasets %} +BandQ_Resprucing_{{ version }}_{{ polarity }}{{ condition }}: + options: + entrypoint: bandq_resprucing.tupling:entry_point + 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" # for SprucingPass, "Hlt2" for RAW data (Hlt2 output) + input_stream: "bandq" # for streamed data + input: + bk_query: "/validation/Collision24/Beam6800GeV-VeloClosed-Mag{{ polarity }}{{ condition }}/Real Data/{{ version }}/90000000/BANDQ.DST" + dq_flags: + - UNCHECKED + - OK + n_test_lfns: 3 +{%- endfor %} diff --git a/bandq_resprucing/tupling.py b/bandq_resprucing/tupling.py new file mode 100644 index 0000000000000000000000000000000000000000..0071b68347a594080c499645d9fb56f88fe18ac4 --- /dev/null +++ b/bandq_resprucing/tupling.py @@ -0,0 +1,33 @@ +from .B2psiX.dv_data import * +from .BforSpectroscopy.dv_data import * +from .double_charm.dv_data_double_charmonia_OS import All as double_charmonia_OS +from .double_charm.dv_data_double_charmonia_SS import All as double_charmonia_SS + +def entry_point(options: Options): + algs_merged = Lb2JpsipK() + algs_merged.update(Lb2Jpsippi()) + algs_merged.update(B2JpsiKpi()) + algs_merged.update(Bp2JpsiphiK()) + algs_merged.update(B2Jpsippbar()) + algs_merged.update(Xib2JpsiLambdaK_LL()) + algs_merged.update(Xib2JpsiLambdaK_DD()) + algs_merged.update(Bp2JpsipLambdabar_LL()) + algs_merged.update(Bp2JpsipLambdabar_DD()) + algs_merged.update(Bp2JpsiKS0pi_LL()) + algs_merged.update(Bp2JpsiKS0pi_DD()) + + algs_merged.update(Bu()) + algs_merged.update(Bd()) + algs_merged.update(Bs()) + algs_merged.update(Bc()) + algs_merged.update(Lb()) + algs_merged.update(Xibm()) + algs_merged.update(Xib0()) + algs_merged.update(Omegab()) + algs_merged.update(SL()) + + + algs_merged.update(double_charmonia_OS()) + algs_merged.update(double_charmonia_SS()) + + return make_config(options, algs_merged) \ No newline at end of file