diff --git a/Lb2Lc3Pi/Lb2Lc3Pi.py b/Lb2Lc3Pi/Lb2Lc3Pi.py new file mode 100644 index 0000000000000000000000000000000000000000..431f7d253b32a6035d0177ed6347f05c74137e67 --- /dev/null +++ b/Lb2Lc3Pi/Lb2Lc3Pi.py @@ -0,0 +1,321 @@ +import Functors as F +import Functors.math as fmath +from DaVinci import Options, make_config +from DaVinci.algorithms import create_lines_filter +from PyConf.reading import get_particles, get_pvs +from Functors.math import log +from FunTuple import FunctorCollection, FunTuple_Particles as FunTuple +from PyConf.application import metainfo_repos +from FunTuple.functorcollections import DecayTreeFitterResults, Kinematics, ParticleID, EventInfo, HltTisTos, SelectionInfo + + + +Hlt1_decisions = [ + "Hlt1TrackMVA", + "Hlt1TwoTrackMVA", + "Hlt1TwoTrackMVACharmXSec", + "Hlt1TwoTrackKs", + "Hlt1KsToPiPi", + "Hlt1GECPassthrough" + 'Hlt1D2KK', + 'Hlt1D2KPi', + 'Hlt1D2PiPi', + 'Hlt1DiMuonHighMass', + 'Hlt1DiMuonLowMass', + 'Hlt1DiMuonSoft', + 'Hlt1LowPtMuon', + 'Hlt1LowPtDiMuon', + 'Hlt1SingleHighPtMuon', + 'Hlt1TrackMuonMVA' +] + +Hlt2_decisions = [ + "Hlt2Topo2Body","Hlt2Topo3Body","Hlt2Topo4Body" +] + + +def make_tistos_hlt1(data): + return HltTisTos( + selection_type="Hlt1", + trigger_lines=[ + f"{x}Decision" for x in Hlt1_decisions if "GECPassthrough" not in x + ], + data=data, + ) + + +# Only for Sprucing -- needs to be reconfigured +def make_tistos_hlt2(data): + return HltTisTos( + selection_type="Hlt2", + trigger_lines=[f"{x}Decision" for x in Hlt2_decisions], + data=data, + ) + + +def make_comp_variables(data): + v2_pvs = get_pvs() + + variables = FunctorCollection({ + "MAX_PT": + F.MAX(F.PT), + "MIN_PT": + F.MIN(F.PT), + "SUM_PT": + F.SUM(F.PT), + "MAX_P": + F.MAX(F.P), + "MIN_P": + F.MIN(F.P), + "BPVDIRA": + F.BPVDIRA(v2_pvs), + "BPVFDIR": + F.BPVFDIR(v2_pvs), + "CHI2VXNDOF": + F.CHI2DOF, + "BPVFDCHI2": + F.BPVFDCHI2(v2_pvs), + "BPVFD": + F.BPVFD(v2_pvs), + "BPVFDVEC": + F.BPVFDVEC(v2_pvs), + "BPVVDRHO": + F.BPVVDRHO(v2_pvs), + "BPVVDX": + F.BPVVDX(v2_pvs), + "BPVVDY": + F.BPVVDY(v2_pvs), + "BPVVDZ": + F.BPVVDZ(v2_pvs), + "BPVDLS": + F.BPVDLS(v2_pvs), + "BPVIPCHI2": + F.BPVIPCHI2(v2_pvs), + "BPVCORRM": + F.BPVCORRM(v2_pvs), + "BPVCORRMERR": + F.BPVCORRMERR(v2_pvs), + "BPVIP": + F.BPVIP(v2_pvs), + "LOGBPVIPCHI2": + log(F.BPVIPCHI2(v2_pvs)), + "BPVLTIME": + F.BPVLTIME(v2_pvs), + "MAX_BPVIPCHI2": + F.MAX(F.BPVIPCHI2(v2_pvs)), + "MIN_BPVIPCHI2": + F.MIN(F.BPVIPCHI2(v2_pvs)), + "MAXDOCACHI2": + F.MAXDOCACHI2, + "MAXDOCA": + F.MAXDOCA, + "MAXSDOCACHI2": + F.MAXSDOCACHI2, + "MAXSDOCA": + F.MAXSDOCA, + "MM12": + F.SUBCOMB(Functor=F.MASS, Indices=(1, 2)), + "MM13": + F.SUBCOMB(Functor=F.MASS, Indices=(1, 3)), + "ETA": + F.ETA, + "PHI": + F.PHI, + "END_VX": + F.END_VX, + "END_VY": + F.END_VY, + "END_VZ": + F.END_VZ, + "BPVX": + F.BPVX(v2_pvs), + "BPVY": + F.BPVY(v2_pvs), + "BPVZ": + F.BPVZ(v2_pvs), + }) + + variables += Kinematics() + variables += ParticleID(extra_info=True) + variables += make_tistos_hlt1(data) + variables += make_tistos_hlt2(data) #-- Only for Sprucing + + return variables + + +def make_basic_variables(data): + v2_pvs = get_pvs() + + variables = FunctorCollection({ + "TRCHI2DOF": + F.CHI2DOF, + "TRGHOSTPROB": + F.GHOSTPROB, + "BPVIPCHI2": + F.BPVIPCHI2(v2_pvs), + "PIDK": + F.PID_K, + "PIDe": + F.PID_E, + "PIDmu": + F.PID_MU, + "PIDp": + F.PID_P, + "ISMUON": + F.ISMUON, + "BPVIP": + F.BPVIP(v2_pvs), + "ETA": + F.ETA, + "PHI": + F.PHI, + #some track-related variables + "NDOF": + F.VALUE_OR(-1) @ F.NDOF @ F.TRACK, + "NFTHITS": + F.VALUE_OR(-1) @ F.NFTHITS @ F.TRACK, + "NHITS": + F.VALUE_OR(-1) @ F.NHITS @ F.TRACK, + "NUTHITS": + F.VALUE_OR(-1) @ F.NUTHITS @ F.TRACK, + "NVPHITS": + F.VALUE_OR(-1) @ F.NVPHITS @ F.TRACK, + "TRACKHASVELO": + F.VALUE_OR(-1) @ F.TRACKHASVELO @ F.TRACK, + "TRACKHISTORY": + F.VALUE_OR(-1) @ F.TRACKHISTORY @ F.TRACK, + "TRACKPT": + F.TRACK_PT, + "ISMUON": + F.ISMUON, + "INMUON": + F.INMUON, + "INECAL": + F.INECAL, + "INHCAL": + F.INHCAL, + }) + + variables += Kinematics() + variables += ParticleID(extra_info=True) + variables += make_tistos_hlt1(data) + + return variables + + +def make_hlt2_event_variables(line_name, line_data): + v2_pvs = get_pvs() + + evt_variables = EventInfo() + evt_variables += SelectionInfo( + selection_type="Hlt1", trigger_lines=Hlt1_decisions) + evt_variables += SelectionInfo( + selection_type="Hlt2", trigger_lines=Hlt2_decisions) + evt_variables += FunctorCollection({ + "NPV": F.SIZE(v2_pvs), + "ALLPVX[NPVs]": F.ALLPVX(v2_pvs), + "ALLPVY[NPVs]": F.ALLPVY(v2_pvs), + "ALLPVZ[NPVs]": F.ALLPVZ(v2_pvs), + }) + return evt_variables + + +def DecayTreeFitter(data, + pv_fit=True, + mass_fit=False, + prefix="DTF", + mass_constraints=[]): + from DecayTreeFitter import DecayTreeFitter + pvs = get_pvs() + variables = FunctorCollection() + variables += Kinematics() + if pv_fit: + DTF = DecayTreeFitter( + name='PV_Fit_{hash}', + input_particles=data, + input_pvs=pvs, + ) + variables += DecayTreeFitterResults( + DTF=DTF, + prefix=prefix + "_PV_", + decay_origin=True, + with_lifetime=True, + with_kinematics=True) + + if mass_fit: + DTFM_excl = DecayTreeFitter( + name='PVandMass_Fit_{hash}', + input_particles=data, + input_pvs=pvs, + mass_constraints=mass_constraints) + variables += DecayTreeFitterResults( + DTF=DTFM_excl, + prefix=prefix + "_PVandMass_", + decay_origin=True, + with_lifetime=True, + with_kinematics=True) + + return variables + +def SpruceB2OC_LbToLcpPiPiPi_LcpToPKPi_Tuple(): + + ################################################### + + spruce_line = "SpruceB2OC_LbToLcpPiPiPi_LcpToPKPi" + + input_data = get_particles(f"/Event/Spruce/{spruce_line}/Particles") + + evt_vars = make_hlt2_event_variables(spruce_line, line_data=input_data) + + fields = { + 'Lb': '[Lambda_b0 -> (Lambda_c+ -> p+ K- pi+) pi- pi+ pi-]CC', + 'LbPi1': '[Lambda_b0 -> (Lambda_c+ -> p+ K- pi+) ^pi- pi+ pi-]CC', + 'LbPi2': '[Lambda_b0 -> (Lambda_c+ -> p+ K- pi+) pi- ^pi+ pi-]CC', + 'LbPi3': '[Lambda_b0 -> (Lambda_c+ -> p+ K- pi+) pi- pi+ ^pi-]CC', + 'Lc': '[Lambda_b0 -> ^(Lambda_c+ -> p+ K- pi+) pi- pi+ pi-]CC', + 'LcP': '[Lambda_b0 -> (Lambda_c+ -> ^p+ K- pi+) pi- pi+ pi-]CC', + 'LcK': '[Lambda_b0 -> (Lambda_c+ -> p+ ^K- pi+) pi- pi+ pi-]CC', + 'LcPi': '[Lambda_b0 -> (Lambda_c+ -> p+ K- ^pi+) pi- pi+ pi-]CC', + } + + + variables = { + "Lb":make_comp_variables(input_data) + DecayTreeFitter(input_data), + "LbPi1":make_basic_variables(input_data), + "LbPi2":make_basic_variables(input_data), + "LbPi3":make_basic_variables(input_data), + "Lc":make_comp_variables(input_data), + "LcP": make_basic_variables(input_data), + "LcK": make_basic_variables(input_data), + "LcPi": make_basic_variables(input_data), + } + + my_tuple = FunTuple( + name="Tuple", + tuple_name="DecayTree", + inputs=input_data, + fields=fields, + variables=variables, + event_variables=evt_vars) + + my_filter = create_lines_filter( + name=f"HDRFilter_{spruce_line}", lines=[f'{spruce_line}']) + + ################################################### + + user_algorithms = {} + user_algorithms.update({"LbToLcpPiPiPi": [my_filter, my_tuple]}) + + return user_algorithms + + + +### CONFIG definition ### + + +def main(options: Options): + + all_user_algorithms = {} + all_user_algorithms.update(SpruceB2OC_LbToLcpPiPiPi_LcpToPKPi_Tuple()) + + return make_config(options, all_user_algorithms) diff --git a/Lb2Lc3Pi/info.yaml b/Lb2Lc3Pi/info.yaml new file mode 100644 index 0000000000000000000000000000000000000000..60163a1ebab4ac1e2dccdda59dada04dcfae4721 --- /dev/null +++ b/Lb2Lc3Pi/info.yaml @@ -0,0 +1,41 @@ +defaults: + inform: + - jiaqi.yang@cern.ch + wg: B2OC + + {%- set datasets = [ + ('2024Data', 'MagUp', '24c2'), + ('2024Data', 'MagUp', '24c3'), + ('2024Data', 'MagUp', '24c4'), + ('2024Data', 'MagDown', '24c2'), + ('2024Data', 'MagDown', '24c3'), + ('2024Data', 'MagDown', '24c4'), +('2024Data', 'MagDown-Excl-UT', '24c1'), + ('2024Data', 'MagDown-Excl-UT', '24c2'), + ('2024Data', 'MagUp-Excl-UT', '24c1'), + ('2024Data', 'MagUp-Excl-UT', '24c2'), +]%} + + {%- for evttype, polarity, campain in datasets %} +Lb2Lc3Pi_{{ evttype }}_{{ polarity }}_{{ campain }}: + application: DaVinci/v64r9 + input: + bk_query: "/LHCb/Collision24/Beam6800GeV-VeloClosed-{{ polarity }}/Real Data/Sprucing{{ campain }}/90000000/B2OC.DST" + dq_flags: + - OK + - UNCHECKED + keep_running: true + n_test_lfns: 1 + output: DATA.ROOT + options: + entrypoint: Lb2Lc3Pi.Lb2Lc3Pi:main + extra_options: + input_raw_format: 0.5 + input_type: ROOT + simulation: False + data_type: "Upgrade" + geometry_version: run3/2024.Q1.2-v00.00 + conditions_version: master + input_process: "Spruce" + input_stream: "b2oc" +{%- endfor %}