From 75268fe3f92cf164105e4d03cef99341cf70952b Mon Sep 17 00:00:00 2001
From: Imanol Corredoira Fernandez <imanol.corredoira.fernandez@cern.ch>
Date: Tue, 11 Mar 2025 08:24:51 +0000
Subject: [PATCH 1/8] Reducing the momentum cut in the DY HLT2 line

---
 Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/drellyan.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/drellyan.py b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/drellyan.py
index dff1de5bdf7..696bd6670b1 100644
--- a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/drellyan.py
+++ b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/drellyan.py
@@ -161,11 +161,11 @@ for is_ss in [True, False]:
             ):
                 pvs = make_pvs()
 
+                muon_min_p = 6 * GeV
+
                 if use_soft_muons:
-                    muon_min_p = 10.0 * GeV
                     muon_min_pt = 1.0 * GeV
                 else:
-                    muon_min_p = 17.5 * GeV
                     muon_min_pt = 1.3 * GeV
 
                 dimuons = make_dimuon_candidates(
-- 
GitLab


From 981611c9e4f192bb4b6d18ddcdb7b96845cc6455 Mon Sep 17 00:00:00 2001
From: Izaac Sanderswood <izaac.sanderswood@cern.ch>
Date: Wed, 12 Mar 2025 12:29:36 +0000
Subject: [PATCH 2/8] Remove unnecessary charge conjugates from decay
 descriptors

---
 Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/qee_builders.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/qee_builders.py b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/qee_builders.py
index 42d3a0be941..b51288d6298 100644
--- a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/qee_builders.py
+++ b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/qee_builders.py
@@ -629,7 +629,7 @@ def make_XtoTT_muons(pvs, mass_min=2000.0):
         filtered_TT_muons,
         filtered_TT_muons,
         pvs,
-        "[KS0 -> mu+ mu-]cc",
+        "KS0 -> mu+ mu-",
         mass_min=mass_min,
     )
 
@@ -638,7 +638,7 @@ def make_XtoTT_muons(pvs, mass_min=2000.0):
 def make_XtoTT_kaons(pvs):
     filtered_TT_kaons = filter_ttrack_kaons_for_high_mass(pvs)
     return qee_ttrack_combiner_highmass(
-        filtered_TT_kaons, filtered_TT_kaons, pvs, "[KS0 -> K+ K-]cc"
+        filtered_TT_kaons, filtered_TT_kaons, pvs, "KS0 -> K+ K-"
     )
 
 
-- 
GitLab


From 4bbea6c67187b3c7cb65b4a881ce7eb84af30641 Mon Sep 17 00:00:00 2001
From: Ross John Hunter <ross.john.hunter@cern.ch>
Date: Thu, 13 Mar 2025 11:56:49 +0000
Subject: [PATCH 3/8] Add a HLT1 filter to the Hlt2SingleHighPtMuon lines

---
 .../python/Hlt2Conf/lines/qee/single_high_pt_muon.py         | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/single_high_pt_muon.py b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/single_high_pt_muon.py
index 8cc398e8ff5..d55da7ce8d1 100644
--- a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/single_high_pt_muon.py
+++ b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/single_high_pt_muon.py
@@ -1,5 +1,5 @@
 ###############################################################################
-# (c) Copyright 2019-2023 CERN for the benefit of the LHCb Collaboration      #
+# (c) Copyright 2019-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".   #
@@ -82,6 +82,7 @@ def single_muon_highpt_line(
         prescale=prescale,
         persistreco=persistreco,
         monitoring_variables=("pt", "eta", "n_candidates"),
+        hlt1_filter_code=["Hlt1SingleHighPtMuonDecision"],
     )
 
 
@@ -100,6 +101,7 @@ def single_muon_highpt_prescale_line(
         prescale=prescale,
         persistreco=persistreco,
         monitoring_variables=("pt", "eta", "n_candidates"),
+        hlt1_filter_code=["Hlt1SingleHighPtMuonDecision"],
     )
 
 
@@ -120,6 +122,7 @@ def single_muon_highpt_iso_line(
         prescale=prescale,
         persistreco=persistreco,
         monitoring_variables=("pt", "eta", "n_candidates"),
+        hlt1_filter_code=["Hlt1SingleHighPtMuonDecision"],
     )
 
 
-- 
GitLab


From bd4bae6e520891de421d47923c3e24be98920941 Mon Sep 17 00:00:00 2001
From: Spencer Collaviti <spencer.edward.collaviti@cern.ch>
Date: Mon, 17 Mar 2025 10:53:06 +0000
Subject: [PATCH 4/8] Retune LL and DD HNL Lines

---
 .../lines/qee/b_to_majolep_majo_to_leplep.py  |  44 +++----
 .../lines/qee/b_to_majolep_majo_to_leppi.py   | 123 ++++++++++++++++--
 .../python/Hlt2Conf/lines/qee/qee_builders.py |   4 +-
 3 files changed, 137 insertions(+), 34 deletions(-)

diff --git a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/b_to_majolep_majo_to_leplep.py b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/b_to_majolep_majo_to_leplep.py
index 7f7f5ecc4e7..2db34009a48 100644
--- a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/b_to_majolep_majo_to_leplep.py
+++ b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/b_to_majolep_majo_to_leplep.py
@@ -1,5 +1,5 @@
 ###############################################################################
-# (c) Copyright 2019 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".   #
@@ -31,8 +31,11 @@ Hlt2QEE_BpToMajoE_MajoToMuE_SS_DD_Tight: tight PID cut line for the B(_c)+ -> e
 Hlt2QEE_BpToMajoE_MajoToMuE_OS_LL_Tight: tight PID cut line for the B(_c)+ -> e HNL(-> mu- e, LL)
 Hlt2QEE_BpToMajoE_MajoToMuE_OS_DD_Tight: tight PID cut line for the B(_c)+ -> e HNL(-> mu- e, DD)
 
-Contact: Louis Henry, louis.henry@cern.ch
-
+Contact:
+- Spencer Collaviti, spencer.collaviti@cern.ch
+- Andrea Merli, andrea.merli@cern.ch
+- Lisa Fantini, lisa.fantini@cern.ch
+- Viacheslav Duk, viacheslav.duk@cern.ch
 """
 
 import Functors as F
@@ -93,20 +96,20 @@ def _custom_monitoring_params(pvs, ptName):
 
 defaultCutDict = {
     "LL": {
-        "AllTracks": {"P": 2000.0 * MeV},
+        "AllTracks": {"P": 2000.0 * MeV, "TRCHI2NDOFMAX": 3.0, "GHOSTPROBMAX": 0.4},
         "Children": {"MINIPCHI2PV": 200},
         "Bachelor": {},
         "Child1": {},
         "Child2": {},
         "Majo": {
             "FDCHI2MIN": 2000,
-            "MASS": [0.2 * GeV, 6.0 * GeV],
+            "MASS": [1.0 * GeV, 6.5 * GeV],
             "MINIPCHI2PV": 20,
         },
         "B": {"MASS": [4.0 * GeV, 7.0 * GeV]},
     },
     "DD": {
-        "AllTracks": {"P": 2000.0 * MeV},
+        "AllTracks": {"P": 2000.0 * MeV, "TRCHI2NDOFMAX": 3.0, "GHOSTPROBMAX": 0.4},
         "Children": {},
         "Bachelor": {},
         "Child1": {},
@@ -117,7 +120,7 @@ defaultCutDict = {
 }
 
 child_muon_pidCut = [F.ISMUON, F.PID_MU > 0.0]
-bach_muon_pidCut = [F.PID_MU > 2]
+bach_muon_pidCut = [F.ISMUON, F.PID_MU > 2]
 
 electron_pidCut = [F.PID_E > -2]
 
@@ -136,13 +139,16 @@ def buildFromList(cutList):
 
 
 # Build a cut from a dictionnary
-def build_cut_on_track(cutDict, pvs):
+def build_cut_on_track(cutDict, pvs, corrm=False):
     listOfFunctors = []
     for cut, cutVal in cutDict.items():
         if cut == "PIDCuts":
             listOfFunctors += cutVal
         elif cut == "MASS":
-            listOfFunctors.append(in_range(cutVal[0], F.MASS, cutVal[1]))
+            if corrm:
+                listOfFunctors.append(in_range(cutVal[0], F.OWNPVCORRM(), cutVal[1]))
+            else:
+                listOfFunctors.append(in_range(cutVal[0], F.MASS, cutVal[1]))
         else:
             functors = {
                 "P": F.P,
@@ -151,6 +157,8 @@ def build_cut_on_track(cutDict, pvs):
                 "FDCHI2MIN": F.OWNPVFDCHI2,
                 "FDCHI2MAX": F.OWNPVFDCHI2,
                 "MAXDOCA": F.MAXDOCA(),
+                "TRCHI2NDOFMAX": F.CHI2DOF,
+                "GHOSTPROBMAX": F.GHOSTPROB,
             }
             if "MAX" in cut:
                 listOfFunctors.append(functors[cut] < cutVal)
@@ -161,18 +169,12 @@ def build_cut_on_track(cutDict, pvs):
     return buildFromList(listOfFunctors)
 
 
-def build_combination_cut(cutDict, pvs):
-    listOfFunctors = []
-    for cut, cutVal in cutDict.items():
-        if cut == "MASS":
-            listOfFunctors.append(in_range(cutVal[0], F.MASS, cutVal[1]))
-    # Build the cut
-    return buildFromList(listOfFunctors)
-
-
 def builder_BToMajoL_line(
-    name, bachelorName, children, cutDict={}, prescale=1, persistreco=True
+    name, bachelorName, children, cutDict=None, prescale=1, persistreco=True
 ):
+    if cutDict is None:
+        cutDict = {}
+
     pvs = make_pvs
     # Interpret name into a B decay
     majoDecayDescr = "KS0 -> " + children[0] + "+ " + children[1] + "-"
@@ -221,8 +223,7 @@ def builder_BToMajoL_line(
         [firstChild, secondChild],
         name="Majo2" + children[0] + children[1] + "_" + recoMode + "_{hash}",
         DecayDescriptor=majoDecayDescr,
-        CombinationCut=build_combination_cut(cutDict["Majo"], pvs),
-        CompositeCut=build_cut_on_track(cutDict["Majo"], pvs),
+        CompositeCut=build_cut_on_track(cutDict["Majo"], pvs, corrm=True),
     )
     # Bachelor
     bachelor = make_filter_tracks(
@@ -235,7 +236,6 @@ def builder_BToMajoL_line(
         [majo, bachelor],
         name=name + "_{hash}",
         DecayDescriptor="[B+ -> KS0 " + bachelorName + "+]cc",
-        CombinationCut=build_combination_cut(cutDict["B"], pvs),
         CompositeCut=build_cut_on_track(cutDict["B"], pvs),
     )
 
diff --git a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/b_to_majolep_majo_to_leppi.py b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/b_to_majolep_majo_to_leppi.py
index 251007ac133..59a4e00a129 100644
--- a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/b_to_majolep_majo_to_leppi.py
+++ b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/b_to_majolep_majo_to_leppi.py
@@ -1,5 +1,5 @@
 ###############################################################################
-# (c) Copyright 2019 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".   #
@@ -21,6 +21,8 @@ List of lines (LL - Long, DD - downstream):
 
 Hlt2QEE_BpToMajoMu_MajoToEPi_LL_Tight: tight PID cut line for the B(_c)+ -> mu HNL(-> epi, LL)
 Hlt2QEE_BpToMajoE_MajoToMuPi_LL_Tight: tight PID cut line for the B(_c)+ -> e HNL(-> mupi, LL)
+Hlt2QEE_BpToMajoMu_MajoToMuPi_LL_Tight: tight PID cut line for the B(_c)+ -> mu HNL(-> mupi, LL)
+Hlt2QEE_BpToMajoE_MajoToEPi_LL_Tight: tight PID cut line for the B(_c)+ -> e HNL(-> epi, LL)
 Hlt2QEE_BpToMajoMu_MajoToEPi_DD_Tight: tight PID cut line for the B(_c)+ -> mu HNL(-> epi, DD)
 Hlt2QEE_BpToMajoE_MajoToMuPi_DD_Tight: tight PID cut line for the B(_c)+ -> e HNL(-> mupi, DD)
 
@@ -33,9 +35,11 @@ Hlt2QEE_BuToKs0Pi_Ks0ToPiPi_LL: B+ -> pi KS0 (->pipi) LL line
 Hlt2QEE_BuToKs0Pi_Ks0ToPiPi_DD: B+ -> pi KS0 (->pipi) DD line
 
 
-Contact: Lera Lukashenko, valeriia.lukashenko@cern.ch
-Contact: Louis Henry, louis.henry@cern.ch
-
+Contact:
+- Spencer Collaviti, spencer.collaviti@cern.ch
+- Andrea Merli, andrea.merli@cern.ch
+- Lisa Fantini, lisa.fantini@cern.ch
+- Viacheslav Duk, viacheslav.duk@cern.ch
 """
 
 import Functors as F
@@ -74,7 +78,7 @@ def BpToMajoMu_MajoToEPi_LL_Tight_line(
 
     muons = make_majorana_lepton(
         leptons=make_long_muons,
-        name="majo_long_muons_{hash}",
+        name="majo_B_long_muons_{hash}",
         pvs=pvs,
         pt_min=700 * MeV,
         pid=F.ISMUON,
@@ -124,7 +128,7 @@ def BpToMajoE_MajoToMuPi_LL_Tight_line(
     pvs = make_pvs
 
     muons = make_majorana_lepton(
-        leptons=make_long_muons, name="majo_long_muons_{hash}", pvs=pvs, pid=F.ISMUON
+        leptons=make_long_muons, name="majo_N_long_muons_{hash}", pvs=pvs, pid=F.ISMUON
     )
 
     electrons_with_brem = make_majorana_lepton(
@@ -165,6 +169,105 @@ def BpToMajoE_MajoToMuPi_LL_Tight_line(
     )
 
 
+@register_line_builder(all_lines)
+def BpToMajoMu_MajoToMuPi_LL_Tight_line(
+    name="Hlt2QEE_BpToMajoMu_MajoToMuPi_LL_Tight", prescale=1
+):
+    pvs = make_pvs
+
+    b_muons = make_majorana_lepton(
+        leptons=make_long_muons,
+        name="majo_B_long_muons_{hash}",
+        pvs=pvs,
+        pt_min=700 * MeV,
+        pid=F.ISMUON,
+    )
+
+    muons = make_majorana_lepton(
+        leptons=make_long_muons, name="majo_N_long_muons_{hash}", pvs=pvs, pid=F.ISMUON
+    )
+
+    pions = make_majorana_lepton(
+        leptons=make_long_pions,
+        name="majo_long_pions_{hash}",
+        pvs=pvs,
+        pid=(F.PID_E <= 0.0),
+    )
+
+    majoranas2piMu = make_majorana(
+        name="Majo2mupi_{hash}",
+        child1=pions,
+        child2=muons,
+        descriptor="[KS0 -> mu- pi+]cc",
+    )
+
+    b2MuN = make_bhadron_majorana(
+        name="B2MajoMu_{hash}",
+        majoranas=majoranas2piMu,
+        bachelor=b_muons,
+        pvs=pvs,
+        descriptor="[B+ -> KS0 mu+]cc",
+    )
+
+    return Hlt2Line(
+        name=name,
+        algs=hnl_prefilter() + [majoranas2piMu, b2MuN],
+        prescale=prescale,
+        monitoring_variables=_HNL_MONITORING_VARIABLES,
+    )
+
+
+@register_line_builder(all_lines)
+def BpToMajoE_MajoToEPi_LL_Tight_line(
+    name="Hlt2QEE_BpToMajoE_MajoToEPi_LL_Tight", prescale=1
+):
+    pvs = make_pvs
+
+    b_electrons_with_brem = make_majorana_lepton(
+        leptons=make_long_electrons_with_brem,
+        name="majo_long_electrons_with_brem_{hash}",
+        pvs=pvs,
+        pt_min=700 * MeV,
+        pid=(F.PID_E > 1.0),
+    )
+
+    electrons_with_brem = make_majorana_lepton(
+        leptons=make_long_electrons_with_brem,
+        name="majo_long_electrons_with_brem_{hash}",
+        pvs=pvs,
+        pid=(F.PID_E > 1.0),
+    )
+
+    pions = make_majorana_lepton(
+        leptons=make_long_pions,
+        name="majo_long_pions_{hash}",
+        pvs=pvs,
+        pid=(F.PID_E <= 0.0),
+    )
+
+    majoranas2piE = make_majorana(
+        name="Majo2epi_{hash}",
+        child1=pions,
+        child2=electrons_with_brem,
+        descriptor="[KS0 -> e- pi+]cc",
+    )
+
+    b2EN = make_bhadron_majorana(
+        name="B2MajoE_{hash}",
+        majoranas=majoranas2piE,
+        bachelor=b_electrons_with_brem,
+        pvs=pvs,
+        descriptor="[B+ -> KS0 e+]cc",
+    )
+
+    return Hlt2Line(
+        name=name,
+        algs=hnl_prefilter() + [majoranas2piE, b2EN],
+        prescale=prescale,
+        monitoring_variables=_HNL_MONITORING_VARIABLES,
+    )
+
+
 @register_line_builder(all_lines)
 def BpToMajoMu_MajoToEPi_DD_Tight_line(
     name="Hlt2QEE_BpToMajoMu_MajoToEPi_DD_Tight", prescale=1
@@ -173,7 +276,7 @@ def BpToMajoMu_MajoToEPi_DD_Tight_line(
 
     muons = make_majorana_lepton(
         leptons=make_long_muons,
-        name="majo_long_muons_{hash}",
+        name="majo_B_long_muons_{hash}",
         pvs=pvs,
         pt_min=700 * MeV,
         pid=F.ISMUON,
@@ -282,7 +385,7 @@ def BpToMajoMu_MajoToEPi_LL_Loose_line(
 
     muons = make_majorana_lepton(
         leptons=make_long_muons,
-        name="majo_long_muons_{hash}",
+        name="majo_B_long_muons_{hash}",
         pvs=pvs,
         pt_min=700 * MeV,
         pid=F.ISMUON,
@@ -332,7 +435,7 @@ def BpToMajoE_MajoToMuPi_LL_Loose_line(
     pvs = make_pvs
 
     muons = make_majorana_lepton(
-        leptons=make_long_muons, name="majo_long_muons_{hash}", pvs=pvs, pid=F.ISMUON
+        leptons=make_long_muons, name="majo_N_long_muons_{hash}", pvs=pvs, pid=F.ISMUON
     )
 
     electrons_with_brem = make_majorana_lepton(
@@ -381,7 +484,7 @@ def BpToMajoMu_MajoToEPi_DD_Loose_line(
 
     muons = make_majorana_lepton(
         leptons=make_long_muons,
-        name="majo_long_muons_{hash}",
+        name="majo_B_long_muons_{hash}",
         pvs=pvs,
         pt_min=700 * MeV,
         pid=F.ISMUON,
diff --git a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/qee_builders.py b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/qee_builders.py
index b51288d6298..dd9f46f9722 100644
--- a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/qee_builders.py
+++ b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/qee_builders.py
@@ -290,8 +290,8 @@ def make_majorana(
     child2,
     name="Generic_Majorana",
     descriptor="",
-    am_min=0.2 * GeV,
-    am_max=7.0 * GeV,
+    am_min=1.0 * GeV,
+    am_max=6.5 * GeV,
     adocachi2=16.0,
     pt_min=0.7 * GeV,
     vtxchi2_max=9.0,
-- 
GitLab


From 61c0a2d573342a5a9ad599e740f130b34d72756f Mon Sep 17 00:00:00 2001
From: Lorenzo Sestini <lorenzo.sestini@cern.ch>
Date: Wed, 19 Mar 2025 09:35:35 +0100
Subject: [PATCH 5/8] New lines for multilepton searches

---
 .../lines/qee/dilepton_persist_leptons.py     | 534 ++++++++++++++++++
 .../python/Hlt2Conf/lines/qee/hlt2_qee.py     |   2 +
 2 files changed, 536 insertions(+)
 create mode 100644 Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/dilepton_persist_leptons.py

diff --git a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/dilepton_persist_leptons.py b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/dilepton_persist_leptons.py
new file mode 100644
index 00000000000..e491bae1a43
--- /dev/null
+++ b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/dilepton_persist_leptons.py
@@ -0,0 +1,534 @@
+###############################################################################
+# (c) Copyright 2019-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.                                       #
+###############################################################################
+"""
+Definition of an HLT2 line to preserve dilepton candidates (dimuons or dielectrons) and any other lepton in the event (muon or electron).
+Aim for new dark photon searches
+Contact: Lorenzo Sestini lorenzo.sestini@cern.ch
+"""
+
+import Functors as F
+from Functors.math import in_range
+from GaudiKernel.SystemOfUnits import MeV, GeV, mm
+from Moore.config import register_line_builder
+from Moore.lines import Hlt2Line
+from PyConf import configurable
+from PyConf.Algorithms import SelectionFromRelationTable, WeightedRelTableAlg
+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_detached_dielectron_with_brem,
+    make_long_electrons_no_brem,
+    make_long_electrons_with_brem,
+    make_prompt_dielectron_with_brem,
+    make_ismuon_long_muon
+)
+
+full_lines = {}
+turbo_lines = {}
+
+#Mass limits now accepts all possible dilepton+lepton combination. May be reduced in the future.
+comb_mass_limits = (0.0 * GeV, 14000.0 * GeV)
+# NOTE: No dielectron mass monitors allowed (custom or default) to avoid potential unblinding.
+_default_monitoring_variables = ("pt", "eta", "n_candidates", "ipchi2", "vchi2")
+
+
+@configurable
+def muon_filter(pvs, make_particles=make_ismuon_long_muon, min_ipchi2=0, pid_mu=-10, p_min=5 * GeV, pt_min=0.0 * GeV):
+    muon_requirements = F.require_all(
+        F.P >= p_min,
+        F.PT >= pt_min,
+        F.MINIPCHI2CUT(IPChi2Cut=min_ipchi2, Vertices=pvs),
+    )
+    if pid_mu:
+        muon_requirements = (F.PID_MU > pid_mu) & muon_requirements
+    return ParticleFilter(make_particles(), F.FILTER(muon_requirements))
+
+@configurable
+def electron_filter(make_particles=make_long_electrons_with_brem, p_min=5 * GeV, pid_e=0.0, pt_min=0.0 * GeV):
+    electron_requirements = F.require_all(
+        F.P >= p_min,
+        F.PT >= pt_min,
+        F.PID_E >= pid_e,
+    )
+
+    return ParticleFilter(make_particles(), F.FILTER(electron_requirements))
+
+@configurable
+def dimuon_maker(
+    pvs,
+    comb_maxdoca=0.1 * mm,
+    vchi2pdof_max=9,
+    min_pt_prod=1 * GeV * GeV,
+    min_ipchi2=0,
+    min_mass=2 * F.PDG_MASS("mu+"),
+    max_mass=110 * GeV,
+    isOS=True,
+    pid_mu=-10,
+    ownpvvdchi2_min=0,
+):
+    muons = make_ismuon_long_muon
+    filtered_muons = muon_filter(pvs, muons, min_ipchi2, pid_mu)
+    combination_code = F.require_all(
+        F.MAXSDOCACUT(comb_maxdoca),
+        F.CHILD(1, F.PT) * F.CHILD(2, F.PT) > min_pt_prod,
+        in_range(min_mass, F.MASS, max_mass),
+    )
+    vertex_code = F.require_all(
+        F.CHI2DOF < vchi2pdof_max, F.OWNPVFDCHI2 > ownpvvdchi2_min
+    )
+    if isOS:
+        DecayDescriptor = "J/psi(1S) -> mu+ mu-"
+    else:
+        DecayDescriptor = "[J/psi(1S) -> mu+ mu+]cc"
+    return ParticleCombiner(
+        Inputs=[filtered_muons, filtered_muons],
+        DecayDescriptor=DecayDescriptor,
+        CombinationCut=combination_code,
+        CompositeCut=vertex_code,
+    )
+
+
+@configurable
+def dielectron_maker_prompt(e_minpt, isOS):
+    return make_prompt_dielectron_with_brem(
+        electron_maker=make_long_electrons_no_brem,
+        opposite_sign=isOS,
+        PIDe_min=0.0,
+        pt_e=e_minpt,
+        maxipchi2=2.0,
+        trghostprob=0.25,
+        dielectron_ID="J/psi(1S)",
+        pt_diE=0 * MeV,
+        m_diE_min=5 * MeV,
+        m_diE_max=300 * MeV,
+        adocachi2cut=30,
+        bpvvdchi2=None,
+        vfaspfchi2ndof=10,
+    )
+
+
+@configurable
+def dielectron_maker_displaced(e_minpt, isOS):
+    return make_detached_dielectron_with_brem(
+        electron_maker=make_long_electrons_no_brem,
+        opposite_sign=isOS,
+        PIDe_min=0.0,
+        pt_e=e_minpt,
+        minipchi2=2.0,
+        trghostprob=0.25,
+        dielectron_ID="J/psi(1S)",
+        pt_diE=0 * MeV,
+        m_diE_min=5 * MeV,
+        m_diE_max=300 * MeV,
+        adocachi2cut=30,
+        bpvvdchi2=0,
+        vfaspfchi2ndof=10,
+    )
+
+
+# OS Prompt lines
+@register_line_builder(turbo_lines)
+@configurable
+def dimuon_mu_el_prompt_line(
+    name="Hlt2QEE_DiMuonPrompt_PersistMuEl",
+    prescale=1,
+    persistreco=False,
+    make_pvs=make_pvs,
+):
+    """This line save muons in prompt mu+mu-  events and any other muon/electron"""
+    pvs = make_pvs()
+
+    dimuons_prompt = dimuon_maker(pvs)
+
+    muons_table = WeightedRelTableAlg(
+        InputCandidates=muon_filter(pvs, pt_min=5 * GeV),
+        ReferenceParticles=dimuons_prompt,
+        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
+    )
+
+    electrons_table = WeightedRelTableAlg(
+        InputCandidates=electron_filter(pt_min=5 * GeV),
+        ReferenceParticles=dimuons_prompt,
+        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
+    )
+
+    return Hlt2Line(
+        name=name,
+        algs=upfront_reconstruction() + [require_pvs(pvs), dimuons_prompt],
+        persistreco=persistreco,
+        extra_outputs=[
+            (
+                "DiElectronPrompt_Muons",
+                SelectionFromRelationTable(
+                    InputRelations=muons_table.OutputRelations
+                ).OutputLocation,
+            ),
+            (
+                "DiElectronPrompt_Electrons",
+                SelectionFromRelationTable(
+                    InputRelations=electrons_table.OutputRelations
+                ).OutputLocation,
+            )
+
+        ],
+        prescale=prescale,
+        monitoring_variables=_default_monitoring_variables,
+        hlt1_filter_code=["Hlt1DiMuonNoIPDecision"],
+    )
+
+
+@register_line_builder(turbo_lines)
+@configurable
+def dielectron_mu_el_prompt_line(
+    name="Hlt2QEE_DiElectronPrompt_PersistMuEl",
+    prescale=1,
+    persistreco=False,
+    e_minpt=0.0,
+    make_pvs=make_pvs,
+):
+    """This line save electrons in prompt e+e-  events and any other muon/electron"""
+    pvs = make_pvs()
+
+    dielectrons_prompt = dielectron_maker_prompt(e_minpt, isOS=True)
+
+    muons_table = WeightedRelTableAlg(
+        InputCandidates=muon_filter(pvs,pt_min=5 * GeV),
+        ReferenceParticles=dielectrons_prompt,
+        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
+    )
+
+    electrons_table = WeightedRelTableAlg(
+        InputCandidates=electron_filter(pt_min=5 * GeV),
+        ReferenceParticles=dielectrons_prompt,
+        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
+    )
+
+    return Hlt2Line(
+        name=name,
+        algs=upfront_reconstruction() + [require_pvs(pvs), dielectrons_prompt],
+        persistreco=persistreco,
+        extra_outputs=[
+            (
+                "DiElectronPrompt_Muons",
+                SelectionFromRelationTable(
+                    InputRelations=muons_table.OutputRelations
+                ).OutputLocation,
+            ),
+            (
+                "DiElectronPrompt_Electrons",
+                SelectionFromRelationTable(
+                    InputRelations=electrons_table.OutputRelations
+                ).OutputLocation,
+            )
+
+        ],
+        prescale=prescale,
+        monitoring_variables=_default_monitoring_variables,
+        hlt1_filter_code=["Hlt1DiElectronLowMass_massSlice.*_promptDecision"],
+    )
+
+# OS displaced lines
+@register_line_builder(turbo_lines)
+@configurable
+def dimuon_mu_el_displaced_line(
+    name="Hlt2QEE_DiMuonDisplaced_PersistMuEl",
+    prescale=1,
+    persistreco=False,
+    make_pvs=make_pvs,
+):
+    """This line save muons in prompt mu+mu-  events and any other muon/electron"""
+    pvs = make_pvs()
+
+    dimuons_displaced = dimuon_maker(pvs, min_ipchi2=16, ownpvvdchi2_min=30)
+
+    muons_table = WeightedRelTableAlg(
+        InputCandidates=muon_filter(pvs, pt_min=5 * GeV),
+        ReferenceParticles=dimuons_displaced,
+        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
+    )
+
+    electrons_table = WeightedRelTableAlg(
+        InputCandidates=electron_filter(pt_min=5 * GeV),
+        ReferenceParticles=dimuons_displaced,
+        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
+    )
+
+    return Hlt2Line(
+        name=name,
+        algs=upfront_reconstruction() + [require_pvs(pvs), dimuons_displaced],
+        persistreco=persistreco,
+        extra_outputs=[
+            (
+                "DiElectronPrompt_Muons",
+                SelectionFromRelationTable(
+                    InputRelations=muons_table.OutputRelations
+                ).OutputLocation,
+            ),
+            (
+                "DiElectronPrompt_Electrons",
+                SelectionFromRelationTable(
+                    InputRelations=electrons_table.OutputRelations
+                ).OutputLocation,
+            )
+
+        ],
+        prescale=prescale,
+        monitoring_variables=_default_monitoring_variables,
+        hlt1_filter_code=["Hlt1DiMuonNoIPDecision"],
+    )
+
+
+@register_line_builder(turbo_lines)
+@configurable
+def dielectron_mu_el_displaced_line(
+    name="Hlt2QEE_DiElectronDisplaced_PersistMuEl",
+    prescale=1,
+    persistreco=False,
+    e_minpt=0.0,
+    make_pvs=make_pvs,
+):
+    """This line save electrons in prompt e+e- events and any other muon/electron"""
+    pvs = make_pvs()
+
+    dielectrons_displaced = dielectron_maker_displaced(e_minpt, isOS=True)
+
+    muons_table = WeightedRelTableAlg(
+        InputCandidates=muon_filter(pvs, pt_min=5 * GeV),
+        ReferenceParticles=dielectrons_displaced,
+        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
+    )
+
+    electrons_table = WeightedRelTableAlg(
+        InputCandidates=electron_filter(pt_min=5 * GeV),
+        ReferenceParticles=dielectrons_displaced,
+        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
+    )
+
+    return Hlt2Line(
+        name=name,
+        algs=upfront_reconstruction() + [require_pvs(pvs), dielectrons_displaced],
+        persistreco=persistreco,
+        extra_outputs=[
+            (
+                "DiElectronDisplaced_Muons",
+                SelectionFromRelationTable(
+                    InputRelations=muons_table.OutputRelations
+                ).OutputLocation,
+            ),
+            (
+                "DiElectronDisplaced_Electrons",
+                SelectionFromRelationTable(
+                    InputRelations=electrons_table.OutputRelations
+                ).OutputLocation,
+            )
+        ],
+        prescale=prescale,
+        monitoring_variables=_default_monitoring_variables,
+        hlt1_filter_code=["Hlt1DiElectronLowMass_massSlice.*_displacedDecision"],
+    )
+
+#SS lines
+@register_line_builder(turbo_lines)
+@configurable
+def dimuon_mu_el_prompt_same_sign_line(
+    name="Hlt2QEE_DiMuonPrompt_PersistMuElSS",
+    prescale=0.1,
+    persistreco=False,
+    make_pvs=make_pvs,
+):
+    """This line save muons in prompt mu+mu+/mu-mu-  events and any other muon/electron"""
+    pvs = make_pvs()
+
+    dimuons_prompt = dimuon_maker(pvs,isOS=False)
+
+    muons_table = WeightedRelTableAlg(
+        InputCandidates=muon_filter(pvs,pt_min=5 * GeV),
+        ReferenceParticles=dimuons_prompt,
+        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
+    )
+
+    electrons_table = WeightedRelTableAlg(
+        InputCandidates=electron_filter(pt_min=5 * GeV),
+        ReferenceParticles=dimuons_prompt,
+        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
+    )
+
+    return Hlt2Line(
+        name=name,
+        algs=upfront_reconstruction() + [require_pvs(pvs), dimuons_prompt],
+        persistreco=persistreco,
+        extra_outputs=[
+            (
+                "DiElectronPrompt_Muons",
+                SelectionFromRelationTable(
+                    InputRelations=muons_table.OutputRelations
+                ).OutputLocation,
+            ),
+            (
+                "DiElectronPrompt_Electrons",
+                SelectionFromRelationTable(
+                    InputRelations=electrons_table.OutputRelations
+                ).OutputLocation,
+            )
+
+        ],
+        prescale=prescale,
+        monitoring_variables=_default_monitoring_variables,
+        hlt1_filter_code=["Hlt1DiMuonNoIP_SSDecision"],
+    )
+
+@register_line_builder(turbo_lines)
+@configurable
+def dielectron_mu_el_prompt_same_sign_line(
+    name="Hlt2QEE_DiElectronPrompt_PersistMuElSS",
+    prescale=0.1,
+    persistreco=False,
+    e_minpt=0.0,
+    make_pvs=make_pvs,
+):
+    """This line save electrons in prompt e+e+/e-e-  events and any other muon/electron"""
+    pvs = make_pvs()
+
+    dielectrons_prompt = dielectron_maker_prompt(e_minpt, isOS=False)
+
+    muons_table = WeightedRelTableAlg(
+        InputCandidates=muon_filter(pvs,pt_min=5 * GeV),
+        ReferenceParticles=dielectrons_prompt,
+        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
+    )
+
+    electrons_table = WeightedRelTableAlg(
+        InputCandidates=electron_filter(pt_min=5 * GeV),
+        ReferenceParticles=dielectrons_prompt,
+        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
+    )
+
+    return Hlt2Line(
+        name=name,
+        algs=upfront_reconstruction() + [require_pvs(pvs), dielectrons_prompt],
+        persistreco=persistreco,
+        extra_outputs=[
+            (
+                "DiElectronPrompt_ss_Muons",
+                SelectionFromRelationTable(
+                    InputRelations=muons_table.OutputRelations
+                ).OutputLocation,
+            ),
+            (
+                "DiElectronPrompt_ss_Electrons",
+                SelectionFromRelationTable(
+                    InputRelations=electrons_table.OutputRelations
+                ).OutputLocation,
+            )
+        ],
+        prescale=prescale,
+        monitoring_variables=_default_monitoring_variables,
+        hlt1_filter_code=["Hlt1DiElectronLowMass_SS_massSlice.*_promptDecision"],
+    )
+
+
+@register_line_builder(turbo_lines)
+@configurable
+def dimuon_mu_el_displaced_same_sign_line(
+    name="Hlt2QEE_DiMuonDisplaced_PersistMuElSS",
+    prescale=0.1,
+    persistreco=False,
+    make_pvs=make_pvs,
+):
+    """This line save muons in displaced mu+mu+/mu-mu-  events and any other muon/electron"""
+    pvs = make_pvs()
+
+    dimuons_displaced = dimuon_maker(pvs, min_ipchi2=16, ownpvvdchi2_min=30, isOS=False)
+
+    muons_table = WeightedRelTableAlg(
+        InputCandidates=muon_filter(pvs, pt_min=5 * GeV),
+        ReferenceParticles=dimuons_displaced,
+        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
+    )
+
+    electrons_table = WeightedRelTableAlg(
+        InputCandidates=electron_filter(pt_min=5 * GeV),
+        ReferenceParticles=dimuons_displaced,
+        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
+    )
+    
+    return Hlt2Line(
+        name=name,
+        algs=upfront_reconstruction() + [require_pvs(pvs), dimuons_displaced],
+        persistreco=persistreco,
+        extra_outputs=[
+            (
+                "DiElectronPrompt_Muons",
+                SelectionFromRelationTable(
+                    InputRelations=muons_table.OutputRelations
+                ).OutputLocation,
+            ),
+            (
+                "DiElectronPrompt_Electrons",
+                SelectionFromRelationTable(
+                    InputRelations=electrons_table.OutputRelations
+                ).OutputLocation,
+            )
+
+        ],
+        prescale=prescale,
+        monitoring_variables=_default_monitoring_variables,
+        hlt1_filter_code=["Hlt1DiMuonNoIP_SSDecision"],
+    )
+
+@register_line_builder(turbo_lines)
+@configurable
+def dielectron_mu_el_displaced_same_sign_line(
+    name="Hlt2QEE_DiElectronDisplaced_PersistElSS",
+    prescale=0.1,
+    persistreco=False,
+    e_minpt=0.0,
+    make_pvs=make_pvs,
+):
+    """This line save electrons in displaced e+e+/e-e-  events and any other muon/electron"""
+    pvs = make_pvs()
+
+    dielectrons_displaced = dielectron_maker_displaced(e_minpt, isOS=False)
+    muons_table = WeightedRelTableAlg(
+        InputCandidates=muon_filter(pvs, pt_min=5 * GeV),
+        ReferenceParticles=dielectrons_displaced,
+        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
+    )
+
+    electrons_table = WeightedRelTableAlg(
+        InputCandidates=electron_filter(pt_min=5 * GeV),
+        ReferenceParticles=dielectrons_displaced,
+        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
+    )
+
+    return Hlt2Line(
+        name=name,
+        algs=upfront_reconstruction() + [require_pvs(pvs), dielectrons_displaced],
+        persistreco=persistreco,
+        extra_outputs=[
+            (
+                "DiElectronDisplaced_ss_Muons",
+                SelectionFromRelationTable(
+                    InputRelations=muons_table.OutputRelations
+                ).OutputLocation,
+            ),
+            (
+                "DiElectronDisplaced_ss_Electrons",
+                SelectionFromRelationTable(
+                    InputRelations=electrons_table.OutputRelations
+                ).OutputLocation,
+            )
+        ],
+        prescale=prescale,
+        monitoring_variables=_default_monitoring_variables,
+        hlt1_filter_code=["Hlt1DiElectronLowMass_SS_massSlice.*_displacedDecision"],
+    )
diff --git a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/hlt2_qee.py b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/hlt2_qee.py
index 38d4f9eb548..3c951e4f623 100644
--- a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/hlt2_qee.py
+++ b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/hlt2_qee.py
@@ -17,6 +17,7 @@ from Hlt2Conf.lines.qee import (
     b_to_majolep_majo_to_leppi,
     busca,
     dielectron_persist_photons,
+    dilepton_persist_leptons,
     dimuon_no_ip,
     diphoton,
     drellyan,
@@ -50,6 +51,7 @@ turbo_lines.update(diphoton.all_lines)
 turbo_lines.update(dimuon_no_ip.turbo_lines)
 turbo_lines.update(drellyan.all_lines)
 turbo_lines.update(dielectron_persist_photons.turbo_lines)
+turbo_lines.update(dilepton_persist_leptons.turbo_lines)
 turbo_lines.update(wz_boson_rare_decays.all_lines)
 turbo_lines.update(ttrack_llps.turbo_lines)
 turbo_lines.update(muon_detector_showers.all_lines)
-- 
GitLab


From 661bbd8bf14ce7a7346edb88ba949d005d30d2de Mon Sep 17 00:00:00 2001
From: Lorenzo Sestini <lorenzo.sestini@cern.ch>
Date: Wed, 19 Mar 2025 09:41:24 +0100
Subject: [PATCH 6/8] Reverting to previous version

---
 .../lines/qee/dilepton_persist_leptons.py     | 534 ------------------
 .../python/Hlt2Conf/lines/qee/hlt2_qee.py     |   2 -
 2 files changed, 536 deletions(-)
 delete mode 100644 Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/dilepton_persist_leptons.py

diff --git a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/dilepton_persist_leptons.py b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/dilepton_persist_leptons.py
deleted file mode 100644
index e491bae1a43..00000000000
--- a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/dilepton_persist_leptons.py
+++ /dev/null
@@ -1,534 +0,0 @@
-###############################################################################
-# (c) Copyright 2019-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.                                       #
-###############################################################################
-"""
-Definition of an HLT2 line to preserve dilepton candidates (dimuons or dielectrons) and any other lepton in the event (muon or electron).
-Aim for new dark photon searches
-Contact: Lorenzo Sestini lorenzo.sestini@cern.ch
-"""
-
-import Functors as F
-from Functors.math import in_range
-from GaudiKernel.SystemOfUnits import MeV, GeV, mm
-from Moore.config import register_line_builder
-from Moore.lines import Hlt2Line
-from PyConf import configurable
-from PyConf.Algorithms import SelectionFromRelationTable, WeightedRelTableAlg
-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_detached_dielectron_with_brem,
-    make_long_electrons_no_brem,
-    make_long_electrons_with_brem,
-    make_prompt_dielectron_with_brem,
-    make_ismuon_long_muon
-)
-
-full_lines = {}
-turbo_lines = {}
-
-#Mass limits now accepts all possible dilepton+lepton combination. May be reduced in the future.
-comb_mass_limits = (0.0 * GeV, 14000.0 * GeV)
-# NOTE: No dielectron mass monitors allowed (custom or default) to avoid potential unblinding.
-_default_monitoring_variables = ("pt", "eta", "n_candidates", "ipchi2", "vchi2")
-
-
-@configurable
-def muon_filter(pvs, make_particles=make_ismuon_long_muon, min_ipchi2=0, pid_mu=-10, p_min=5 * GeV, pt_min=0.0 * GeV):
-    muon_requirements = F.require_all(
-        F.P >= p_min,
-        F.PT >= pt_min,
-        F.MINIPCHI2CUT(IPChi2Cut=min_ipchi2, Vertices=pvs),
-    )
-    if pid_mu:
-        muon_requirements = (F.PID_MU > pid_mu) & muon_requirements
-    return ParticleFilter(make_particles(), F.FILTER(muon_requirements))
-
-@configurable
-def electron_filter(make_particles=make_long_electrons_with_brem, p_min=5 * GeV, pid_e=0.0, pt_min=0.0 * GeV):
-    electron_requirements = F.require_all(
-        F.P >= p_min,
-        F.PT >= pt_min,
-        F.PID_E >= pid_e,
-    )
-
-    return ParticleFilter(make_particles(), F.FILTER(electron_requirements))
-
-@configurable
-def dimuon_maker(
-    pvs,
-    comb_maxdoca=0.1 * mm,
-    vchi2pdof_max=9,
-    min_pt_prod=1 * GeV * GeV,
-    min_ipchi2=0,
-    min_mass=2 * F.PDG_MASS("mu+"),
-    max_mass=110 * GeV,
-    isOS=True,
-    pid_mu=-10,
-    ownpvvdchi2_min=0,
-):
-    muons = make_ismuon_long_muon
-    filtered_muons = muon_filter(pvs, muons, min_ipchi2, pid_mu)
-    combination_code = F.require_all(
-        F.MAXSDOCACUT(comb_maxdoca),
-        F.CHILD(1, F.PT) * F.CHILD(2, F.PT) > min_pt_prod,
-        in_range(min_mass, F.MASS, max_mass),
-    )
-    vertex_code = F.require_all(
-        F.CHI2DOF < vchi2pdof_max, F.OWNPVFDCHI2 > ownpvvdchi2_min
-    )
-    if isOS:
-        DecayDescriptor = "J/psi(1S) -> mu+ mu-"
-    else:
-        DecayDescriptor = "[J/psi(1S) -> mu+ mu+]cc"
-    return ParticleCombiner(
-        Inputs=[filtered_muons, filtered_muons],
-        DecayDescriptor=DecayDescriptor,
-        CombinationCut=combination_code,
-        CompositeCut=vertex_code,
-    )
-
-
-@configurable
-def dielectron_maker_prompt(e_minpt, isOS):
-    return make_prompt_dielectron_with_brem(
-        electron_maker=make_long_electrons_no_brem,
-        opposite_sign=isOS,
-        PIDe_min=0.0,
-        pt_e=e_minpt,
-        maxipchi2=2.0,
-        trghostprob=0.25,
-        dielectron_ID="J/psi(1S)",
-        pt_diE=0 * MeV,
-        m_diE_min=5 * MeV,
-        m_diE_max=300 * MeV,
-        adocachi2cut=30,
-        bpvvdchi2=None,
-        vfaspfchi2ndof=10,
-    )
-
-
-@configurable
-def dielectron_maker_displaced(e_minpt, isOS):
-    return make_detached_dielectron_with_brem(
-        electron_maker=make_long_electrons_no_brem,
-        opposite_sign=isOS,
-        PIDe_min=0.0,
-        pt_e=e_minpt,
-        minipchi2=2.0,
-        trghostprob=0.25,
-        dielectron_ID="J/psi(1S)",
-        pt_diE=0 * MeV,
-        m_diE_min=5 * MeV,
-        m_diE_max=300 * MeV,
-        adocachi2cut=30,
-        bpvvdchi2=0,
-        vfaspfchi2ndof=10,
-    )
-
-
-# OS Prompt lines
-@register_line_builder(turbo_lines)
-@configurable
-def dimuon_mu_el_prompt_line(
-    name="Hlt2QEE_DiMuonPrompt_PersistMuEl",
-    prescale=1,
-    persistreco=False,
-    make_pvs=make_pvs,
-):
-    """This line save muons in prompt mu+mu-  events and any other muon/electron"""
-    pvs = make_pvs()
-
-    dimuons_prompt = dimuon_maker(pvs)
-
-    muons_table = WeightedRelTableAlg(
-        InputCandidates=muon_filter(pvs, pt_min=5 * GeV),
-        ReferenceParticles=dimuons_prompt,
-        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
-    )
-
-    electrons_table = WeightedRelTableAlg(
-        InputCandidates=electron_filter(pt_min=5 * GeV),
-        ReferenceParticles=dimuons_prompt,
-        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
-    )
-
-    return Hlt2Line(
-        name=name,
-        algs=upfront_reconstruction() + [require_pvs(pvs), dimuons_prompt],
-        persistreco=persistreco,
-        extra_outputs=[
-            (
-                "DiElectronPrompt_Muons",
-                SelectionFromRelationTable(
-                    InputRelations=muons_table.OutputRelations
-                ).OutputLocation,
-            ),
-            (
-                "DiElectronPrompt_Electrons",
-                SelectionFromRelationTable(
-                    InputRelations=electrons_table.OutputRelations
-                ).OutputLocation,
-            )
-
-        ],
-        prescale=prescale,
-        monitoring_variables=_default_monitoring_variables,
-        hlt1_filter_code=["Hlt1DiMuonNoIPDecision"],
-    )
-
-
-@register_line_builder(turbo_lines)
-@configurable
-def dielectron_mu_el_prompt_line(
-    name="Hlt2QEE_DiElectronPrompt_PersistMuEl",
-    prescale=1,
-    persistreco=False,
-    e_minpt=0.0,
-    make_pvs=make_pvs,
-):
-    """This line save electrons in prompt e+e-  events and any other muon/electron"""
-    pvs = make_pvs()
-
-    dielectrons_prompt = dielectron_maker_prompt(e_minpt, isOS=True)
-
-    muons_table = WeightedRelTableAlg(
-        InputCandidates=muon_filter(pvs,pt_min=5 * GeV),
-        ReferenceParticles=dielectrons_prompt,
-        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
-    )
-
-    electrons_table = WeightedRelTableAlg(
-        InputCandidates=electron_filter(pt_min=5 * GeV),
-        ReferenceParticles=dielectrons_prompt,
-        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
-    )
-
-    return Hlt2Line(
-        name=name,
-        algs=upfront_reconstruction() + [require_pvs(pvs), dielectrons_prompt],
-        persistreco=persistreco,
-        extra_outputs=[
-            (
-                "DiElectronPrompt_Muons",
-                SelectionFromRelationTable(
-                    InputRelations=muons_table.OutputRelations
-                ).OutputLocation,
-            ),
-            (
-                "DiElectronPrompt_Electrons",
-                SelectionFromRelationTable(
-                    InputRelations=electrons_table.OutputRelations
-                ).OutputLocation,
-            )
-
-        ],
-        prescale=prescale,
-        monitoring_variables=_default_monitoring_variables,
-        hlt1_filter_code=["Hlt1DiElectronLowMass_massSlice.*_promptDecision"],
-    )
-
-# OS displaced lines
-@register_line_builder(turbo_lines)
-@configurable
-def dimuon_mu_el_displaced_line(
-    name="Hlt2QEE_DiMuonDisplaced_PersistMuEl",
-    prescale=1,
-    persistreco=False,
-    make_pvs=make_pvs,
-):
-    """This line save muons in prompt mu+mu-  events and any other muon/electron"""
-    pvs = make_pvs()
-
-    dimuons_displaced = dimuon_maker(pvs, min_ipchi2=16, ownpvvdchi2_min=30)
-
-    muons_table = WeightedRelTableAlg(
-        InputCandidates=muon_filter(pvs, pt_min=5 * GeV),
-        ReferenceParticles=dimuons_displaced,
-        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
-    )
-
-    electrons_table = WeightedRelTableAlg(
-        InputCandidates=electron_filter(pt_min=5 * GeV),
-        ReferenceParticles=dimuons_displaced,
-        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
-    )
-
-    return Hlt2Line(
-        name=name,
-        algs=upfront_reconstruction() + [require_pvs(pvs), dimuons_displaced],
-        persistreco=persistreco,
-        extra_outputs=[
-            (
-                "DiElectronPrompt_Muons",
-                SelectionFromRelationTable(
-                    InputRelations=muons_table.OutputRelations
-                ).OutputLocation,
-            ),
-            (
-                "DiElectronPrompt_Electrons",
-                SelectionFromRelationTable(
-                    InputRelations=electrons_table.OutputRelations
-                ).OutputLocation,
-            )
-
-        ],
-        prescale=prescale,
-        monitoring_variables=_default_monitoring_variables,
-        hlt1_filter_code=["Hlt1DiMuonNoIPDecision"],
-    )
-
-
-@register_line_builder(turbo_lines)
-@configurable
-def dielectron_mu_el_displaced_line(
-    name="Hlt2QEE_DiElectronDisplaced_PersistMuEl",
-    prescale=1,
-    persistreco=False,
-    e_minpt=0.0,
-    make_pvs=make_pvs,
-):
-    """This line save electrons in prompt e+e- events and any other muon/electron"""
-    pvs = make_pvs()
-
-    dielectrons_displaced = dielectron_maker_displaced(e_minpt, isOS=True)
-
-    muons_table = WeightedRelTableAlg(
-        InputCandidates=muon_filter(pvs, pt_min=5 * GeV),
-        ReferenceParticles=dielectrons_displaced,
-        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
-    )
-
-    electrons_table = WeightedRelTableAlg(
-        InputCandidates=electron_filter(pt_min=5 * GeV),
-        ReferenceParticles=dielectrons_displaced,
-        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
-    )
-
-    return Hlt2Line(
-        name=name,
-        algs=upfront_reconstruction() + [require_pvs(pvs), dielectrons_displaced],
-        persistreco=persistreco,
-        extra_outputs=[
-            (
-                "DiElectronDisplaced_Muons",
-                SelectionFromRelationTable(
-                    InputRelations=muons_table.OutputRelations
-                ).OutputLocation,
-            ),
-            (
-                "DiElectronDisplaced_Electrons",
-                SelectionFromRelationTable(
-                    InputRelations=electrons_table.OutputRelations
-                ).OutputLocation,
-            )
-        ],
-        prescale=prescale,
-        monitoring_variables=_default_monitoring_variables,
-        hlt1_filter_code=["Hlt1DiElectronLowMass_massSlice.*_displacedDecision"],
-    )
-
-#SS lines
-@register_line_builder(turbo_lines)
-@configurable
-def dimuon_mu_el_prompt_same_sign_line(
-    name="Hlt2QEE_DiMuonPrompt_PersistMuElSS",
-    prescale=0.1,
-    persistreco=False,
-    make_pvs=make_pvs,
-):
-    """This line save muons in prompt mu+mu+/mu-mu-  events and any other muon/electron"""
-    pvs = make_pvs()
-
-    dimuons_prompt = dimuon_maker(pvs,isOS=False)
-
-    muons_table = WeightedRelTableAlg(
-        InputCandidates=muon_filter(pvs,pt_min=5 * GeV),
-        ReferenceParticles=dimuons_prompt,
-        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
-    )
-
-    electrons_table = WeightedRelTableAlg(
-        InputCandidates=electron_filter(pt_min=5 * GeV),
-        ReferenceParticles=dimuons_prompt,
-        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
-    )
-
-    return Hlt2Line(
-        name=name,
-        algs=upfront_reconstruction() + [require_pvs(pvs), dimuons_prompt],
-        persistreco=persistreco,
-        extra_outputs=[
-            (
-                "DiElectronPrompt_Muons",
-                SelectionFromRelationTable(
-                    InputRelations=muons_table.OutputRelations
-                ).OutputLocation,
-            ),
-            (
-                "DiElectronPrompt_Electrons",
-                SelectionFromRelationTable(
-                    InputRelations=electrons_table.OutputRelations
-                ).OutputLocation,
-            )
-
-        ],
-        prescale=prescale,
-        monitoring_variables=_default_monitoring_variables,
-        hlt1_filter_code=["Hlt1DiMuonNoIP_SSDecision"],
-    )
-
-@register_line_builder(turbo_lines)
-@configurable
-def dielectron_mu_el_prompt_same_sign_line(
-    name="Hlt2QEE_DiElectronPrompt_PersistMuElSS",
-    prescale=0.1,
-    persistreco=False,
-    e_minpt=0.0,
-    make_pvs=make_pvs,
-):
-    """This line save electrons in prompt e+e+/e-e-  events and any other muon/electron"""
-    pvs = make_pvs()
-
-    dielectrons_prompt = dielectron_maker_prompt(e_minpt, isOS=False)
-
-    muons_table = WeightedRelTableAlg(
-        InputCandidates=muon_filter(pvs,pt_min=5 * GeV),
-        ReferenceParticles=dielectrons_prompt,
-        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
-    )
-
-    electrons_table = WeightedRelTableAlg(
-        InputCandidates=electron_filter(pt_min=5 * GeV),
-        ReferenceParticles=dielectrons_prompt,
-        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
-    )
-
-    return Hlt2Line(
-        name=name,
-        algs=upfront_reconstruction() + [require_pvs(pvs), dielectrons_prompt],
-        persistreco=persistreco,
-        extra_outputs=[
-            (
-                "DiElectronPrompt_ss_Muons",
-                SelectionFromRelationTable(
-                    InputRelations=muons_table.OutputRelations
-                ).OutputLocation,
-            ),
-            (
-                "DiElectronPrompt_ss_Electrons",
-                SelectionFromRelationTable(
-                    InputRelations=electrons_table.OutputRelations
-                ).OutputLocation,
-            )
-        ],
-        prescale=prescale,
-        monitoring_variables=_default_monitoring_variables,
-        hlt1_filter_code=["Hlt1DiElectronLowMass_SS_massSlice.*_promptDecision"],
-    )
-
-
-@register_line_builder(turbo_lines)
-@configurable
-def dimuon_mu_el_displaced_same_sign_line(
-    name="Hlt2QEE_DiMuonDisplaced_PersistMuElSS",
-    prescale=0.1,
-    persistreco=False,
-    make_pvs=make_pvs,
-):
-    """This line save muons in displaced mu+mu+/mu-mu-  events and any other muon/electron"""
-    pvs = make_pvs()
-
-    dimuons_displaced = dimuon_maker(pvs, min_ipchi2=16, ownpvvdchi2_min=30, isOS=False)
-
-    muons_table = WeightedRelTableAlg(
-        InputCandidates=muon_filter(pvs, pt_min=5 * GeV),
-        ReferenceParticles=dimuons_displaced,
-        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
-    )
-
-    electrons_table = WeightedRelTableAlg(
-        InputCandidates=electron_filter(pt_min=5 * GeV),
-        ReferenceParticles=dimuons_displaced,
-        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
-    )
-    
-    return Hlt2Line(
-        name=name,
-        algs=upfront_reconstruction() + [require_pvs(pvs), dimuons_displaced],
-        persistreco=persistreco,
-        extra_outputs=[
-            (
-                "DiElectronPrompt_Muons",
-                SelectionFromRelationTable(
-                    InputRelations=muons_table.OutputRelations
-                ).OutputLocation,
-            ),
-            (
-                "DiElectronPrompt_Electrons",
-                SelectionFromRelationTable(
-                    InputRelations=electrons_table.OutputRelations
-                ).OutputLocation,
-            )
-
-        ],
-        prescale=prescale,
-        monitoring_variables=_default_monitoring_variables,
-        hlt1_filter_code=["Hlt1DiMuonNoIP_SSDecision"],
-    )
-
-@register_line_builder(turbo_lines)
-@configurable
-def dielectron_mu_el_displaced_same_sign_line(
-    name="Hlt2QEE_DiElectronDisplaced_PersistElSS",
-    prescale=0.1,
-    persistreco=False,
-    e_minpt=0.0,
-    make_pvs=make_pvs,
-):
-    """This line save electrons in displaced e+e+/e-e-  events and any other muon/electron"""
-    pvs = make_pvs()
-
-    dielectrons_displaced = dielectron_maker_displaced(e_minpt, isOS=False)
-    muons_table = WeightedRelTableAlg(
-        InputCandidates=muon_filter(pvs, pt_min=5 * GeV),
-        ReferenceParticles=dielectrons_displaced,
-        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
-    )
-
-    electrons_table = WeightedRelTableAlg(
-        InputCandidates=electron_filter(pt_min=5 * GeV),
-        ReferenceParticles=dielectrons_displaced,
-        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
-    )
-
-    return Hlt2Line(
-        name=name,
-        algs=upfront_reconstruction() + [require_pvs(pvs), dielectrons_displaced],
-        persistreco=persistreco,
-        extra_outputs=[
-            (
-                "DiElectronDisplaced_ss_Muons",
-                SelectionFromRelationTable(
-                    InputRelations=muons_table.OutputRelations
-                ).OutputLocation,
-            ),
-            (
-                "DiElectronDisplaced_ss_Electrons",
-                SelectionFromRelationTable(
-                    InputRelations=electrons_table.OutputRelations
-                ).OutputLocation,
-            )
-        ],
-        prescale=prescale,
-        monitoring_variables=_default_monitoring_variables,
-        hlt1_filter_code=["Hlt1DiElectronLowMass_SS_massSlice.*_displacedDecision"],
-    )
diff --git a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/hlt2_qee.py b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/hlt2_qee.py
index 3c951e4f623..38d4f9eb548 100644
--- a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/hlt2_qee.py
+++ b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/hlt2_qee.py
@@ -17,7 +17,6 @@ from Hlt2Conf.lines.qee import (
     b_to_majolep_majo_to_leppi,
     busca,
     dielectron_persist_photons,
-    dilepton_persist_leptons,
     dimuon_no_ip,
     diphoton,
     drellyan,
@@ -51,7 +50,6 @@ turbo_lines.update(diphoton.all_lines)
 turbo_lines.update(dimuon_no_ip.turbo_lines)
 turbo_lines.update(drellyan.all_lines)
 turbo_lines.update(dielectron_persist_photons.turbo_lines)
-turbo_lines.update(dilepton_persist_leptons.turbo_lines)
 turbo_lines.update(wz_boson_rare_decays.all_lines)
 turbo_lines.update(ttrack_llps.turbo_lines)
 turbo_lines.update(muon_detector_showers.all_lines)
-- 
GitLab


From bbcd19dbbbe7a0b5cdee6a3527c2645ab1a56ae0 Mon Sep 17 00:00:00 2001
From: Lorenzo Sestini <lorenzo.sestini@cern.ch>
Date: Wed, 19 Mar 2025 10:13:54 +0100
Subject: [PATCH 7/8] New multilepton lines saved

---
 .../lines/qee/dilepton_persist_leptons.py     | 534 ++++++++++++++++++
 .../python/Hlt2Conf/lines/qee/hlt2_qee.py     |   2 +
 2 files changed, 536 insertions(+)
 create mode 100644 Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/dilepton_persist_leptons.py

diff --git a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/dilepton_persist_leptons.py b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/dilepton_persist_leptons.py
new file mode 100644
index 00000000000..e491bae1a43
--- /dev/null
+++ b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/dilepton_persist_leptons.py
@@ -0,0 +1,534 @@
+###############################################################################
+# (c) Copyright 2019-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.                                       #
+###############################################################################
+"""
+Definition of an HLT2 line to preserve dilepton candidates (dimuons or dielectrons) and any other lepton in the event (muon or electron).
+Aim for new dark photon searches
+Contact: Lorenzo Sestini lorenzo.sestini@cern.ch
+"""
+
+import Functors as F
+from Functors.math import in_range
+from GaudiKernel.SystemOfUnits import MeV, GeV, mm
+from Moore.config import register_line_builder
+from Moore.lines import Hlt2Line
+from PyConf import configurable
+from PyConf.Algorithms import SelectionFromRelationTable, WeightedRelTableAlg
+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_detached_dielectron_with_brem,
+    make_long_electrons_no_brem,
+    make_long_electrons_with_brem,
+    make_prompt_dielectron_with_brem,
+    make_ismuon_long_muon
+)
+
+full_lines = {}
+turbo_lines = {}
+
+#Mass limits now accepts all possible dilepton+lepton combination. May be reduced in the future.
+comb_mass_limits = (0.0 * GeV, 14000.0 * GeV)
+# NOTE: No dielectron mass monitors allowed (custom or default) to avoid potential unblinding.
+_default_monitoring_variables = ("pt", "eta", "n_candidates", "ipchi2", "vchi2")
+
+
+@configurable
+def muon_filter(pvs, make_particles=make_ismuon_long_muon, min_ipchi2=0, pid_mu=-10, p_min=5 * GeV, pt_min=0.0 * GeV):
+    muon_requirements = F.require_all(
+        F.P >= p_min,
+        F.PT >= pt_min,
+        F.MINIPCHI2CUT(IPChi2Cut=min_ipchi2, Vertices=pvs),
+    )
+    if pid_mu:
+        muon_requirements = (F.PID_MU > pid_mu) & muon_requirements
+    return ParticleFilter(make_particles(), F.FILTER(muon_requirements))
+
+@configurable
+def electron_filter(make_particles=make_long_electrons_with_brem, p_min=5 * GeV, pid_e=0.0, pt_min=0.0 * GeV):
+    electron_requirements = F.require_all(
+        F.P >= p_min,
+        F.PT >= pt_min,
+        F.PID_E >= pid_e,
+    )
+
+    return ParticleFilter(make_particles(), F.FILTER(electron_requirements))
+
+@configurable
+def dimuon_maker(
+    pvs,
+    comb_maxdoca=0.1 * mm,
+    vchi2pdof_max=9,
+    min_pt_prod=1 * GeV * GeV,
+    min_ipchi2=0,
+    min_mass=2 * F.PDG_MASS("mu+"),
+    max_mass=110 * GeV,
+    isOS=True,
+    pid_mu=-10,
+    ownpvvdchi2_min=0,
+):
+    muons = make_ismuon_long_muon
+    filtered_muons = muon_filter(pvs, muons, min_ipchi2, pid_mu)
+    combination_code = F.require_all(
+        F.MAXSDOCACUT(comb_maxdoca),
+        F.CHILD(1, F.PT) * F.CHILD(2, F.PT) > min_pt_prod,
+        in_range(min_mass, F.MASS, max_mass),
+    )
+    vertex_code = F.require_all(
+        F.CHI2DOF < vchi2pdof_max, F.OWNPVFDCHI2 > ownpvvdchi2_min
+    )
+    if isOS:
+        DecayDescriptor = "J/psi(1S) -> mu+ mu-"
+    else:
+        DecayDescriptor = "[J/psi(1S) -> mu+ mu+]cc"
+    return ParticleCombiner(
+        Inputs=[filtered_muons, filtered_muons],
+        DecayDescriptor=DecayDescriptor,
+        CombinationCut=combination_code,
+        CompositeCut=vertex_code,
+    )
+
+
+@configurable
+def dielectron_maker_prompt(e_minpt, isOS):
+    return make_prompt_dielectron_with_brem(
+        electron_maker=make_long_electrons_no_brem,
+        opposite_sign=isOS,
+        PIDe_min=0.0,
+        pt_e=e_minpt,
+        maxipchi2=2.0,
+        trghostprob=0.25,
+        dielectron_ID="J/psi(1S)",
+        pt_diE=0 * MeV,
+        m_diE_min=5 * MeV,
+        m_diE_max=300 * MeV,
+        adocachi2cut=30,
+        bpvvdchi2=None,
+        vfaspfchi2ndof=10,
+    )
+
+
+@configurable
+def dielectron_maker_displaced(e_minpt, isOS):
+    return make_detached_dielectron_with_brem(
+        electron_maker=make_long_electrons_no_brem,
+        opposite_sign=isOS,
+        PIDe_min=0.0,
+        pt_e=e_minpt,
+        minipchi2=2.0,
+        trghostprob=0.25,
+        dielectron_ID="J/psi(1S)",
+        pt_diE=0 * MeV,
+        m_diE_min=5 * MeV,
+        m_diE_max=300 * MeV,
+        adocachi2cut=30,
+        bpvvdchi2=0,
+        vfaspfchi2ndof=10,
+    )
+
+
+# OS Prompt lines
+@register_line_builder(turbo_lines)
+@configurable
+def dimuon_mu_el_prompt_line(
+    name="Hlt2QEE_DiMuonPrompt_PersistMuEl",
+    prescale=1,
+    persistreco=False,
+    make_pvs=make_pvs,
+):
+    """This line save muons in prompt mu+mu-  events and any other muon/electron"""
+    pvs = make_pvs()
+
+    dimuons_prompt = dimuon_maker(pvs)
+
+    muons_table = WeightedRelTableAlg(
+        InputCandidates=muon_filter(pvs, pt_min=5 * GeV),
+        ReferenceParticles=dimuons_prompt,
+        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
+    )
+
+    electrons_table = WeightedRelTableAlg(
+        InputCandidates=electron_filter(pt_min=5 * GeV),
+        ReferenceParticles=dimuons_prompt,
+        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
+    )
+
+    return Hlt2Line(
+        name=name,
+        algs=upfront_reconstruction() + [require_pvs(pvs), dimuons_prompt],
+        persistreco=persistreco,
+        extra_outputs=[
+            (
+                "DiElectronPrompt_Muons",
+                SelectionFromRelationTable(
+                    InputRelations=muons_table.OutputRelations
+                ).OutputLocation,
+            ),
+            (
+                "DiElectronPrompt_Electrons",
+                SelectionFromRelationTable(
+                    InputRelations=electrons_table.OutputRelations
+                ).OutputLocation,
+            )
+
+        ],
+        prescale=prescale,
+        monitoring_variables=_default_monitoring_variables,
+        hlt1_filter_code=["Hlt1DiMuonNoIPDecision"],
+    )
+
+
+@register_line_builder(turbo_lines)
+@configurable
+def dielectron_mu_el_prompt_line(
+    name="Hlt2QEE_DiElectronPrompt_PersistMuEl",
+    prescale=1,
+    persistreco=False,
+    e_minpt=0.0,
+    make_pvs=make_pvs,
+):
+    """This line save electrons in prompt e+e-  events and any other muon/electron"""
+    pvs = make_pvs()
+
+    dielectrons_prompt = dielectron_maker_prompt(e_minpt, isOS=True)
+
+    muons_table = WeightedRelTableAlg(
+        InputCandidates=muon_filter(pvs,pt_min=5 * GeV),
+        ReferenceParticles=dielectrons_prompt,
+        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
+    )
+
+    electrons_table = WeightedRelTableAlg(
+        InputCandidates=electron_filter(pt_min=5 * GeV),
+        ReferenceParticles=dielectrons_prompt,
+        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
+    )
+
+    return Hlt2Line(
+        name=name,
+        algs=upfront_reconstruction() + [require_pvs(pvs), dielectrons_prompt],
+        persistreco=persistreco,
+        extra_outputs=[
+            (
+                "DiElectronPrompt_Muons",
+                SelectionFromRelationTable(
+                    InputRelations=muons_table.OutputRelations
+                ).OutputLocation,
+            ),
+            (
+                "DiElectronPrompt_Electrons",
+                SelectionFromRelationTable(
+                    InputRelations=electrons_table.OutputRelations
+                ).OutputLocation,
+            )
+
+        ],
+        prescale=prescale,
+        monitoring_variables=_default_monitoring_variables,
+        hlt1_filter_code=["Hlt1DiElectronLowMass_massSlice.*_promptDecision"],
+    )
+
+# OS displaced lines
+@register_line_builder(turbo_lines)
+@configurable
+def dimuon_mu_el_displaced_line(
+    name="Hlt2QEE_DiMuonDisplaced_PersistMuEl",
+    prescale=1,
+    persistreco=False,
+    make_pvs=make_pvs,
+):
+    """This line save muons in prompt mu+mu-  events and any other muon/electron"""
+    pvs = make_pvs()
+
+    dimuons_displaced = dimuon_maker(pvs, min_ipchi2=16, ownpvvdchi2_min=30)
+
+    muons_table = WeightedRelTableAlg(
+        InputCandidates=muon_filter(pvs, pt_min=5 * GeV),
+        ReferenceParticles=dimuons_displaced,
+        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
+    )
+
+    electrons_table = WeightedRelTableAlg(
+        InputCandidates=electron_filter(pt_min=5 * GeV),
+        ReferenceParticles=dimuons_displaced,
+        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
+    )
+
+    return Hlt2Line(
+        name=name,
+        algs=upfront_reconstruction() + [require_pvs(pvs), dimuons_displaced],
+        persistreco=persistreco,
+        extra_outputs=[
+            (
+                "DiElectronPrompt_Muons",
+                SelectionFromRelationTable(
+                    InputRelations=muons_table.OutputRelations
+                ).OutputLocation,
+            ),
+            (
+                "DiElectronPrompt_Electrons",
+                SelectionFromRelationTable(
+                    InputRelations=electrons_table.OutputRelations
+                ).OutputLocation,
+            )
+
+        ],
+        prescale=prescale,
+        monitoring_variables=_default_monitoring_variables,
+        hlt1_filter_code=["Hlt1DiMuonNoIPDecision"],
+    )
+
+
+@register_line_builder(turbo_lines)
+@configurable
+def dielectron_mu_el_displaced_line(
+    name="Hlt2QEE_DiElectronDisplaced_PersistMuEl",
+    prescale=1,
+    persistreco=False,
+    e_minpt=0.0,
+    make_pvs=make_pvs,
+):
+    """This line save electrons in prompt e+e- events and any other muon/electron"""
+    pvs = make_pvs()
+
+    dielectrons_displaced = dielectron_maker_displaced(e_minpt, isOS=True)
+
+    muons_table = WeightedRelTableAlg(
+        InputCandidates=muon_filter(pvs, pt_min=5 * GeV),
+        ReferenceParticles=dielectrons_displaced,
+        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
+    )
+
+    electrons_table = WeightedRelTableAlg(
+        InputCandidates=electron_filter(pt_min=5 * GeV),
+        ReferenceParticles=dielectrons_displaced,
+        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
+    )
+
+    return Hlt2Line(
+        name=name,
+        algs=upfront_reconstruction() + [require_pvs(pvs), dielectrons_displaced],
+        persistreco=persistreco,
+        extra_outputs=[
+            (
+                "DiElectronDisplaced_Muons",
+                SelectionFromRelationTable(
+                    InputRelations=muons_table.OutputRelations
+                ).OutputLocation,
+            ),
+            (
+                "DiElectronDisplaced_Electrons",
+                SelectionFromRelationTable(
+                    InputRelations=electrons_table.OutputRelations
+                ).OutputLocation,
+            )
+        ],
+        prescale=prescale,
+        monitoring_variables=_default_monitoring_variables,
+        hlt1_filter_code=["Hlt1DiElectronLowMass_massSlice.*_displacedDecision"],
+    )
+
+#SS lines
+@register_line_builder(turbo_lines)
+@configurable
+def dimuon_mu_el_prompt_same_sign_line(
+    name="Hlt2QEE_DiMuonPrompt_PersistMuElSS",
+    prescale=0.1,
+    persistreco=False,
+    make_pvs=make_pvs,
+):
+    """This line save muons in prompt mu+mu+/mu-mu-  events and any other muon/electron"""
+    pvs = make_pvs()
+
+    dimuons_prompt = dimuon_maker(pvs,isOS=False)
+
+    muons_table = WeightedRelTableAlg(
+        InputCandidates=muon_filter(pvs,pt_min=5 * GeV),
+        ReferenceParticles=dimuons_prompt,
+        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
+    )
+
+    electrons_table = WeightedRelTableAlg(
+        InputCandidates=electron_filter(pt_min=5 * GeV),
+        ReferenceParticles=dimuons_prompt,
+        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
+    )
+
+    return Hlt2Line(
+        name=name,
+        algs=upfront_reconstruction() + [require_pvs(pvs), dimuons_prompt],
+        persistreco=persistreco,
+        extra_outputs=[
+            (
+                "DiElectronPrompt_Muons",
+                SelectionFromRelationTable(
+                    InputRelations=muons_table.OutputRelations
+                ).OutputLocation,
+            ),
+            (
+                "DiElectronPrompt_Electrons",
+                SelectionFromRelationTable(
+                    InputRelations=electrons_table.OutputRelations
+                ).OutputLocation,
+            )
+
+        ],
+        prescale=prescale,
+        monitoring_variables=_default_monitoring_variables,
+        hlt1_filter_code=["Hlt1DiMuonNoIP_SSDecision"],
+    )
+
+@register_line_builder(turbo_lines)
+@configurable
+def dielectron_mu_el_prompt_same_sign_line(
+    name="Hlt2QEE_DiElectronPrompt_PersistMuElSS",
+    prescale=0.1,
+    persistreco=False,
+    e_minpt=0.0,
+    make_pvs=make_pvs,
+):
+    """This line save electrons in prompt e+e+/e-e-  events and any other muon/electron"""
+    pvs = make_pvs()
+
+    dielectrons_prompt = dielectron_maker_prompt(e_minpt, isOS=False)
+
+    muons_table = WeightedRelTableAlg(
+        InputCandidates=muon_filter(pvs,pt_min=5 * GeV),
+        ReferenceParticles=dielectrons_prompt,
+        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
+    )
+
+    electrons_table = WeightedRelTableAlg(
+        InputCandidates=electron_filter(pt_min=5 * GeV),
+        ReferenceParticles=dielectrons_prompt,
+        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
+    )
+
+    return Hlt2Line(
+        name=name,
+        algs=upfront_reconstruction() + [require_pvs(pvs), dielectrons_prompt],
+        persistreco=persistreco,
+        extra_outputs=[
+            (
+                "DiElectronPrompt_ss_Muons",
+                SelectionFromRelationTable(
+                    InputRelations=muons_table.OutputRelations
+                ).OutputLocation,
+            ),
+            (
+                "DiElectronPrompt_ss_Electrons",
+                SelectionFromRelationTable(
+                    InputRelations=electrons_table.OutputRelations
+                ).OutputLocation,
+            )
+        ],
+        prescale=prescale,
+        monitoring_variables=_default_monitoring_variables,
+        hlt1_filter_code=["Hlt1DiElectronLowMass_SS_massSlice.*_promptDecision"],
+    )
+
+
+@register_line_builder(turbo_lines)
+@configurable
+def dimuon_mu_el_displaced_same_sign_line(
+    name="Hlt2QEE_DiMuonDisplaced_PersistMuElSS",
+    prescale=0.1,
+    persistreco=False,
+    make_pvs=make_pvs,
+):
+    """This line save muons in displaced mu+mu+/mu-mu-  events and any other muon/electron"""
+    pvs = make_pvs()
+
+    dimuons_displaced = dimuon_maker(pvs, min_ipchi2=16, ownpvvdchi2_min=30, isOS=False)
+
+    muons_table = WeightedRelTableAlg(
+        InputCandidates=muon_filter(pvs, pt_min=5 * GeV),
+        ReferenceParticles=dimuons_displaced,
+        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
+    )
+
+    electrons_table = WeightedRelTableAlg(
+        InputCandidates=electron_filter(pt_min=5 * GeV),
+        ReferenceParticles=dimuons_displaced,
+        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
+    )
+    
+    return Hlt2Line(
+        name=name,
+        algs=upfront_reconstruction() + [require_pvs(pvs), dimuons_displaced],
+        persistreco=persistreco,
+        extra_outputs=[
+            (
+                "DiElectronPrompt_Muons",
+                SelectionFromRelationTable(
+                    InputRelations=muons_table.OutputRelations
+                ).OutputLocation,
+            ),
+            (
+                "DiElectronPrompt_Electrons",
+                SelectionFromRelationTable(
+                    InputRelations=electrons_table.OutputRelations
+                ).OutputLocation,
+            )
+
+        ],
+        prescale=prescale,
+        monitoring_variables=_default_monitoring_variables,
+        hlt1_filter_code=["Hlt1DiMuonNoIP_SSDecision"],
+    )
+
+@register_line_builder(turbo_lines)
+@configurable
+def dielectron_mu_el_displaced_same_sign_line(
+    name="Hlt2QEE_DiElectronDisplaced_PersistElSS",
+    prescale=0.1,
+    persistreco=False,
+    e_minpt=0.0,
+    make_pvs=make_pvs,
+):
+    """This line save electrons in displaced e+e+/e-e-  events and any other muon/electron"""
+    pvs = make_pvs()
+
+    dielectrons_displaced = dielectron_maker_displaced(e_minpt, isOS=False)
+    muons_table = WeightedRelTableAlg(
+        InputCandidates=muon_filter(pvs, pt_min=5 * GeV),
+        ReferenceParticles=dielectrons_displaced,
+        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
+    )
+
+    electrons_table = WeightedRelTableAlg(
+        InputCandidates=electron_filter(pt_min=5 * GeV),
+        ReferenceParticles=dielectrons_displaced,
+        Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
+    )
+
+    return Hlt2Line(
+        name=name,
+        algs=upfront_reconstruction() + [require_pvs(pvs), dielectrons_displaced],
+        persistreco=persistreco,
+        extra_outputs=[
+            (
+                "DiElectronDisplaced_ss_Muons",
+                SelectionFromRelationTable(
+                    InputRelations=muons_table.OutputRelations
+                ).OutputLocation,
+            ),
+            (
+                "DiElectronDisplaced_ss_Electrons",
+                SelectionFromRelationTable(
+                    InputRelations=electrons_table.OutputRelations
+                ).OutputLocation,
+            )
+        ],
+        prescale=prescale,
+        monitoring_variables=_default_monitoring_variables,
+        hlt1_filter_code=["Hlt1DiElectronLowMass_SS_massSlice.*_displacedDecision"],
+    )
diff --git a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/hlt2_qee.py b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/hlt2_qee.py
index 38d4f9eb548..3c951e4f623 100644
--- a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/hlt2_qee.py
+++ b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/hlt2_qee.py
@@ -17,6 +17,7 @@ from Hlt2Conf.lines.qee import (
     b_to_majolep_majo_to_leppi,
     busca,
     dielectron_persist_photons,
+    dilepton_persist_leptons,
     dimuon_no_ip,
     diphoton,
     drellyan,
@@ -50,6 +51,7 @@ turbo_lines.update(diphoton.all_lines)
 turbo_lines.update(dimuon_no_ip.turbo_lines)
 turbo_lines.update(drellyan.all_lines)
 turbo_lines.update(dielectron_persist_photons.turbo_lines)
+turbo_lines.update(dilepton_persist_leptons.turbo_lines)
 turbo_lines.update(wz_boson_rare_decays.all_lines)
 turbo_lines.update(ttrack_llps.turbo_lines)
 turbo_lines.update(muon_detector_showers.all_lines)
-- 
GitLab


From 494840b5c0799d2ed9aaae66fedf7ed6f2bbb57c Mon Sep 17 00:00:00 2001
From: Gitlab CI <noreply@cern.ch>
Date: Wed, 19 Mar 2025 09:14:56 +0000
Subject: [PATCH 8/8] pre-commit fixes

patch generated by https://gitlab.cern.ch/lhcb/Moore/-/jobs/52958354
---
 .../lines/qee/dilepton_persist_leptons.py     | 61 +++++++++++--------
 1 file changed, 37 insertions(+), 24 deletions(-)

diff --git a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/dilepton_persist_leptons.py b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/dilepton_persist_leptons.py
index e491bae1a43..95d9dda56b2 100644
--- a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/dilepton_persist_leptons.py
+++ b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/dilepton_persist_leptons.py
@@ -16,7 +16,7 @@ Contact: Lorenzo Sestini lorenzo.sestini@cern.ch
 
 import Functors as F
 from Functors.math import in_range
-from GaudiKernel.SystemOfUnits import MeV, GeV, mm
+from GaudiKernel.SystemOfUnits import GeV, MeV, mm
 from Moore.config import register_line_builder
 from Moore.lines import Hlt2Line
 from PyConf import configurable
@@ -26,23 +26,30 @@ from RecoConf.event_filters import require_pvs
 from RecoConf.reconstruction_objects import make_pvs, upfront_reconstruction
 from RecoConf.standard_particles import (
     make_detached_dielectron_with_brem,
+    make_ismuon_long_muon,
     make_long_electrons_no_brem,
     make_long_electrons_with_brem,
     make_prompt_dielectron_with_brem,
-    make_ismuon_long_muon
 )
 
 full_lines = {}
 turbo_lines = {}
 
-#Mass limits now accepts all possible dilepton+lepton combination. May be reduced in the future.
+# Mass limits now accepts all possible dilepton+lepton combination. May be reduced in the future.
 comb_mass_limits = (0.0 * GeV, 14000.0 * GeV)
 # NOTE: No dielectron mass monitors allowed (custom or default) to avoid potential unblinding.
 _default_monitoring_variables = ("pt", "eta", "n_candidates", "ipchi2", "vchi2")
 
 
 @configurable
-def muon_filter(pvs, make_particles=make_ismuon_long_muon, min_ipchi2=0, pid_mu=-10, p_min=5 * GeV, pt_min=0.0 * GeV):
+def muon_filter(
+    pvs,
+    make_particles=make_ismuon_long_muon,
+    min_ipchi2=0,
+    pid_mu=-10,
+    p_min=5 * GeV,
+    pt_min=0.0 * GeV,
+):
     muon_requirements = F.require_all(
         F.P >= p_min,
         F.PT >= pt_min,
@@ -52,8 +59,14 @@ def muon_filter(pvs, make_particles=make_ismuon_long_muon, min_ipchi2=0, pid_mu=
         muon_requirements = (F.PID_MU > pid_mu) & muon_requirements
     return ParticleFilter(make_particles(), F.FILTER(muon_requirements))
 
+
 @configurable
-def electron_filter(make_particles=make_long_electrons_with_brem, p_min=5 * GeV, pid_e=0.0, pt_min=0.0 * GeV):
+def electron_filter(
+    make_particles=make_long_electrons_with_brem,
+    p_min=5 * GeV,
+    pid_e=0.0,
+    pt_min=0.0 * GeV,
+):
     electron_requirements = F.require_all(
         F.P >= p_min,
         F.PT >= pt_min,
@@ -62,6 +75,7 @@ def electron_filter(make_particles=make_long_electrons_with_brem, p_min=5 * GeV,
 
     return ParticleFilter(make_particles(), F.FILTER(electron_requirements))
 
+
 @configurable
 def dimuon_maker(
     pvs,
@@ -177,8 +191,7 @@ def dimuon_mu_el_prompt_line(
                 SelectionFromRelationTable(
                     InputRelations=electrons_table.OutputRelations
                 ).OutputLocation,
-            )
-
+            ),
         ],
         prescale=prescale,
         monitoring_variables=_default_monitoring_variables,
@@ -201,7 +214,7 @@ def dielectron_mu_el_prompt_line(
     dielectrons_prompt = dielectron_maker_prompt(e_minpt, isOS=True)
 
     muons_table = WeightedRelTableAlg(
-        InputCandidates=muon_filter(pvs,pt_min=5 * GeV),
+        InputCandidates=muon_filter(pvs, pt_min=5 * GeV),
         ReferenceParticles=dielectrons_prompt,
         Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
     )
@@ -228,14 +241,14 @@ def dielectron_mu_el_prompt_line(
                 SelectionFromRelationTable(
                     InputRelations=electrons_table.OutputRelations
                 ).OutputLocation,
-            )
-
+            ),
         ],
         prescale=prescale,
         monitoring_variables=_default_monitoring_variables,
         hlt1_filter_code=["Hlt1DiElectronLowMass_massSlice.*_promptDecision"],
     )
 
+
 # OS displaced lines
 @register_line_builder(turbo_lines)
 @configurable
@@ -278,8 +291,7 @@ def dimuon_mu_el_displaced_line(
                 SelectionFromRelationTable(
                     InputRelations=electrons_table.OutputRelations
                 ).OutputLocation,
-            )
-
+            ),
         ],
         prescale=prescale,
         monitoring_variables=_default_monitoring_variables,
@@ -329,14 +341,15 @@ def dielectron_mu_el_displaced_line(
                 SelectionFromRelationTable(
                     InputRelations=electrons_table.OutputRelations
                 ).OutputLocation,
-            )
+            ),
         ],
         prescale=prescale,
         monitoring_variables=_default_monitoring_variables,
         hlt1_filter_code=["Hlt1DiElectronLowMass_massSlice.*_displacedDecision"],
     )
 
-#SS lines
+
+# SS lines
 @register_line_builder(turbo_lines)
 @configurable
 def dimuon_mu_el_prompt_same_sign_line(
@@ -348,10 +361,10 @@ def dimuon_mu_el_prompt_same_sign_line(
     """This line save muons in prompt mu+mu+/mu-mu-  events and any other muon/electron"""
     pvs = make_pvs()
 
-    dimuons_prompt = dimuon_maker(pvs,isOS=False)
+    dimuons_prompt = dimuon_maker(pvs, isOS=False)
 
     muons_table = WeightedRelTableAlg(
-        InputCandidates=muon_filter(pvs,pt_min=5 * GeV),
+        InputCandidates=muon_filter(pvs, pt_min=5 * GeV),
         ReferenceParticles=dimuons_prompt,
         Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
     )
@@ -378,14 +391,14 @@ def dimuon_mu_el_prompt_same_sign_line(
                 SelectionFromRelationTable(
                     InputRelations=electrons_table.OutputRelations
                 ).OutputLocation,
-            )
-
+            ),
         ],
         prescale=prescale,
         monitoring_variables=_default_monitoring_variables,
         hlt1_filter_code=["Hlt1DiMuonNoIP_SSDecision"],
     )
 
+
 @register_line_builder(turbo_lines)
 @configurable
 def dielectron_mu_el_prompt_same_sign_line(
@@ -401,7 +414,7 @@ def dielectron_mu_el_prompt_same_sign_line(
     dielectrons_prompt = dielectron_maker_prompt(e_minpt, isOS=False)
 
     muons_table = WeightedRelTableAlg(
-        InputCandidates=muon_filter(pvs,pt_min=5 * GeV),
+        InputCandidates=muon_filter(pvs, pt_min=5 * GeV),
         ReferenceParticles=dielectrons_prompt,
         Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
     )
@@ -428,7 +441,7 @@ def dielectron_mu_el_prompt_same_sign_line(
                 SelectionFromRelationTable(
                     InputRelations=electrons_table.OutputRelations
                 ).OutputLocation,
-            )
+            ),
         ],
         prescale=prescale,
         monitoring_variables=_default_monitoring_variables,
@@ -460,7 +473,7 @@ def dimuon_mu_el_displaced_same_sign_line(
         ReferenceParticles=dimuons_displaced,
         Cut=in_range(comb_mass_limits[0], F.COMB_MASS(), comb_mass_limits[1]),
     )
-    
+
     return Hlt2Line(
         name=name,
         algs=upfront_reconstruction() + [require_pvs(pvs), dimuons_displaced],
@@ -477,14 +490,14 @@ def dimuon_mu_el_displaced_same_sign_line(
                 SelectionFromRelationTable(
                     InputRelations=electrons_table.OutputRelations
                 ).OutputLocation,
-            )
-
+            ),
         ],
         prescale=prescale,
         monitoring_variables=_default_monitoring_variables,
         hlt1_filter_code=["Hlt1DiMuonNoIP_SSDecision"],
     )
 
+
 @register_line_builder(turbo_lines)
 @configurable
 def dielectron_mu_el_displaced_same_sign_line(
@@ -526,7 +539,7 @@ def dielectron_mu_el_displaced_same_sign_line(
                 SelectionFromRelationTable(
                     InputRelations=electrons_table.OutputRelations
                 ).OutputLocation,
-            )
+            ),
         ],
         prescale=prescale,
         monitoring_variables=_default_monitoring_variables,
-- 
GitLab