diff --git a/Hlt/Hlt2Conf/python/Hlt2Conf/hlt1_tistos.py b/Hlt/Hlt2Conf/python/Hlt2Conf/hlt1_tistos.py index 4174d8e9910cfa5b52f60fbf56294271454b4c01..a05e0965c9624646b8c2beaca3ba810e1ff4a63f 100644 --- a/Hlt/Hlt2Conf/python/Hlt2Conf/hlt1_tistos.py +++ b/Hlt/Hlt2Conf/python/Hlt2Conf/hlt1_tistos.py @@ -92,3 +92,52 @@ def hlt1_tis_or_tos_on_any_filter( name = "Hlt1TISORTOSFilter_{hash}" return ParticleFilter(data, F.FILTER(hlt1_combination), name=name) + + +def hlt1_tistos_on_any_filter( + *, hlt1_trigger_lines, data, name=None, advanced_tistos_arguments={} +) -> ParticleFilter: + tis_tos_table = get_hlt1_tistos_relations( + trigger_lines=hlt1_trigger_lines, + data=data, + advanced_tistos_arguments=advanced_tistos_arguments, + ) + + tis_functors = [F.IS_TIS(line, tis_tos_table) == 1 for line in hlt1_trigger_lines] + tis_combination = F.require_any(*tis_functors) + tos_functors = [F.IS_TOS(line, tis_tos_table) == 1 for line in hlt1_trigger_lines] + tos_combination = F.require_any(*tos_functors) + + tistos_combination = F.require_all(tis_combination, tos_combination) + + if not name: + name = "Hlt1TISTOSFilter_{hash}" + + return ParticleFilter(data, F.FILTER(tistos_combination), name=name) + + +def hlt1_numerator_tistos_filter( + *, hlt1_tis_lines, hlt1_tos_line, data, name=None, advanced_tistos_arguments={} +) -> ParticleFilter: + """Function to compute numerator for TISTOS method: + hlt1_tos_line & (hlt1_tis_line[i] or hlt1_tis_line[j]...) + hlt1_tos_line expected to be one of the ht1_tis_lines""" + tis_tos_table = get_hlt1_tistos_relations( + trigger_lines=hlt1_tis_lines, + data=data, + advanced_tistos_arguments=advanced_tistos_arguments, + ) + + tistos_functors = [ + F.require_all( + F.IS_TIS(line, tis_tos_table) == 1, + F.IS_TOS(hlt1_tos_line, tis_tos_table) == 1, + ) + for line in hlt1_tis_lines + ] + combination = F.require_any(*tistos_functors) + + if not name: + name = "Hlt1_num_TISTOSFilter_{hash}" + + return ParticleFilter(data, F.FILTER(combination), name=name) diff --git a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/monitoring/__init__.py b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/monitoring/__init__.py index 3c09ed18a9382d75cc14025ccb39403ca8d0c941..7d61c2a94481aee38ab28a801e5847f5cbd7fa4e 100644 --- a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/monitoring/__init__.py +++ b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/monitoring/__init__.py @@ -1,5 +1,5 @@ ############################################################################### -# (c) Copyright 2021 CERN for the benefit of the LHCb Collaboration # +# (c) Copyright 2021-2025 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". # diff --git a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/monitoring/calibmon.py b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/monitoring/calibmon.py index 8fca47b6669236d1dd786132fb9a0b7fd2d5b45f..596fbda30fc0e246cee0cb5c643064558209dbc6 100644 --- a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/monitoring/calibmon.py +++ b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/monitoring/calibmon.py @@ -1,5 +1,5 @@ ############################################################################### -# (c) Copyright 2024 CERN for the benefit of the LHCb Collaboration # +# (c) Copyright 2025 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". # @@ -70,7 +70,11 @@ from RecoConf.standard_particles import ( from SelAlgorithms.monitoring import histogram_1d, histogram_2d, histogram_axis, monitor from Hlt2Conf.hlt1_tistos import hlt1_tos_on_any_filter +from Hlt2Conf.lines.monitoring.calibmon_utils import _make_hist_list from Hlt2Conf.lines.trackeff import KSVeloLong +from Hlt2Conf.lines.triggereff import triggereff_beauty_hlt2, triggereff_charm_hlt2 + +# from RecoConf.hlt1_allen import make_converted_tracks from Hlt2Conf.probe_muons import ( make_downstream_muons, make_muonut_muons, @@ -78,8 +82,6 @@ from Hlt2Conf.probe_muons import ( make_velomuon_muons, ) -# from RecoConf.hlt1_allen import make_converted_tracks - def _calibmon_filters(pvs): rb_filters = [] @@ -101,45 +103,6 @@ def _calibmon_filters(pvs): return rb_filters + [odin_bb_filter, require_pvs(pvs)] -def _make_hist_list(hist_dict, line_name): - # rearrange histos so that the the monitoring runs only once per input DataHandle - histos = {} - hist_list = [] - for histname, params in hist_dict.items(): - comb_name = params["input"].location.replace("/", "__") - ax = lambda xy: histogram_axis( - functor=params[f"variable_{xy}"], - label=params[f"label_{xy}"], - bins=params[f"bins_{xy}"], - range=params[f"range_{xy}"], - ) - if "variable_x" in params: - hist = histogram_2d( - name=f"/{line_name}/{histname}", - title=line_name, - xaxis=ax("x"), - yaxis=ax("y"), - ) - else: - hist = histogram_1d( - functor=params["variable"], - name=f"/{line_name}/{histname}", - label=params["label"], - bins=params["bins"], - range=params["range"], - title=line_name, - ) - if comb_name in histos.keys(): - histos[comb_name]["histograms"].append(hist) - else: - histos[comb_name] = dict(histograms=[hist], data_handle=params["input"]) - for params in histos.values(): - hist_list.append( - monitor(data=params["data_handle"], histograms=params["histograms"]) - ) - return hist_list - - # define a few shortcuts to make the code better readable def _CHILDMASS(i=1): return F.CHILD(i, F.MASS) @@ -194,6 +157,8 @@ def _HLT1_DEC(lines): all_lines = {} +all_lines.update(triggereff_beauty_hlt2.all_lines) +all_lines.update(triggereff_charm_hlt2.all_lines) @register_line_builder(all_lines) diff --git a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/monitoring/calibmon_utils.py b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/monitoring/calibmon_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..7b7c561a1739aba0164285755319053dc5df7dad --- /dev/null +++ b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/monitoring/calibmon_utils.py @@ -0,0 +1,50 @@ +############################################################################### +# (c) Copyright 2025 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. # +############################################################################### +from SelAlgorithms.monitoring import histogram_1d, histogram_2d, histogram_axis, monitor + + +def _make_hist_list(hist_dict, line_name): + # rearrange histos so that the the monitoring runs only once per input DataHandle + histos = {} + hist_list = [] + for histname, params in hist_dict.items(): + comb_name = params["input"].location.replace("/", "__") + ax = lambda xy: histogram_axis( + functor=params[f"variable_{xy}"], + label=params[f"label_{xy}"], + bins=params[f"bins_{xy}"], + range=params[f"range_{xy}"], + ) + if "variable_x" in params: + hist = histogram_2d( + name=f"/{line_name}/{histname}", + title=line_name, + xaxis=ax("x"), + yaxis=ax("y"), + ) + else: + hist = histogram_1d( + functor=params["variable"], + name=f"/{line_name}/{histname}", + label=params["label"], + bins=params["bins"], + range=params["range"], + title=line_name, + ) + if comb_name in histos.keys(): + histos[comb_name]["histograms"].append(hist) + else: + histos[comb_name] = dict(histograms=[hist], data_handle=params["input"]) + for params in histos.values(): + hist_list.append( + monitor(data=params["data_handle"], histograms=params["histograms"]) + ) + return hist_list diff --git a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/triggereff/__init__.py b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/triggereff/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b80112219f9d1bcb319a42555802e952fc42a63e --- /dev/null +++ b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/triggereff/__init__.py @@ -0,0 +1,19 @@ +############################################################################### +# (c) Copyright 2025 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. # +############################################################################### +""" +Submodule that defines all the Trigger efficiency HLT2 lines +""" + +from . import triggereff_beauty_hlt2, triggereff_charm_hlt2 + +all_lines = {} +all_lines.update(triggereff_beauty_hlt2.all_lines) +all_lines.update(triggereff_charm_hlt2.all_lines) diff --git a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/triggereff/monitoring_function.py b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/triggereff/monitoring_function.py new file mode 100644 index 0000000000000000000000000000000000000000..2b84ac4acee7f34a03e925a39d78e2c2f1f88d66 --- /dev/null +++ b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/triggereff/monitoring_function.py @@ -0,0 +1,87 @@ +############################################################################### +# (c) Copyright 2025 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 Hlt2Conf.lines.monitoring.calibmon_utils import _make_hist_list + + +def monitoring(input_particle, particles_dictionary, line_name): + """ + Function to create the histogram list for monitoring of + triggereff HLT2 lines with the TISTOS method + + - input_particle: Particle without any TISTOS filters + - particles_dictionary: Dictiornary containing the input_particle + with the following filters: + - hlt1_numerator_tistos_filter for TrackMVA + - hlt1_numerator_tistos_filter for TwoTrackMVA + - hlt1_tis_on_any_filter + - hlt1_tistos_on_any_filter + - line_name: Name of the HLT2 line + """ + + mass_range = (1000, 2500) + eta_range = (1.5, 5.5) + pt_range = (0, 30 * 1e3) + mass_label = "m [MeV]" + + hist_dict = {} + mass_part_dict = { + "bins": 50, + } + hist_dict["m"] = dict( + mass_part_dict, + input=input_particle, + variable=F.MASS, + range=mass_range, + label=mass_label, + ) + hist_dict["pt"] = dict( + mass_part_dict, + input=input_particle, + variable=F.PT, + range=pt_range, + label="pt [MeV]", + ) + hist_dict["eta"] = dict( + mass_part_dict, + input=input_particle, + variable=F.ETA, + range=(0, 1000000), + label="eta", + ) + + pt_bins = [0, 5e3, 10e3, 15e3, 20e3, 25e3] + eta_bins = [2.0, 3.0, 4.0, 5.0] + for hist_name, hist_input in particles_dictionary.items(): + for i in range(0, len(pt_bins) - 1): + min_pt, max_pt = pt_bins[i], pt_bins[i + 1] + hist_dict[f"{hist_name}_pt_{min_pt}_{max_pt}"] = dict( + bins=1, + input=hist_input, + variable=F.MASS * F.POD(in_range(min_pt, F.PT, max_pt)), + range=mass_range, + label=mass_label, + ) + for i in range(0, len(eta_bins) - 1): + min_eta, max_eta = eta_bins[i], eta_bins[i + 1] + hist_dict[f"{hist_name}_eta_{min_eta}_{max_eta}"] = dict( + bins=1, + input=hist_input, + variable=F.MASS * F.POD(in_range(min_eta, F.ETA, max_eta)), + range=eta_range, + label="eta", + ) + + hist_list = _make_hist_list(hist_dict, line_name) + + return hist_list diff --git a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/triggereff/triggereff_beauty_hlt2.py b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/triggereff/triggereff_beauty_hlt2.py new file mode 100644 index 0000000000000000000000000000000000000000..ad5283cac19c327f1473cb6acb7a30cf0e79e9dc --- /dev/null +++ b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/triggereff/triggereff_beauty_hlt2.py @@ -0,0 +1,231 @@ +############################################################################### +# (c) Copyright 2025 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 import require_all +from Functors.math import in_range +from GaudiKernel.SystemOfUnits import GeV, MeV, picosecond +from Moore.config import register_line_builder +from Moore.lines import Hlt2Line +from RecoConf.algorithms_thor import ParticleCombiner, ParticleFilter +from RecoConf.event_filters import require_pvs +from RecoConf.reconstruction_objects import make_pvs, upfront_reconstruction +from RecoConf.standard_particles import ( + make_has_rich_long_kaons, + make_ismuon_long_muon, + make_long_kaons, + make_long_muons, +) + +from Hlt2Conf.hlt1_tistos import ( + hlt1_numerator_tistos_filter, + hlt1_tis_on_any_filter, + hlt1_tistos_on_any_filter, +) + +from . import monitoring_function + +all_lines = {} + + +def prefilter(): + return upfront_reconstruction() + [require_pvs(make_pvs())] + + +# make_BuToJpsimumuKplus_detached_line +@register_line_builder(all_lines) +def Hlt2TriggerEff_BuToJpsiKplus_JpsiToMuMu_B2CC_line( + process="hlt2", name="Hlt2TriggerEff_BuToJpsiKplus_JpsiToMuMu_B2CC" +): + assert process in ["hlt2", "spruce"], ( + "Line must be defined as Hlt2 or Sprucing line!" + ) + + # Build muons + muons_filter = require_all( + F.PT > 500.0 * MeV, + F.P > 0 * MeV, + F.MINIPCHI2(make_pvs()) > 0, + F.PID_MU > -5, + F.ISMUON, + F.ETA < 5.0, + ) + muons = ParticleFilter(make_ismuon_long_muon(), F.FILTER(muons_filter)) + + # Build jpsi + combination_jpsi = require_all( + in_range(2700.0 * MeV, F.MASS, 3400.0 * MeV), + F.MAXSDOCACHI2CUT(20.0), + F.SUM(F.PT) > 0.0 * MeV, + ) + vertex_jpsi = require_all( + F.PT > 500.0 * MeV, F.CHI2 < 16.0, in_range(2950.0 * MeV, F.MASS, 3250.0 * MeV) + ) + + jpsi = ParticleCombiner( + [muons, muons], + DecayDescriptor="J/psi(1S) -> mu+ mu-", + CombinationCut=combination_jpsi, + CompositeCut=vertex_jpsi, + ) + + # Build kaons + filter_kaons = ( + require_all(F.PT > 800 * MeV, F.P > 3000 * MeV) + & (F.MINIPCHI2(make_pvs()) > 0) + & (F.PID_K > -1) + ) + kplus = ParticleFilter(make_has_rich_long_kaons(), F.FILTER(filter_kaons)) + + # Build B+ + combination_B2JpsiK = in_range(5000 * MeV, F.MASS, 6000 * MeV) + vertex_B2JpsiK = require_all( + in_range(5000 * MeV, F.MASS, 6000 * MeV), + (F.OWNPVDIRA > -10.0), + (F.CHI2DOF < 10), + (F.OWNPVLTIME > 0.2 * picosecond), + in_range(1900 * MeV, F.MASS - F.CHILD(1, F.MASS), 2700 * MeV), + ) + b2jpsikplus = ParticleCombiner( + Inputs=[jpsi, kplus], + DecayDescriptor="[B+ -> J/psi(1S) K+]cc", + CombinationCut=combination_B2JpsiK, + CompositeCut=vertex_B2JpsiK, + ) + + b_numerator_onetrack = hlt1_numerator_tistos_filter( + hlt1_tis_lines=["Hlt1TrackMVADecision", "Hlt1TwoTrackMVADecision"], + hlt1_tos_line="Hlt1TrackMVADecision", + data=b2jpsikplus, + ) + b_numerator_twotrack = hlt1_numerator_tistos_filter( + hlt1_tis_lines=["Hlt1TrackMVADecision", "Hlt1TwoTrackMVADecision"], + hlt1_tos_line="Hlt1TwoTrackMVADecision", + data=b2jpsikplus, + ) + b_tis_on_any = hlt1_tis_on_any_filter( + hlt1_trigger_lines=["Hlt1TrackMVADecision", "Hlt1TwoTrackMVADecision"], + data=b2jpsikplus, + ) + b_tistos_on_any = hlt1_tistos_on_any_filter( + hlt1_trigger_lines=["Hlt1TrackMVADecision", "Hlt1TwoTrackMVADecision"], + data=b2jpsikplus, + ) + + dict_variables = { + "numerator_onetrack": b_numerator_onetrack, + "numerator_twotracks": b_numerator_twotrack, + "tis_onany": b_tis_on_any, + "tistos_onany": b_tistos_on_any, + } + + b_hist_list = monitoring_function.monitoring(b2jpsikplus, dict_variables, name) + + return Hlt2Line( + name=name, + prescale=1, + algs=prefilter() + [jpsi, kplus, b2jpsikplus] + b_hist_list, + tagging_particles=True, + pv_tracks=True, + postscale=0, + persistreco=True, + ) + + +@register_line_builder(all_lines) +def Hlt2TriggerEff_BuToJpsiKplus_JpsiToMuMu_RD_line( + name="Hlt2TriggerEff_BuToJpsiKplus_JpsiToMuMu_RD", +): + kaon_pvs = make_pvs() + kaon_cuts = F.require_all( + F.PT > 250.0 * MeV, F.P > 2.0 * GeV, F.PID_K > 2, F.MINIPCHI2(kaon_pvs) > 9 + ) + kaons = ParticleFilter( + make_long_kaons(), + Cut=F.FILTER(kaon_cuts), + ) + + muon_pvs = make_pvs() + muon_cuts = F.require_all( + F.PT > 300.0 * MeV, + F.P > 3000.0 * MeV, + F.ISMUON, + F.PID_MU > 3, + F.MINIPCHI2(muon_pvs) > 9, + ) + muon = ParticleFilter( + make_long_muons(), + name="triggereff_detached_muons_{hash}", + Cut=F.FILTER(muon_cuts), + ) + + jpsi_combination_cut = F.require_all( + in_range(0.0 * MeV, F.MASS, 5500.0 * MeV), + F.PT > 0.0 * MeV, + F.MAXDOCACHI2CUT(30.0), + ) + # jpsi_pvs = make_pvs() + jpsi_vertex = F.require_all(F.CHI2DOF < 30.0, F.OWNPVFDCHI2 > 30.0) + + jpsi = ParticleCombiner( + [muon, muon], + DecayDescriptor="J/psi(1S) -> mu+ mu-", + CombinationCut=jpsi_combination_cut, + CompositeCut=jpsi_vertex, + ) + + # pvs = make_pvs() + b_cuts = in_range(4000 * MeV, F.MASS, 6500 * MeV) + b_vertex_cuts = F.require_all( + F.CHI2DOF < 9.0, + F.OWNPVIPCHI2 < 25, + F.OWNPVFDCHI2 > 100, + F.OWNPVDIRA > 0.995, + ) + bu = ParticleCombiner( + [jpsi, kaons], + DecayDescriptor="[B+ -> J/psi(1S) K+]cc", + CombinationCut=b_cuts, + CompositeCut=b_vertex_cuts, + ) + + b_numerator_onetrack = hlt1_numerator_tistos_filter( + hlt1_tis_lines=["Hlt1TrackMVADecision", "Hlt1TwoTrackMVADecision"], + hlt1_tos_line="Hlt1TrackMVADecision", + data=bu, + ) + b_numerator_twotrack = hlt1_numerator_tistos_filter( + hlt1_tis_lines=["Hlt1TrackMVADecision", "Hlt1TwoTrackMVADecision"], + hlt1_tos_line="Hlt1TwoTrackMVADecision", + data=bu, + ) + b_tis_on_any = hlt1_tis_on_any_filter( + hlt1_trigger_lines=["Hlt1TrackMVADecision", "Hlt1TwoTrackMVADecision"], data=bu + ) + b_tistos_on_any = hlt1_tistos_on_any_filter( + hlt1_trigger_lines=["Hlt1TrackMVADecision", "Hlt1TwoTrackMVADecision"], data=bu + ) + + dict_variables = { + "numerator_onetrack": b_numerator_onetrack, + "numerator_twotracks": b_numerator_twotrack, + "tis_onany": b_tis_on_any, + "tistos_onany": b_tistos_on_any, + } + + b_hist_list = monitoring_function.monitoring(bu, dict_variables, name) + + return Hlt2Line( + name=name, + prescale=1, + algs=prefilter() + [kaons, jpsi, bu] + b_hist_list, + postscale=0, + persistreco=True, + ) diff --git a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/triggereff/triggereff_charm_hlt2.py b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/triggereff/triggereff_charm_hlt2.py new file mode 100644 index 0000000000000000000000000000000000000000..c3ed0d666e42e3179d2d3ad02e55d84d56c9cba4 --- /dev/null +++ b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/triggereff/triggereff_charm_hlt2.py @@ -0,0 +1,124 @@ +############################################################################### +# (c) Copyright 2025 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 +from Moore.config import register_line_builder +from Moore.lines import Hlt2Line +from RecoConf.algorithms_thor import ParticleCombiner, ParticleFilter +from RecoConf.event_filters import require_pvs +from RecoConf.reconstruction_objects import make_pvs, upfront_reconstruction +from RecoConf.standard_particles import ( + make_has_rich_long_kaons, + make_has_rich_long_pions, + make_long_pions, +) + +from Hlt2Conf.hlt1_tistos import ( + hlt1_numerator_tistos_filter, + hlt1_tis_on_any_filter, + hlt1_tistos_on_any_filter, +) + +from . import monitoring_function + +all_lines = {} + + +def prefilter(): + return upfront_reconstruction() + [require_pvs(make_pvs())] + + +@register_line_builder(all_lines) +def Hlt2TriggerEff_Dstp2D0Pip_D02KmPip_line(name="Hlt2TriggerEff_Dstp2D0Pip_D02KmPip"): + kaons_cuts = F.require_all( + F.MINIPCHI2CUT(IPChi2Cut=4.0, Vertices=make_pvs()), + F.PT > 800 * MeV, + F.P > 5 * GeV, + F.PID_K > 5.0, + ) + kaons = ParticleFilter(make_has_rich_long_kaons(), F.FILTER(kaons_cuts)) + + pions_cuts = F.require_all( + F.MINIPCHI2CUT(IPChi2Cut=4.0, Vertices=make_pvs()), + F.PT > 800 * MeV, + F.P > 5 * GeV, + F.PID_K < 5.0, + ) + pions = ParticleFilter(make_has_rich_long_pions(), F.FILTER(pions_cuts)) + + dzero_combination = F.require_all( + in_range(1685 * MeV, F.MASS, 2045 * MeV), + F.PT > 2 * GeV, + F.MAX(F.PT) > 1200 * MeV, + F.MAXSDOCACUT(0.1 * mm), + ) + dzero_composite = F.require_all( + in_range(1715 * MeV, F.MASS, 2015 * MeV), + F.CHI2DOF < 10.0, + F.OWNPVFDCHI2 > 25.0, + F.OWNPVDIRA > 0.99985, + ) + dzeros = ParticleCombiner( + [kaons, pions], + DecayDescriptor="[D0 -> K- pi+]cc", + CombinationCut=dzero_combination, + CompositeCut=dzero_composite, + ) + + pions_dst = ParticleFilter( + make_long_pions(), F.FILTER(F.require_all(F.PT > 200 * MeV, F.P > 1 * GeV)) + ) + dst_combination = F.MASS - F.CHILD(1, F.MASS) < 165 * MeV + dst_composite = F.require_all( + F.MASS - F.CHILD(1, F.MASS) < 160 * MeV, F.CHI2DOF < (25.0) + ) + dst = ParticleCombiner( + [dzeros, pions_dst], + DecayDescriptor="[D*(2010)+ -> D0 pi+]cc", + CombinationCut=dst_combination, + CompositeCut=dst_composite, + ) + + numerator_onetrack = hlt1_numerator_tistos_filter( + hlt1_tis_lines=["Hlt1TrackMVADecision", "Hlt1TwoTrackMVADecision"], + hlt1_tos_line="Hlt1TrackMVADecision", + data=dzeros, + ) + numerator_twotrack = hlt1_numerator_tistos_filter( + hlt1_tis_lines=["Hlt1TrackMVADecision", "Hlt1TwoTrackMVADecision"], + hlt1_tos_line="Hlt1TwoTrackMVADecision", + data=dzeros, + ) + tis_on_any = hlt1_tis_on_any_filter( + hlt1_trigger_lines=["Hlt1TrackMVADecision", "Hlt1TwoTrackMVADecision"], + data=dzeros, + ) + tistos_on_any = hlt1_tistos_on_any_filter( + hlt1_trigger_lines=["Hlt1TrackMVADecision", "Hlt1TwoTrackMVADecision"], + data=dzeros, + ) + + dict_variables = { + "numerator_onetrack": numerator_onetrack, + "numerator_twotracks": numerator_twotrack, + "tis_onany": tis_on_any, + "tistos_onany": tistos_on_any, + } + + hist_list = monitoring_function.monitoring(dzeros, dict_variables, name) + + return Hlt2Line( + name=name, + algs=prefilter() + [dst, dzeros] + hist_list, + postscale=0, + persistreco=True, + ) diff --git a/Hlt/Hlt2Conf/tests/options/streaming/sprucing_physicsstreams_config_check.py b/Hlt/Hlt2Conf/tests/options/streaming/sprucing_physicsstreams_config_check.py index e2e5f8e1f4f28907b1278cda2d5ae5d23868c62f..9f9e6a71bfee016b4ff2fb82abc3df50a8ae9302 100644 --- a/Hlt/Hlt2Conf/tests/options/streaming/sprucing_physicsstreams_config_check.py +++ b/Hlt/Hlt2Conf/tests/options/streaming/sprucing_physicsstreams_config_check.py @@ -56,7 +56,12 @@ def get_hlt2_streaming(hlt2optsdumpfile): # Lumi line not to be streamed to disk omit_lines = ["Hlt2Lumi"] # Monitoring and DQ lines not to be streamed to disk -turcal_omit_lines = ["Hlt2Monitoring", "Hlt2DQ", "Hlt2CalibMon"] + omit_lines +turcal_omit_lines = [ + "Hlt2Monitoring", + "Hlt2DQ", + "Hlt2CalibMon", + "Hlt2TriggerEff", +] + omit_lines ##Get HLT2 lines by stream ("Decision" suffix added for TURBO for regex compatibility) decisions = get_hlt2_streaming("hlt2_pp_2024_optsdump.py") diff --git a/Hlt/Hlt2Conf/tests/options/streaming/sprucing_physicsstreams_config_check_pp_ref_2024.py b/Hlt/Hlt2Conf/tests/options/streaming/sprucing_physicsstreams_config_check_pp_ref_2024.py index 7944e77d9d9abf858967df99c346738630f507cd..387cf8a390b49792301115fd8738cb77ed40a7ea 100644 --- a/Hlt/Hlt2Conf/tests/options/streaming/sprucing_physicsstreams_config_check_pp_ref_2024.py +++ b/Hlt/Hlt2Conf/tests/options/streaming/sprucing_physicsstreams_config_check_pp_ref_2024.py @@ -55,7 +55,12 @@ def get_hlt2_streaming(hlt2optsdumpfile): # Lumi line not to be streamed to disk omit_lines = ["Hlt2Lumi"] # Monitoring and DQ lines not to be streamed to disk -turcal_omit_lines = ["Hlt2Monitoring", "Hlt2DQ", "Hlt2CalibMon"] + omit_lines +turcal_omit_lines = [ + "Hlt2Monitoring", + "Hlt2DQ", + "Hlt2CalibMon", + "Hlt2TriggerEff", +] + omit_lines ##Get HLT2 lines by stream ("Decision" suffix added for TURBO for regex compatibility) decisions = get_hlt2_streaming("hlt2_pp_ref_2024_optsdump.py")