diff --git a/RD_BToXll_2023_v0/b_to_xll_data.py b/RD_BToXll_2023_v0/b_to_xll_data.py
new file mode 100644
index 0000000000000000000000000000000000000000..038348c1535c887602e67cd19f5f39d84bbfdcee
--- /dev/null
+++ b/RD_BToXll_2023_v0/b_to_xll_data.py
@@ -0,0 +1,306 @@
+###############################################################################
+# (c) Copyright 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.                                       #
+###############################################################################
+
+from RD_BToXll_2023_v0.tupling_funcs_data import (
+    make_composite_variables,
+    make_basic_variables,
+    make_hlt_event_variables,
+    make_dtf_variables,
+    make_mva_variables,
+    make_ft_variables,
+    make_track_variables,
+    make_neutral_variables,
+    Funtuple_with_filter,
+    make_intermediate_resonances_variables,
+)
+from PyConf.components import force_location
+from DaVinci import make_config, Options
+from FunTuple.functorcollections import SelectionInfo
+from PyConf.reading import get_particles, get_pvs
+
+from RecoConf.reconstruction_objects import reconstruction
+from FunTuple import FunctorCollection
+import Functors as F
+
+
+def bd2kstMuMu23_alg_config(options: Options):
+
+    line_name = "Hlt2RD_B0ToKpPimMuMu_2023"
+    name = "bd2kstMuMu23"
+    data = get_particles(f"/Event/HLT2/{line_name}/Particles")
+
+    variables = {
+        "B0": make_composite_variables(options, data) + make_dtf_variables(options, data, ismass=True, mB="B0"),
+        "Jpsi": make_basic_variables(options, data)+ make_intermediate_resonances_variables(options, data) + make_dtf_variables(options, data, ismass=True, mB="B0"),
+        "L1": make_basic_variables(options, data) + make_track_variables(options, data),
+        "L2": make_basic_variables(options, data) + make_track_variables(options, data),
+        "Kst": make_basic_variables(options, data) + make_intermediate_resonances_variables(options, data),
+        "K": make_basic_variables(options, data) + make_track_variables(options, data),
+        "Pi": make_basic_variables(options, data) + make_track_variables(options, data),
+    }
+    
+    return Funtuple_with_filter(
+        options,
+        line_name,
+        {
+          "B0": "[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",
+          "L1": "[B0 -> (J/psi(1S) -> ^mu+ mu-) (K*(892)0 -> K+ pi-)]CC",
+          "L2": "[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",
+          "K": "[B0 -> (J/psi(1S) -> mu+ mu-) (K*(892)0 -> ^K+ pi-)]CC",
+          "Pi": "[B0 -> (J/psi(1S) -> mu+ mu-) (K*(892)0 -> K+ ^pi-)]CC",
+        },
+        variables,
+        data,
+        name,
+        event_variables=make_hlt_event_variables(options, line_name),
+    )
+    
+def bu2kMuMu23_alg_config(options: Options):
+
+    line_name = "Hlt2RD_BuToKpMuMu_2023"
+    name = "bu2kMuMu23"
+    data = get_particles(f"/Event/HLT2/{line_name}/Particles")
+
+    
+    variables = {
+        "B": make_composite_variables(options, data) + make_dtf_variables(options, data, ismass=True, mB="B+"),
+        "Jpsi": make_basic_variables(options, data) + make_intermediate_resonances_variables(options, data) + make_dtf_variables(options, data, ismass=True, mB="B+"),
+        "L1": make_basic_variables(options, data) + make_track_variables(options, data),
+        "L2": make_basic_variables(options, data) + make_track_variables(options, data),
+        "K": make_basic_variables(options, data) + make_track_variables(options, data),
+    }
+    
+    return Funtuple_with_filter(
+        options,
+        line_name,
+        {
+            "B": "[B+ -> (J/psi(1S) -> mu+ mu-) K+]CC",
+            "Jpsi": "[B+ -> ^(J/psi(1S) -> mu+ mu-) K+]CC",
+            "L1": "[B+ -> (J/psi(1S) -> ^mu+ mu-) K+]CC",
+            "L2": "[B+ -> (J/psi(1S) -> mu+ ^mu-) K+]CC",
+            "K": "[B+ -> (J/psi(1S) -> mu+ mu-) ^K+]CC",
+        },
+        variables,
+        data,
+        name,
+        event_variables=make_hlt_event_variables(options, line_name),
+    )
+
+def bd2kstMuMu_alg_config(options: Options):
+
+    line_name = "Hlt2RD_B0ToKpPimMuMu"
+    name = "bd2kstMuMu"
+    data = get_particles(f"/Event/HLT2/{line_name}/Particles")
+
+    
+    variables = {
+        "B0": make_composite_variables(options, data) + make_dtf_variables(options, data, ismass=True, mB="B0"),
+        "Jpsi": make_basic_variables(options, data)+ make_intermediate_resonances_variables(options, data) + make_dtf_variables(options, data, ismass=True, mB="B0"),
+        "L1": make_basic_variables(options, data) + make_track_variables(options, data),
+        "L2": make_basic_variables(options, data) + make_track_variables(options, data),
+        "Kst": make_basic_variables(options, data) + make_intermediate_resonances_variables(options, data),
+        "K": make_basic_variables(options, data) + make_track_variables(options, data),
+        "Pi": make_basic_variables(options, data) + make_track_variables(options, data),
+    }
+    
+    return Funtuple_with_filter(
+        options,
+        line_name,
+        {
+          "B0": "[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",
+          "L1": "[B0 -> (J/psi(1S) -> ^mu+ mu-) (K*(892)0 -> K+ pi-)]CC",
+          "L2": "[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",
+          "K": "[B0 -> (J/psi(1S) -> mu+ mu-) (K*(892)0 -> ^K+ pi-)]CC",
+          "Pi": "[B0 -> (J/psi(1S) -> mu+ mu-) (K*(892)0 -> K+ ^pi-)]CC",
+        },
+        variables,
+        data,
+        name,
+        event_variables=make_hlt_event_variables(options, line_name),
+    )
+    
+def bu2kMuMu_alg_config(options: Options):
+
+    line_name = "Hlt2RD_BuToKpMuMu"
+    name = "bu2kMuMu"
+    data = get_particles(f"/Event/HLT2/{line_name}/Particles")
+
+    
+    variables = {
+        "B": make_composite_variables(options, data) + make_dtf_variables(options, data, ismass=True, mB="B+"),
+        "Jpsi": make_basic_variables(options, data)+ make_intermediate_resonances_variables(options, data) + make_dtf_variables(options, data, ismass=True, mB="B+"),
+        "L1": make_basic_variables(options, data) + make_track_variables(options, data),
+        "L2": make_basic_variables(options, data) + make_track_variables(options, data),
+        "K": make_basic_variables(options, data) + make_track_variables(options, data),
+    }
+    
+    return Funtuple_with_filter(
+        options,
+        line_name,
+        {
+            "B": "[B+ -> (J/psi(1S) -> mu+ mu-) K+]CC",
+            "Jpsi": "[B+ -> ^(J/psi(1S) -> mu+ mu-) K+]CC",
+            "L1": "[B+ -> (J/psi(1S) -> ^mu+ mu-) K+]CC",
+            "L2": "[B+ -> (J/psi(1S) -> mu+ ^mu-) K+]CC",
+            "K": "[B+ -> (J/psi(1S) -> mu+ mu-) ^K+]CC",
+        },
+        variables,
+        data,
+        name,
+        event_variables=make_hlt_event_variables(options, line_name),
+    )
+
+def bu2kMuMu_B2CC_alg_config(options: Options):
+
+    line_name = "Hlt2B2CC_BuToJpsiKplus_JpsiToMuMu_Detached"
+    name = "bu2kMuMu_B2CC"
+    data = get_particles(f"/Event/HLT2/{line_name}/Particles")
+
+    
+    variables = {
+        "B": make_composite_variables(options, data) + make_dtf_variables(options, data,  ismass=True, mB="B+"),
+        "Jpsi": make_basic_variables(options, data)+ make_intermediate_resonances_variables(options, data) + make_dtf_variables(options, data, ismass=True, mB="B+"),
+        "L1": make_basic_variables(options, data) + make_track_variables(options, data),
+        "L2": make_basic_variables(options, data) + make_track_variables(options, data),
+        "K": make_basic_variables(options, data) + make_track_variables(options, data),
+    }
+    
+    return Funtuple_with_filter(
+        options,
+        line_name,
+        {
+            "B": "[B+ -> (J/psi(1S) -> mu+ mu-) K+]CC",
+            "Jpsi": "[B+ -> ^(J/psi(1S) -> mu+ mu-) K+]CC",
+            "L1": "[B+ -> (J/psi(1S) -> ^mu+ mu-) K+]CC",
+            "L2": "[B+ -> (J/psi(1S) -> mu+ ^mu-) K+]CC",
+            "K": "[B+ -> (J/psi(1S) -> mu+ mu-) ^K+]CC",
+        },
+        variables,
+        data,
+        name,
+        event_variables=make_hlt_event_variables(options, line_name),
+    )
+
+
+# tested and working!
+def main_iddl2(options: Options):
+    
+    line_name = "Hlt2_InclDetDiMuon"
+    name = "JpsiToMuMu"
+    data = get_particles(f"/Event/HLT2/{line_name}/Particles")
+
+    variables = {
+        "Jpsi": make_basic_variables(options, data)+ make_intermediate_resonances_variables(options, data),
+        "L1": make_basic_variables(options, data) + make_track_variables(options, data),
+        "L2": make_basic_variables(options, data) + make_track_variables(options, data),
+    }
+    return Funtuple_with_filter(
+        options,
+        line_name,
+        {
+        'Jpsi': "[J/psi(1S) -> mu+ mu-]CC",
+        'L1': "[J/psi(1S)-> ^mu+ mu-]CC",
+        'L2': "[J/psi(1S) -> mu+ ^mu-]CC",
+        },
+        variables,
+        data,
+        name,
+        event_variables=make_hlt_event_variables(options, line_name),
+    )    
+
+#tested and working!
+def main_iddl3(options: Options):
+    line_name = "Hlt2_InclDetDiMuon_3Body"
+    name = "BpToKpJpsiToMuMu"
+    data = get_particles(f"/Event/HLT2/{line_name}/Particles")
+
+    variables = {
+        "B": make_composite_variables(options, data) + make_dtf_variables(options, data, ismass=True, mB="B+"),
+        "Jpsi": make_basic_variables(options, data)+ make_intermediate_resonances_variables(options, data) + make_dtf_variables(options, data, ismass=True, mB="B+"),
+        "L1": make_basic_variables(options, data) + make_track_variables(options, data),
+        "L2": make_basic_variables(options, data) + make_track_variables(options, data),
+        "K": make_basic_variables(options, data) + make_track_variables(options, data),
+    }
+    return Funtuple_with_filter(
+        options,
+        line_name,
+        {
+            "B": "[B+ -> (J/psi(1S) -> mu+ mu-) K+]CC",
+            "Jpsi": "[B+ -> ^(J/psi(1S) -> mu+ mu-) K+]CC",
+            "L1": "[B+ -> (J/psi(1S) -> ^mu+ mu-) K+]CC",
+            "L2": "[B+ -> (J/psi(1S) -> mu+ ^mu-) K+]CC",
+            "K": "[B+ -> (J/psi(1S) -> mu+ mu-) ^K+]CC",
+        },
+        variables,
+        data,
+        name,
+        event_variables=make_hlt_event_variables(options, line_name),
+    )    
+    
+
+def main_iddl4(options: Options):
+    line_iddl4 = "Hlt2_InclDetDiMuon_4Body"
+    particles_iddl4 = get_particles(
+        f"/Event/HLT2/{line_iddl4}/Particles")
+    fields_iddl4 = {
+            "B0": "[B0 -> (J/psi(1S) -> mu+ mu-) pi+ pi-]CC",
+            "Jpsi": "[B0 -> ^(J/psi(1S) -> mu+ mu-) pi+ pi-]CC",
+            "L1": "[B0 -> (J/psi(1S) -> ^mu+ mu-) pi+ pi-]CC",
+            "L2": "[B0 -> (J/psi(1S) -> mu+ ^mu-) pi+ pi-]CC",
+            "Pim": "[B0 -> (J/psi(1S) -> mu+ mu-) ^pi+ pi-]CC",
+            "Pip": "[B0 -> (J/psi(1S) -> mu+ mu-) pi+ ^pi-]CC",
+    }
+    line_name = "Hlt2_InclDetDiMuon_4Body"
+    name = "BpToPipPimJpsiToMuMu"
+    data = get_particles(f"/Event/HLT2/{line_name}/Particles")
+
+    variables = {
+        "B0": make_composite_variables(options, data) + make_dtf_variables(options, data, ismass=True, mB="B0"),
+        "Jpsi": make_basic_variables(options, data)+ make_intermediate_resonances_variables(options, data) + make_dtf_variables(options, data, ismass=True, mB="B0"),
+        "L1": make_basic_variables(options, data) + make_track_variables(options, data),
+        "L2": make_basic_variables(options, data) + make_track_variables(options, data),
+        "Pim": make_basic_variables(options, data) + make_track_variables(options, data),
+        "Pip": make_basic_variables(options, data) + make_track_variables(options, data),
+    }
+    return Funtuple_with_filter(
+        options,
+        line_name,
+        {
+            "B0": "[B0 -> (J/psi(1S) -> mu+ mu-) pi+ pi-]CC",
+            "Jpsi": "[B0 -> ^(J/psi(1S) -> mu+ mu-) pi+ pi-]CC",
+            "L1": "[B0 -> (J/psi(1S) -> ^mu+ mu-) pi+ pi-]CC",
+            "L2": "[B0 -> (J/psi(1S) -> mu+ ^mu-) pi+ pi-]CC",
+            "Pim": "[B0 -> (J/psi(1S) -> mu+ mu-) ^pi+ pi-]CC",
+            "Pip": "[B0 -> (J/psi(1S) -> mu+ mu-) pi+ ^pi-]CC",
+        },
+        variables,
+        data,
+        name,
+        event_variables=make_hlt_event_variables(options, line_name),
+    )  
+
+def All(options: Options):
+    user_algorithms = {}
+    user_algorithms = {
+        "Hlt2RD_B0ToKpPimMuMu": bd2kstMuMu_alg_config(options),
+        "Hlt2RD_BuToKpMuMu": bu2kMuMu_alg_config(options),
+        "Hlt2RD_B0ToKpPimMuMu_2023": bd2kstMuMu23_alg_config(options),
+        "Hlt2RD_BuToKpMuMu_2023": bu2kMuMu23_alg_config(options),
+        "Hlt2B2CC_BuToJpsiKplus_JpsiToMuMu_Detached": bu2kMuMu_B2CC_alg_config(options),
+        "Hlt2_InclDetDiMuon": main_iddl2(options),
+        "Hlt2_InclDetDiMuon_3Body": main_iddl3(options),
+        "Hlt2_InclDetDiMuon_4Body": main_iddl4(options),    }
+    config = make_config(options, user_algorithms)
+    return config
diff --git a/RD_BToXll_2023_v0/info.yaml b/RD_BToXll_2023_v0/info.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..f8583ed6d8b1f71cb14b39e5f1211c3fbc12ddd2
--- /dev/null
+++ b/RD_BToXll_2023_v0/info.yaml
@@ -0,0 +1,103 @@
+defaults:
+  inform:
+    - matzeni.atzeni@cern.ch
+  wg: RD
+
+{%- set datasets = [
+  ('turbo',      'MagDown', "v0", "/LHCb/Commissioning23/Beam6800GeV-VeloOpen-MagDown-Excl-UT/Real Data/94000000/RAW"),]%}
+
+{%- for cat, polarity, version, bkp in datasets %}
+
+{{ cat }}_{{ polarity }}_2023_{{version}}_data_Tuple:
+  application: "DaVinci/v63r6"
+  input:
+    bk_query: {{ bkp }}
+    runs:
+      - 265872
+      - 263859
+      - 263858
+      - 263856
+      - 263855
+      - 263854
+      - 263853
+      - 263852
+      - 263849
+      - 263848
+      - 263846
+      - 263840
+      - 263839
+      - 263838
+      - 263837
+      - 263836
+      - 263835
+      - 263834
+      - 263832
+      - 263831
+      - 263828
+      - 263827
+      - 263823
+      - 263822
+      - 263821
+      - 263819
+      - 263818
+      - 263817
+      - 263816
+      - 263815
+      - 263814
+      - 263813
+      - 263812
+      - 263811
+      - 263810
+      - 263138
+      - 263137
+      - 263134
+      - 263133
+      - 263132
+      - 263123
+      - 263122
+      - 263121
+      - 263093
+      - 263092
+      - 263091
+      - 263089
+      - 263088
+      - 262967
+      - 262966
+      - 262965
+      - 262963
+      - 262962
+      - 262961
+      - 262960
+      - 262958
+      - 262957
+      - 262956
+      - 262544
+      - 262543
+      - 262542
+      - 262541
+      - 263847
+      - 263829
+      - 263124
+      - 263857
+
+    dq_flags: 
+      - UNCHECKED
+      - OK
+  output: DATA_{{ cat }}_COMMISSIONING_2023_{{version}}.ROOT
+
+  options:
+    entrypoint: RD_BToXll_2023_{{version}}.b_to_xll_data:All
+    extra_options:
+      input_raw_format: 0.5
+      input_type: RAW
+      simulation: False
+      data_type: "Upgrade"
+      dddb_tag: trunk
+      conddb_tag: master
+      input_process: "Hlt2"
+      compression:
+        algorithm: ZSTD
+        level: 1
+        max_buffer_size: 1048576
+
+{%- endfor %}
\ No newline at end of file
diff --git a/RD_BToXll_2023_v0/tupling_funcs_data.py b/RD_BToXll_2023_v0/tupling_funcs_data.py
new file mode 100644
index 0000000000000000000000000000000000000000..61dcf4bab5674e3eeea80ee001dce684c57305d0
--- /dev/null
+++ b/RD_BToXll_2023_v0/tupling_funcs_data.py
@@ -0,0 +1,468 @@
+###############################################################################
+# (c) Copyright 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.                                       #
+###############################################################################
+"""Common configuration functions
+"""
+from PyConf.components import force_location
+
+import Functors as F
+from Functors.math import log
+
+from FunTuple import FunctorCollection
+from FunTuple.functorcollections import (
+    MCHierarchy,
+    Kinematics,
+    SelectionInfo,
+    MCVertexInfo,
+    MCKinematics,
+    EventInfo,
+    HltTisTos,
+)
+from FunTuple import FunTuple_Particles as Funtuple
+from PyConf.application import metainfo_repos
+
+from DaVinci.algorithms import add_filter
+from PyConf.reading import (
+    get_pvs, 
+    get_pvs_v1, 
+    get_particles, 
+    get_rec_summary,
+    get_charged_protoparticles,
+    get_neutral_protoparticles,)
+####
+
+metainfo_repos.global_bind(extra_central_tags=['commissioning'])
+#Hlt1OneMuonTrackLineDecisionHlt1LowPtMuonDecision
+Hlt1_decisions = [
+    "Hlt1TwoTrackMVACharmXSecDecision",
+    "Hlt1TrackMVADecision",
+    "Hlt1TwoTrackMVADecision",
+    "Hlt1DisplacedLeptonsDecision",
+    "Hlt1SingleHighEtDecision",
+    'Hlt1DiMuonHighMassDecision',
+    'Hlt1DiMuonLowMassDecision',
+    'Hlt1DiMuonSoftDecision',
+    'Hlt1LowPtMuonDecision',
+    'Hlt1LowPtDiMuonDecision', 
+    'Hlt1SingleHighPtMuonDecision',
+    'Hlt1TrackMuonMVADecision',
+    'Hlt1OneMuonTrackLineDecision',
+    'Hlt1DiMuonNoIPDecision',
+    'Hlt1DiMuonNoIP_ssDecision'
+]
+
+Hlt2_decisions = [
+    "Hlt2RD_BsToPhiGammaDecision",
+    "Hlt2RD_BdToKstGammaDecision",
+    "Hlt2RD_BToHHGamma_InclDecision",
+    "Hlt2_JpsiToMuMuDecision",
+    "Hlt2B2CC_BuToJpsiKplus_JpsiToMuMu_DetachedDecision"
+]
+
+
+def sum_hh(functor):
+    return F.CHILD(1, F.SUM(functor)) + F.CHILD(2, functor)
+def sum_hhh(functor):
+    return F.CHILD(1, F.CHILD(1, F.SUM(functor))) + F.CHILD(1, F.CHILD(2, functor)) + F.CHILD(2, functor)
+
+def make_composite_variables(options, data):
+    v2_pvs = get_pvs()
+    variables = (
+        FunctorCollection(
+            {
+                #kinematic vars
+                "MAX_PT": F.MAX(F.PT),
+                "MIN_PT": F.MIN(F.PT),
+                "SUM_PT": F.SUM(F.PT),
+                "MAX_P": F.MAX(F.P),
+                "MIN_P": F.MIN(F.P),
+                "ETA": F.ETA,
+                "PHI": F.PHI,
+                "CHI2": F.CHILD(1,F.CHI2),
+                "CHI2VXNDOF": F.CHI2DOF,
+                #property vars
+                "ID": F.PARTICLE_ID,
+                "KEY": F.OBJECT_KEY,
+                #BPV vars
+                "BPVCORRM": F.BPVCORRM(v2_pvs),
+                "BPVDIRA": F.BPVDIRA(v2_pvs),
+                "BPVDLS": F.BPVDLS(v2_pvs),
+                "BPVETA": F.BPVETA(v2_pvs),
+                "BPVFD": F.BPVFD(v2_pvs),
+                "BPVFDCHI2": F.BPVFDCHI2(v2_pvs),
+                "BPVFDIR": F.BPVFDIR(v2_pvs),
+                "BPVFDVEC": F.BPVFDVEC(v2_pvs),
+                "BPVIPCHI2": F.BPVIPCHI2(v2_pvs),
+                "BPVLTIME": F.BPVLTIME(v2_pvs),
+                "BPVVDRHO": F.BPVVDRHO(v2_pvs),
+                "BPVX": F.BPVX(v2_pvs),
+                "BPVY": F.BPVY(v2_pvs),
+                "BPVZ": F.BPVZ(v2_pvs),
+                "END_VX": F.END_VX,
+                "END_VY": F.END_VY,
+                "END_VZ": F.END_VZ,
+                "MAX_BPVIPCHI2": F.MAX(F.BPVIPCHI2(v2_pvs)),
+                "MIN_BPVIPCHI2": F.MIN(F.BPVIPCHI2(v2_pvs)),
+                "R_BPVCORRM": F.CHILD(1, F.BPVCORRM(v2_pvs)),
+                #geometry vars
+                "ALV": F.ALV(1,2),
+                "R_ALV": F.CHILD(1, F.ALV(1,2)),
+                "MAXDOCACHI2": F.MAXDOCACHI2,
+                "MAXDOCA": F.MAXDOCA,
+                "MAXSDOCACHI2": F.MAXSDOCACHI2,
+                "MAXSDOCA": F.MAXSDOCA,
+                "DOCA": F.CHILD(1, F.SDOCA(1,2)),
+                #
+            }
+        ) + Kinematics()
+    )
+    return variables
+
+def make_intermediate_resonances_variables(options, data):
+    v2_pvs = get_pvs()
+    variables = FunctorCollection({
+            "BPVFDCHI2": F.BPVFDCHI2(v2_pvs),
+            "BPVFD": F.BPVFD(v2_pvs),
+            'BPVLTIME': F.BPVLTIME(v2_pvs),
+            "BPVDIRA": F.BPVDIRA(v2_pvs),
+            "CHI2DOF": F.CHI2DOF,
+            "BPVVDRHO": F.BPVVDRHO(v2_pvs),
+            "BPVVDZ": F.BPVVDZ(v2_pvs),
+            "MAX_BPVIPCHI2": F.MAX(F.BPVIPCHI2(v2_pvs)),
+            "MIN_BPVIPCHI2": F.MIN(F.BPVIPCHI2(v2_pvs)),
+            "MAXDOCACHI2": F.MAXDOCACHI2,
+            "MAXDOCA": F.MAXDOCA,
+            "MAXSDOCACHI2": F.MAXSDOCACHI2,
+            "MAXSDOCA": F.MAXSDOCA,
+            "ALV": F.ALV(1,2),
+            'CHI2': F.CHI2,
+            'END_VX': F.END_VX,
+            'END_VY': F.END_VY,
+            'END_VZ': F.END_VZ,
+            "MAX_PT": F.MAX(F.PT),
+            "MIN_PT": F.MIN(F.PT),
+            "SUM_PT": F.SUM(F.PT),
+            "MAX_P": F.MAX(F.P),
+            "MIN_P": F.MIN(F.P),
+            "KEY": F.OBJECT_KEY,
+        })    
+
+    return variables
+
+def make_dtf_variables(options, data, ismass=True, mB="B+"):
+    from DecayTreeFitter import DecayTreeFitter
+    v2_pvs = get_pvs()
+    pvs = get_pvs_v1()
+    pv_fun = {
+    'BPVLTIME': F.BPVLTIME(v2_pvs),
+    'BPVIPCHI2': F.BPVIPCHI2(v2_pvs),
+    'BPVDIRA': F.BPVDIRA(v2_pvs),
+    'BPVDLS': F.BPVDLS(v2_pvs),
+    'BPVFD': F.BPVFD(v2_pvs),
+    }
+    pv_coll = FunctorCollection(pv_fun)
+    DTF = DecayTreeFitter(
+        name = 'PVFit_{hash}',
+        input_particles = data)
+    dtf_variables = FunctorCollection({'PVFit_'+ k: DTF(Functor=v) for k, v in pv_coll.get_thor_functors().items()})
+    dtf_variables_d = FunctorCollection({'PVFit_'+ k: DTF(Functor=v) for k, v in Kinematics().get_thor_functors().items()})
+    variables = dtf_variables
+    variables_d = dtf_variables_d 
+
+    if ismass:
+        DTFM_excl = DecayTreeFitter(
+            name = 'PVandBMassFit_{hash}',
+            input_particles = data,
+            mass_constraints = [mB])
+        variables += FunctorCollection({'PVandBMassFit_' + k: DTFM_excl(Functor=v) for k, v in pv_coll.get_thor_functors().items()})
+        variables_d += FunctorCollection({'PVandBMassFit_' + k: DTFM_excl(Functor=v) for k, v in Kinematics().get_thor_functors().items()})
+        
+        DTFM_jpsi = DecayTreeFitter(
+            name = 'PVandJpsiMassFit_{hash}',
+            input_particles = data,
+            mass_constraints = ["J/psi(1S)"])
+        variables += FunctorCollection({'PVandJpsiMassFit_' + k: DTFM_jpsi(Functor=v) for k, v in pv_coll.get_thor_functors().items()})
+        variables_d += FunctorCollection({'PVandJpsiMassFit_' + k: DTFM_jpsi(Functor=v) for k, v in Kinematics().get_thor_functors().items()})
+        
+
+
+    return variables + variables_d
+
+def make_ft_variables(options,data):
+    from PyConf.Algorithms import ParticleTaggerAlg, ParticleContainerMerger
+    from PyConf.Algorithms import FunctionalSSPionTagger
+    from DaVinci.common_particles import make_long_pions
+    tagging_pion = make_long_pions()
+    v2_pvs = get_pvs()
+    sspion_tagging = FunctionalSSPionTagger(
+        BCandidates = data,
+        TaggingPions = tagging_pion,
+        PrimaryVertices = v2_pvs,
+        OutputLevel=3
+    )
+    tagging_container = ParticleContainerMerger( InputContainers = [tagging_pion]).OutputContainer
+    tagAlg = ParticleTaggerAlg(Input = data, TaggingContainer = tagging_container, OutputLevel=3)
+    tagAlg_rels = tagAlg.OutputRelations
+    variables = FunctorCollection({
+        "SSPionBDT_DEC": F.SSPionBDT_Decision(sspion_tagging.OutputFlavourTags),
+        "SSPionBDT_ETA": F.SSPionBDT_Mistag(sspion_tagging.OutputFlavourTags),
+        "TagTr_P": F.MAP_INPUT_ARRAY(Functor=F.P, Relations=tagAlg_rels),
+    })
+    return variables
+    
+def make_mva_variables(options, data, line_name="HHgamma"):
+    from GaudiKernel.SystemOfUnits import GeV
+    pvs = get_pvs()
+    from Hlt2Conf.lines.rd.builders.b_tmva_builder import rad_BDT_functor
+    mva = rad_BDT_functor(pvs, line_name)
+    bdt_variables = FunctorCollection({
+        "BDT": mva,
+    })
+    def sum_finalstates_hh(functor):
+        return F.CHILD(1, F.SUM(functor)) + F.CHILD(2, functor)
+
+    def sum_finalstates_hhh(functor):
+        return F.CHILD(1, F.CHILD(1, (F.SUM(functor)))) + F.CHILD(
+            1, F.CHILD(2, functor)) + F.CHILD(2, functor)
+
+    hhg_vars_thor = FunctorCollection({
+        "ipchi2": log(F.BPVIPCHI2(pvs)) / log(10),
+        'ipchi2_min': log(F.CHILD(1, F.MIN(F.BPVIPCHI2(pvs)))) / log(10),
+        'gamma_pt': F.CHILD(2, F.PT),
+        'm_corrected': F.BPVCORRM(pvs),
+        'vm_corrected': F.CHILD(1, F.BPVCORRM(pvs)),
+        'fdchi2': log(F.BPVFDCHI2(pvs)) / log(10),
+        'vtx_chi2': log(F.CHILD(1, F.CHI2)) / log(10),
+        'doca': F.CHILD(1, F.SDOCA(1, 2))
+    })
+    hhgee_vars_thor = FunctorCollection({
+        'mcor':
+        F.BPVCORRM(pvs),
+        'chi2':
+        F.CHILD(1, F.CHI2),
+        'sumpt':
+        sum_finalstates_hh(F.PT),
+        'eta':
+        F.BPVETA(pvs),
+        'fdchi2':
+        F.BPVFDCHI2(pvs),
+        'minpt':
+        F.MINTREE(((F.IS_ABS_ID('K+')) | (F.IS_ID('KS0')) |
+                   (F.IS_ABS_ID('Lambda0')) | (F.IS_ABS_ID('gamma'))), F.PT),
+        'nlt16':
+        sum_finalstates_hh(F.BPVIPCHI2(pvs) < 16),
+        'ipchi2':
+        F.BPVIPCHI2(pvs),
+        'n1trk':
+        sum_finalstates_hh((F.PT > 1 * GeV) & (F.BPVIPCHI2(pvs) > 16))
+    })
+
+    hhhg_vars_thor = FunctorCollection({
+        'ipchi2':
+        log(F.BPVIPCHI2(pvs)) / log(10),
+        'ipchi2_min':
+        log(
+            F.MINTREE((F.IS_ABS_ID('K+')) | (F.IS_ID('KS0')) |
+                      (F.IS_ABS_ID('Lambda0')), F.BPVIPCHI2(pvs))) / log(10),
+        'gamma_pt':
+        F.CHILD(2, F.PT),
+        'gamma_p':
+        F.CHILD(2, F.P),
+        'm_corrected':
+        F.BPVCORRM(pvs),
+        'fdchi2':
+        log(F.BPVFDCHI2(pvs)) / log(10),
+        'vtx_chi2':
+        log(F.CHILD(1, F.CHI2)) / log(10),
+        'chi2dof_max':
+        F.MAXTREE(F.IS_ABS_ID('K+'), F.CHI2DOF()),
+    })
+    hhhgee_vars_thor = FunctorCollection({
+        'mcor':
+        F.BPVCORRM(pvs),
+        'chi2':
+        F.CHILD(1, F.CHI2),
+        'sumpt':
+        sum_finalstates_hhh(F.PT),
+        'eta':
+        F.BPVETA(pvs),
+        'fdchi2':
+        F.BPVFDCHI2(pvs),
+        'minpt':
+        F.MINTREE(((F.IS_ABS_ID('K+')) | (F.IS_ID('KS0')) |
+                   (F.IS_ABS_ID('Lambda0')) | (F.IS_ABS_ID('gamma'))), F.PT),
+        'nlt16':
+        sum_finalstates_hhh(F.BPVIPCHI2(pvs) < 16),
+        'ipchi2':
+        F.BPVIPCHI2(pvs),
+        'n1trk':
+        sum_finalstates_hhh((F.PT > 1 * GeV) & (F.BPVIPCHI2(pvs) > 16))
+    })
+
+    bdt_vars_thor = {
+        "HHgamma": hhg_vars_thor,
+        "HHgammaEE": hhgee_vars_thor,
+        "HHHgamma": hhhg_vars_thor,
+        "HHHgammaEE": hhhgee_vars_thor
+    }
+
+    bdt_variables += bdt_vars_thor[line_name]
+    
+    return bdt_variables
+
+def make_basic_variables(options, data):
+    v2_pvs = get_pvs()
+    variables = (
+        FunctorCollection(
+            {
+                "ID": F.PARTICLE_ID,
+                "ETA": F.ETA,
+                "PHI": F.PHI,
+                "BPVIPCHI2": F.BPVIPCHI2(v2_pvs),
+                "BPVX": F.BPVX(v2_pvs),
+                "BPVY": F.BPVY(v2_pvs),
+                "BPVZ": F.BPVZ(v2_pvs),
+            })) + Kinematics()
+    return variables
+
+def make_track_variables(options, data):
+    v2_pvs = get_pvs()
+    pvs = get_pvs_v1()
+    variables = FunctorCollection(
+        {
+            "IS_NOT_H": F.IS_NOT_H,
+            "IS_PHOTON": F.IS_PHOTON,
+            "TRCHI2DOF": F.CHI2DOF,
+            "TRGHOSTPROB": F.GHOSTPROB,
+            "PID_K": F.PID_K,
+            "PID_E": F.PID_E,
+            "PID_MU": F.PID_MU,
+            "PID_PI": F.PID_PI,
+            "PID_P": F.PID_P,
+            "ISMUON": F.ISMUON,
+            "INECAL": F.INECAL,
+            "ECALPIDE": F.ECALPIDE,
+            "ECALPIDMU": F.ECALPIDMU,
+            "PROBNN_E": F.PROBNN_E,
+            "PROBNN_GHOST": F.PROBNN_GHOST,
+            "PROBNN_K": F.PROBNN_K,
+            "PROBNN_MU": F.PROBNN_MU,
+            "PROBNN_P": F.PROBNN_P,
+            "PROBNN_PI": F.PROBNN_PI,
+            "NVPHITS": F.VALUE_OR(-1) @ F.NVPHITS @ F.TRACK,
+            "NFTHITS": F.VALUE_OR(-1) @ F.NFTHITS @ F.TRACK,
+            "NDOF": F.VALUE_OR(-1) @ F.NDOF @ F.TRACK,
+            "QOVERP": F.QOVERP @ F.TRACK,
+            "CHI2DOF ": F.VALUE_OR(-1) @ F.CHI2DOF @ F.TRACK,
+            "CHI2_": F.CHI2,
+            "GHOSTPROB": F.GHOSTPROB @ F.TRACK,
+            #as electron
+            "ELECTRONMATCH_CHI2": F.ELECTRONMATCH_CHI2,
+            "ELECTRONSHOWEREOP": F.ELECTRONSHOWEREOP,
+            "ELECTRONENERGY": F.ELECTRONENERGY,
+            "ELECTRONID": F.ELECTRONID,
+            #ECAL
+            "CLUSTERMATCH_CHI2": F.CLUSTERMATCH_CHI2,
+            #HCAL
+            "HCALEOP": F.HCALEOP,
+            "HCALPIDE": F.HCALPIDE,
+            "HCALPIDMU": F.HCALPIDMU,
+            "INHCAL": F.INHCAL,
+            #brem vars
+            "INBREM": F.INBREM,
+            "HASBREM": F.HASBREM,
+            "BREMENERGY": F.BREMENERGY,
+            "BREMBENDCORR": F.BREMBENDCORR,
+            "BREMHYPOID": F.BREMHYPOID,
+            "BREMHYPOENERGY": F.BREMHYPOENERGY,
+            "BREMHYPODELTAX": F.BREMHYPODELTAX,
+            "BREMHYPOMATCH_CHI2": F.BREMHYPOMATCH_CHI2,
+            "BREMPIDE": F.BREMPIDE,
+            "BREMTRACKBREMENERGY": F.BREMTRACKBREMENERGY,
+            #RICH
+            #"RICH_DLL_BT": F.RICH_DLL_BT,
+            #"RICH_DLL_E": F.RICH_DLL_E,
+            #"RICH_DLL_K": F.RICH_DLL_K,
+            #"RICH_DLL_MU": F.RICH_DLL_MU,
+            #"RICH_DLL_P": F.RICH_DLL_P,
+            #"RICH_DLL_PI": F.RICH_DLL_PI,
+            # muon
+            "INMUON": F.INMUON,
+            'TRACKHASVELO':  F.VALUE_OR(-1) @ F.TRACKHASVELO @ F.TRACK,
+            'TRACKHASUT': F.VALUE_OR(-1) @ F.TRACKHASUT @ F.TRACK,
+            'TX': F.TX,
+            'TY': F.TY,
+            "KEY": F.OBJECT_KEY,#
+        }
+    )
+    variables += HltTisTos(selection_type="Hlt1", trigger_lines=Hlt1_decisions, data=data)
+    return variables
+
+def make_neutral_variables(options, data):
+    variables = FunctorCollection({
+        "IS_NOT_H": F.IS_NOT_H,
+        "IS_PHOTON": F.IS_PHOTON,
+        "CALO_E19": F.CALO_NEUTRAL_1TO9_ENERGY_RATIO,
+        "CALO_E49": F.CALO_NEUTRAL_4TO9_ENERGY_RATIO,
+        "CALO_E": F.CALO_NEUTRAL_ECAL_ENERGY,
+        "CALO_ID": F.CALO_NEUTRAL_ID,
+        "CALO_HTOE": F.CALO_NEUTRAL_HCAL2ECAL_ENERGY_RATIO,
+        "CALO_SHOWERSHAPE": F.CALO_NEUTRAL_SHOWER_SHAPE,
+        "CALO_NUM_SAT": F.CALO_NUM_SATURATED_CELLS,
+        "CLUSTERMATCH_CHI2": F.CLUSTERMATCH_CHI2,
+        "CALO_CLUSTER_MASS": F.CALO_CLUSTER_MASS,
+
+    })
+    return variables 
+    
+def make_hlt_event_variables(options, line_name):
+    #get ODIN and DecReports location
+    rec_summary = get_rec_summary()
+    #define event level variables
+    evt_variables = FunctorCollection({
+        "nTracks": F.VALUE_OR(-1) @ F.NTRACKS(rec_summary),
+        "nPVs": F.VALUE_OR(-1) @ F.NPVS(rec_summary),
+        "nFTClusters": F.VALUE_OR(-1) @ F.NFTCLUSTERS(rec_summary)
+    })
+    evt_variables += EventInfo()
+
+    # define event level variables
+    #evt_variables = EventInfo(odin, extra_info=True)
+    evt_variables += SelectionInfo(selection_type="Hlt2", trigger_lines=Hlt2_decisions)
+    evt_variables += SelectionInfo(selection_type="Hlt1", trigger_lines=Hlt1_decisions)
+    
+    return evt_variables
+
+def Funtuple_with_filter(
+    options,
+    line_name,
+    fields,
+    variables,
+    inputs,
+    name="Tuple",
+    tuple_name="DecayTree",
+    event_variables=None,
+):
+    hlt_filter = add_filter(
+        "HDRFilter_{hash}",
+        f"HLT_PASS('{line_name}')",
+    )
+
+    return [
+        hlt_filter,
+        Funtuple(
+            name=name,
+            tuple_name=tuple_name,
+            fields=fields,
+            variables=variables,
+            inputs=inputs,
+            event_variables=event_variables,
+        ),
+    ]