From e4caeec21ececdccafe378ff7927046c1b42d7b6 Mon Sep 17 00:00:00 2001
From: Abhijit Mathad <abhijit.mathad@cern.ch>
Date: Fri, 3 Jun 2022 13:57:10 +0200
Subject: [PATCH] Update add_filter with checks and append suffix Decision if
 necessary

---
 .../tupling/example-tupling-AllFunctors.py    |  3 +--
 .../tupling/example-tupling-DTF-filtered.py   |  2 +-
 .../option_davinci_tupling_array_taggers.py   |  5 ++--
 ...option_davinci_tupling_from_collections.py |  9 +++----
 .../option_davinci_tupling_from_hlt2.py       | 24 ++++++------------
 ...tion_davinci_tupling_from_hlt2_gaudirun.py |  7 +++---
 ...option_davinci_tupling_from_passthrough.py |  2 +-
 .../option_davinci_tupling_from_spruce.py     | 17 ++++++-------
 .../option_davinci_tupling_from_spruce_mc.py  |  6 ++---
 Phys/DaVinci/python/DaVinci/algorithms.py     | 25 ++++++++++++++++++-
 10 files changed, 54 insertions(+), 46 deletions(-)

diff --git a/DaVinciExamples/python/DaVinciExamples/tupling/example-tupling-AllFunctors.py b/DaVinciExamples/python/DaVinciExamples/tupling/example-tupling-AllFunctors.py
index be2012447..6c62d8476 100644
--- a/DaVinciExamples/python/DaVinciExamples/tupling/example-tupling-AllFunctors.py
+++ b/DaVinciExamples/python/DaVinciExamples/tupling/example-tupling-AllFunctors.py
@@ -312,8 +312,7 @@ def alg_config():
     #
     # Sprucing filter
     #
-    my_filter = add_filter("HDRFilter_B0DsK",
-                           f"HLT_PASS('{bd2dsk_line}Decision')")
+    my_filter = add_filter("HDRFilter_B0DsK", f"HLT_PASS('{bd2dsk_line}')")
 
     #
     # FunTuple
diff --git a/DaVinciExamples/python/DaVinciExamples/tupling/example-tupling-DTF-filtered.py b/DaVinciExamples/python/DaVinciExamples/tupling/example-tupling-DTF-filtered.py
index e89c9fa8c..cd6109fa8 100644
--- a/DaVinciExamples/python/DaVinciExamples/tupling/example-tupling-DTF-filtered.py
+++ b/DaVinciExamples/python/DaVinciExamples/tupling/example-tupling-DTF-filtered.py
@@ -59,7 +59,7 @@ variables_ds = FunctorCollection({
 #associate FunctorCollection to field (branch) name
 variables = {'ALL': variables_all, 'Ds': variables_ds}
 
-filter_data = add_filter("SpruceFilter", f"HLT_PASS('{spruce_line}Decision')")
+filter_data = add_filter("SpruceFilter", f"HLT_PASS('{spruce_line}')")
 
 #Configure Funtuple algorithm
 tuple_data = Funtuple(
diff --git a/DaVinciExamples/python/DaVinciExamples/tupling/option_davinci_tupling_array_taggers.py b/DaVinciExamples/python/DaVinciExamples/tupling/option_davinci_tupling_array_taggers.py
index 290867b90..2baf3e4a3 100644
--- a/DaVinciExamples/python/DaVinciExamples/tupling/option_davinci_tupling_array_taggers.py
+++ b/DaVinciExamples/python/DaVinciExamples/tupling/option_davinci_tupling_array_taggers.py
@@ -12,7 +12,7 @@
  Option file for testing the ParticleTaggerAlg algorithm and the related ThOr functors MAP_ARRAY and MAP_RANGE.
  The job runs over a spruced sample and retrieves a set of B0 -> Ds K+ candidates. For each candidate the ParticleTaggerAlg
  looks at the TES location defined via the 'make_long_pions_from_spruce' function and creates a 'one-to-many' relation map
- relating all the available tracks to the B candidate of the events. 
+ relating all the available tracks to the B candidate of the events.
  Then the MAP_ARRAY functor takes in input this relation map and for each entry stores the output of an external functor (i.e F.P, F.PT)
  in a vector via the MAP_RANGE functor.
 
@@ -81,8 +81,7 @@ tuple_B0DsK = Funtuple(
     variables=variables,
     inputs=bd2dsk_data)
 
-filter_B0DsK = add_filter("HDRFilter_B0DsK",
-                          f"HLT_PASS('{bd2dsk_line}Decision')")
+filter_B0DsK = add_filter("HDRFilter_B0DsK", f"HLT_PASS('{bd2dsk_line}')")
 
 options.annsvc_config = 'root://eoslhcb.cern.ch//eos/lhcb/wg/dpa/wp3/tests/spruce_all_lines_realtime_newPacking.tck.json'
 options.histo_file = 'DV-example-tagger-his.root'
diff --git a/DaVinciExamples/python/DaVinciExamples/tupling/option_davinci_tupling_from_collections.py b/DaVinciExamples/python/DaVinciExamples/tupling/option_davinci_tupling_from_collections.py
index af60c97d4..d5f5156e4 100644
--- a/DaVinciExamples/python/DaVinciExamples/tupling/option_davinci_tupling_from_collections.py
+++ b/DaVinciExamples/python/DaVinciExamples/tupling/option_davinci_tupling_from_collections.py
@@ -20,7 +20,8 @@ from DaVinci import options
 from DaVinci.truth_matching import configured_MCTruthAndBkgCatAlg
 from DaVinci.algorithms import get_odin, get_decreports
 
-d02kpi_data = force_location("/Event/HLT2/Hlt2CharmD0ToKmPipLine/Particles")
+line_name = 'Hlt2CharmD0ToKmPipLine'
+d02kpi_data = force_location(f"/Event/HLT2/{line_name}/Particles")
 
 #get configured "MCTruthAndBkgCatAlg" algorithm for HLT2 output
 mctruth = configured_MCTruthAndBkgCatAlg(
@@ -40,10 +41,9 @@ collections = [
     functorcollections.MCVertexInfo(mctruth)
 ]
 
-hlt2_line_names = ['Hlt2CharmD0ToKmPipLineDecision']
 evt_collections = [
     functorcollections.EventInfo(odin),
-    functorcollections.SelectionInfo("Hlt2", dec, hlt2_line_names)
+    functorcollections.SelectionInfo("Hlt2", dec, [line_name])
 ]
 
 assert len(collections) + len(evt_collections) == len(
@@ -84,7 +84,6 @@ my_tuple = Funtuple(
 
 
 def main():
-    my_filter = add_filter("HDRFilter_D0Kpi",
-                           "HLT_PASS('Hlt2CharmD0ToKmPipLineDecision')")
+    my_filter = add_filter("HDRFilter_D0Kpi", f"HLT_PASS('{line_name}')")
 
     return {"UserAlgs": [my_filter, my_tuple]}, []
diff --git a/DaVinciExamples/python/DaVinciExamples/tupling/option_davinci_tupling_from_hlt2.py b/DaVinciExamples/python/DaVinciExamples/tupling/option_davinci_tupling_from_hlt2.py
index ea3d66dc4..d426b375e 100644
--- a/DaVinciExamples/python/DaVinciExamples/tupling/option_davinci_tupling_from_hlt2.py
+++ b/DaVinciExamples/python/DaVinciExamples/tupling/option_davinci_tupling_from_hlt2.py
@@ -20,6 +20,7 @@ from DaVinci.algorithms import add_filter
 from DaVinci import options
 from DaVinci.truth_matching import configured_MCTruthAndBkgCatAlg
 from DaVinci.algorithms import get_odin, get_decreports
+from FunTuple.functorcollections import SelectionInfo
 
 options.process = 'Hlt2'
 
@@ -66,11 +67,10 @@ variables = {
 
 
 def main():
-    d02kpi_data = force_location(
-        "/Event/HLT2/Hlt2CharmD0ToKmPipLine/Particles")
+    line_name = 'Hlt2CharmD0ToKmPipLine'
+    d02kpi_data = force_location(f"/Event/HLT2/{line_name}/Particles")
 
-    my_filter = add_filter("HDRFilter_D0Kpi",
-                           "HLT_PASS('Hlt2CharmD0ToKmPipLineDecision')")
+    my_filter = add_filter("HDRFilter_D0Kpi", f"HLT_PASS('{line_name}')")
 
     #get configured "MCTruthAndBkgCatAlg" algorithm for HLT2 output
     mctruth = configured_MCTruthAndBkgCatAlg(
@@ -105,23 +105,15 @@ def main():
     odin = get_odin(options)
     hlt2_dec = get_decreports("Hlt2", options)
 
-    #Since input is from this line should return 1 for decisions
-    hlt2_lines = ['Hlt2CharmD0ToKmPipLineDecision']
-
     #define event level variables
     evt_variables = FunctorCollection({
-        "RUNNUMBER":
-        F.RUNNUMBER(odin),
-        "EVENTNUMBER":
-        F.EVENTNUMBER(odin),
-        "Hlt2_TCK":
-        F.TCK(hlt2_dec),
-        "Sel":
-        F.DECISIONS(Lines=hlt2_lines, DecReports=hlt2_dec),
+        "RUNNUMBER": F.RUNNUMBER(odin),
+        "EVENTNUMBER": F.EVENTNUMBER(odin)
     })
+    evt_variables += SelectionInfo("Hlt2", hlt2_dec, [line_name])
     #For now remove: The 'Hlt2' line decision tuples fine but breaks unit test with an error. (Why?)
     #see linked issue here: https://gitlab.cern.ch/lhcb/DaVinci/-/merge_requests/654#note_5320732
-    evt_variables.pop('Sel')
+    evt_variables.pop('Hlt2')
 
     #define FunTuple instance
     my_tuple = Funtuple(
diff --git a/DaVinciExamples/python/DaVinciExamples/tupling/option_davinci_tupling_from_hlt2_gaudirun.py b/DaVinciExamples/python/DaVinciExamples/tupling/option_davinci_tupling_from_hlt2_gaudirun.py
index c35bee677..c18f7cad0 100644
--- a/DaVinciExamples/python/DaVinciExamples/tupling/option_davinci_tupling_from_hlt2_gaudirun.py
+++ b/DaVinciExamples/python/DaVinciExamples/tupling/option_davinci_tupling_from_hlt2_gaudirun.py
@@ -50,11 +50,10 @@ variables = {
 
 
 def main():
-    d02kpi_data = force_location(
-        "/Event/HLT2/Hlt2CharmD0ToKmPipLine/Particles")
+    line_name = 'Hlt2CharmD0ToKmPipLine'
+    d02kpi_data = force_location(f"/Event/HLT2/{line_name}/Particles")
 
-    my_filter = add_filter("HDRFilter_D0Kpi",
-                           "HLT_PASS('Hlt2CharmD0ToKmPipLineDecision')")
+    my_filter = add_filter("HDRFilter_D0Kpi", f"HLT_PASS('{line_name}')")
     my_tuple = Funtuple(
         name="Tuple",
         tuple_name="DecayTree",
diff --git a/DaVinciExamples/python/DaVinciExamples/tupling/option_davinci_tupling_from_passthrough.py b/DaVinciExamples/python/DaVinciExamples/tupling/option_davinci_tupling_from_passthrough.py
index 90b97f4ca..787740868 100644
--- a/DaVinciExamples/python/DaVinciExamples/tupling/option_davinci_tupling_from_passthrough.py
+++ b/DaVinciExamples/python/DaVinciExamples/tupling/option_davinci_tupling_from_passthrough.py
@@ -34,7 +34,7 @@ variables = {
 
 def main():
     filter_bs = add_filter("HDRFilter_Bs2JpsiPhi",
-                           f"HLT_PASS('{bs2jpsiphi_line}Decision')")
+                           f"HLT_PASS('{bs2jpsiphi_line}')")
 
     tuple_bs = Funtuple(
         name="Bs2JpsiPhi_Tuple",
diff --git a/DaVinciExamples/python/DaVinciExamples/tupling/option_davinci_tupling_from_spruce.py b/DaVinciExamples/python/DaVinciExamples/tupling/option_davinci_tupling_from_spruce.py
index 33056b000..4bd35aca0 100644
--- a/DaVinciExamples/python/DaVinciExamples/tupling/option_davinci_tupling_from_spruce.py
+++ b/DaVinciExamples/python/DaVinciExamples/tupling/option_davinci_tupling_from_spruce.py
@@ -18,10 +18,10 @@ from PyConf.components import force_location
 from DaVinci.algorithms import add_filter
 from DaVinci import options
 
-bd2dsk_line = force_location(
-    "/Event/Spruce/SpruceB2OC_BdToDsmK_DsmToHHH_FEST_Line/Particles")
-bd2dspi_line = force_location(
-    "/Event/Spruce/SpruceB2OC_BdToDsmPi_DsmToKpKmPim_Line/Particles")
+line_B0DsK = 'SpruceB2OC_BdToDsmK_DsmToHHH_FEST_Line'
+line_B0Dspi = 'SpruceB2OC_BdToDsmPi_DsmToKpKmPim_Line'
+bd2dsk_line = force_location(f"/Event/Spruce/{line_B0DsK}/Particles")
+bd2dspi_line = force_location(f"/Event/Spruce/{line_B0Dspi}/Particles")
 
 fields_dsk = {
     'B0': "[B0 -> D_s- K+]CC",
@@ -91,12 +91,9 @@ def main():
     options.ntuple_file = "DV_example_sprucing_ntp.root"
     options.histo_file = "DV_example_sprucing_his.root"
 
-    filter_B0DsK = add_filter(
-        "HDRFilter_B0DsK",
-        "HLT_PASS('SpruceB2OC_BdToDsmK_DsmToHHH_FEST_LineDecision')")
-    filter_B0Dspi = add_filter(
-        "HDRFilter_B0Dspi",
-        "HLT_PASS('SpruceB2OC_BdToDsmPi_DsmToKpKmPim_LineDecision')")
+    filter_B0DsK = add_filter("HDRFilter_B0DsK", f"HLT_PASS('{line_B0DsK}')")
+    filter_B0Dspi = add_filter("HDRFilter_B0Dspi",
+                               f"HLT_PASS('{line_B0Dspi}')")
 
     tools = []
     algs = {
diff --git a/DaVinciExamples/python/DaVinciExamples/tupling/option_davinci_tupling_from_spruce_mc.py b/DaVinciExamples/python/DaVinciExamples/tupling/option_davinci_tupling_from_spruce_mc.py
index a4a51c13f..001ba01be 100644
--- a/DaVinciExamples/python/DaVinciExamples/tupling/option_davinci_tupling_from_spruce_mc.py
+++ b/DaVinciExamples/python/DaVinciExamples/tupling/option_davinci_tupling_from_spruce_mc.py
@@ -34,10 +34,10 @@ variables = {
 
 def main():
 
-    B_data = force_location("/Event/Spruce/Spruce_Test_line/Particles")
+    line_name = 'Spruce_Test_line'
+    B_data = force_location(f"/Event/Spruce/{line_name}/Particles")
 
-    my_filter = add_filter("HDRFilter_B",
-                           "HLT_PASS('Spruce_Test_lineDecision')")
+    my_filter = add_filter("HDRFilter_B", f"HLT_PASS('{line_name}')")
 
     #get configured "MCTruthAndBkgCatAlg" algorithm for HLT2 output
     mctruth = configured_MCTruthAndBkgCatAlg(inputs=B_data)
diff --git a/Phys/DaVinci/python/DaVinci/algorithms.py b/Phys/DaVinci/python/DaVinci/algorithms.py
index 53db29c2a..431c5d95c 100644
--- a/Phys/DaVinci/python/DaVinci/algorithms.py
+++ b/Phys/DaVinci/python/DaVinci/algorithms.py
@@ -92,6 +92,29 @@ def add_filter(name, code):
     """
     import re
     from DaVinci import options
+
+    #if code ends with HLT_PASS then check that the lines inside
+    # HLT_PASS contain suffix decision
+    if code.startswith("HLT_PASS("):
+        #check if it ends with braces
+        if not code.endswith(")"):
+            raise Exception("The specified code must end with brackets ')'")
+
+        #find all the line names between apostrophe
+        # e.g. turns string "HLT_PASS('Line1 ','Line2')" to list('Line1', 'Line2)
+        line_names = re.findall(r"\'([^\']*)\'", code)
+
+        #remove whitespace
+        remove_whitespace = lambda s: s.replace(' ', '')
+        line_names = list(map(remove_whitespace, line_names))
+
+        #check for suffix 'Decision', if not add one
+        add_suff_to_elem = lambda s: s + 'Decision' if not s.endswith('Decision') else s
+        line_names = list(map(add_suff_to_elem, line_names))
+
+        #put back the code together
+        code = 'HLT_PASS(\'' + '\',\''.join(line_names) + '\')'
+
     dec_reports = None
     for source in ["Hlt2", "Spruce"]:
         if re.search("^HLT_PASS.*" + source, code):
@@ -460,7 +483,7 @@ def filter_on(location, decay_descriptor=None, bank_type=None):
 
 def expand_input_files(options):
     """
-    Function to expand input files list including all the files matching 
+    Function to expand input files list including all the files matching
     a specified pattern according to the rules used by Unix (uses `glob`).
 
     Args:
-- 
GitLab