diff --git a/cutbased_dilepton_trigger_2023_data/info.yaml b/cutbased_dilepton_trigger_2023_data/info.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..19172a3fb3c9c3d8427358b3e63cf829074f3e99
--- /dev/null
+++ b/cutbased_dilepton_trigger_2023_data/info.yaml
@@ -0,0 +1,35 @@
+defaults:
+  automatically_configure: no
+  inform:
+    - jamie.gooding@cern.ch
+  wg: RD
+
+{%- set datasets = [
+  ('full', 'Collision23',     'VeloClosed', 'MagDown',  '/LHCb/Collision23/Beam6800GeV-VeloClosed-MagDown-Excl-UT/Real Data/SprucingPass23r1/94000000/RD.DST'),
+  ('full', 'Commissioning23', 'VeloClosed', 'MagDown',  '/LHCb/Commissioning23/Beam6800GeV-VeloClosed-MagDown-Excl-UT/Real Data/SprucingPass23/94000000/RD.DST'),
+]%}
+
+{%- for category, data_type, velo_state, polarity, bk_path in datasets %}
+
+Tuple_{{ data_type }}_{{ velo_state }}_{{ polarity }}_from_SprucingPass:
+  application: DaVinci/v63r12
+  input: 
+    bk_query: {{ bk_path }}
+    dq_flags:
+      - UNCHECKED
+      - OK
+    n_test_lfns: 4
+  output: Tuple_HLT2.ROOT
+  options:
+    entrypoint: cutbased_dilepton_trigger_2023_data.options.DaVinci.options:tuple_hlt2
+    extra_options:
+      input_raw_format: 0.5
+      input_type: RAW
+      simulation: False
+      data_type: "Upgrade"
+      dddb_tag: trunk
+      conddb_tag: AlignmentV13_2023_07_24
+      input_process: "Hlt2"
+
+{%- endfor %}
+
diff --git a/cutbased_dilepton_trigger_2023_data/options/DaVinci/options.py b/cutbased_dilepton_trigger_2023_data/options/DaVinci/options.py
new file mode 100644
index 0000000000000000000000000000000000000000..46247a4b890cf1622b5342312671a00546b53bf5
--- /dev/null
+++ b/cutbased_dilepton_trigger_2023_data/options/DaVinci/options.py
@@ -0,0 +1,153 @@
+###############################################################################
+# (c) Copyright 2021-2022 CERN for the benefit of the LHCb Collaboration      #
+#                                                                             #
+# This software is distributed under the terms of the GNU General Public      #
+# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   #
+#                                                                             #
+# In applying this licence, CERN does not waive the privileges and immunities #
+# granted to it by virtue of its status as an Intergovernmental Organization  #
+# or submit itself to any jurisdiction.                                       #
+###############################################################################
+import Functors as F
+from FunTuple import FunctorCollection as FC
+from FunTuple import FunTuple_Particles as Funtuple
+from PyConf.reading import get_particles, get_pvs, get_odin, get_decreports
+from DaVinci import Options, make_config
+from DaVinci.algorithms import create_lines_filter
+from DaVinciMCTools import MCTruthAndBkgCat
+from itertools import product
+
+from .spruced_tuples import dielectron, dimuon
+
+
+def construct_tuple(line, fields, label, options: Options, sprucing=False):
+    pvs = get_pvs()
+
+    composite_functors = {
+                    "ID": F.PARTICLE_ID,
+                    "KEY": F.OBJECT_KEY,
+                    'M': F.MASS,
+                    "PT": F.PT,
+                    "PX": F.PX,
+                    "PY": F.PY,
+                    "PZ": F.PZ,
+                    "PE": F.ENERGY,
+                    "P": F.P,
+                    "ETA": F.ETA,
+                    "TAU": F.BPVLTIME(pvs),
+                    "BPVDIRA": F.BPVDIRA(pvs),
+                    "BPVFD": F.BPVFD(pvs),
+                    "BPVFDCHI2": F.BPVFDCHI2(pvs),
+                    "BPVIP": F.BPVIP(pvs),
+                    "BPVIPCHI2": F.BPVIPCHI2(pvs),
+                    "CHI2": F.CHI2,
+                    "CHI2DOF": F.CHI2DOF,
+                    "MAXDOCA": F.MAXDOCA,
+                    "MAXDOCACHI2": F.MAXDOCACHI2 
+                }
+
+    daughter_functors = {
+                    "ID": F.PARTICLE_ID,
+                    "PT": F.PT,
+                    "PX": F.PX,
+                    "PY": F.PY,
+                    "PZ": F.PZ,
+                    "PE": F.ENERGY,
+                    "P": F.P,
+                    "ETA": F.ETA,
+                    "BPVIPCHI2": F.BPVIPCHI2(pvs),
+                    "PIDe": F.PID_E,
+                    "PIDmu": F.PID_MU,
+                    "PIDpi": F.PID_PI,
+                    "PIDk": F.PID_K,
+                    "PIDk": F.PID_P,
+                }
+
+    if sprucing:
+        data = get_particles(f"/Event/Spruce/{line}/Particles")
+        print(data)
+    else:
+        data = get_particles(f"/Event/HLT2/{line}/Particles") 
+
+    hdr_filter = create_lines_filter(f"HDRFilter_{label}", [line])
+
+    odin = get_odin()
+    DecReports = [get_decreports("Hlt1"), get_decreports("Hlt2")]
+    linesets = [['Hlt1TrackMuonMVADecision','Hlt1DiMuonLowMassDecision','Hlt1DiMuonHighMassDecision', 'Hlt1LowPtDiMuonDecision','Hlt1TwoTrackMVADecision'],
+                ['Hlt2CutBasedInclDielectronDecision','Hlt2CutBasedInclDielectronPlusTrackDecision','Hlt2CutBasedInclDielectronPlusTwoTrackDecision',
+                 'Hlt2CutBasedInclDimuonDecision','Hlt2CutBasedInclDimuonPlusTrackDecision','Hlt2CutBasedInclDimuonPlusTwoTrackDecision']]
+    if sprucing:
+        DecReports += [get_decreports("Spruce")]
+        linesets += [['SpruceRD_BToEEDecision', 'SpruceRD_BToMuMuDecision','SpruceRD_BuToKpEEDecision', 'SpruceRD_BuToKpMuMuDecision','SpruceRD_B0ToKpPimEEDecision', 'SpruceRD_B0ToKpPimMuMuDecision']]
+
+    evt_var_dict = {}
+    for DecReport, lineset in zip(DecReports, linesets):
+        for line in lineset:
+            evt_var_dict.update({f"{line}_DEC" : F.DECISION(DecReports=DecReport, trigger_line_name=line)})
+
+    evt_variables = FC(evt_var_dict)
+    variables = {
+                    "B"  : FC(composite_functors)
+                }
+    if 'Jpsi' in fields:
+        variables.update({"Jpsi": FC(composite_functors)})
+    for particle, charge in product(('e','mu','pi', 'K'), ('P', 'M')):
+        if particle+charge in fields:
+            variables.update({particle+charge: FC(daughter_functors)})
+
+    funtuple = Funtuple(name=label,
+                            tuple_name="DecayTree",
+                            fields=fields,
+                            variables=variables,
+                            event_variables=evt_variables,
+                            inputs=data)
+    return {f"{line}_Algs": [hdr_filter, funtuple]}
+
+def tuple_hlt2(options: Options):
+        
+    tuples = {}
+    
+    for lepton_label, lepton in zip(("Dielectron", "Dimuon"), ("e", "mu")):
+    
+        two_body_fields = {
+            "B"          : f"[B_s0 -> {lepton}+ {lepton}-]CC",
+            f"{lepton}P" : f"[B_s0 -> ^{lepton}+ {lepton}-]CC",
+            f"{lepton}M" : f"[B_s0 -> {lepton}+ ^{lepton}-]CC",
+        } 
+
+        three_body_fields = {
+            "B"   : f"[B+ -> (J/psi(1S) -> {lepton}+ {lepton}-) pi+]CC",
+            "Jpsi": f"[B+ -> (^J/psi(1S) -> {lepton}+ {lepton}-) pi+]CC",
+            "piP" : f"[B+ -> (J/psi(1S) -> {lepton}+ {lepton}-) ^pi+]CC",
+            f"{lepton}P" : f"[B+ -> (J/psi(1S) -> ^{lepton}+ {lepton}-) pi+]CC",
+            f"{lepton}M" : f"[B+ -> (J/psi(1S) -> {lepton}+ ^{lepton}-) pi+]CC",
+        }
+
+        four_body_fields = {
+            "B"   : f"[B_s0 -> (J/psi(1S) -> {lepton}+ {lepton}-) pi+ pi-]CC",
+            "Jpsi": f"[B_s0 -> (^J/psi(1S) -> {lepton}+ {lepton}-) pi+ pi-]CC",
+            "piP" : f"[B_s0 -> (J/psi(1S) -> {lepton}+ {lepton}-) ^pi+ pi-]CC",
+            "piM" : f"[B_s0 -> (J/psi(1S) -> {lepton}+ {lepton}-) pi+ ^pi-]CC",
+            f"{lepton}P" : f"[B_s0 -> (J/psi(1S) -> ^{lepton}+ {lepton}-) pi+ pi-]CC",
+            f"{lepton}M" : f"[B_s0 -> (J/psi(1S) -> {lepton}+ ^{lepton}-) pi+ pi-]CC",
+        }
+
+        for line, fields, tuple_label in zip ((f"Hlt2CutBasedIncl{lepton_label}", f"Hlt2CutBasedIncl{lepton_label}PlusTrack", f"Hlt2CutBasedIncl{lepton_label}PlusTwoTrack"),\
+                                              (two_body_fields, three_body_fields, four_body_fields),\
+                                              (f"twoBody{lepton_label}Tuple", f"threeBody{lepton_label}Tuple", f"fourBody{lepton_label}Tuple")):
+            tuples.update(construct_tuple(line, fields, tuple_label, options, False))
+
+    config = make_config(options, tuples)    
+    return config
+
+
+def tuple_spruce(options: Options):
+     
+    tuples = {}
+
+    for dileptons in (dielectron, dimuon):
+        for tuple_setup in dileptons.values():
+            tuples.update(construct_tuple(tuple_setup["line"], tuple_setup["fields"], tuple_setup["tuple_label"], options, True))
+    
+    config = make_config(options, tuples)
+    return config
\ No newline at end of file
diff --git a/cutbased_dilepton_trigger_2023_data/options/DaVinci/spruced_tuples.py b/cutbased_dilepton_trigger_2023_data/options/DaVinci/spruced_tuples.py
new file mode 100644
index 0000000000000000000000000000000000000000..9372377ff7db2c9e83a00e83e5b48c0c973ae23a
--- /dev/null
+++ b/cutbased_dilepton_trigger_2023_data/options/DaVinci/spruced_tuples.py
@@ -0,0 +1,71 @@
+dielectron =    {
+                        "Bs2EE": {
+                            "line"        : "SpruceRD_BToEE",
+                            "fields"      : {
+                                                "B"  : "[B_s0 -> e+ e-]CC",
+                                                "eP" : "[B_s0 -> ^e+ e-]CC",
+                                                "eM" : "[B_s0 -> e+ ^e-]CC",
+                                            },
+                            "tuple_label" : "dielectronBs2EETuple"
+                        },
+                        "Bu2JpsiK": {
+                            "line"        : "SpruceRD_BuToKpEE",
+                            "fields"      : {
+                                                "B"   : "[B+ -> (J/psi(1S) -> e+ e-) K+]CC",
+                                                "Jpsi": "[B+ -> (^J/psi(1S) -> e+ e-) K+]CC",
+                                                "KP"  : "[B+ -> (J/psi(1S) -> e+ e-) ^K+]CC",
+                                                "eP"  : "[B+ -> (J/psi(1S) -> ^e+ e-) K+]CC",
+                                                "eM"  : "[B+ -> (J/psi(1S) -> e+ ^e-) K+]CC",
+                                            },
+                            "tuple_label" : "dielectronBu2JpsiKTuple"
+                        },
+                        "Bd2KstEE": {
+                            "line"        : "SpruceRD_B0ToKpPimEE",
+                            "fields"      : {
+                                                "B"   : "[B0 -> (J/psi(1S) -> e+ e-) (K*(892)0 -> K+ pi-)]CC",
+                                                "Kst" : "[B0 -> (J/psi(1S) -> e+ e-) (^K*(892)0 -> K+ pi-)]CC",
+                                                "KP"  : "[B0 -> (J/psi(1S) -> e+ e-) (K*(892)0 -> ^K+ pi-)]CC",
+                                                "piM" : "[B0 -> (J/psi(1S) -> e+ e-) (K*(892)0 -> K+ ^pi-)]CC",
+                                                "Jpsi": "[B0 -> (^J/psi(1S) -> e+ e-) (K*(892)0 -> K+ pi-)]CC",
+                                                "eP"  : "[B0 -> (J/psi(1S) -> ^e+ e-) (K*(892)0 -> K+ pi-)]CC",
+                                                "eM"  : "[B0 -> (J/psi(1S) -> e+ ^e-) (K*(892)0 -> K+ pi-)]CC",
+                                            },
+                            "tuple_label" : "dielectronBd2KstEETuple"
+                        }
+                }
+
+dimuon =        {
+                    "Bs2MuMu": {
+                        "line"        : "SpruceRD_BToMuMu",
+                        "fields"      : {
+                                            "B"  : "[B_s0 -> mu+ mu-]CC",
+                                            "muP" : "[B_s0 -> ^mu+ mu-]CC",
+                                            "muM" : "[B_s0 -> mu+ ^mu-]CC",
+                                        },
+                        "tuple_label" : "dimuonBs2MuMuTuple"
+                    },
+                    "Bu2JpsiK": {
+                        "line"        : "SpruceRD_BuToKpMuMu",
+                        "fields"      : {
+                                            "B"   : "[B+ -> (J/psi(1S) -> mu+ mu-) K+]CC",
+                                            "Jpsi": "[B+ -> (^J/psi(1S) -> mu+ mu-) K+]CC",
+                                            "KP"  : "[B+ -> (J/psi(1S) -> mu+ mu-) ^K+]CC",
+                                            "muP"  : "[B+ -> (J/psi(1S) -> ^mu+ mu-) K+]CC",
+                                            "muM"  : "[B+ -> (J/psi(1S) -> mu+ ^mu-) K+]CC",
+                                        },
+                        "tuple_label" : "dimuonBu2JpsiKTuple"
+                    },
+                    "Bd2KstMuMu": {
+                        "line"        : "SpruceRD_B0ToKpPimMuMu",
+                        "fields"      : {
+                                            "B"   : "[B0 -> (J/psi(1S) -> mu+ mu-) (K*(892)0 -> K+ pi-)]CC",
+                                            "Kst" : "[B0 -> (J/psi(1S) -> mu+ mu-) (^K*(892)0 -> K+ pi-)]CC",
+                                            "KP"  : "[B0 -> (J/psi(1S) -> mu+ mu-) (K*(892)0 -> ^K+ pi-)]CC",
+                                            "piM" : "[B0 -> (J/psi(1S) -> mu+ mu-) (K*(892)0 -> K+ ^pi-)]CC",
+                                            "Jpsi": "[B0 -> (^J/psi(1S) -> mu+ mu-) (K*(892)0 -> K+ pi-)]CC",
+                                            "muP" : "[B0 -> (J/psi(1S) -> ^mu+ mu-) (K*(892)0 -> K+ pi-)]CC",
+                                            "muM" : "[B0 -> (J/psi(1S) -> mu+ ^mu-) (K*(892)0 -> K+ pi-)]CC",
+                                        },
+                        "tuple_label" : "dimuonBd2KstMuMuTuple"
+                    }
+                }
\ No newline at end of file
diff --git a/cutbased_dilepton_trigger_2023_data/options/Moore/options.py b/cutbased_dilepton_trigger_2023_data/options/Moore/options.py
new file mode 100644
index 0000000000000000000000000000000000000000..c01d2100156790ce7dea51c70797c8da10f836ae
--- /dev/null
+++ b/cutbased_dilepton_trigger_2023_data/options/Moore/options.py
@@ -0,0 +1,38 @@
+###############################################################################
+# (c) Copyright 2021 CERN for the benefit of the LHCb Collaboration           #
+#                                                                             #
+# This software is distributed under the terms of the GNU General Public      #
+# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   #
+#                                                                             #
+# In applying this licence, CERN does not waive the privileges and immunities #
+# granted to it by virtue of its status as an Intergovernmental Organization  #
+# or submit itself to any jurisdiction.                                       #
+###############################################################################
+
+from Moore import Options, run_moore
+
+from RecoConf.hlt2_global_reco import make_light_reconstruction
+from RecoConf.reconstruction_objects import reconstruction
+
+from RecoConf.global_tools import stateProvider_with_simplified_geom
+public_tools=[stateProvider_with_simplified_geom()]
+
+from RecoConf.decoders import default_ft_decoding_version
+default_ft_decoding_version.global_bind(value=4)
+
+from Hlt2Conf.lines.rd import b_to_ll_spruce, b_to_xll_spruce
+
+def spruce_lines():
+    linesets = [b_to_ll_spruce.sprucing_lines, b_to_xll_spruce.sprucing_lines]
+    spruce_lines = []
+    for lineset in linesets:
+        for line in lineset.values():
+            spruce_lines.append(line())
+    return spruce_lines
+
+
+def spruce(options: Options):
+    with reconstruction.bind(from_file=True, spruce=True),\
+           make_light_reconstruction.bind(skipUT=True, use_pr_kf=False):
+            config = run_moore(options, spruce_lines, public_tools)
+            return config