diff --git a/Run3_LcD0_SMOG2/Run3_LcD0_SMOG2.py b/Run3_LcD0_SMOG2/Run3_LcD0_SMOG2.py new file mode 100644 index 0000000000000000000000000000000000000000..db3252796c159ff5af2710c689f440111b9765f0 --- /dev/null +++ b/Run3_LcD0_SMOG2/Run3_LcD0_SMOG2.py @@ -0,0 +1,346 @@ +from DaVinci import Options, make_config +from DaVinci.algorithms import create_lines_filter +from PyConf.reading import get_particles, get_pvs, get_rec_summary +from Hlt2Conf.algorithms_thor import ParticleFilter, ParticleCombiner +from Hlt2Conf.standard_particles import * +# from Hlt2Conf.utils import get_dtf_variables +from Functors.math import in_range, sqrt, pow +# from Hlt2Conf.lines.ift.builders.smog2_builders import ( +# make_smog2_common_particles, +# make_smog2_prefilters, +# ) + +# from ..tools.tupling_maker import * +# from ..tools.make_dtf import * +import Functors as F +from FunTuple import FunctorCollection +import FunTuple.functorcollections as FC +from FunTuple import FunTuple_Particles as Funtuple +import Functors.math as fmath +from GaudiKernel.SystemOfUnits import MeV, mm, picosecond, ps +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 DecayTreeFitter import DecayTreeFitter +import sys + +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), + "M" : F.MASS, + + } + ) + + 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_'+ 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_'+ 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, constrain, constrainPDG): + from DecayTreeFitter import DecayTreeFitter + + DTFvtxmassConstrain = DecayTreeFitter( + name=f'DTF_PV_Constrain_{{hash}}', + input_particles=input_data, + input_pvs=pvs, + mass_constraints=[constrainPDG]) + + + dtf_vars = make_composite_dtf_variables(pvs, input_data, + DTF=DTFvtxmassConstrain, + pv_constraint=True, + mass_constraint=True, particle_name=constrain) + return dtf_vars + + +def main(options: Options): + + hlt1lines_muon = [ "Hlt1SMOG2SingleMuonDecision", "Hlt1SMOG2DiMuonHighMassDecision"] + hlt1lines_BE = [ "Hlt1SMOG2BENoBiasDecision", "Hlt1SMOG2PassThroughLowMult5Decision", "Hlt1SMOG2BELowMultElectronsDecision"] + hlt1lines_MB = [ "Hlt1SMOG2MinimumBiasDecision", "Hlt1PassthroughPVinSMOG2Decision"] + + hlt1lines_track = [ "Hlt1SMOG2SingleTrackHighPtDecision", "Hlt1SMOG2SingleTrackVeryHighPtDecision", "Hlt1SMOG22BodyGenericDecision", "Hlt1SMOG22BodyGenericPromptDecision"] + hlt1lines_hadron = [ "Hlt1SMOG2etacToppDecision", "Hlt1SMOG2D2KpiDecision"] + hlt1lines_longlived = [ "Hlt1SMOG2L0ToppiDecision", "Hlt1SMOG2KsTopipiDecision"] + hlt1lines_pp = [ "Hlt1TrackMVADecision", "Hlt1TrackMuonMVADecision", "Hlt1TwoTrackMVADecision"] + + hlt1lines = [] + hlt1lines += hlt1lines_muon + hlt1lines += hlt1lines_BE + hlt1lines += hlt1lines_MB + hlt1lines += hlt1lines_track + hlt1lines += hlt1lines_hadron + hlt1lines += hlt1lines_longlived + hlt1lines += hlt1lines_pp + Hlt1_decisions = hlt1lines + + names = [ "D0Kpi", + "LcpKpi", + ] + + full_line_list = { "D0Kpi":'SpruceIFT_SMOG2D02KPi', #no persistent reco + "LcpKpi":'SpruceIFT_SMOG2LcTopKPi', + } + parts = { 'D0Kpi':["D0", "Km", "pip"], + 'LcpKpi':["Lc", "pp", "Km", "pip"], + } + + fields = { 'D0Kpi':{"D0": "[D0 -> K- pi+]CC", + "Km": "[D0 ->^K- pi+]CC", + "pip": "[D0 -> K- ^pi+]CC", + }, + 'LcpKpi':{"Lc": "[Lambda_c+ -> p+ K- pi+]CC", + "pp": "[Lambda_c+ -> ^p+ K- pi+]CC", + "Km": "[Lambda_c+ -> p+ ^K- pi+]CC", + "pip": "[Lambda_c+ -> p+ K- ^pi+]CC", + }, + } + + v2_pvs = get_pvs() + rec_summary = get_rec_summary() + all_variables = FunctorCollection({ 'ID': F.PARTICLE_ID, + 'KEY': F.OBJECT_KEY, + 'CHARGE': F.CHARGE, + 'PT': F.PT, + 'PX': F.PX, + 'PY': F.PY, + 'PZ': F.PZ, + 'ETA': F.ETA, + 'PHI': F.PHI, + 'YSTAR':0.5*fmath.log( (F.ENERGY+F.PZ)/(F.ENERGY-F.PZ))-4.79, + 'Y':0.5*fmath.log( (F.ENERGY+F.PZ)/(F.ENERGY-F.PZ)), + 'MASS':F.MASS, + 'ENERGY': F.ENERGY, + 'P': F.P, + 'FOURMOMENTUM': F.FOURMOMENTUM, + 'CHI2': F.CHI2, + 'CHI2DOF': F.CHI2DOF, + 'B_PV_Z':F.BPVZ(v2_pvs), + 'B_PV_X':F.BPVX(v2_pvs), + 'B_PV_Y':F.BPVY(v2_pvs), + 'BPVIP': F.BPVIP(v2_pvs), + 'BPVIPCHI2': F.BPVIPCHI2(v2_pvs), + 'nBestPVTracks': F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.SIZE_OF @ F.PVTRACKS @ F.BPV(v2_pvs), + 'nBestPVbackTracks': F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.COUNT_IF( F.TRACKISVELOBACKWARD ) @ F.PVTRACKS @ F.BPV(v2_pvs), + }) + + parent_variables = FunctorCollection({ 'DOCA': F.DOCA(Child1=1, Child2=2), + 'DOCACHI2': F.DOCACHI2(Child1=1, Child2=2), + 'SDOCA': F.SDOCA(Child1=1, Child2=2), + 'SDOCACHI2': F.SDOCACHI2(Child1=1, Child2=2), + 'END_VX': F.END_VX, + 'END_VY': F.END_VY, + 'END_VZ': F.END_VZ, + 'END_VRHO': F.END_VRHO, + 'BPVFDCHI2': F.BPVFDCHI2(v2_pvs), + 'BPVLTIME': F.BPVLTIME(v2_pvs), + 'BPVFD': F.BPVFD(v2_pvs), + 'BPVDIRA': F.BPVDIRA(v2_pvs), + }) + + children_variables = FunctorCollection({ 'PIDE':F.PID_E, + 'PIDK':F.PID_K, + 'PIDMU':F.PID_MU, + 'PIDP':F.PID_P, + 'PIDPI':F.PID_PI, + 'PROBNNE':F.PROBNN_E, + 'PROBNNK':F.PROBNN_K, + 'PROBNNMU':F.PROBNN_MU, + 'PROBNNP':F.PROBNN_P, + 'PROBNNPI':F.PROBNN_PI, + 'PROBNNGHOST':F.PROBNN_GHOST, + 'PROBNND':F.PROBNN_D, + 'GHOSTPROB':F.GHOSTPROB, + 'ISMUON':F.ISMUON, + 'IS_NOT_H': F.IS_NOT_H, + 'IS_PHOTON': F.IS_PHOTON, + 'TRACK_NVPHITS':F.VALUE_OR(-1) @ F.NVPHITS @ F.TRACK, + 'TRACK_NFTHITS':F.VALUE_OR(-1) @ F.NFTHITS @ F.TRACK, + 'TRACK_NUTHITS':F.VALUE_OR(-1) @ F.NUTHITS @ F.TRACK, + "TRACK_POS_CLOSESTTOBEAM_X": F.POSITION_X @ F.STATE_AT("ClosestToBeam") @ F.TRACK, + "TRACK_POS_CLOSESTTOBEAM_Y": F.POSITION_Y @ F.STATE_AT("ClosestToBeam") @ F.TRACK, + "TRACK_POS_CLOSESTTOBEAM_Z": F.POSITION_Z @ F.STATE_AT("ClosestToBeam") @ F.TRACK, + }) + + evt_vars = FunctorCollection( + { "FILLNUMBER": F.VALUE_OR(-1) @ F.FILL_NUMBER, + "nLongTracks": F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nLongTracks"), + 'nUpTracks': F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nUpstreamTracks"), + 'nDownTracks': F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nDownstreamTracks"), + 'nBackTracks': F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nBackTracks"), + "nVeloTracks": F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nVeloTracks"), + "nMuonTracks": F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nMuonTracks"), + "nTracks": F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nTracks"), + "nTTracks": F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nTTracks"), + + "nVeloClusters":F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nVeloClusters"), + "nVPClusters": F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nVPClusters"), + "nFTClusters": F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nFTClusters"), + "nRich1Hits": F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nRich1Hits"), + "nRich2Hits": F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nRich2Hits"), + "eCalTot": F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "eCalTot"), + "hCalTot": F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "hCalTot"), + "nEcalClusters":F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nEcalClusters"), + "nMuonCoordsS0":F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nMuonCoordsS0"), + "nMuonCoordsS1":F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nMuonCoordsS1"), + "nMuonCoordsS2":F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nMuonCoordsS2"), + "nMuonCoordsS3":F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nMuonCoordsS3"), + "nMuonCoordsS4":F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nMuonCoordsS4"), + + "nPVs": F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nPVs"), + "PVZ[nPV]": F.VALUE_OR(-1) @ F.ALLPVZ(v2_pvs), + "PVX[nPV]": F.VALUE_OR(-1) @ F.ALLPVX(v2_pvs), + "PVY[nPV]": F.VALUE_OR(-1) @ F.ALLPVY(v2_pvs), + "ALLPVX_ERR[nPV]": F.VALUE_OR(-1) @ F.MAP(F.SQRT @ F.CALL(0, 0) @ F.POS_COV_MATRIX) @ F.TES(v2_pvs), + "ALLPVY_ERR[nPV]": F.VALUE_OR(-1) @ F.MAP(F.SQRT @ F.CALL(1, 1) @ F.POS_COV_MATRIX) @ F.TES(v2_pvs), + "ALLPVZ_ERR[nPV]": F.VALUE_OR(-1) @ F.MAP(F.SQRT @ F.CALL(2, 2) @ F.POS_COV_MATRIX) @ F.TES(v2_pvs), + "PVCHI2NDOF[nPV]": F.VALUE_OR(-1) @ F.MAP( F.CHI2DOF ) @ F.TES(v2_pvs), + "PVCHI2[nPV]": F.VALUE_OR(-1) @ F.MAP( F.CHI2 ) @ F.TES(v2_pvs), + "PVNDOF[nPV]": F.VALUE_OR(-1) @ F.MAP( F.NDOF ) @ F.TES(v2_pvs), + 'nPVTracks[nPV]': F.VALUE_OR(-1) @ F.MAP( F.CAST_TO_INT @ F.SIZE_OF @ F.PVTRACKS ) @ F.TES(v2_pvs), + 'nPVbackTracks[nPV]':F.VALUE_OR(-1) @ F.MAP( F.CAST_TO_INT @ F.COUNT_IF( F.TRACKISVELOBACKWARD ) @ F.PVTRACKS ) @ F.TES(v2_pvs), + } + ) + + evt_vars += FC.EventInfo() + evt_vars += FC.SMOGInfo() + evt_vars += FC.SelectionInfo( selection_type="Hlt1", trigger_lines=Hlt1_decisions ) # hlt1 trigger decisions + + d_input_data, d_variables, d_mytuple = {},{},{} + + for line in names: + d_input_data[line] = get_particles('/Event/Spruce/'+full_line_list[line]+'/Particles') #CharmPions/Particles + # input_data_tuple = d_input_data[line] + # long_muons = make_long_muons() + # long_pions = make_long_pions() + # long_protons = make_long_protons() + # long_kaons = make_long_kaons() + # long_rich_pions = make_has_rich_long_pions() + # long_rich_kaons = make_has_rich_long_kaons() + # long_rich_protons = make_has_rich_long_protons() + if line == "D0Kpi": + D0Spruced = ParticleFilter(d_input_data[line], Cut=F.FILTER(F.require_all( + in_range(1800.*MeV, F.MASS, 1940.*MeV), + F.BPVDIRA(get_pvs()) > 0.999, + F.CHI2DOF < 50) + )) + output_data_tuple = D0Spruced + if line == "LcpKpi": + LcSpruced = ParticleFilter(d_input_data[line], Cut=F.FILTER(F.require_all( + in_range(2000.*MeV, F.MASS, 2550.*MeV), + F.BPVDIRA(get_pvs()) > 0.999, + F.CHI2DOF < 50) + )) + output_data_tuple = LcSpruced + + TisTos_variables = FC.HltTisTos( selection_type="Hlt1", trigger_lines=Hlt1_decisions, data=output_data_tuple ) + + d_variables[line] = { parts[line][0]:all_variables+TisTos_variables+parent_variables } + + for ichildren in range( 1, len(parts[line]) ): + d_variables[line][parts[line][ichildren]] = all_variables+TisTos_variables+children_variables + + + d_mytuple[line] = Funtuple( line, + 'DecayFunTuple', + fields=fields[line], + variables=d_variables[line], + event_variables=evt_vars, + inputs=output_data_tuple, + store_multiple_cand_info=True ) + + alg_list = [] + for line in names: alg_list += [ d_mytuple[line] ] + + config = make_config( options, alg_list ) + return config + + + + + diff --git a/Run3_LcD0_SMOG2/info.yaml b/Run3_LcD0_SMOG2/info.yaml new file mode 100644 index 0000000000000000000000000000000000000000..27eba146c2be16d393037ef05433e4120bf1c7d2 --- /dev/null +++ b/Run3_LcD0_SMOG2/info.yaml @@ -0,0 +1,49 @@ +defaults: + inform: + - nicolas.schmidt@cern.ch + wg: IFT + +# data configuration +{%- set datasets = [ + ('Collision24', 'Sprucing24c2/90000000','c2', 'MagUp'), + ('Collision24', 'Sprucing24c3/90000000','c3', 'MagUp'), + ('Collision24', 'Sprucing24c4/90000000','c4', 'MagUp'), + ('Collision24', 'Sprucing24c2/90000000','c2', 'MagDown'), + ('Collision24', 'Sprucing24c3/90000000','c3', 'MagDown'), +]%} + +{%- for data, Type, typekey, polarity in datasets %} + +SMOG2_2024__{{typekey}}_{{polarity}}_Spruce: + application: DaVinci/v64r14@x86_64_v2-el9-clang16-opt + input: + bk_query: "/LHCb/{{data}}/Beam6800GeV-VeloClosed-{{polarity}}/Real Data/{{Type}}/IFT.DST" + dq_flags: + - UNCHECKED + - OK + smog2_state: + - Argon + - Helium + - Hydrogen + - Neon + - ArgonUnstable + - HeliumUnstable + - HydrogenUnstable + - NeonUnstable + keep_running: True + n_test_lfns: 2 + output: OHF_SMOG2_{{data}}{{typekey}}.root + options: + entrypoint: Run3_LcD0_SMOG2.Run3_LcD0_SMOG2:main + extra_options: + input_raw_format: 0.5 + input_type: ROOT # ROOT for SprucingPass, RAW for RAW data (Hlt2 output) + simulation: False + data_type: "Upgrade" + geometry_version: run3/2024.Q1.2-v00.00 + conditions_version: master + input_process: "Spruce" + input_stream: "ift" + +{%- endfor %} +