From d8de8cdc7f4306c874fbb893c815e27ea8e5db41 Mon Sep 17 00:00:00 2001 From: Xiaojie Cao Date: Thu, 11 Dec 2025 11:35:07 +0100 Subject: [PATCH 1/3] Add lines for Velo2Long proton efficiency in L0ToPpPim --- .../lines/trackeff/L0ToPpPimVeloLong.py | 333 ++++++++++++++++++ 1 file changed, 333 insertions(+) create mode 100644 Hlt/Hlt2Conf/python/Hlt2Conf/lines/trackeff/L0ToPpPimVeloLong.py diff --git a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/trackeff/L0ToPpPimVeloLong.py b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/trackeff/L0ToPpPimVeloLong.py new file mode 100644 index 00000000000..0fc17ded52f --- /dev/null +++ b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/trackeff/L0ToPpPimVeloLong.py @@ -0,0 +1,333 @@ +############################################################################### +# (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. # +############################################################################### +import Functors as F +from Functors.math import in_range +from GaudiKernel.SystemOfUnits import GeV, MeV, mm, ns +from Moore.config import register_line_builder +from Moore.lines import Hlt2Line +from PyConf.Algorithms import ( + FlattenDecayTree, + L0LongVeloFilter, + LHCbIDOverlapRelationTable, + SelectionFromWeightedRelationTable, +) +from PyConf.tonic import configurable +from Hlt2Conf.algorithms_thor import ( + ParticleCombiner, + ParticleContainersMerger, + ParticleFilter, +) +from RecoConf.event_filters import require_pvs +from RecoConf.reconstruction_objects import ( + make_pvs, + upfront_reconstruction, +) +from Hlt2Conf.standard_particles import make_long_pions, make_up_pions, make_long_protons, make_up_protons, _make_particles, get_all_track_selector + +from Hlt2Conf.hlt1_tistos import hlt1_tis_on_any_filter +from Hlt2Conf.lines.ift.builders.smog2_builders import ( + bpv_in_smog2, + make_smog2_prefilters, +) +from Hlt2Conf.probe_muons import make_velo_muons + +from Hlt2Conf.lines.pid.utils import constants +from Hlt2Conf.lines.pid.utils import filters as flt + +from RecoConf.hlt2_probetracks import ( + make_charged_downstream, + make_charged_seed, + make_charged_velo, + make_muonut_particles, + make_VeloMuon_tracks, +) + + +turbo_lines = {} +turcal_lines = {} + +hlt1_tis_lines = [ + "Hlt1TrackMuonMVADecision", + "Hlt1TrackMVADecision", + "Hlt1TwoTrackMVADecision", + "Hlt1OneMuonTrackLineDecision", + "Hlt1DiMuonHighMassDecision", + "Hlt1DiMuonNoIPDecision", + "Hlt1PassthroughDecision", + "Hlt1GECPassthroughDecision", + "Hlt1D2KPiDecision", + "Hlt1Dst2D0PiDecision", + "Hlt1SingleHighPtMuonNoMuIDDecision", + "Hlt1DetJpsiToMuMuPosTagLineDecision", + "Hlt1DetJpsiToMuMuNegTagLineDecision", + "Hlt1SingleHighPtMuonDecision", + "Hlt1DisplacedDiMuonDecision", + "Hlt1TrackElectronMVADecision", + "Hlt1SingleHighPtElectronDecision", + "Hlt1DisplacedDielectronDecision", + "Hlt1SingleHighEtDecision", +] + +hlt1_tis_lines_smog2 = [ + "Hlt1SMOG22BodyGenericDecision", + "Hlt1SMOG22BodyGenericPromptDecision", + "Hlt1SMOG2SingleTrackHighPtDecision", + "Hlt1SMOG2SingleTrackVeryHighPtDecision", + "Hlt1PassthroughPVinSMOG2Decision", + "Hlt1SMOG2MinimumBiasDecision", + "Hlt1SMOG2BENoBiasDecision", + "Hlt1SMOG2etacToppDecision", + "Hlt1SMOG2D2KpiDecision", + "Hlt1SMOG2KsTopipiDecision", + "Hlt1SMOG2L0ToppiDecision", + "Hlt1SMOG2SingleMuonDecision", + "Hlt1SMOG2DiMuonHighMassDecision", + "Hlt1SMOG2JPsiToMuMuTaP_PosTagDecision", + "Hlt1SMOG2JPsiToMuMuTaP_NegTagDecision", + "Hlt1SMOG2DisplacedDiMuonDecision", + "Hlt1SMOG2BELowMultElectronsDecision", + "Hlt1SMOG2PassThroughLowMult5Decision", +] + + +@configurable +def filter_pions(particles, pvs=None, pt_min=0 * GeV, fromSMOG2=False): + cut = F.require_all(F.PT > pt_min) + if fromSMOG2: + cut &= F.P > 2000 + else: + cut &= F.PID_K < 5 + cut &= F.CHI2DOF < 4 + cut &= F.MINIPCHI2(pvs) < 4000 + cut &= F.OWNPVIPCHI2 > 36 + return ParticleFilter(particles, F.FILTER(cut)) + + +def filter_protons(particles, pvs=None, p_min=2.0 * GeV, pt_min=0 * GeV, pt_max=1000 * GeV, bpvipchi2_min=1.8, fromSMOG2=False): + code = F.require_all( + F.P > p_min, + F.PT > pt_min, + F.PT < pt_max, + F.BPVIPCHI2(pvs) > bpvipchi2_min + ) + return ParticleFilter(particles, F.FILTER(code)) + + + +@configurable +def filter_particles_velo(particles, pvs, fromSMOG2=False): + cut = F.require_all( + F.ETA > 1.5, + ) + if fromSMOG2: + cut &= F.ETA < 5.2 + else: + cut &= F.ETA < 5.5 + cut &= F.MINIP(pvs) > 0.5 * mm + return ParticleFilter(particles, F.FILTER(cut)) + + +@configurable +def filter_particles_tis_velo(particles, pvs, fromSMOG2=False): + pre_filtered_particles = filter_particles_velo(particles, pvs, fromSMOG2=fromSMOG2) + + hlt1_filter_lines = hlt1_tis_lines[:] + if fromSMOG2: + hlt1_filter_lines += hlt1_tis_lines_smog2 + + return hlt1_tis_on_any_filter( + hlt1_trigger_lines=hlt1_filter_lines, + data=pre_filtered_particles, + name="Hlt1TISFilter_Velo2Long_{hash}", + advanced_tistos_arguments={ + "TOSFracFT": 0.0, + "TISFracUT": 0.0, + "TOSFracVP": 1.0, + }, + ) + + + +@configurable +def make_l0lls( + protons, + pions, + decay_descriptor, + pvs, + mm_min=600 * MeV, + mm_max=2000 * MeV, + vchi2_max=30, + mipchi2_max=50, + bpvdira=0, + bpvfdchi2=63, + eta_max=5.3, +): + combination_code = F.require_all( + in_range(mm_min, F.MASS, mm_max) + ) + + composite_code = F.require_all( + F.CHI2DOF < vchi2_max, + F.MINIPCHI2(pvs) < mipchi2_max, + F.BPVDIRA(pvs) > bpvdira, + F.BPVFDCHI2(pvs) > bpvfdchi2, + F.ETA < eta_max, + ) + + return ParticleCombiner( + [protons, pions], + name="L0ToPPi_LL_Combiner_{hash}", + DecayDescriptor=decay_descriptor, + CombinationCut=combination_code, + CompositeCut=composite_code, + ) + +def make_l0_p_piminus(protons, pions, pvs): + l0_particle_combinations = [ + #make_l0lls(protons, pions, "Lambda0 -> p+ pi+", pvs), + make_l0lls(protons, pions, "[Lambda0 -> p+ pi-]cc", pvs), + #make_l0lls(protons, pions, "Lambda0 -> p- pi-", pvs), + #make_l0lls(protons, pions, "Lambda0 -> p- pi+", pvs), + ] + + return ParticleContainersMerger( + l0_particle_combinations, name="L0_combinations_{hash}" + ) + + +def make_velo_protons(): + return _make_particles( + species="proton", + get_track_selector=get_all_track_selector, + make_protoparticles=make_charged_velo, + ) + + + +def construct_hlt2_line( + *, + name, + prescale, + pt_min, + pt_max, + p_min=2000.0, + filter_tis=False, + fromSMOG2=False, +): + pvs = make_pvs() + + pions = filter_pions(make_long_pions(), pvs, fromSMOG2=fromSMOG2) + turbo_line = name.find("Hlt2Turbo") != -1 + + if filter_tis: + protonsVelo = filter_particles_tis_velo( + make_long_protons(), pvs, fromSMOG2=fromSMOG2 + ) + else: + protonsVelo = filter_protons(make_velo_protons(), pvs, pt_max=16 * GeV) + + lambda0s = make_l0_p_piminus( + protonsVelo, + pions, + pvs=pvs, + ) # probe should be on index 1 + + filtered_lambda0s = L0LongVeloFilter( + InputParticle=lambda0s, + InputPVs=pvs, + PVConstrainedMassMin=1000.0, + PVConstrainedMassMax=1200.0, + PVConstrainedProbePtMin=pt_min, + PVConstrainedProbePtMax=pt_max, + PVConstrainedProbePMin=p_min, + name=f"TrackEffFilter_{name}", + ).OutputParticles + + if turbo_line: + """ Selective persistence""" + lambda0_flat_tree = FlattenDecayTree( + InputParticles=filtered_lambda0s, name=f"FlattenL0_{name}" + ) + lambda0_flat_daughters = ParticleFilter( + lambda0_flat_tree.OutputParticles, + F.FILTER(F.require_all(F.ISBASICPARTICLE, (F.TRACKISVELO @ F.TRACK))), + ) + + relation_table_match_by_lhcbid_long = LHCbIDOverlapRelationTable( + MatchFrom=lambda0_flat_daughters, + MatchTo=make_long_protons(), + IncludeVP=True, + IncludeFT=False, + IncludeUT=False, + MinMatchFraction=0.2, + ).OutputRelations + + relation_table_match_by_lhcbid_upstream = LHCbIDOverlapRelationTable( + MatchFrom=lambda0_flat_daughters, + MatchTo=make_up_protons(), + IncludeVP=True, + IncludeFT=False, + IncludeUT=False, + MinMatchFraction=0.2, + ).OutputRelations + + matched_long_pions = SelectionFromWeightedRelationTable( + InputRelations=relation_table_match_by_lhcbid_long + ).OutputLocation + matched_upstream_pions = SelectionFromWeightedRelationTable( + InputRelations=relation_table_match_by_lhcbid_upstream + ).OutputLocation + + particles_to_match = [ + ("MatchedLongPions", matched_long_pions), + ("MatchedUpstreamPions", matched_upstream_pions), + ] + else: + particles_to_match = None + + algs_list = upfront_reconstruction() + [require_pvs(pvs), filtered_lambda0s] + + if fromSMOG2: + algs_list = make_smog2_prefilters(pvs=make_pvs) + [filtered_lambda0s] + + return Hlt2Line( + name=name, + algs=algs_list, + prescale=prescale, + monitoring_variables=["m"], + extra_outputs=particles_to_match, + persistreco=not turbo_line, + ) + + +@register_line_builder(turbo_lines) +@configurable +def turbo_l0_velo_long_line(name="Hlt2TurboVelo2Long_Lambda0", prescale=1.0): + return construct_hlt2_line( + name=name, + prescale=prescale, + pt_min=0.0, + pt_max=20000.0, + p_min=2000.0, + ) + +@register_line_builder(turcal_lines) +@configurable +def turcal_l0_velo_long_line( + name="Hlt2TurCalVelo2Long_Lambda0", prescale=1.0 +): + return construct_hlt2_line( + name=name, + prescale=prescale, + pt_min=0.0, + pt_max=20000.0, + p_min=5000.0 + ) -- GitLab From 070a226e7582e338a56ba002a282b4427808663b Mon Sep 17 00:00:00 2001 From: Xiaojie Cao Date: Fri, 12 Dec 2025 04:28:18 +0100 Subject: [PATCH 2/3] modify lines for Velo2Long proton efficiency in L0ToPpPim --- .../trackeff/Velo2Long_L2PPi_ProtonProbe.py | 212 +++++++++--------- 1 file changed, 110 insertions(+), 102 deletions(-) diff --git a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/trackeff/Velo2Long_L2PPi_ProtonProbe.py b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/trackeff/Velo2Long_L2PPi_ProtonProbe.py index 0342de678d3..10f34753d32 100644 --- a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/trackeff/Velo2Long_L2PPi_ProtonProbe.py +++ b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/trackeff/Velo2Long_L2PPi_ProtonProbe.py @@ -10,14 +10,14 @@ ############################################################################### import Functors as F from Functors.math import in_range -from GaudiKernel.SystemOfUnits import GeV, MeV, mm +from GaudiKernel.SystemOfUnits import GeV, MeV, mm, ns from Moore.config import register_line_builder from Moore.lines import Hlt2Line from PyConf.Algorithms import ( FlattenDecayTree, + L0LongVeloFilter, LHCbIDOverlapRelationTable, SelectionFromWeightedRelationTable, - Velo2Long_L2ProtonPi_TrackEffFilter, ) from PyConf.tonic import configurable from RecoConf.algorithms_thor import ( @@ -26,13 +26,23 @@ from RecoConf.algorithms_thor import ( ParticleFilter, ) from RecoConf.event_filters import require_pvs +from RecoConf.hlt2_probetracks import ( + make_charged_downstream, + make_charged_seed, + make_charged_velo, + make_muonut_particles, + make_VeloMuon_tracks, +) from RecoConf.reconstruction_objects import ( make_pvs, upfront_reconstruction, ) from RecoConf.standard_particles import ( + _make_particles, + get_all_track_selector, make_long_pions, make_long_protons, + make_up_pions, make_up_protons, ) @@ -41,10 +51,12 @@ from Hlt2Conf.lines.ift.builders.smog2_builders import ( bpv_in_smog2, make_smog2_prefilters, ) +from Hlt2Conf.lines.pid.utils import constants +from Hlt2Conf.lines.pid.utils import filters as flt +from Hlt2Conf.probe_muons import make_velo_muons turbo_lines = {} turcal_lines = {} -monitoring_lines = {} hlt1_tis_lines = [ "Hlt1TrackMuonMVADecision", @@ -89,46 +101,44 @@ hlt1_tis_lines_smog2 = [ "Hlt1SMOG2PassThroughLowMult5Decision", ] -from RecoConf.hlt2_probetracks import make_charged_velo -from RecoConf.standard_particles import ( - _make_particles, - get_all_track_selector, - standard_protoparticle_filter, -) - @configurable -def filter_pions(particles, pvs=None, pt_min=0.4 * GeV, fromSMOG2=False): - cut = F.require_all( - F.PT > pt_min, - F.ETA < 5.0, - F.ETA > 1.5, - ) +def filter_pions(particles, pvs=None, pt_min=0 * GeV, fromSMOG2=False): + cut = F.require_all(F.PT > pt_min) if fromSMOG2: cut &= F.P > 2000 else: - cut &= F.P > 5000 - cut &= F.PID_P < 5 - cut &= F.MINIP(pvs) > 0.4 * mm + cut &= F.PID_K < 5 + cut &= F.CHI2DOF < 4 + cut &= F.MINIPCHI2(pvs) < 4000 + cut &= F.OWNPVIPCHI2 > 36 return ParticleFilter(particles, F.FILTER(cut)) -def make_velo_protons(): - """creates LHCb::Particles from LHCb::ProtoParticles of VELO tracks""" - return _make_particles( - species="proton", - get_track_selector=get_all_track_selector, - make_protoparticles=make_charged_velo, +def filter_protons( + particles, + pvs=None, + p_min=2.0 * GeV, + pt_min=0 * GeV, + pt_max=1000 * GeV, + bpvipchi2_min=1.8, + fromSMOG2=False, +): + code = F.require_all( + F.P > p_min, F.PT > pt_min, F.PT < pt_max, F.BPVIPCHI2(pvs) > bpvipchi2_min ) + return ParticleFilter(particles, F.FILTER(code)) @configurable def filter_particles_velo(particles, pvs, fromSMOG2=False): - cut = F.require_all(F.ETA > 1.7) + cut = F.require_all( + F.ETA > 1.5, + ) if fromSMOG2: cut &= F.ETA < 5.2 else: - cut &= F.ETA < 4.7 + cut &= F.ETA < 5.5 cut &= F.MINIP(pvs) > 0.5 * mm return ParticleFilter(particles, F.FILTER(cut)) @@ -154,61 +164,56 @@ def filter_particles_tis_velo(particles, pvs, fromSMOG2=False): @configurable -def make_l0_pion_proton_specific_charge( - probe_tracks, +def make_l0lls( + protons, pions, decay_descriptor, pvs, - comb_m_min=0 * MeV, - comb_m_max=2650 * MeV, - comb_maxdoca=0.15 * mm, - fromSMOG2=False, - name="Velo2Long_L2PiPCombiner_{hash}", + mm_min=600 * MeV, + mm_max=2000 * MeV, + vchi2_max=30, + mipchi2_max=50, + bpvdira=0, + bpvfdchi2=63, + eta_max=5.3, ): - combination_code = F.require_all( - in_range(comb_m_min, F.MASS, comb_m_max), - F.MAXDOCACUT(comb_maxdoca), - ) - vertex_code = F.require_all( - F.END_VRHO < 100 * mm, - F.END_VZ < 600 * mm, + combination_code = F.require_all(in_range(mm_min, F.MASS, mm_max)) + + composite_code = F.require_all( + F.CHI2DOF < vchi2_max, + F.MINIPCHI2(pvs) < mipchi2_max, + F.BPVDIRA(pvs) > bpvdira, + F.BPVFDCHI2(pvs) > bpvfdchi2, + F.ETA < eta_max, ) - if fromSMOG2: - vertex_code &= F.END_VZ > -550 * mm - vertex_code &= bpv_in_smog2(make_pvs) - else: - vertex_code &= F.END_VZ > 18 * mm - - vertex_code &= F.OWNPVFD > 5 * mm - vertex_code &= F.OWNPVVDRHO > 2 * mm return ParticleCombiner( - [pions, probe_tracks], - name=name, + [protons, pions], + name="L0ToPPi_LL_Combiner_{hash}", DecayDescriptor=decay_descriptor, CombinationCut=combination_code, - CompositeCut=vertex_code, + CompositeCut=composite_code, ) -def make_lambda_to_pion_proton(tag_pions, probe_protons, **kwargs): +def make_l0_p_piminus(protons, pions, pvs): l0_particle_combinations = [ - make_l0_pion_proton_specific_charge( - probe_protons, tag_pions, "Lambda0 -> pi- p+", **kwargs - ), - make_l0_pion_proton_specific_charge( - probe_protons, tag_pions, "Lambda0 -> pi- p~-", **kwargs - ), - make_l0_pion_proton_specific_charge( - probe_protons, tag_pions, "Lambda0 -> pi+ p~-", **kwargs - ), - make_l0_pion_proton_specific_charge( - probe_protons, tag_pions, "Lambda0 -> pi+ p+", **kwargs - ), + # make_l0lls(protons, pions, "Lambda0 -> p+ pi+", pvs), + make_l0lls(protons, pions, "[Lambda0 -> p+ pi-]cc", pvs), + # make_l0lls(protons, pions, "Lambda0 -> p- pi-", pvs), + # make_l0lls(protons, pions, "Lambda0 -> p- pi+", pvs), ] return ParticleContainersMerger( - l0_particle_combinations, name="L0_velo2long_combinations_{hash}" + l0_particle_combinations, name="L0_combinations_{hash}" + ) + + +def make_velo_protons(): + return _make_particles( + species="proton", + get_track_selector=get_all_track_selector, + make_protoparticles=make_charged_velo, ) @@ -218,58 +223,51 @@ def construct_hlt2_line( prescale, pt_min, pt_max, - p_min=5000.0, + p_min=2000.0, filter_tis=False, - apply_lambda_veto=False, fromSMOG2=False, ): pvs = make_pvs() - pions = filter_pions(make_long_pions(), pvs, pt_min=0.4 * GeV, fromSMOG2=fromSMOG2) + pions = filter_pions(make_long_pions(), pvs, fromSMOG2=fromSMOG2) turbo_line = name.find("Hlt2Turbo") != -1 if filter_tis: - probe_protons_velo = filter_particles_tis_velo( - make_velo_protons(), pvs, fromSMOG2=fromSMOG2 + protonsVelo = filter_particles_tis_velo( + make_long_protons(), pvs, fromSMOG2=fromSMOG2 ) else: - probe_protons_velo = filter_particles_velo( - make_velo_protons(), pvs, fromSMOG2=fromSMOG2 - ) + protonsVelo = filter_protons(make_velo_protons(), pvs, pt_max=16 * GeV) - lambdas = make_lambda_to_pion_proton( - tag_pions=pions, - probe_protons=probe_protons_velo, + lambda0s = make_l0_p_piminus( + protonsVelo, + pions, pvs=pvs, - comb_m_max=1500, - comb_m_min=0, - fromSMOG2=fromSMOG2, ) # probe should be on index 1 - filtered_lambdas = Velo2Long_L2ProtonPi_TrackEffFilter( - InputParticle=lambdas, + filtered_lambda0s = L0LongVeloFilter( + InputParticle=lambda0s, InputPVs=pvs, - PVConstrainedMassMin=1000.0, # 1115.683 - PVConstrainedMassMax=1220.0, + PVConstrainedMassMin=1000.0, + PVConstrainedMassMax=1200.0, PVConstrainedProbePtMin=pt_min, PVConstrainedProbePtMax=pt_max, PVConstrainedProbePMin=p_min, - IPperpendicularMax=0.01, - IPMax=0.5, - name=f"Velo2Long_L0_TrackEffFilter_{name}", + name=f"TrackEffFilter_{name}", ).OutputParticles + if turbo_line: """ Selective persistence""" - flat_tree = FlattenDecayTree( - InputParticles=filtered_lambdas, name=f"FlattenL0_{name}" + lambda0_flat_tree = FlattenDecayTree( + InputParticles=filtered_lambda0s, name=f"FlattenL0_{name}" ) - flat_daughters = ParticleFilter( - flat_tree.OutputParticles, + lambda0_flat_daughters = ParticleFilter( + lambda0_flat_tree.OutputParticles, F.FILTER(F.require_all(F.ISBASICPARTICLE, (F.TRACKISVELO @ F.TRACK))), ) relation_table_match_by_lhcbid_long = LHCbIDOverlapRelationTable( - MatchFrom=flat_daughters, + MatchFrom=lambda0_flat_daughters, MatchTo=make_long_protons(), IncludeVP=True, IncludeFT=False, @@ -278,7 +276,7 @@ def construct_hlt2_line( ).OutputRelations relation_table_match_by_lhcbid_upstream = LHCbIDOverlapRelationTable( - MatchFrom=flat_daughters, + MatchFrom=lambda0_flat_daughters, MatchTo=make_up_protons(), IncludeVP=True, IncludeFT=False, @@ -294,20 +292,20 @@ def construct_hlt2_line( ).OutputLocation particles_to_match = [ - ("MatchedLong", matched_long_pions), - ("MatchedUpstream", matched_upstream_pions), + ("MatchedLongPions", matched_long_pions), + ("MatchedUpstreamPions", matched_upstream_pions), ] else: particles_to_match = None - algs_list = [require_pvs(pvs), filtered_lambdas] + algs_list = upfront_reconstruction() + [require_pvs(pvs), filtered_lambda0s] + if fromSMOG2: - algs_list = make_smog2_prefilters(pvs=make_pvs) + [filtered_lambdas] + algs_list = make_smog2_prefilters(pvs=make_pvs) + [filtered_lambda0s] return Hlt2Line( name=name, algs=algs_list, - stream="trackeff" if turbo_line else None, prescale=prescale, monitoring_variables=["m"], extra_outputs=particles_to_match, @@ -317,9 +315,19 @@ def construct_hlt2_line( @register_line_builder(turbo_lines) @configurable -def turbo_lambda_velo_long_line_nominal( - name="Hlt2TurboVelo2Long_Lambda_ProtonProbe", prescale=0.2 -): +def turbo_l0_velo_long_line(name="Hlt2TurboVelo2Long_Lambda0", prescale=1.0): + return construct_hlt2_line( + name=name, + prescale=prescale, + pt_min=0.0, + pt_max=20000.0, + p_min=2000.0, + ) + + +@register_line_builder(turcal_lines) +@configurable +def turcal_l0_velo_long_line(name="Hlt2TurCalVelo2Long_Lambda0", prescale=1.0): return construct_hlt2_line( - name=name, prescale=prescale, pt_min=1200.0, pt_max=15000.0, filter_tis=True + name=name, prescale=prescale, pt_min=0.0, pt_max=20000.0, p_min=5000.0 ) -- GitLab From d43d18fa459c493b9b61abddc522d49dd5050609 Mon Sep 17 00:00:00 2001 From: Xiaojie Cao Date: Fri, 12 Dec 2025 04:31:32 +0100 Subject: [PATCH 3/3] modify lines for Velo2Long proton efficiency in L0ToPpPim --- .../lines/trackeff/L0ToPpPimVeloLong.py | 333 ------------------ 1 file changed, 333 deletions(-) delete mode 100644 Hlt/Hlt2Conf/python/Hlt2Conf/lines/trackeff/L0ToPpPimVeloLong.py diff --git a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/trackeff/L0ToPpPimVeloLong.py b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/trackeff/L0ToPpPimVeloLong.py deleted file mode 100644 index 0fc17ded52f..00000000000 --- a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/trackeff/L0ToPpPimVeloLong.py +++ /dev/null @@ -1,333 +0,0 @@ -############################################################################### -# (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. # -############################################################################### -import Functors as F -from Functors.math import in_range -from GaudiKernel.SystemOfUnits import GeV, MeV, mm, ns -from Moore.config import register_line_builder -from Moore.lines import Hlt2Line -from PyConf.Algorithms import ( - FlattenDecayTree, - L0LongVeloFilter, - LHCbIDOverlapRelationTable, - SelectionFromWeightedRelationTable, -) -from PyConf.tonic import configurable -from Hlt2Conf.algorithms_thor import ( - ParticleCombiner, - ParticleContainersMerger, - ParticleFilter, -) -from RecoConf.event_filters import require_pvs -from RecoConf.reconstruction_objects import ( - make_pvs, - upfront_reconstruction, -) -from Hlt2Conf.standard_particles import make_long_pions, make_up_pions, make_long_protons, make_up_protons, _make_particles, get_all_track_selector - -from Hlt2Conf.hlt1_tistos import hlt1_tis_on_any_filter -from Hlt2Conf.lines.ift.builders.smog2_builders import ( - bpv_in_smog2, - make_smog2_prefilters, -) -from Hlt2Conf.probe_muons import make_velo_muons - -from Hlt2Conf.lines.pid.utils import constants -from Hlt2Conf.lines.pid.utils import filters as flt - -from RecoConf.hlt2_probetracks import ( - make_charged_downstream, - make_charged_seed, - make_charged_velo, - make_muonut_particles, - make_VeloMuon_tracks, -) - - -turbo_lines = {} -turcal_lines = {} - -hlt1_tis_lines = [ - "Hlt1TrackMuonMVADecision", - "Hlt1TrackMVADecision", - "Hlt1TwoTrackMVADecision", - "Hlt1OneMuonTrackLineDecision", - "Hlt1DiMuonHighMassDecision", - "Hlt1DiMuonNoIPDecision", - "Hlt1PassthroughDecision", - "Hlt1GECPassthroughDecision", - "Hlt1D2KPiDecision", - "Hlt1Dst2D0PiDecision", - "Hlt1SingleHighPtMuonNoMuIDDecision", - "Hlt1DetJpsiToMuMuPosTagLineDecision", - "Hlt1DetJpsiToMuMuNegTagLineDecision", - "Hlt1SingleHighPtMuonDecision", - "Hlt1DisplacedDiMuonDecision", - "Hlt1TrackElectronMVADecision", - "Hlt1SingleHighPtElectronDecision", - "Hlt1DisplacedDielectronDecision", - "Hlt1SingleHighEtDecision", -] - -hlt1_tis_lines_smog2 = [ - "Hlt1SMOG22BodyGenericDecision", - "Hlt1SMOG22BodyGenericPromptDecision", - "Hlt1SMOG2SingleTrackHighPtDecision", - "Hlt1SMOG2SingleTrackVeryHighPtDecision", - "Hlt1PassthroughPVinSMOG2Decision", - "Hlt1SMOG2MinimumBiasDecision", - "Hlt1SMOG2BENoBiasDecision", - "Hlt1SMOG2etacToppDecision", - "Hlt1SMOG2D2KpiDecision", - "Hlt1SMOG2KsTopipiDecision", - "Hlt1SMOG2L0ToppiDecision", - "Hlt1SMOG2SingleMuonDecision", - "Hlt1SMOG2DiMuonHighMassDecision", - "Hlt1SMOG2JPsiToMuMuTaP_PosTagDecision", - "Hlt1SMOG2JPsiToMuMuTaP_NegTagDecision", - "Hlt1SMOG2DisplacedDiMuonDecision", - "Hlt1SMOG2BELowMultElectronsDecision", - "Hlt1SMOG2PassThroughLowMult5Decision", -] - - -@configurable -def filter_pions(particles, pvs=None, pt_min=0 * GeV, fromSMOG2=False): - cut = F.require_all(F.PT > pt_min) - if fromSMOG2: - cut &= F.P > 2000 - else: - cut &= F.PID_K < 5 - cut &= F.CHI2DOF < 4 - cut &= F.MINIPCHI2(pvs) < 4000 - cut &= F.OWNPVIPCHI2 > 36 - return ParticleFilter(particles, F.FILTER(cut)) - - -def filter_protons(particles, pvs=None, p_min=2.0 * GeV, pt_min=0 * GeV, pt_max=1000 * GeV, bpvipchi2_min=1.8, fromSMOG2=False): - code = F.require_all( - F.P > p_min, - F.PT > pt_min, - F.PT < pt_max, - F.BPVIPCHI2(pvs) > bpvipchi2_min - ) - return ParticleFilter(particles, F.FILTER(code)) - - - -@configurable -def filter_particles_velo(particles, pvs, fromSMOG2=False): - cut = F.require_all( - F.ETA > 1.5, - ) - if fromSMOG2: - cut &= F.ETA < 5.2 - else: - cut &= F.ETA < 5.5 - cut &= F.MINIP(pvs) > 0.5 * mm - return ParticleFilter(particles, F.FILTER(cut)) - - -@configurable -def filter_particles_tis_velo(particles, pvs, fromSMOG2=False): - pre_filtered_particles = filter_particles_velo(particles, pvs, fromSMOG2=fromSMOG2) - - hlt1_filter_lines = hlt1_tis_lines[:] - if fromSMOG2: - hlt1_filter_lines += hlt1_tis_lines_smog2 - - return hlt1_tis_on_any_filter( - hlt1_trigger_lines=hlt1_filter_lines, - data=pre_filtered_particles, - name="Hlt1TISFilter_Velo2Long_{hash}", - advanced_tistos_arguments={ - "TOSFracFT": 0.0, - "TISFracUT": 0.0, - "TOSFracVP": 1.0, - }, - ) - - - -@configurable -def make_l0lls( - protons, - pions, - decay_descriptor, - pvs, - mm_min=600 * MeV, - mm_max=2000 * MeV, - vchi2_max=30, - mipchi2_max=50, - bpvdira=0, - bpvfdchi2=63, - eta_max=5.3, -): - combination_code = F.require_all( - in_range(mm_min, F.MASS, mm_max) - ) - - composite_code = F.require_all( - F.CHI2DOF < vchi2_max, - F.MINIPCHI2(pvs) < mipchi2_max, - F.BPVDIRA(pvs) > bpvdira, - F.BPVFDCHI2(pvs) > bpvfdchi2, - F.ETA < eta_max, - ) - - return ParticleCombiner( - [protons, pions], - name="L0ToPPi_LL_Combiner_{hash}", - DecayDescriptor=decay_descriptor, - CombinationCut=combination_code, - CompositeCut=composite_code, - ) - -def make_l0_p_piminus(protons, pions, pvs): - l0_particle_combinations = [ - #make_l0lls(protons, pions, "Lambda0 -> p+ pi+", pvs), - make_l0lls(protons, pions, "[Lambda0 -> p+ pi-]cc", pvs), - #make_l0lls(protons, pions, "Lambda0 -> p- pi-", pvs), - #make_l0lls(protons, pions, "Lambda0 -> p- pi+", pvs), - ] - - return ParticleContainersMerger( - l0_particle_combinations, name="L0_combinations_{hash}" - ) - - -def make_velo_protons(): - return _make_particles( - species="proton", - get_track_selector=get_all_track_selector, - make_protoparticles=make_charged_velo, - ) - - - -def construct_hlt2_line( - *, - name, - prescale, - pt_min, - pt_max, - p_min=2000.0, - filter_tis=False, - fromSMOG2=False, -): - pvs = make_pvs() - - pions = filter_pions(make_long_pions(), pvs, fromSMOG2=fromSMOG2) - turbo_line = name.find("Hlt2Turbo") != -1 - - if filter_tis: - protonsVelo = filter_particles_tis_velo( - make_long_protons(), pvs, fromSMOG2=fromSMOG2 - ) - else: - protonsVelo = filter_protons(make_velo_protons(), pvs, pt_max=16 * GeV) - - lambda0s = make_l0_p_piminus( - protonsVelo, - pions, - pvs=pvs, - ) # probe should be on index 1 - - filtered_lambda0s = L0LongVeloFilter( - InputParticle=lambda0s, - InputPVs=pvs, - PVConstrainedMassMin=1000.0, - PVConstrainedMassMax=1200.0, - PVConstrainedProbePtMin=pt_min, - PVConstrainedProbePtMax=pt_max, - PVConstrainedProbePMin=p_min, - name=f"TrackEffFilter_{name}", - ).OutputParticles - - if turbo_line: - """ Selective persistence""" - lambda0_flat_tree = FlattenDecayTree( - InputParticles=filtered_lambda0s, name=f"FlattenL0_{name}" - ) - lambda0_flat_daughters = ParticleFilter( - lambda0_flat_tree.OutputParticles, - F.FILTER(F.require_all(F.ISBASICPARTICLE, (F.TRACKISVELO @ F.TRACK))), - ) - - relation_table_match_by_lhcbid_long = LHCbIDOverlapRelationTable( - MatchFrom=lambda0_flat_daughters, - MatchTo=make_long_protons(), - IncludeVP=True, - IncludeFT=False, - IncludeUT=False, - MinMatchFraction=0.2, - ).OutputRelations - - relation_table_match_by_lhcbid_upstream = LHCbIDOverlapRelationTable( - MatchFrom=lambda0_flat_daughters, - MatchTo=make_up_protons(), - IncludeVP=True, - IncludeFT=False, - IncludeUT=False, - MinMatchFraction=0.2, - ).OutputRelations - - matched_long_pions = SelectionFromWeightedRelationTable( - InputRelations=relation_table_match_by_lhcbid_long - ).OutputLocation - matched_upstream_pions = SelectionFromWeightedRelationTable( - InputRelations=relation_table_match_by_lhcbid_upstream - ).OutputLocation - - particles_to_match = [ - ("MatchedLongPions", matched_long_pions), - ("MatchedUpstreamPions", matched_upstream_pions), - ] - else: - particles_to_match = None - - algs_list = upfront_reconstruction() + [require_pvs(pvs), filtered_lambda0s] - - if fromSMOG2: - algs_list = make_smog2_prefilters(pvs=make_pvs) + [filtered_lambda0s] - - return Hlt2Line( - name=name, - algs=algs_list, - prescale=prescale, - monitoring_variables=["m"], - extra_outputs=particles_to_match, - persistreco=not turbo_line, - ) - - -@register_line_builder(turbo_lines) -@configurable -def turbo_l0_velo_long_line(name="Hlt2TurboVelo2Long_Lambda0", prescale=1.0): - return construct_hlt2_line( - name=name, - prescale=prescale, - pt_min=0.0, - pt_max=20000.0, - p_min=2000.0, - ) - -@register_line_builder(turcal_lines) -@configurable -def turcal_l0_velo_long_line( - name="Hlt2TurCalVelo2Long_Lambda0", prescale=1.0 -): - return construct_hlt2_line( - name=name, - prescale=prescale, - pt_min=0.0, - pt_max=20000.0, - p_min=5000.0 - ) -- GitLab