diff --git a/bs2ksks-run3/davinci_options_data.py b/bs2ksks-run3/davinci_options_data.py new file mode 100644 index 0000000000000000000000000000000000000000..c7b3b586447c9d2861f238a9d153a62c432278b5 --- /dev/null +++ b/bs2ksks-run3/davinci_options_data.py @@ -0,0 +1,289 @@ +from PyConf.reading import get_particles, get_pvs + +from DaVinci import make_config, Options +from DaVinci.algorithms import create_lines_filter +from FunTuple import FunTuple_Particles as Funtuple +from FunTuple import FunctorCollection +import FunTuple.functorcollections as FC +import Functors as F + +# First create a new B list with unbiased PVs +from PyConf.reading import get_extended_pvs +from PyConf.Algorithms import ParticleUnbiasedPVAdder +from DecayTreeFitter import DecayTreeFitter +def main(options: Options): + #line = "Hlt2BnoC_BdsToKSKS_LLLL" #need to add the downstream tracks later + #line = "Hlt2BnoC_BdsToKSKS_LLDD" + #line = "Hlt2BnoC_BdsToKSKS_DDDD" + #data = get_particles(f"/Event/HLT2/{line}/Particles") + #line_prefilter = create_lines_filter(name=f"PreFilter_{line}", lines=[line]) + + + + line = "Hlt2BnoC_BdsToKSKS_LLLL" #need to add the downstream tracks later + from PyConf.Algorithms import ParticleContainerMerger + line_name_ll = 'Hlt2BnoC_BdsToKSKS_LLLL' + line_name_dd = 'Hlt2BnoC_BdsToKSKS_DDDD' + line_name_ld = 'Hlt2BnoC_BdsToKSKS_LLDD' + bz_data_dd = get_particles(f'/Event/HLT2/{line_name_dd}/Particles') + bz_data_ll = get_particles(f'/Event/HLT2/{line_name_ll}/Particles') + bz_data_ld = get_particles(f'/Event/HLT2/{line_name_ld}/Particles') + + #combined_particles = ParticleContainerMerger( + data = ParticleContainerMerger( + name = 'particles_merger', + InputContainers = [bz_data_dd, bz_data_ll, bz_data_ld], + ).OutputContainer + + + line_prefilter = create_lines_filter(name=f"PreFilter_Hlt2BnoC_BdsToKSKS", lines=[line_name_ll,line_name_dd,line_name_ld]) + + + + pvs = get_pvs() + fields = { + 'Bs': '[B_s0 -> (KS0 -> pi+ pi-) (KS0 -> pi+ pi-)]CC', + 'V1': '[B_s0 -> ^(KS0 -> pi+ pi-) (KS0 -> pi+ pi-)]CC', + 'V2': '[B_s0 -> (KS0 -> pi+ pi-) ^(KS0 -> pi+ pi-)]CC', + 'hp1': '[B_s0 -> (KS0 -> ^pi+ pi-) (KS0 -> pi+ pi-)]CC', + 'hm1': '[B_s0 -> (KS0 -> pi+ ^pi-) (KS0 -> pi+ pi-)]CC', + 'hp2': '[B_s0 -> (KS0 -> pi+ pi-) (KS0 -> ^pi+ pi-)]CC', + 'hm2': '[B_s0 -> (KS0 -> pi+ pi-) (KS0 -> pi+ ^pi-)]CC', + } + + variables = FunctorCollection({ + "M": F.MASS, + "P": F.P, + "PT": F.PT, + "ENERGY": F.ENERGY, + "PX": F.PX, + "PY": F.PY, + "PZ": F.PZ, + "ID": F.PARTICLE_ID, # PDG ID of the particle + "Q": F.CHARGE, # Electric charge + "ETA": F.ETA, # Pseudorapidity + "PHI": F.PHI, # Azimuthal angle + "CHI2": F.CHI2, # χ² + "CHI2DOF": F.CHI2DOF, # χ² of degrees of freedom + "OWNPVIP": F.OWNPVIP, # Impact parameter wrt own PV + "OWNPVIPCHI2": F.OWNPVIPCHI2, # Impact parameter χ² wrt own PV + + }) + + + base_composite_variables = FunctorCollection({ + "VTXCHI2NDOF": F.CHI2DOF, # Vertex fit χ²/ndf + "END_VX": F.END_VX, # x-coordinate of decay vertex + "END_VY": F.END_VY, # y-coordinate of decay vertex + "END_VZ": F.END_VZ, # z-coordinate of decay vertex + # OWNPV values + "OWNPV_X": F.OWNPVX, # x-coordinate of best PV + "OWNPV_Y": F.OWNPVY, # y-coordinate of best PV + "OWNPV_Z": F.OWNPVZ, # z-coordinate of best PV + "OWNPV_DIRA": F.OWNPVDIRA, # Direction angle cosine wrt own PV + "OWNPV_FD": F.OWNPVFD, # Flight distance wrt own PV + "OWNPV_FDCHI2": F.OWNPVFDCHI2, # Flight distance χ² wrt own PV + "OWNPV_VDRHO": F.OWNPVVDRHO, # Radial flight distance wrt own PV + "OWNPV_VDZ": F.OWNPVVDZ, # z-direction flight distance + "OWNPV_LTIME": F.OWNPVLTIME, # Proper lifetime + "OWNPV_DLS": F.OWNPVDLS, # Decay length significance + # DOCA + "DOCA12": F.DOCA(1, 2), # DOCA between first and second daughter + "DOCA12CHI2": F.DOCACHI2(1, 2), # DOCA χ² between first and second daughter + # Daughter Max, Min and Sums + "MAX_PT": F.MAX(F.PT), # Maximum PT of daughters + "MIN_PT": F.MIN(F.PT), # Minimum PT of daughters + "SUM_PT": F.SUM(F.PT), # Sum of daughters' PT + "MAX_P": F.MAX(F.P), # Maximum momentum of daughters + "MIN_P": F.MIN(F.P), # Minimum momentum of daughters + "SUM_P": F.SUM(F.P), # Sum of daughters' momentum + "MAX_OWNPVIPCHI2": F.MAX(F.OWNPVIPCHI2), # Max IP χ² of daughters + "MIN_OWNPVIPCHI2": F.MIN(F.OWNPVIPCHI2), # Min IP χ² of daughters + "SUM_OWNPVIPCHI2": F.SUM(F.OWNPVIPCHI2), # Sum of daughters' IP χ² + "MAXDOCACHI2": F.MAXDOCACHI2, # Maximum DOCA χ² between any daughters + "MAXDOCA": F.MAXDOCA, # Maximum DOCA between any daughters + "MAXSDOCACHI2": F.MAXSDOCACHI2, # Maximum signed DOCA χ² + "MAXSDOCA": F.MAXSDOCA, # Maximum signed DOCA + "OWNPVLTIME":F.OWNPVLTIME, + + }) + + track_variables = FunctorCollection({ + # Standard PID + "PIDp": F.PID_P, # Proton PID likelihood + "PIDK": F.PID_K, # Kaon PID likelihood + "PIDPi": F.PID_PI, # Pion PID likelihood + "PIDe": F.PID_E, # Electron PID likelihood + "PIDmu": F.PID_MU, # Muon PID likelihood + # PROBNNs + "PROBNN_pi": F.PROBNN_PI, # Neural net probability of being a pion + "PROBNN_p": F.PROBNN_P, # Neural net probability of being a proton + "PROBNN_K": F.PROBNN_K, # Neural net probability of being a kaon + "PROBNN_e": F.PROBNN_E, # Neural net probability of being an electron + "PROBNN_mu": F.PROBNN_MU, # Neural net probability of being a muon + "PROBNN_GHOST": F.PROBNN_GHOST, # Neural net probability of being a ghost track + "ISMUON": F.ISMUON, # Boolean: is it identified as a muon 0 or 1? + # Additional track related info + # F.TRACK gets the track object + # F.NDOF gets the NDOF for that track + # F.VALUE_OR(-1) means if no value exists return -1 instead of failing + "TRNDOF": F.VALUE_OR(-1) @ F.NDOF @ F.TRACK, # NDOF in track fit, if this is higher then more hits used in fit + "NHITS": F.VALUE_OR(-1) @ F.NHITS @ F.TRACK, # Total number of hits in all detectors + "NVPHITS": F.VALUE_OR(-1) @ F.NVPHITS @ F.TRACK, # Total number of hits in VELO phi sensors + "NUTHITS": F.VALUE_OR(-1) @ F.NUTHITS @ F.TRACK, # Total number of hits in UT + "NFTHITS": F.VALUE_OR(-1) @ F.NFTHITS @ F.TRACK, # Total number of hits in Fibre Tracker (SciFi) + "TRACKHISTORY": F.VALUE_OR(-1) @ F.TRACKHISTORY @ F.TRACK, # Track reconstruction history + "TRACKTYPE": F.VALUE_OR(-1) @ F.TRACKTYPE @ F.TRACK, + }) + + + + # 1: the PV already associated with the particle + + DTF_OWNPV = DecayTreeFitter( + name="DTF_OwnPV", + input_particles=data, + mass_constraints=["KS0"], + constrain_to_ownpv=True, + ) + +# 2: The "unbiased" PV + + + + B_Data_unbiasedpv = ParticleUnbiasedPVAdder( + InputParticles=data, PrimaryVertices=get_extended_pvs() + ).OutputParticles + + DTF_UNBIASEDPV = DecayTreeFitter( + name="DTF_UnbiasedPV", + input_particles=B_Data_unbiasedpv, + mass_constraints=["KS0"], + constrain_to_ownpv=True, + ) + +# 3: The "best" PV: +# First get the list of possible PVs + pvs = get_pvs() + + DTF_BESTPV = DecayTreeFitter( + "DTF_BESTPV", # name of algorithm + data, # input particles + input_pvs=pvs, + mass_constraints=["KS0"], + ) + + +# 4 simple mass constrain + DTF_KsConst = DecayTreeFitter( + name="DTF_KsConst", + input_particles=data, + mass_constraints=["KS0"], + constrain_to_ownpv=False, + ) + +# Define some functors that will be affected by the PV constraint + pv_fun = {} + pv_fun["BPVLTIME"] = F.BPVLTIME(pvs) + pv_fun["BPVIPCHI2"] = F.BPVIPCHI2(pvs) + pv_coll = FunctorCollection(pv_fun) + +# Again, make the DTF versions of the functors but this time add them to the existing functor collection + pv_coll += FunctorCollection( {"DTF_OWNPV_" + k: DTF_OWNPV(v) for k, v in pv_coll.get_thor_functors().items()}) + pv_coll += FunctorCollection({"DTF_BESTPV_" + k: DTF_BESTPV(v) for k, v in pv_coll.get_thor_functors().items()}) + pv_coll += FunctorCollection({"DTF_UNBIASEDPV_" + k: DTF_UNBIASEDPV(v) for k, v in pv_coll.get_thor_functors().items()}) + + + dtf_vars_KsConst = FC.DecayTreeFitterResults( + DTF = DTF_KsConst, + prefix = 'DTF_KsConst', + decay_origin = True, # Add the variables describing the origin vertex of the decaying particle + with_lifetime = True, # Add the decay time, the flight distance and their uncertainties + with_kinematics = True, # Add the 4-momentum components + ) + dtf_vars_OWVPV = FC.DecayTreeFitterResults( + DTF = DTF_OWNPV, + prefix = 'DTF_PV_FC', + decay_origin = True, # Add the variables describing the origin vertex of the decaying particle + with_lifetime = True, # Add the decay time, the flight distance and their uncertainties + with_kinematics = True, # Add the 4-momentum components + ) + + dtf_vars_BestPV = FC.DecayTreeFitterResults( + DTF = DTF_BESTPV, + # DTF = DTF_PV, + prefix = 'DTF_PV_FC_BestPV', + decay_origin = True, # Add the variables describing the origin vertex of the decaying particle + with_lifetime = True, # Add the decay time, the flight distance and their uncertainties + with_kinematics = True, # Add the 4-momentum components + ) + + + dtf_vars_UnbiasedPV = FC.DecayTreeFitterResults( + DTF = DTF_UNBIASEDPV, + prefix = 'DTF_PV_FC_UnbiasedPV', + decay_origin = True, # Add the variables describing the origin vertex of the decaying particle + with_lifetime = True, # Add the decay time, the flight distance and their uncertainties + with_kinematics = True, # Add the 4-momentum components + ) + + + + + + #### Trigger TISTOS + Hlt1_decisions = [ + "Hlt1TrackMVADecision", + "Hlt1TwoTrackMVADecision", + "Hlt1D2KKDecision", + "Hlt1D2KPiDecision", + "Hlt1D2PiPiDecision", + "Hlt1DiMuonHighMassDecision", + "Hlt1DiMuonLowMassDecision", + "Hlt1DiMuonSoftDecision", + "Hlt1GECPassthroughDecision", + "Hlt1KsToPiPiDecision", + "Hlt1LowPtMuonDecision", + "Hlt1LowPtDiMuonDecision", + "Hlt1SingleHighPtMuonDecision", + "Hlt1TrackMuonMVADecision", + "Hlt1TrackKsDecision" + ] + Hlt2_decisions = ["Hlt2BnoC_BdsToKSKS_LLLL", "Hlt2BnoC_BdsToKSKS_DDDD", "Hlt2BnoC_BdsToKSKS_LLDD"] + # define event level variables + evt_variables = FC.SelectionInfo( + selection_type="Hlt1", trigger_lines=Hlt1_decisions + ) + evt_variables += FC.SelectionInfo( + selection_type="Hlt2", trigger_lines=Hlt2_decisions + ) + evt_variables += FC.EventInfo() + evt_variables += FC.RecSummary() + + + variables += FC.HltTisTos( + selection_type="Hlt1", trigger_lines=Hlt1_decisions, data=data + ) + variables += FC.HltTisTos( + selection_type="Hlt2", trigger_lines=Hlt2_decisions, data=data + ) + variables = {"ALL": variables, + "Bs":dtf_vars_OWVPV + dtf_vars_BestPV+dtf_vars_UnbiasedPV+dtf_vars_KsConst+pv_coll+base_composite_variables, + "V1": base_composite_variables, + "V2": base_composite_variables, + "hp1":track_variables, + "hp2":track_variables, + "hm1":track_variables, + "hm2":track_variables} + funtuple = Funtuple( + name="myTuple", + tuple_name="DecayTree", + fields=fields, + variables=variables, + event_variables=evt_variables, + inputs=data, + ) + + algs = {line: [line_prefilter, funtuple]} + return make_config(options, algs) + diff --git a/bs2ksks-run3/info.yaml b/bs2ksks-run3/info.yaml new file mode 100644 index 0000000000000000000000000000000000000000..8ee53c157f40eeb487df3f96cea51e987451682e --- /dev/null +++ b/bs2ksks-run3/info.yaml @@ -0,0 +1,50 @@ +defaults: + inform: + - yasmine.sara.amhis@cern.ch + wg: BnoC + +bs2ksks_data_2024_MagUp_job: + application: "DaVinci/v64r13@x86_64_v2-el9-clang16-opt" + input: + bk_query: /LHCb/Collision24/Beam6800GeV-VeloClosed-MagUp/Real Data/Sprucing24c3/94000000/BNOC.DST + dq_flags: + - UNCHECKED + - OK + keep_running: true + output: DV_data.root + options: + entrypoint: bs2ksks-run3.davinci_options_data:main + extra_options: + input_type: ROOT + input_raw_format: 0.5 + simulation: False + data_type: "Upgrade" + geometry_version: run3/trunk + conditions_version: master + input_process: "TurboPass" + input_stream: "bnoc" + + +bs2ksks_data_2024_MagDown_job: + application: "DaVinci/v64r13@x86_64_v2-el9-clang16-opt" + input: + bk_query: /LHCb/Collision24/Beam6800GeV-VeloClosed-MagDown/Real Data/Sprucing24c3/94000000/BNOC.DST + dq_flags: + - UNCHECKED + - OK + keep_running: true + output: DV_data.root + options: + entrypoint: bs2ksks-run3.davinci_options_data:main + extra_options: + input_type: ROOT + input_raw_format: 0.5 + simulation: False + data_type: "Upgrade" + geometry_version: run3/trunk + conditions_version: master + input_process: "TurboPass" + input_stream: "bnoc" + + +