diff --git a/Lb2D0Lz_run3/dtf_maker.py b/Lb2D0Lz_run3/dtf_maker.py new file mode 100644 index 0000000000000000000000000000000000000000..e6d9bf4cb312524faab88e4451b7cf95c8c7837c --- /dev/null +++ b/Lb2D0Lz_run3/dtf_maker.py @@ -0,0 +1,164 @@ +############################################################################## +# (c) Copyright 2024 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### +"""Configuration functions for DTF +""" +import Functors as F +from Functors.math import log + +from FunTuple import FunctorCollection +from FunTuple.functorcollections import Kinematics + +from DecayTreeFitter import DecayTreeFitter + +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, + "MINIPCHI2" : F.MINIPCHI2(pvs), + "MINIP" : F.MINIP(pvs), + "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_Fix'+ 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_Fix'+ 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( + { + "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), + "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), +# "LOGBPVIPCHI2": log(F.BPVIPCHI2(pvs)), + "BPVLTIME": F.BPVLTIME(pvs), + "MAXBPVIPCHI2": F.MAX(F.BPVIPCHI2(pvs)), #MAX_ + "MINBPVIPCHI2": F.MIN(F.BPVIPCHI2(pvs)), + "MAXBPVIP": F.MAX(F.BPVIP(pvs)), + "MINBPVIP": F.MIN(F.BPVIP(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 += '_Fix' + 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_Fix'+ 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_Fix'+ 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_lb2d0lz(pvs, input_data, ptype): + + if ptype not in ["basic", "composite"]: + Exception(f"I want \'basic\' or \'composite\'. Got {ptype}") + + DTF = DecayTreeFitter( name=f'DTF_{{hash}}' , input_particles=input_data) + DTF_PV = DecayTreeFitter( name=f'DTF_PV_{{hash}}' , input_particles=input_data, input_pvs=pvs) + DTF_PV_FixD = DecayTreeFitter( name=f'DTF_PV_FixD_{{hash}}' , input_particles=input_data, input_pvs=pvs, mass_constraints=["D0"]) + DTF_PV_FixLz = DecayTreeFitter( name=f'DTF_PV_FixLz_{{hash}}' , input_particles=input_data, input_pvs=pvs, mass_constraints=["Lambda0"]) + DTF_PV_FixDLz = DecayTreeFitter( name=f'DTF_PV_FixDLz_{{hash}}' , input_particles=input_data, input_pvs=pvs, mass_constraints=[ "D0", "Lambda0"]) + DTF_PV_FixB = DecayTreeFitter( name=f'DTF_PV_FixB_{{hash}}' , input_particles=input_data, input_pvs=pvs, mass_constraints=["Lambda_b0", "D0", "Lambda0"]) + + 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=DTF_PV, pv_constraint=True, mass_constraint=False) + dtf_vars += make_basic_dtf_variables(pvs, input_data, DTF=DTF_PV_FixD, pv_constraint=True, mass_constraint=True, particle_name="D") + dtf_vars += make_basic_dtf_variables(pvs, input_data, DTF=DTF_PV_FixLz, pv_constraint=True, mass_constraint=True, particle_name="Lz") + dtf_vars += make_basic_dtf_variables(pvs, input_data, DTF=DTF_PV_FixDLz, pv_constraint=True, mass_constraint=True, particle_name="DLz") + dtf_vars += make_basic_dtf_variables(pvs, input_data, DTF=DTF_PV_FixB, pv_constraint=True, mass_constraint=True, particle_name="B") + 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=DTF_PV, pv_constraint=True, mass_constraint=False) + dtf_vars += make_composite_dtf_variables(pvs, input_data, DTF=DTF_PV_FixD, pv_constraint=True, mass_constraint=True, particle_name="D") + dtf_vars += make_composite_dtf_variables(pvs, input_data, DTF=DTF_PV_FixLz, pv_constraint=True, mass_constraint=True, particle_name="Lz") + dtf_vars += make_composite_dtf_variables(pvs, input_data, DTF=DTF_PV_FixDLz, pv_constraint=True, mass_constraint=True, particle_name="DLz") + dtf_vars += make_composite_dtf_variables(pvs, input_data, DTF=DTF_PV_FixB, pv_constraint=True, mass_constraint=True, particle_name="B") + return dtf_vars diff --git a/Lb2D0Lz_run3/dv_Lb2D0Lz.py b/Lb2D0Lz_run3/dv_Lb2D0Lz.py new file mode 100644 index 0000000000000000000000000000000000000000..7edd6a6cbed6ba1ab1f5735cd2f862073d96e1a5 --- /dev/null +++ b/Lb2D0Lz_run3/dv_Lb2D0Lz.py @@ -0,0 +1,495 @@ +import Functors as F +from FunTuple import FunctorCollection as FC +from FunTuple import FunTuple_Particles as Funtuple +from PyConf.reading import get_particles, get_pvs, get_rec_summary, get_odin +from DaVinci.algorithms import create_lines_filter +from DaVinci import Options, make_config +from DaVinciMCTools import MCTruthAndBkgCat +from FunTuple.functorcollections import MCHierarchy, MCPrimaries, MCPromptDecay, Kinematics, SelectionInfo, HltTisTos, MCVertexInfo, MCKinematics, ParticleID, EventInfo +from DecayTreeFitter import DecayTreeFitter +import Functors.math as fmath +from .dtf_maker import make_dtf_variables_lb2d0lz + +_basic = "basic" +_composite = "composite" + +def all_variables(pvs, ptype, nbodydecay=2): + """ + 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 = FC({}) + + comp = _composite == ptype # is composite + basic = _basic == ptype # is not composite + + # First import everything that comes in functorcollections + all_vars += Kinematics() + if basic: + all_vars += ParticleID(extra_info=True) + + 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 comp: + 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_COVARIANCE": F.TRACK_COVARIANCE @ F.TRACKSTATE @ F.TRACK}) + #all_vars.update({"TRACK_POS_CLOSESTTOBEAM_": F.TRACK_POSVEC_CLOSESTTOBEAM}) + #all_vars.update({"POSITION_STATEAT_FirstMeasurement_X" : F.POSITION_X @ F.STATE_AT("FirstMeasurement")@ F.TRACK}) #NB only long tracks + #all_vars.update({"POSITION_STATEAT_FirstMeasurement_Y" : F.POSITION_Y @ F.STATE_AT("FirstMeasurement")@ F.TRACK}) #NB only long tracks + #all_vars.update({"POSITION_STATEAT_FirstMeasurement_Z" : F.POSITION_Z @ F.STATE_AT("FirstMeasurement")@ F.TRACK}) #NB only long tracks + + 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({"POS_COV_MATRIX": F.POS_COV_MATRIX}) + #all_vars.update({"THREE_MOM_COV_MATRIX": F.THREE_MOM_COV_MATRIX}) + + 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: + if nbodydecay == 2: + all_vars.update({"DOCA" : F.DOCA(Child1=1, Child2=2)}) + all_vars.update({"DOCACHI2" : F.DOCACHI2(Child1=1, Child2=2)}) + all_vars.update({"SDOCA" : F.SDOCA(1, 2)}) + all_vars.update({"SDOCACHI2": F.SDOCACHI2(1, 2)}) + all_vars.update({"ALV" : F.ALV(Child1=1, Child2=2)}) + if nbodydecay == 3: + all_vars.update({"DOCA_12" : F.DOCA(Child1=1, Child2=2)}) + all_vars.update({"DOCA_13" : F.DOCA(Child1=1, Child2=3)}) + all_vars.update({"DOCA_23" : F.DOCA(Child1=2, Child2=3)}) + all_vars.update({"DOCACHI2_12" : F.DOCACHI2(Child1=1, Child2=2)}) + all_vars.update({"DOCACHI2_13" : F.DOCACHI2(Child1=1, Child2=3)}) + all_vars.update({"DOCACHI2_23" : F.DOCACHI2(Child1=2, Child2=3)}) + all_vars.update({"SDOCA_12" : F.SDOCA(Child1=1, Child2=2)}) + all_vars.update({"SDOCA_13" : F.SDOCA(Child1=1, Child2=3)}) + all_vars.update({"SDOCA_23" : F.SDOCA(Child1=2, Child2=3)}) + all_vars.update({"SDOCACHI2_12": F.SDOCACHI2(Child1=1, Child2=2)}) + all_vars.update({"SDOCACHI2_13": F.SDOCACHI2(Child1=1, Child2=3)}) + all_vars.update({"SDOCACHI2_23": F.SDOCACHI2(Child1=2, Child2=3)}) + all_vars.update({"MM12" : F.SUBCOMB(Functor=F.MASS, Indices=(1, 2))}) + all_vars.update({"MM13" : F.SUBCOMB(Functor=F.MASS, Indices=(1, 3))}) + all_vars.update({"MM23" : F.SUBCOMB(Functor=F.MASS, Indices=(2, 3))}) + all_vars.update({"ALV_12" : F.ALV(Child1=1, Child2=2)}) + all_vars.update({"ALV_13" : F.ALV(Child1=1, Child2=3)}) + all_vars.update({"ALV_23" : F.ALV(Child1=2, Child2=3)}) + if nbodydecay == 4: + all_vars.update({"DOCA_12" : F.DOCA(Child1=1, Child2=2)}) + all_vars.update({"DOCA_13" : F.DOCA(Child1=1, Child2=3)}) + all_vars.update({"DOCA_14" : F.DOCA(Child1=1, Child2=4)}) + all_vars.update({"DOCA_23" : F.DOCA(Child1=2, Child2=3)}) + all_vars.update({"DOCA_24" : F.DOCA(Child1=2, Child2=4)}) + all_vars.update({"DOCA_34" : F.DOCA(Child1=3, Child2=4)}) + all_vars.update({"DOCACHI2_12" : F.DOCACHI2(Child1=1, Child2=2)}) + all_vars.update({"DOCACHI2_13" : F.DOCACHI2(Child1=1, Child2=3)}) + all_vars.update({"DOCACHI2_14" : F.DOCACHI2(Child1=1, Child2=4)}) + all_vars.update({"DOCACHI2_23" : F.DOCACHI2(Child1=2, Child2=3)}) + all_vars.update({"DOCACHI2_24" : F.DOCACHI2(Child1=2, Child2=4)}) + all_vars.update({"DOCACHI2_34" : F.DOCACHI2(Child1=3, Child2=4)}) + all_vars.update({"SDOCA_12" : F.SDOCA(Child1=1, Child2=2)}) + all_vars.update({"SDOCA_13" : F.SDOCA(Child1=1, Child2=3)}) + all_vars.update({"SDOCA_14" : F.SDOCA(Child1=1, Child2=4)}) + all_vars.update({"SDOCA_23" : F.SDOCA(Child1=2, Child2=3)}) + all_vars.update({"SDOCA_24" : F.SDOCA(Child1=2, Child2=4)}) + all_vars.update({"SDOCA_34" : F.SDOCA(Child1=3, Child2=4)}) + all_vars.update({"SDOCACHI2_12": F.SDOCACHI2(Child1=1, Child2=2)}) + all_vars.update({"SDOCACHI2_13": F.SDOCACHI2(Child1=1, Child2=3)}) + all_vars.update({"SDOCACHI2_14": F.SDOCACHI2(Child1=1, Child2=4)}) + all_vars.update({"SDOCACHI2_23": F.SDOCACHI2(Child1=2, Child2=3)}) + all_vars.update({"SDOCACHI2_24": F.SDOCACHI2(Child1=2, Child2=4)}) + all_vars.update({"SDOCACHI2_34": F.SDOCACHI2(Child1=3, Child2=4)}) + all_vars.update({"MM12" : F.SUBCOMB(Functor=F.MASS, Indices=(1, 2))}) + all_vars.update({"MM13" : F.SUBCOMB(Functor=F.MASS, Indices=(1, 3))}) + all_vars.update({"MM14" : F.SUBCOMB(Functor=F.MASS, Indices=(1, 4))}) + all_vars.update({"MM23" : F.SUBCOMB(Functor=F.MASS, Indices=(2, 3))}) + all_vars.update({"MM24" : F.SUBCOMB(Functor=F.MASS, Indices=(2, 4))}) + all_vars.update({"MM34" : F.SUBCOMB(Functor=F.MASS, Indices=(3, 4))}) + all_vars.update({"ALV_12" : F.ALV(Child1=1, Child2=2)}) + all_vars.update({"ALV_13" : F.ALV(Child1=1, Child2=3)}) + all_vars.update({"ALV_14" : F.ALV(Child1=1, Child2=4)}) + all_vars.update({"ALV_23" : F.ALV(Child1=2, Child2=3)}) + all_vars.update({"ALV_24" : F.ALV(Child1=2, Child2=4)}) + all_vars.update({"ALV_34" : F.ALV(Child1=3, Child2=4)}) + if basic: + all_vars.update({"SHOWER_SHAPE": F.CALO_NEUTRAL_SHOWER_SHAPE}) + + if comp: + 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): + """ + event variables + """ + + evt_vars = FC({}) + evt_vars += EventInfo() + + + + if ODIN: + evt_vars.update({"EVENTTYPE": F.EVENTTYPE(ODIN)}) + + evt_vars.update({"PV_SIZE": F.SIZE(PVs)}) + + + + print(f"### For event returning variables {evt_vars.functor_dict.keys()}") + return evt_vars + +############################################################## + +#### Lb->D0DstmKp + +############################################################## + +def alg_config_LbToD0Lz(options:Options): + name,line_data,my_filter={},{},{} + for tracktype in ["LL","DD"]: + for Dstate in ["HH","HHHH"]: + name[f"{tracktype}_{Dstate}"]=f"LbToD0Lz{tracktype}_D02{Dstate}" + line=f"SpruceB2OC_LbToLambda{tracktype}D0_D0To{Dstate}" + evtpath_prefix = "/Event/Spruce/" + line_data[f"{tracktype}_{Dstate}"] =get_particles(f"{evtpath_prefix}{line}/Particles") + my_filter[f"{tracktype}_{Dstate}"] = create_lines_filter(name=f"PreFilter_{line}", lines=[f"{line}"]) + + 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", + ] + Hlt2_decisions = ['Hlt2Topo2BodyDecision', 'Hlt2Topo3BodyDecision', 'Hlt2Topo4BodyDecision'] + + + all_fields = {} + for tracktype in ["LL","DD"]: + all_fields[f"Lb2D0Lz{tracktype}_D02HH"] = { + 'Lb': '[Lambda_b0 -> ([D0]CC -> K- pi+) (Lambda0 -> p+ pi-) ]CC', +# + 'Dz': '[Lambda_b0 -> ^([D0]CC -> K- pi+) (Lambda0 -> p+ pi-) ]CC', + 'Lz': '[Lambda_b0 -> ([D0]CC -> K- pi+) ^(Lambda0 -> p+ pi-) ]CC', +# + 'Dz_Km': '[Lambda_b0 -> ([D0]CC -> ^K- pi+) (Lambda0 -> p+ pi-) ]CC', + 'Dz_pip': '[Lambda_b0 -> ([D0]CC -> K- ^pi+) (Lambda0 -> p+ pi-) ]CC', + 'Lz_pp': '[Lambda_b0 -> ([D0]CC -> K- pi+) (Lambda0 -> ^p+ pi-) ]CC', + 'Lz_pim': '[Lambda_b0 -> ([D0]CC -> K- pi+) (Lambda0 -> p+ ^pi-) ]CC', + } + all_fields[f"Lb2D0Lz{tracktype}_D02HHHH"] = { + 'Lb': '[Lambda_b0 -> ([D0]CC -> K- pi+ pi- pi+) (Lambda0 -> p+ pi-) ]CC', +# + 'Dz': '[Lambda_b0 -> ^([D0]CC -> K- pi+ pi- pi+) (Lambda0 -> p+ pi-) ]CC', + 'Lz': '[Lambda_b0 -> ([D0]CC -> K- pi+ pi- pi+) ^(Lambda0 -> p+ pi-) ]CC', +# + 'Dz_Km': '[Lambda_b0 -> ([D0]CC -> ^K- pi+ pi- pi+) (Lambda0 -> p+ pi-) ]CC', + 'Dz_pip1': '[Lambda_b0 -> ([D0]CC -> K- ^pi+ pi- pi+) (Lambda0 -> p+ pi-) ]CC', + 'Dz_pim': '[Lambda_b0 -> ([D0]CC -> K- pi+ ^pi- pi+) (Lambda0 -> p+ pi-) ]CC', + 'Dz_pip2': '[Lambda_b0 -> ([D0]CC -> K- pi+ pi- ^pi+) (Lambda0 -> p+ pi-) ]CC', + 'Lz_pp': '[Lambda_b0 -> ([D0]CC -> K- pi+ pi- pi+) (Lambda0 -> ^p+ pi-) ]CC', + 'Lz_pim': '[Lambda_b0 -> ([D0]CC -> K- pi+ pi- pi+) (Lambda0 -> p+ ^pi-) ]CC', + } + + # Creating v2 reconstructed vertices to be used in the following functor + pvs = get_pvs() + + b_composite_variables = FC( + { + "ID" : F.PARTICLE_ID, + "END_VCHI2DOF": F.CHI2DOF @ F.ENDVERTEX, + "BPVCHI2DOF" : F.CHI2DOF @ F.BPV(pvs), + "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, + # B2OC generic B hadron NN Hlt2 algorithm, + # not planning to use it directly for B2OC EM + "MVA": F.MVA( + MVAType="SigmaNet", + Config={ + "File": + "paramfile://data/Hlt2B2OC_B_SigmaNet_Run3-v2.json", + "Name": + "B2OC_SigmaNet_Generic", + "Lambda": + "2.0", + "NLayers": + "3", + "InputSize": + "6", + "Monotone_Constraints": + "[1,-1,-1,-1,-1,-1]", + "Variables": + "log_B_PT,B_ETA,log_B_DIRA,log_B_ENDVERTEX_CHI2,log_B_IPCHI2_OWNPV,log_B_IP_OWNPV", + }, + Inputs={ + "log_B_PT" : fmath.log(F.PT), + "B_ETA" : F.ETA, + "log_B_DIRA" : fmath.log(1. + 1.e-6 - F.BPVDIRA(pvs)), + "log_B_ENDVERTEX_CHI2": fmath.log(F.CHI2DOF), + "log_B_IPCHI2_OWNPV" : fmath.log(F.BPVIPCHI2(pvs)), + "log_B_IP_OWNPV" : fmath.log(F.BPVIP(pvs)), + }), + } + ) + composite_variables = FC( + { + "ID" : F.PARTICLE_ID, + "END_VCHI2DOF": F.CHI2DOF @ F.ENDVERTEX, + "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, + } + ) + com_vars={} + for tracktype in ["LL","DD"]: + for Dstate in ["HH","HHHH"]: + com_vars[f"{tracktype}_{Dstate}"]=composite_variables+HltTisTos( selection_type="Hlt1", trigger_lines=Hlt1_decisions, data=line_data[f"{tracktype}_{Dstate}"])+HltTisTos( selection_type="Hlt2", trigger_lines=Hlt2_decisions, data=line_data[f"{tracktype}_{Dstate}"]) + + daughter_variables = FC( + { + "ID" : F.PARTICLE_ID, + "PIDK" : F.PID_K, + "PIDp" : F.PID_P, + "PIDe" : F.PID_E, + "PIDmu" : F.PID_MU, + "ProbNNp" : F.PROBNN_P, + "ProbNNpi" : F.PROBNN_PI, + "ProbNNk" : F.PROBNN_K, + } + ) + variables={} + for tracktype in ["LL","DD"]: + for Dstate in ["HH","HHHH"]: + variables[f"{tracktype}_{Dstate}"]={ + "Lb" : all_variables(pvs, _composite, 2) + b_composite_variables + make_dtf_variables_lb2d0lz(pvs, line_data[f"{tracktype}_{Dstate}"], _composite), + "Lz" : all_variables(pvs, _composite, 2) + composite_variables + make_dtf_variables_lb2d0lz(pvs, line_data[f"{tracktype}_{Dstate}"], _composite), + "Lz_pp" : all_variables(pvs, _basic ) + daughter_variables + make_dtf_variables_lb2d0lz(pvs, line_data[f"{tracktype}_{Dstate}"], _basic), + "Lz_pim" : all_variables(pvs, _basic ) + daughter_variables + make_dtf_variables_lb2d0lz(pvs, line_data[f"{tracktype}_{Dstate}"], _basic), + } + if Dstate=="HH": + variables[f"{tracktype}_{Dstate}"]["Dz"] = all_variables(pvs, _composite, 2) + composite_variables + make_dtf_variables_lb2d0lz(pvs, line_data[f"{tracktype}_{Dstate}"], _composite) + variables[f"{tracktype}_{Dstate}"]["Dz_Km"] = all_variables(pvs, _basic ) + daughter_variables + make_dtf_variables_lb2d0lz(pvs, line_data[f"{tracktype}_{Dstate}"], _basic) + variables[f"{tracktype}_{Dstate}"]["Dz_pip"] = all_variables(pvs, _basic ) + daughter_variables + make_dtf_variables_lb2d0lz(pvs, line_data[f"{tracktype}_{Dstate}"], _basic) + elif Dstate=="HHHH": + variables[f"{tracktype}_{Dstate}"]["Dz"] = all_variables(pvs, _composite, 4) + composite_variables + make_dtf_variables_lb2d0lz(pvs, line_data[f"{tracktype}_{Dstate}"], _composite) + variables[f"{tracktype}_{Dstate}"]["Dz_Km"] = all_variables(pvs, _basic ) + daughter_variables + make_dtf_variables_lb2d0lz(pvs, line_data[f"{tracktype}_{Dstate}"], _basic) + variables[f"{tracktype}_{Dstate}"]["Dz_pip1"] = all_variables(pvs, _basic ) + daughter_variables + make_dtf_variables_lb2d0lz(pvs, line_data[f"{tracktype}_{Dstate}"], _basic) + variables[f"{tracktype}_{Dstate}"]["Dz_pim"] = all_variables(pvs, _basic ) + daughter_variables + make_dtf_variables_lb2d0lz(pvs, line_data[f"{tracktype}_{Dstate}"], _basic) + variables[f"{tracktype}_{Dstate}"]["Dz_pip2"] = all_variables(pvs, _basic ) + daughter_variables + make_dtf_variables_lb2d0lz(pvs, line_data[f"{tracktype}_{Dstate}"], _basic) + else: + print("expect HH or HHHH!") + exit() + + if options.simulation: + # get configured "MCTruthAndBkgCatAlg" algorithm for HLT2 output + mctruth = MCTruthAndBkgCat(line_data[f"{tracktype}_{Dstate}"]) + # add helper lambda that configures a functor to get truth information + MCTRUTH = lambda func: F.MAP_INPUT(Functor=func, Relations=mctruth.MCAssocTable) + trueid_bkgcat_info = { + # Important note: specify an invalid value for integer functors if there exists no truth info. + # The invalid value for floating point functors is set to nan. + "TRUEID" : F.VALUE_OR(0) @ MCTRUTH(F.PARTICLE_ID), + "TRUEKEY" : F.VALUE_OR(-1) @ MCTRUTH(F.OBJECT_KEY), + "TRUEPT" : MCTRUTH(F.PT), + "TRUEPX" : MCTRUTH(F.PX), + "TRUEPY" : MCTRUTH(F.PY), + "TRUEPZ" : MCTRUTH(F.PZ), + "TRUEENERGY" : MCTRUTH(F.ENERGY), + "TRUEP" : MCTRUTH(F.P), + "TRUEFOURMOMENTUM": MCTRUTH(F.FOURMOMENTUM), + "BKGCAT" : F.BKGCAT(Relations=mctruth.BkgCatTable), + } + for field in variables[f"{tracktype}_{Dstate}"].keys(): + variables[f"{tracktype}_{Dstate}"][field] += FC(trueid_bkgcat_info) + + #define event level variables + odin = get_odin() + decreports = None + rec_sum=get_rec_summary() + evt_variables = event_variables(pvs, odin) + FC({ + "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), + }) + + evt_variables += SelectionInfo( + selection_type="Hlt1", trigger_lines=Hlt1_decisions + ) + evt_variables += SelectionInfo( + selection_type="Hlt2", trigger_lines=Hlt2_decisions + ) + + + # define FunTuple instance + user_algorithms = {} + my_tuple={} + for tracktype in ["LL","DD"]: + for Dstate in ["HH","HHHH"]: + my_tuple[f"{tracktype}_{Dstate}"] = Funtuple( + name=f"{tracktype}_{Dstate}", + tuple_name="DecayTree", + fields=all_fields[f"Lb2D0Lz{tracktype}_D02{Dstate}"], + variables=variables[f"{tracktype}_{Dstate}"], + event_variables=evt_variables, + inputs=line_data[f"{tracktype}_{Dstate}"], + store_multiple_cand_info=True + ) + user_algorithms[f"{tracktype}_{Dstate}"]= [my_filter[f"{tracktype}_{Dstate}"], my_tuple[f"{tracktype}_{Dstate}"]] + + + return make_config(options, user_algorithms) + + + diff --git a/Lb2D0Lz_run3/info.yaml b/Lb2D0Lz_run3/info.yaml new file mode 100644 index 0000000000000000000000000000000000000000..94da0a598ad20f3a675a7ec946f29db2885eea3d --- /dev/null +++ b/Lb2D0Lz_run3/info.yaml @@ -0,0 +1,40 @@ +defaults: + application: "DaVinci/v64r10@x86_64_v2-el9-clang16-opt" + output: DATA.ROOT + inform: + - dong.ao@cern.ch + wg: B2OC + +{%- set datasets = [ + ('2024Data', 'MagDown', '24c2'), + ('2024Data', 'MagUp', '24c2'), + ('2024Data', 'MagUp', '24c3'), + ('2024Data', 'MagDown', '24c3'), + ('2024Data', 'MagDown', '24c4'), +]%} + + + +{%- for evttype, polarity, campain in datasets %} + +Lb2D0Lz_{{ evttype }}_{{ polarity }}_{{ campain }}: + options: + entrypoint: Lb2D0Lz_run3.dv_Lb2D0Lz:alg_config_LbToD0Lz + 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: "b2oc" # for streamed data + input: + bk_query: "/LHCb/Collision24/Beam6800GeV-VeloClosed-{{ polarity }}/Real Data/Sprucing{{ campain }}/90000000/B2OC.DST" + dq_flags: + - UNCHECKED + - OK + keep_running: true + n_test_lfns: 1 + +{%- endfor %}