diff --git a/ift_spruce_validation/MB_SMOG2_val_tuple.py b/ift_spruce_validation/MB_SMOG2_val_tuple.py
new file mode 100644
index 0000000000000000000000000000000000000000..63cd24827c6436af76cd9bf074ce004d4d16617c
--- /dev/null
+++ b/ift_spruce_validation/MB_SMOG2_val_tuple.py
@@ -0,0 +1,515 @@
+from DaVinci import Options, make_config
+from DaVinci.algorithms import create_lines_filter
+from PyConf.reading import (get_odin, get_particles, get_charged_protoparticles, get_pvs, get_rec_summary, _get_unpacked)
+
+import Functors as F
+from FunTuple import FunctorCollection 
+import FunTuple.functorcollections as FC
+from FunTuple import FunTuple_Event
+from FunTuple import FunTuple_Particles as FunTuple
+
+from Hlt2Conf.lines.ift.builders.smog2_charm_builders import make_charm_protons_tight
+from Hlt2Conf.lines.ift.builders.smog2_builders import bpv_in_smog2
+from Hlt2Conf.standard_particles import make_has_rich_long_protons
+from Hlt2Conf.standard_particles import make_merged_pi0s, make_resolved_pi0s
+from GaudiKernel.SystemOfUnits import GeV, MeV, mm, picosecond
+
+from PyConf.reading import get_neutral_protoparticles
+from Hlt2Conf.algorithms_thor import ParticleCombiner, ParticleFilter
+from Hlt2Conf.standard_particles import make_photons, make_long_electrons_with_brem, make_down_electrons_no_brem
+from Functors.math import in_range
+
+from RecoConf.event_filters import require_pvs
+import FunTuple.functorcollections as FC
+import Functors.math as fmath
+import sys
+
+from RecoConf import track_refitting
+
+
+def make_gamma2ee_LL(name='gamma2ee_LL',
+                     descriptor="gamma -> e+ e-",
+                     am_max=500. * MeV,
+                     m_max=100. * MeV,
+                     pt_min=50. * MeV,
+                     ePID=-5,
+                     maxVertexChi2=16):
+    electrons = make_long_electrons_with_brem()
+    if ePID: filtered_electrons = ParticleFilter( electrons, F.FILTER( F.PID_E>ePID ))
+    else: filtered_electrons = electrons
+
+    combination_code = (F.MASS < am_max)
+    vertex_code = F.require_all(F.PT > pt_min, F.MASS < am_max,
+                                F.CHI2 < maxVertexChi2)
+    return ParticleCombiner(
+        name=name,
+        Inputs=[filtered_electrons, filtered_electrons],
+        DecayDescriptor=descriptor,
+        CombinationCut=combination_code,
+        CompositeCut=vertex_code)
+
+
+def make_gamma2ee_DD(name='gamma2ee_DD',
+                     descriptor="gamma -> e+ e-",
+                     am_max=500. * MeV,
+                     m_max=100. * MeV,
+                     pt_min=50. * MeV,
+                     ePID=None,
+                     maxVertexChi2=16):
+
+    electrons = make_down_electrons_no_brem()
+    if ePID: filtered_electrons = ParticleFilter( electrons, F.FILTER( F.PID_E>ePID ))
+    else: filtered_electrons = electrons
+
+    combination_code = (F.MASS < am_max)
+    vertex_code = F.require_all(F.PT > pt_min, F.MASS < am_max,
+                                F.CHI2 < maxVertexChi2)
+
+    return ParticleCombiner(
+        name=name,
+        Inputs=[filtered_electrons, filtered_electrons],
+        DecayDescriptor=descriptor,
+        CombinationCut=combination_code,
+        CompositeCut=vertex_code)
+
+def make_basic_variables(options, data, pv=True):
+    pvs = get_pvs()
+    variables = FunctorCollection({
+        "ID":F.PARTICLE_ID,
+        'KEY':F.OBJECT_KEY,
+        'ENERGY':F.ENERGY,
+        'CHARGE':F.CHARGE,
+        'P':F.P,
+        'PT':F.PT,
+        'PX':F.PX,
+        'PY':F.PY,
+        'PZ':F.PZ,
+        'Y':0.5 * fmath.log((F.ENERGY + F.PZ) / (F.ENERGY - F.PZ)),
+        'YSTAR':0.5 * fmath.log((F.ENERGY + F.PZ) / (F.ENERGY - F.PZ)) - 4.79,
+        'MASS':F.MASS,
+        "ETA":F.ETA,
+        "PHI":F.PHI,
+        "TX":F.TX,
+        "TY":F.TY,
+        'CHI2': F.CHI2, 'CHI2DOF': F.CHI2DOF,
+
+    })
+
+    if pv:
+        variables += FunctorCollection({
+            'B_PV_Z':F.BPVZ(pvs),'B_PV_X':F.BPVX(pvs),'B_PV_Y':F.BPVY(pvs),
+            'BPVIP': F.BPVIP(pvs),'BPVIPCHI2': F.BPVIPCHI2(pvs),
+            'nBestPVTracks':    F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.SIZE_OF @ F.PVTRACKS @ F.BPV(pvs),
+            'nBestPVbackTracks':    F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.COUNT_IF( F.TRACKISVELOBACKWARD ) @ F.PVTRACKS @ F.BPV(pvs),
+        })
+    return variables
+
+def make_track_variables(options, data):
+    variables = FunctorCollection({
+        'PIDE':F.PID_E,
+        'PIDK':F.PID_K,
+        'PIDMU':F.PID_MU,
+        'PIDP':F.PID_P,
+        'PIDPI':F.PID_PI,
+        'PROBNNE':F.PROBNN_E,
+        'PROBNNK':F.PROBNN_K,
+        'PROBNNMU':F.PROBNN_MU,
+        'PROBNNP':F.PROBNN_P,
+        'PROBNNPI':F.PROBNN_PI,
+        'PROBNNGHOST':F.PROBNN_GHOST,
+        'PROBNND':F.PROBNN_D,
+        'GHOSTPROB':F.GHOSTPROB,
+        'ISMUON':F.ISMUON,
+        'TRACK_NVPHITS':F.VALUE_OR(-1) @ F.NVPHITS @ F.TRACK,
+        'TRACK_NFTHITS':F.VALUE_OR(-1) @ F.NFTHITS @ F.TRACK,
+        'TRACK_NUTHITS':F.VALUE_OR(-1) @ F.NUTHITS @ F.TRACK,
+    })
+    #variables += ParticleID(True)
+    return variables
+
+def make_composite_variables(options, data, pv=True):
+    pvs = get_pvs()
+    variables = FunctorCollection({
+        # kinematic vars
+        'SDOCA': F.SDOCA(Child1=1, Child2=2), 'SDOCACHI2': F.SDOCACHI2(Child1=1, Child2=2),
+        'DOCA': F.DOCA(Child1=1, Child2=2), 'DOCACHI2': F.DOCACHI2(Child1=1, Child2=2),
+    })
+
+    if pv:
+        variables += FunctorCollection({
+        'END_VX': F.END_VX, 'END_VY': F.END_VY, 'END_VZ': F.END_VZ, 'END_VRHO': F.END_VRHO,
+        'BPVFDCHI2': F.BPVFDCHI2(pvs),'BPVLTIME': F.BPVLTIME(pvs),'BPVFD': F.BPVFD(pvs), 
+        'BPVDIRA': F.BPVDIRA(pvs),
+    })
+
+    return variables
+
+def make_calo_variables(options, data):
+    variables = FunctorCollection({
+        "IS_NOT_H": F.IS_NOT_H,
+        "IS_PHOTON": F.IS_PHOTON,
+        'CaloTrackMatchChi2': F.CLUSTERMATCH_CHI2,
+        'CaloNeutralShowerShape': F.CALO_NEUTRAL_SHOWER_SHAPE,
+        'CaloClusterMass': F.CALO_CLUSTER_MASS,
+        'CaloNeutralEcalEnergy': F.CALO_NEUTRAL_ECAL_ENERGY,
+        'CaloNeutral1To9EnergyRatio': F.CALO_NEUTRAL_1TO9_ENERGY_RATIO,
+        'CaloNeutral4To9EnergyRatio': F.CALO_NEUTRAL_4TO9_ENERGY_RATIO,
+        'CaloNeutralHcal2EcalEnergyRatio': F.CALO_NEUTRAL_HCAL2ECAL_ENERGY_RATIO,
+        'CaloNeutralID': F.CALO_NEUTRAL_ID,
+        'CaloNumSaturatedCells': F.CALO_NUM_SATURATED_CELLS,
+    })
+   # variables += NeutralCaloInfo()
+    return variables
+
+def make_charged_calo_variables(options, data):
+    #variables = ChargedCaloInfo()
+    variables = FunctorCollection({
+        'INECAL': F.INECAL,
+        'INHCAL': F.INHCAL,
+        'INBREM': F.INBREM,
+        'HASBREM': F.HASBREM,
+        #'HASBREMADDED': F.HASBREMADDED,
+        'BREMENERGY': F.BREMENERGY,
+        'BREMPIDE': F.BREMPIDE,
+        'ECALPIDE': F.ECALPIDE,
+        'ECALPIDMU': F.ECALPIDMU,
+        'HCALPIDE': F.HCALPIDE,
+        'HCALPIDMU': F.HCALPIDMU,
+        #'CLUSTERID': F.CLUSTERID,
+        #'CLUSTERMATCH_CHI2': F.CLUSTERMATCH_CHI2,
+        'ELECTRONSHOWEREOP': F.ELECTRONSHOWEREOP,
+        'ELECTRONSHOWERDLL': F.ELECTRONSHOWERDLL,
+        'ELECTRONMATCH_CHI2': F.ELECTRONMATCH_CHI2,
+        'ELECTRONENERGY': F.ELECTRONENERGY,
+        'ELECTRONID': F.ELECTRONID,
+        'BREMBENDCORR': F.BREMBENDCORR,
+        'BREMHYPOID': F.BREMHYPOID,
+        'BREMHYPOMATCH_CHI2': F.BREMHYPOMATCH_CHI2,
+        'BREMHYPOENERGY': F.BREMHYPOENERGY,
+        'BREMHYPODELTAX': F.BREMHYPODELTAX,
+    #'BREMTRACKBASEDENERGY': F.BREMTRACKBASEDENERGY,
+        'HCALEOP': F.HCALEOP,
+        })
+    return variables
+
+def count_evt_variables(options, Pi_loc, photoncal_loc=False, photonconvLL_loc=False, photonconvDD_loc=False ):
+    evt_variables = FunctorCollection({ 
+        "n_Pi0": F.SIZE(Pi_loc),
+    })
+    if photoncal_loc: evt_variables += FunctorCollection({ "n_GammaCal": F.SIZE(photoncal_loc), })
+    if photonconvLL_loc: evt_variables += FunctorCollection({ "n_GammaConvLL": F.SIZE(photonconvLL_loc), })
+    if photonconvDD_loc: evt_variables += FunctorCollection({ "n_GammaConvDD": F.SIZE(photonconvDD_loc), })
+
+    return evt_variables
+
+def main(options: Options):
+
+
+    rec_summary = get_rec_summary()
+    v2_pvs = get_pvs()
+    odin = get_odin()
+
+    hlt2_velotracks = lambda : _get_unpacked(type_name='Tracks', location="/Event/Spruce/HLT2/Rec/Track/Velo" )
+    hlt2_longtracks = lambda : _get_unpacked(type_name='Tracks', location="/Event/Spruce/HLT2/Rec/Track/BestLong" )
+    velo_tracks = hlt2_velotracks()
+    long_tracks = hlt2_longtracks()
+
+    Spruce_decisions = [ 'SpruceIFT_SMOG2Passthrough_PV_in_SMOG2', 'SpruceIFT_SMOG2Passthrough', 'SpruceIFT_SMOG2LumiPassthrough'
+                         'SpruceIFT_SMOG2CEPPassthrough', 'SpruceIFT_SMOG2MBPassthrough'
+    ]
+
+    Hlt2_decisions = [ 'Hlt2IFTFull_SMOG2Passthrough_PV_in_SMOG2', 'Hlt2IFTFull_SMOG2Passthrough', 'Hlt2IFTFull_SMOG2LumiPassthrough',
+                       'Hlt2IFTFull_SMOG2CEPPassthrough', 'Hlt2IFTFull_SMOG2MBPassthrough', 
+    ]
+
+    hlt1lines_muon = [ "Hlt1SMOG2SingleMuonDecision", "Hlt1SMOG2DiMuonHighMassDecision",]
+    hlt1lines_BE = [ "Hlt1SMOG2BENoBiasDecision", "Hlt1SMOG2PassThroughLowMult5Decision", "Hlt1SMOG2BELowMultElectronsDecision" ]
+    hlt1lines_MB = [ "Hlt1SMOG2MinimumBiasDecision", "Hlt1PassthroughPVinSMOG2Decision" ]
+    
+    hlt1lines_track = [ "Hlt1SMOG2SingleTrackHighPtDecision", "Hlt1SMOG2SingleTrackVeryHighPtDecision", "Hlt1SMOG22BodyGenericDecision", "Hlt1SMOG22BodyGenericPromptDecision"]
+    hlt1lines_hadron = [ "Hlt1SMOG2etacToppDecision", "Hlt1SMOG2D2KpiDecision", ]
+    hlt1lines_longlived = [ "Hlt1SMOG2L0ToppiDecision", "Hlt1SMOG2KsTopipiDecision", ]
+    hlt1lines_pp = [ "Hlt1TrackMVADecision", "Hlt1TrackMuonMVADecision", "Hlt1TwoTrackMVADecision", "Hlt1VeloMicroBiasDecision",
+                     "Hlt1DiMuonHighMassDecision", "Hlt1D2KPiDecision","Hlt1SingleHighPtMuonDecision", 
+                     "Hlt1SingleHighPtMuonNoMuIDDecision", "Hlt1TrackMuonMVADecision", 
+    ]
+
+    hlt1lines = []
+    hlt1lines += hlt1lines_muon
+    hlt1lines += hlt1lines_BE
+    hlt1lines += hlt1lines_MB
+    hlt1lines += hlt1lines_track
+    hlt1lines += hlt1lines_hadron
+    hlt1lines += hlt1lines_longlived
+
+    Hlt1_decisions_SMOG2 = hlt1lines[:]
+
+    hlt1lines += hlt1lines_pp
+    Hlt1_decisions = hlt1lines
+    HLT2_TisTos = [ "Hlt2IFTTurbo_SMOG2Etac2ppbar", "Hlt2IFTFull_SMOG2LowDiMuon",
+                    "Hlt2IFTFull_SMOG2LowDiMuonSS", "Hlt2IFTFull_SMOG2Jpsi2MuMu",
+                    "Hlt2IFTFull_SMOG2Jpsi2MuMuSS"
+                    ]
+
+
+    v2_pvs      = get_pvs()
+    protons_etac = make_charm_protons_tight( bpvipchi2=None,
+                                             minPIDProton=15,
+                                             minPIDProtonKaon=7,
+                                             min_pt=900 * MeV,
+                                             min_p=15 * GeV,
+                                             max_trchi2dof=5
+                                            )
+    protons_etac_insmog2 = ParticleFilter( protons_etac, Cut=F.FILTER(F.require_all( bpv_in_smog2( get_pvs ) )) )
+
+    fields_proton = { "p": "[p+]CC" }
+
+    proton_variables = FunctorCollection({ 'ID': F.PARTICLE_ID, 'KEY': F.OBJECT_KEY, 'CHARGE': F.CHARGE, 
+                                           'PT': F.PT, 'PX': F.PX, 'PY': F.PY,'PZ': F.PZ,'ETA': F.ETA,'PHI': F.PHI,
+                                           'YSTAR':0.5*fmath.log( (F.ENERGY+F.PZ)/(F.ENERGY-F.PZ))-4.79,
+                                           'Y':0.5*fmath.log( (F.ENERGY+F.PZ)/(F.ENERGY-F.PZ)),
+                                           'MASS':F.MASS, 'ENERGY': F.ENERGY,'P': F.P,'FOURMOMENTUM': F.FOURMOMENTUM,
+                                           'CHI2': F.CHI2, 'CHI2DOF': F.CHI2DOF,
+                                           'B_PV_Z':F.BPVZ(v2_pvs),'B_PV_X':F.BPVX(v2_pvs),'B_PV_Y':F.BPVY(v2_pvs),
+                                           'BPVIP': F.BPVIP(v2_pvs),'BPVIPCHI2': F.BPVIPCHI2(v2_pvs),
+                                           'PIDE':F.PID_E, 'PIDK':F.PID_K, 'PIDMU':F.PID_MU, 'PIDP':F.PID_P, 'PIDPI':F.PID_PI,
+                                           'PROBNNE':F.PROBNN_E, 'PROBNNK':F.PROBNN_K, 'PROBNNMU':F.PROBNN_MU, 'PROBNNP':F.PROBNN_P, 'PROBNNPI':F.PROBNN_PI,
+                                           'PROBNNGHOST':F.PROBNN_GHOST, 'PROBNND':F.PROBNN_D, 'GHOSTPROB':F.GHOSTPROB, 'ISMUON':F.ISMUON,
+                                           'IS_NOT_H': F.IS_NOT_H, 'IS_PHOTON': F.IS_PHOTON,
+                                           'TRACK_NVPHITS':F.VALUE_OR(-1) @ F.NVPHITS @ F.TRACK,
+                                           'TRACK_NFTHITS':F.VALUE_OR(-1) @ F.NFTHITS @ F.TRACK,
+                                           'TRACK_NUTHITS':F.VALUE_OR(-1) @ F.NUTHITS @ F.TRACK,
+                                           #'TRACK_INECAL':F.INECAL @ F.TRACK, 'TRACK_INHCAL':F.INHCAL @ F.TRACK, 'TRACK_INMUON':F.INMUON @ F.TRACK,
+                                           "TRACK_POS_CLOSESTTOBEAM_X"        : F.POSITION_X @ F.STATE_AT("ClosestToBeam")   @ F.TRACK,
+                                           "TRACK_POS_CLOSESTTOBEAM_Y"        : F.POSITION_Y @ F.STATE_AT("ClosestToBeam")   @ F.TRACK,
+                                           "TRACK_POS_CLOSESTTOBEAM_Z"        : F.POSITION_Z @ F.STATE_AT("ClosestToBeam")   @ F.TRACK,
+                                           'nBestPVTracks':    F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.SIZE_OF @ F.PVTRACKS @ F.BPV(v2_pvs),
+                                           'nBestPVbackTracks':    F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.COUNT_IF( F.TRACKISVELOBACKWARD ) @ F.PVTRACKS @ F.BPV(v2_pvs),
+                                        })
+
+
+    fields_pi0= {"pi0CalCal": { "pi0": 'pi0 -> gamma gamma',
+                            "calphoton1": 'pi0 -> ^gamma gamma',
+                            "calphoton2": 'pi0 -> gamma ^gamma'},
+                 "pi0CovCalLL":{  "pi0": 'pi0 -> ( gamma -> e+ e- )  gamma',
+                                 "calphoton": 'pi0 -> ( gamma -> e+ e- )  ^gamma',
+                                 "covphoton": 'pi0 -> ^( gamma -> e+ e- )  gamma',
+                                 "ep": 'pi0 -> ( gamma -> ^e+ e- )  gamma',
+                                 "em": 'pi0 -> ( gamma -> e+ ^e- )  gamma'},
+                 "pi0CovCalDD":{ "pi0": 'pi0 -> ( gamma -> e+ e- )  gamma',
+                                 "calphoton": 'pi0 -> ( gamma -> e+ e- )  ^gamma',
+                                 "covphoton": 'pi0 -> ^( gamma -> e+ e- )  gamma',
+                                 "ep": 'pi0 -> ( gamma -> ^e+ e- )  gamma',
+                                 "em": 'pi0 -> ( gamma -> e+ ^e- )  gamma'},
+            }
+
+    
+    rec_summary = get_rec_summary()
+    
+    evt_vars = FunctorCollection(
+        {   "FILLNUMBER":   F.VALUE_OR(-1) @ F.FILL_NUMBER,
+            "nLongTracks":  F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nLongTracks"),
+            'nUpTracks':    F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nUpstreamTracks"),
+            'nDownTracks':  F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nDownstreamTracks"),
+            'nBackTracks':  F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nBackTracks"),
+            "nVeloTracks":  F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nVeloTracks"),
+            "nMuonTracks":  F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nMuonTracks"),
+
+            "nVPClusters":  F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nVPClusters"),
+            "nFTClusters":  F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nFTClusters"),
+            "nRich1Hits":   F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nRich1Hits"),
+            "nRich2Hits":   F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nRich2Hits"),
+            "ECalETot":     F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "eCalTot"),
+            "HCalETot":     F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "hCalTot"),
+            "nEcalClusters":F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nEcalClusters"),
+            "nPVs":         F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nPVs"),
+
+            "nVeloClusters":F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nVeloClusters"),
+            "nMuonCoordsS0":F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nMuonCoordsS0"),
+            "nMuonCoordsS1":F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nMuonCoordsS1"),
+            "nMuonCoordsS2":F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nMuonCoordsS2"),
+            "nMuonCoordsS3":F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nMuonCoordsS3"),
+            "nMuonCoordsS4":F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nMuonCoordsS4"),
+
+            "PVZ[nPV]":          F.VALUE_OR(-1) @ F.ALLPVZ(v2_pvs),            
+            "PVX[nPV]":          F.VALUE_OR(-1) @ F.ALLPVX(v2_pvs),
+            "PVY[nPV]":          F.VALUE_OR(-1) @ F.ALLPVY(v2_pvs),
+            "ALLPVX_ERR[nPV]":F.MAP(F.SQRT @ F.CALL(0, 0) @ F.POS_COV_MATRIX) @ F.TES(v2_pvs),
+            "ALLPVY_ERR[nPV]":F.MAP(F.SQRT @ F.CALL(1, 1) @ F.POS_COV_MATRIX) @ F.TES(v2_pvs),
+            "ALLPVZ_ERR[nPV]":F.MAP(F.SQRT @ F.CALL(2, 2) @ F.POS_COV_MATRIX) @ F.TES(v2_pvs),
+            "PVCHI2NDOF[nPV]":      F.VALUE_OR(-1) @ F.MAP( F.CHI2DOF ) @ F.TES(v2_pvs),
+            "PVCHI2[nPV]":          F.VALUE_OR(-1) @ F.MAP( F.CHI2 ) @ F.TES(v2_pvs),
+            "PVNDOF[nPV]":          F.VALUE_OR(-1) @ F.MAP( F.NDOF ) @ F.TES(v2_pvs),
+            'nPVTracks[nPV]':    F.VALUE_OR(-1) @ F.MAP( F.CAST_TO_INT @ F.SIZE_OF @ F.PVTRACKS ) @ F.TES(v2_pvs),
+            'nPVbackTracks[nPV]':F.VALUE_OR(-1) @ F.MAP( F.CAST_TO_INT @ F.COUNT_IF( F.TRACKISVELOBACKWARD ) @ F.PVTRACKS ) @ F.TES(v2_pvs),           
+        }
+    )
+
+    evt_tracks_var = FunctorCollection({
+            "VELOTRACK_CHARGE[VELOTRACK]":F.VALUE_OR(-1) @ F.MAP( F.CHARGE ) @ F.TES( velo_tracks ),
+            "VELOTRACK_PX[VELOTRACK]":F.VALUE_OR(-1) @ F.MAP( F.X_COORDINATE @ F.FOURMOMENTUM ) @ F.TES( velo_tracks ),
+            "VELOTRACK_PY[VELOTRACK]":F.VALUE_OR(-1) @ F.MAP( F.Y_COORDINATE @ F.FOURMOMENTUM ) @ F.TES( velo_tracks ),
+            "VELOTRACK_PZ[VELOTRACK]":F.VALUE_OR(-1) @ F.MAP( F.Z_COORDINATE @ F.FOURMOMENTUM ) @ F.TES( velo_tracks ),
+            
+            "VELOTRACK_RHO[VELOTRACK]":F.VALUE_OR(-1) @ F.MAP( F.RHO_COORDINATE @ F.FOURMOMENTUM ) @ F.TES( velo_tracks ),
+            "VELOTRACK_ETA[VELOTRACK]":F.VALUE_OR(-1) @ F.MAP( F.ETA ) @ F.TES( velo_tracks ),
+            "VELOTRACK_PHI[VELOTRACK]":F.VALUE_OR(-1) @ F.MAP( F.PHI ) @ F.TES( velo_tracks ),
+            "VELOTRACK_ISBACKWARD[VELOTRACK]":F.VALUE_OR(-1) @ F.MAP( F.TRACKISVELOBACKWARD ) @ F.TES( velo_tracks ),
+            #'VELOTRACK_POS_CLOSESTTOBEAM_X[VELOTRACK]': F.MAP( F.TRACK_POS_CLOSESTTOBEAM_X ) @ F.TES( velo_tracks ),
+            #'VELOTRACK_POS_CLOSESTTOBEAM_Y[VELOTRACK]': F.MAP( F.TRACK_POS_CLOSESTTOBEAM_Y ) @ F.TES( velo_tracks ),
+            #'VELOTRACK_POS_CLOSESTTOBEAM_Z[VELOTRACK]': F.MAP( F.TRACK_POS_CLOSESTTOBEAM_Z ) @ F.TES( velo_tracks ),
+            'VELOTRACK_NVPHITS[VELOTRACK]':F.VALUE_OR(-1) @  F.MAP( F.NVPHITS ) @ F.TES( velo_tracks ),
+            'VELOTRACK_CHI2[VELOTRACK]': F.VALUE_OR(-1) @  F.MAP( F.CHI2 ) @ F.TES( velo_tracks ),
+            'VELOTRACK_CHI2DOF[VELOTRACK]': F.VALUE_OR(-1) @  F.MAP( F.CHI2DOF ) @ F.TES( velo_tracks ), 
+            'VELOTRACK_NDOF[VELOTRACK]': F.VALUE_OR(-1) @  F.MAP( F.NDOF ) @ F.TES( velo_tracks ),
+            "VELOTRACK_KEY[VELOTRACK]": F.VALUE_OR(-1) @  F.MAP( F.OBJECT_KEY ) @ F.TES( velo_tracks ),
+            "VELOTRACK_GHOSTPROB[LONGTRACK]":F.VALUE_OR(-1) @ F.MAP( F.GHOSTPROB ) @ F.TES( velo_tracks ),
+
+            "LONGTRACK_CHARGE[LONGTRACK]":F.VALUE_OR(-1) @ F.MAP( F.CHARGE ) @ F.TES( long_tracks ),
+            "LONGTRACK_PX[LONGTRACK]":F.VALUE_OR(-1) @ F.MAP( F.X_COORDINATE @ F.FOURMOMENTUM ) @ F.TES( long_tracks ),
+            "LONGTRACK_PY[LONGTRACK]":F.VALUE_OR(-1) @ F.MAP( F.Y_COORDINATE @ F.FOURMOMENTUM ) @ F.TES( long_tracks ),
+            "LONGTRACK_PZ[LONGTRACK]":F.VALUE_OR(-1) @ F.MAP( F.Z_COORDINATE @ F.FOURMOMENTUM ) @ F.TES( long_tracks ),
+            "LONGTRACK_RHO[LONGTRACK]":F.VALUE_OR(-1) @ F.MAP( F.RHO_COORDINATE @ F.FOURMOMENTUM ) @ F.TES( long_tracks ),
+            "LONGTRACK_ETA[LONGTRACK]":F.VALUE_OR(-1) @ F.MAP( F.ETA ) @ F.TES( long_tracks ),
+            "LONGTRACK_PHI[LONGTRACK]":F.VALUE_OR(-1) @ F.MAP( F.PHI ) @ F.TES( long_tracks ),
+            "LONGTRACK_P[LONGTRACK]":F.VALUE_OR(-1) @ F.MAP( F.P ) @ F.TES( long_tracks ),
+            "LONGTRACK_PT[LONGTRACK]":F.VALUE_OR(-1) @ F.MAP( F.PT ) @ F.TES( long_tracks ),
+            "LONGTRACK_GHOSTPROB[LONGTRACK]":F.VALUE_OR(-1) @ F.MAP( F.GHOSTPROB ) @ F.TES( long_tracks ),
+            #'LONGTRACK_POS_CLOSESTTOBEAM_X[LONGTRACK]': F.MAP( F.TRACK_POS_CLOSESTTOBEAM_X ) @ F.TES( long_tracks ),
+            #'LONGTRACK_POS_CLOSESTTOBEAM_Y[LONGTRACK]': F.MAP( F.TRACK_POS_CLOSESTTOBEAM_Y ) @ F.TES( long_tracks ),
+            #'LONGTRACK_POS_CLOSESTTOBEAM_Z[LONGTRACK]': F.MAP( F.TRACK_POS_CLOSESTTOBEAM_Z ) @ F.TES( long_tracks ),
+            'LONGTRACK_NVPHITS[LONGTRACK]':F.VALUE_OR(-1) @  F.MAP( F.NVPHITS ) @ F.TES( long_tracks ),
+            'LONGTRACK_NFTHITS[LONGTRACK]':F.VALUE_OR(-1) @  F.MAP( F.NFTHITS ) @ F.TES( long_tracks ),
+            'LONGTRACK_NUTHITS[LONGTRACK]':F.VALUE_OR(-1) @  F.MAP( F.NUTHITS ) @ F.TES( long_tracks ),
+            'LONGTRACK_CHI2[LONGTRACK]': F.VALUE_OR(-1) @  F.MAP( F.CHI2 ) @ F.TES( long_tracks ),
+            'LONGTRACK_CHI2DOF[LONGTRACK]': F.VALUE_OR(-1) @  F.MAP( F.CHI2DOF ) @ F.TES( long_tracks ), 
+            'LONGTRACK_NDOF[LONGTRACK]': F.VALUE_OR(-1) @  F.MAP( F.NDOF ) @ F.TES( long_tracks ),
+            "LONGTRACK_KEY[LONGTRACK]": F.VALUE_OR(-1) @  F.MAP( F.OBJECT_KEY ) @ F.TES( long_tracks ),
+        }
+    )
+
+    my_HLT1_filter = create_lines_filter(name="HDRFilter_HLT1", lines=Hlt1_decisions_SMOG2)
+    my_HLT2_filter = create_lines_filter(name="HDRFilter_HLT2", lines=Hlt2_decisions)
+    my_Spruce_filter = create_lines_filter(name="HDRFilter_Spruce", lines=Spruce_decisions)
+
+    evt_vars += FC.EventInfo()
+    evt_vars += FC.SMOGInfo()
+    evt_vars += FC.SelectionInfo( selection_type="Hlt1", trigger_lines=Hlt1_decisions ) # hlt1 trigger decisions
+    evt_vars += FC.SelectionInfo( selection_type="Hlt2", trigger_lines=Hlt2_decisions ) # hlt2 trigger decisions
+    evt_vars += FC.SelectionInfo( selection_type="Spruce", trigger_lines=Spruce_decisions ) # Spruces trigger decisions
+
+    evt_vars_pv = evt_vars
+
+    var_ip = FunctorCollection(
+        {"VELOTRACK_BIP[VELOTRACK]":F.VALUE_OR(-1) @ F.MAP( F.BPVIP(v2_pvs) ) @ F.TES( velo_tracks ),
+         "VELOTRACK_BIPCHI2[VELOTRACK]":F.VALUE_OR(-1) @ F.MAP( F.BPVIPCHI2(v2_pvs) ) @ F.TES( velo_tracks ),
+         "VELOTRACK_B_PV_Z[VELOTRACK]":F.VALUE_OR(-1) @ F.MAP( F.BPVZ(v2_pvs) ) @ F.TES( velo_tracks ),
+         "VELOTRACK_B_PV_Y[VELOTRACK]":F.VALUE_OR(-1) @ F.MAP( F.BPVY(v2_pvs) ) @ F.TES( velo_tracks ),
+         "VELOTRACK_B_PV_X[VELOTRACK]":F.VALUE_OR(-1) @ F.MAP( F.BPVX(v2_pvs) ) @ F.TES( velo_tracks ),
+
+         "LONGTRACK_BIP[LONGTRACK]":F.VALUE_OR(-1) @ F.MAP( F.BPVIP(v2_pvs) ) @ F.TES( long_tracks ),
+         "LONGTRACK_BIPCHI2[LONGTRACK]":F.VALUE_OR(-1) @ F.MAP( F.BPVIPCHI2(v2_pvs) ) @ F.TES( long_tracks ),
+         "LONGTRACK_B_PV_Z[LONGTRACK]":F.VALUE_OR(-1) @ F.MAP( F.BPVZ(v2_pvs) ) @ F.TES( long_tracks ),
+         "LONGTRACK_B_PV_Y[LONGTRACK]":F.VALUE_OR(-1) @ F.MAP( F.BPVY(v2_pvs) ) @ F.TES( long_tracks ),
+         "LONGTRACK_B_PV_X[LONGTRACK]":F.VALUE_OR(-1) @ F.MAP( F.BPVX(v2_pvs) ) @ F.TES( long_tracks ),
+        }
+    )
+    evt_vars_pv += var_ip+evt_tracks_var
+    my_event_tuple = FunTuple_Event(name="EventTuple", tuple_name="EventTuple", variables=evt_vars+evt_tracks_var )
+    my_event_tuple_PV = FunTuple_Event(name="EventTuplePV", tuple_name="EventTuplePV", variables=evt_vars_pv+evt_tracks_var )
+
+    my_tuple_proton = FunTuple(
+        name="protons_etac",
+        inputs=protons_etac_insmog2,
+        tuple_name="DecayTreeProton",
+        fields=fields_proton,
+        variables={"ALL":proton_variables},
+        event_variables=evt_vars,
+        store_multiple_cand_info=True,
+        )
+    
+    algs = { "EventTuple":[ my_HLT1_filter, my_HLT2_filter, my_Spruce_filter, my_event_tuple ],
+             "EventTuplePV":[ require_pvs(v2_pvs), my_HLT1_filter, my_HLT2_filter, my_Spruce_filter, my_event_tuple_PV ],
+             "ProtonEtacTuple":[ require_pvs(v2_pvs), my_HLT1_filter, my_HLT2_filter, my_Spruce_filter, my_tuple_proton ],
+             }
+
+    # add pi0 tuples
+    variables_pi0, my_tuples_pi0, datapi0, count_variables = {},{},{},{}
+    for field in fields_pi0:
+        variables_pi0[field] = {}
+        calo_photon = make_photons(make_neutral_protoparticles=get_neutral_protoparticles, pv_maker=get_pvs)
+        calo_photon_filtered = ParticleFilter(calo_photon, Cut=F.FILTER(F.require_all(F.PT > 200.)))
+        if field=="pi0CalCal":
+            datapi0[field] = ParticleCombiner(
+                 Inputs = [calo_photon_filtered, calo_photon_filtered],
+                 DecayDescriptor="pi0 -> gamma gamma",
+                 CombinationCut=F.require_all(in_range(0, F.MASS, 600)),
+                 CompositeCut=F.require_all(in_range(0, F.MASS, 600)),
+                 name="name_pi0CalCal",
+                 ParticleCombiner="ParticleAdder",
+                 )
+            count_variables[field] = count_evt_variables(options, datapi0[field], photoncal_loc=calo_photon_filtered )
+        elif field=="pi0CovCalLL":
+            convLL_photon = make_gamma2ee_LL()
+            convLL_photon_filtered = ParticleFilter(convLL_photon, Cut=F.FILTER(F.require_all(F.PT > 200., bpv_in_smog2( get_pvs ))) )
+
+            datapi0[field] = ParticleCombiner(
+                [calo_photon_filtered, convLL_photon_filtered],
+                DecayDescriptor="pi0 -> gamma gamma",
+                CombinationCut=F.require_all(in_range(0, F.MASS, 600)),
+                name="name_pi0CovCalLL", 
+                AllowDiffInputsForSameIDChildren = True,
+                ParticleCombiner="ParticleAdder",
+                )
+            count_variables[field] = count_evt_variables(options, datapi0[field], photoncal_loc=calo_photon_filtered, photonconvLL_loc=convLL_photon_filtered )
+        elif field=="pi0CovCalDD":
+            convDD_photon = make_gamma2ee_DD()
+            convDD_photon_filtered = ParticleFilter(convDD_photon, Cut=F.FILTER(F.require_all(F.PT > 200.)))
+
+            datapi0[field] = ParticleCombiner(
+                [calo_photon_filtered, convDD_photon_filtered],
+                DecayDescriptor="pi0 -> gamma gamma",
+                CombinationCut=F.require_all(in_range(0, F.MASS, 600)),
+                name="name_pi0CovCalDD", 
+                AllowDiffInputsForSameIDChildren = True, 
+                ParticleCombiner="ParticleAdder",
+                )
+            count_variables[field] = count_evt_variables(options, datapi0[field], photoncal_loc=calo_photon_filtered, photonconvDD_loc=convDD_photon_filtered )
+        TisTos_variables_HLT1 = FC.HltTisTos( selection_type="Hlt1", trigger_lines=Hlt1_decisions, data=datapi0[field] )
+        #TisTos_variables_HLT2 = FC.HltTisTos( selection_type="Hlt2", trigger_lines=HLT2_TisTos, data=datapi0[field] )
+
+        composite_variables = make_composite_variables(options, datapi0[field])
+        composite_variables_nopv = make_composite_variables(options, datapi0[field], pv=False)
+        basic_variables_nopv = make_basic_variables(options, datapi0[field], pv=False)
+        basic_variables = make_basic_variables(options, datapi0[field])
+        track_variables = make_track_variables(options, datapi0[field])
+        calo_variables = make_calo_variables(options, datapi0[field])
+        charged_variables = make_charged_calo_variables(options, datapi0[field])
+        
+        if field=="pi0CalCal":        
+            variables_pi0[field]['ALL'] = basic_variables_nopv+TisTos_variables_HLT1 # + TisTos_variables_HLT2
+            variables_pi0[field]['pi0'] = basic_variables_nopv+composite_variables_nopv
+
+            variables_pi0[field]['calphoton1'] = basic_variables+calo_variables
+            variables_pi0[field]['calphoton2'] = basic_variables+calo_variables            
+                
+        elif field in ["pi0CovCalLL", "pi0CovCalDD"]:
+            variables_pi0[field]['ALL'] = basic_variables + TisTos_variables_HLT1 # + TisTos_variables_HLT2
+            variables_pi0[field]['pi0'] = basic_variables_nopv+composite_variables_nopv
+
+            variables_pi0[field]['calphoton'] = basic_variables+calo_variables
+            variables_pi0[field]['covphoton'] = calo_variables+basic_variables+composite_variables
+            variables_pi0[field]['ep'] = charged_variables+track_variables+basic_variables
+            variables_pi0[field]['em'] = charged_variables+track_variables+basic_variables
+
+        my_tuples_pi0[field] = FunTuple( name=f'{field}',
+                                         inputs=datapi0[field],
+                                         tuple_name="DecayTree",
+                                         fields=fields_pi0[field],
+                                         variables=variables_pi0[field],
+                                         event_variables=evt_vars+count_variables[field], 
+                                         store_multiple_cand_info=True,
+                                         )
+        algs[field] = [ require_pvs(v2_pvs), my_HLT1_filter, my_HLT2_filter, my_Spruce_filter, my_tuples_pi0[field] ]
+
+    return make_config( options, algs )
\ No newline at end of file
diff --git a/ift_spruce_validation/full-Excl-UT_SMOG2_val_tuple.py b/ift_spruce_validation/full-Excl-UT_SMOG2_val_tuple.py
new file mode 100644
index 0000000000000000000000000000000000000000..27f473a1c4dd0fd7412ae8c93e911b80f79b8c6d
--- /dev/null
+++ b/ift_spruce_validation/full-Excl-UT_SMOG2_val_tuple.py
@@ -0,0 +1,326 @@
+from DaVinci import Options, make_config
+from DaVinci.algorithms import create_lines_filter
+from PyConf.reading import get_particles, get_pvs, get_rec_summary
+
+import Functors as F
+from FunTuple import FunctorCollection 
+import FunTuple.functorcollections as FC
+from FunTuple import FunTuple_Particles as Funtuple
+
+import Functors.math as fmath
+
+import sys
+
+def main(options: Options):
+
+    full_line_list = [  'SpruceIFT_SMOG2KS2PiPiLL',
+                        'SpruceIFT_SMOG2Lambda02PPiLL',
+                        'SpruceIFT_SMOG2Phi2kk',
+                        'SpruceIFT_SMOG2D02KPi', 
+                        'SpruceIFT_SMOG2Dpm2kpipi',
+                        'SpruceIFT_SMOG2DsToKKPi',
+                        'SpruceIFT_SMOG2LcTopKPi',
+                        'SpruceIFT_SMOG2SingleTrackHighPT',
+                        'SpruceIFT_SMOG2LowDiMuon',
+                        'SpruceIFT_SMOG2LowDiMuonSS',
+                        'SpruceIFT_SMOG2Jpsi2MuMu',
+                        'SpruceIFT_SMOG2Jpsi2MuMuSS',
+                        'SpruceIFT_SMOG2Xi2Lambda0pi_lll',
+                        'SpruceIFT_SMOG2Omega2Lambda0K_lll',
+                        'SpruceIFT_SMOG2DY2MuMuExcludeCCBarLow',
+                        'SpruceIFT_SMOG2DY2MuMuExcludeCCBarHigh',
+                        'SpruceIFT_5GeVIsolatedGamma',
+                        'SpruceIFT_10GeVIsolatedGamma',
+                        'SpruceIFT_20GeVIsolatedGamma'
+                    ]
+
+    lines_intermediate_daughters = ['SpruceIFT_SMOG2Xi2Lambda0pi_lll', 'SpruceIFT_SMOG2Omega2Lambda0K_lll']
+
+    lines_nocomposite = ['SpruceIFT_SMOG2SingleTrackHighPT', 'SpruceIFT_5GeVIsolatedGamma', 'SpruceIFT_10GeVIsolatedGamma', 'SpruceIFT_20GeVIsolatedGamma']
+
+    Hlt2_TISTOS = [
+        "Hlt2IFTFull_SMOG2LowDiMuon",
+        "Hlt2IFTFull_SMOG2LowDiMuonSS",
+        "Hlt2IFTFull_SMOG2Jpsi2MuMu",
+        "Hlt2IFTFull_SMOG2Jpsi2MuMuSS"
+        ]
+
+    parts = { 'SpruceIFT_SMOG2KS2PiPiLL':["KS0","pip", "pim"], 
+              'SpruceIFT_SMOG2Lambda02PPiLL':["Lambda", "pbar", "pim"],
+              'SpruceIFT_SMOG2Phi2kk':["Phi", "kp", "km"],
+              'SpruceIFT_SMOG2D02KPi':["D0", "km", "pip" ],
+              'SpruceIFT_SMOG2Dpm2kpipi':["Dp", "km", "pip", "pip2"],
+              'SpruceIFT_SMOG2DsToKKPi':["Ds", "km", "kp", "pip"],
+              'SpruceIFT_SMOG2LcTopKPi':["Lc", "pbar", "km","pip"],
+              'SpruceIFT_SMOG2SingleTrackHighPT':["pi"],
+              'SpruceIFT_SMOG2LowDiMuon':["Jpsi", "mup", "mum"],
+              'SpruceIFT_SMOG2LowDiMuonSS':["Jpsi", "mu1", "mu2"],
+              'SpruceIFT_SMOG2Jpsi2MuMu':["Jpsi", "mup", "mum"],
+              'SpruceIFT_SMOG2Jpsi2MuMuSS':["Jpsi", "mu1", "mu2"],
+              'SpruceIFT_SMOG2Xi2Lambda0pi_lll':[ "Xim", "Lambda", "pbar", "Lambda_pim", "Xi_pim"],
+              'SpruceIFT_SMOG2Omega2Lambda0K_lll':["Omegam", "Lambda", "pbar", "pim", "km"],
+              'SpruceIFT_SMOG2DY2MuMuExcludeCCBarLow':["Jpsi", "mup", "mum"],
+              'SpruceIFT_SMOG2DY2MuMuExcludeCCBarHigh':["Jpsi", "mup", "mum"],
+              'SpruceIFT_5GeVIsolatedGamma': ["gamma"],
+              'SpruceIFT_10GeVIsolatedGamma': ["gamma"],
+              'SpruceIFT_20GeVIsolatedGamma': ["gamma"],
+            }
+
+    hlt1lines_muon = [ "Hlt1SMOG2SingleMuonDecision", "Hlt1SMOG2DiMuonHighMassDecision"]
+    hlt1lines_BE = [ "Hlt1SMOG2BENoBiasDecision", "Hlt1SMOG2PassThroughLowMult5Decision", "Hlt1SMOG2BELowMultElectronsDecision"]
+    hlt1lines_MB = [ "Hlt1SMOG2MinimumBiasDecision", "Hlt1PassthroughPVinSMOG2Decision"]
+        
+    hlt1lines_track = [ "Hlt1SMOG2SingleTrackHighPtDecision", "Hlt1SMOG2SingleTrackVeryHighPtDecision", "Hlt1SMOG22BodyGenericDecision", "Hlt1SMOG22BodyGenericPromptDecision"]
+    hlt1lines_hadron = [ "Hlt1SMOG2etacToppDecision", "Hlt1SMOG2D2KpiDecision"]
+    hlt1lines_longlived = [ "Hlt1SMOG2L0ToppiDecision", "Hlt1SMOG2KsTopipiDecision"]
+    hlt1lines_pp = [ "Hlt1TrackMVADecision", "Hlt1TrackMuonMVADecision", "Hlt1TwoTrackMVADecision"]
+
+    hlt1lines = []
+    hlt1lines += hlt1lines_muon
+    hlt1lines += hlt1lines_BE
+    hlt1lines += hlt1lines_MB
+    hlt1lines += hlt1lines_track
+    hlt1lines += hlt1lines_hadron
+    hlt1lines += hlt1lines_longlived
+    hlt1lines += hlt1lines_pp
+    Hlt1_decisions = hlt1lines
+
+    names = { "SpruceIFT_SMOG2KS2PiPiLL":"Ks0pipi",
+              "SpruceIFT_SMOG2Lambda02PPiLL":"Lambdappi",
+              "SpruceIFT_SMOG2Phi2kk":"Phi2kk",
+              'SpruceIFT_SMOG2D02KPi':"D02KPi",
+              'SpruceIFT_SMOG2Dpm2kpipi': "Dpm2Kpipi",
+              'SpruceIFT_SMOG2DsToKKPi': "Ds2KKpi",
+              'SpruceIFT_SMOG2LcTopKPi':"Lc2pkpi",
+              'SpruceIFT_SMOG2SingleTrackHighPT': 'SingleTrackHighPT',
+              'SpruceIFT_SMOG2LowDiMuon': 'LowDiMuon', 
+              'SpruceIFT_SMOG2LowDiMuonSS': 'LowDiMuonSS',
+              'SpruceIFT_SMOG2Jpsi2MuMu':"Jpsi2MuMu",
+              'SpruceIFT_SMOG2Jpsi2MuMuSS':"Jpsi2MuMuSS",
+              'SpruceIFT_SMOG2DY2MuMuExcludeCCBarLow':"qq2MuMulow",
+              'SpruceIFT_SMOG2DY2MuMuExcludeCCBarHigh':"qq2MuMuhigh",
+              'SpruceIFT_SMOG2Xi2Lambda0pi_lll':"Xi2Lambdaplll",
+              'SpruceIFT_SMOG2Omega2Lambda0K_lll':"Omega2LambdaKlll",
+              'SpruceIFT_5GeVIsolatedGamma': "5GeVGamma",
+              'SpruceIFT_10GeVIsolatedGamma': "10GeVGamma",
+              'SpruceIFT_20GeVIsolatedGamma': "20GeVGamma"
+              }
+
+    fields = { 'SpruceIFT_SMOG2KS2PiPiLL':{"KS0": "KS0 -> pi+ pi-",
+                                           "pip": "KS0 ->^pi+ pi-",
+                                           "pim": "KS0 -> pi+ ^pi-",
+                },
+               'SpruceIFT_SMOG2Lambda02PPiLL':{"Lambda": "[Lambda0 -> p+ pi-]CC",
+                                               "pbar": "[Lambda0 -> ^p+ pi-]CC",
+                                               "pim": "[Lambda0 -> p+ ^pi-]CC",
+                },
+               'SpruceIFT_SMOG2Phi2kk':{"Phi":'phi(1020) -> K+ K-', 
+                                        "kp":'phi(1020) -> ^K+ K-',
+                                        "km":'phi(1020) -> K+ ^K-',
+                },
+               'SpruceIFT_SMOG2D02KPi':{"D0":'[ D0 -> K- pi+ ]CC', 
+                                        "km":'[ D0 -> ^K- pi+ ]CC', 
+                                        "pip":'[ D0 -> K- ^pi+ ]CC',  
+                },
+               'SpruceIFT_SMOG2Dpm2kpipi':{"Dp": '[D+ -> K- pi+ pi+]CC',
+                                           "km": '[D+ -> ^K- pi+ pi+]CC',
+                                           "pip": '[D+ -> K- ^pi+ pi+]CC',
+                                           "pip2": '[D+ -> K- pi+ ^pi+]CC', 
+                },
+               'SpruceIFT_SMOG2DsToKKPi':{"Ds": "[D_s+ -> K- K+ pi+]CC",
+                                          "km": "[D_s+ -> ^K- K+ pi+]CC",
+                                          "kp": "[D_s+ -> K- ^K+ pi+]CC",
+                                          "pip": "[D_s+ -> K- K+ ^pi+]CC",
+               },
+               'SpruceIFT_SMOG2LcTopKPi':{"Lc": "[Lambda_c+ -> p+ K- pi+]CC",
+                                            "pbar": "[Lambda_c+ -> ^p+ K- pi+]CC",
+                                            "km": "[Lambda_c+ -> p+ ^K- pi+]CC",
+                                            "pip": "[Lambda_c+ -> p+ K- ^pi+]CC",
+               },
+               'SpruceIFT_SMOG2SingleTrackHighPT':{"pi": "[pi+]CC"},
+               'SpruceIFT_SMOG2LowDiMuon':{"Jpsi":'J/psi(1S) -> mu- mu+',
+                                           "mum":'J/psi(1S) -> ^mu- mu+',
+                                           "mup":'J/psi(1S) -> mu- ^mu+',                       
+               },
+               'SpruceIFT_SMOG2LowDiMuonSS':{"Jpsi":'[J/psi(1S) -> mu+ mu+]CC',
+                                           "mu1":'[J/psi(1S) -> ^mu+ mu+]CC',
+                                           "mu2":'[J/psi(1S) -> mu+ ^mu+]CC',                       
+               },
+               'SpruceIFT_SMOG2Jpsi2MuMu':{"Jpsi":'J/psi(1S) -> mu- mu+',
+                                           "mum":'J/psi(1S) -> ^mu- mu+',
+                                           "mup":'J/psi(1S) -> mu- ^mu+',                       
+               },
+               'SpruceIFT_SMOG2Jpsi2MuMuSS':{"Jpsi":'[J/psi(1S) -> mu+ mu+]CC',
+                                           "mu1":'[J/psi(1S) -> ^mu+ mu+]CC',
+                                           "mu2":'[J/psi(1S) -> mu+ ^mu+]CC',                       
+               },
+               'SpruceIFT_SMOG2DY2MuMuExcludeCCBarLow':{ "Jpsi":'J/psi(1S) -> mu- mu+',
+                                                         "mum":'J/psi(1S) -> ^mu- mu+',
+                                                         "mup":'J/psi(1S) -> mu- ^mu+',                       
+               },
+               'SpruceIFT_SMOG2DY2MuMuExcludeCCBarHigh':{ "Jpsi":'J/psi(1S) -> mu- mu+',
+                                                          "mum":'J/psi(1S) -> ^mu- mu+',
+                                                          "mup":'J/psi(1S) -> mu- ^mu+',                       
+               },
+               'SpruceIFT_SMOG2Xi2Lambda0pi_lll':{"Xim":"[Xi- -> (Lambda0 -> p+ pi-) pi-]CC",
+                                                  "Lambda":"[Xi- -> ^(Lambda0 -> p+ pi-) pi-]CC",
+                                                  "pbar":"[Xi- -> (Lambda0 -> ^p+ pi-) pi-]CC",
+                                                  "Lambda_pim":"[Xi- -> (Lambda0 -> p+ ^pi-) pi-]CC",
+                                                  "Xi_pim":"[Xi- -> (Lambda0 -> p+ pi-) ^pi-]CC",
+               },
+               'SpruceIFT_SMOG2Omega2Lambda0K_lll':{"Omegam": "[Omega- -> (Lambda0 -> p+ pi-) K-]CC",
+                                                    "Lambda": "[Omega- -> ^(Lambda0 -> p+ pi-) K-]CC",
+                                                    "pbar": "[Omega- -> (Lambda0 -> ^p+ pi-) K-]CC",
+                                                    "pim": "[Omega- -> (Lambda0 -> p+ ^pi-) K-]CC",
+                                                    "km": "[Omega- -> (Lambda0 -> p+ pi-) ^K-]CC", 
+               },
+              'SpruceIFT_5GeVIsolatedGamma': {"gamma": "gamma"},
+              'SpruceIFT_10GeVIsolatedGamma': {"gamma": "gamma"},
+              'SpruceIFT_20GeVIsolatedGamma': {"gamma": "gamma"}
+    }
+
+
+    v2_pvs      = get_pvs()
+    rec_summary = get_rec_summary()
+    all_variables = FunctorCollection({ 'ID': F.PARTICLE_ID, 
+                                        'KEY': F.OBJECT_KEY, 
+                                        'CHARGE': F.CHARGE, 
+                                        'PT': F.PT, 
+                                        'PX': F.PX, 
+                                        'PY': F.PY,
+                                        'PZ': F.PZ,
+                                        'ETA': F.ETA,
+                                        'PHI': F.PHI,
+                                        'YSTAR':0.5*fmath.log( (F.ENERGY+F.PZ)/(F.ENERGY-F.PZ))-4.79,
+                                        'Y':0.5*fmath.log( (F.ENERGY+F.PZ)/(F.ENERGY-F.PZ)),
+                                        'MASS':F.MASS, 
+                                        'ENERGY': F.ENERGY,
+                                        'P': F.P,
+                                        'FOURMOMENTUM': F.FOURMOMENTUM,
+                                        'CHI2': F.CHI2, 
+                                        'CHI2DOF': F.CHI2DOF,
+                                        'B_PV_Z':F.BPVZ(v2_pvs),
+                                        'B_PV_X':F.BPVX(v2_pvs),
+                                        'B_PV_Y':F.BPVY(v2_pvs),
+                                        'BPVIP': F.BPVIP(v2_pvs),
+                                        'BPVIPCHI2': F.BPVIPCHI2(v2_pvs),
+                                        ### BestPVnTracks
+                                        'nBestPVTracks':    F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.SIZE_OF @ F.PVTRACKS @ F.BPV(v2_pvs),
+                                        'nBestPVbackTracks':    F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.COUNT_IF( F.TRACKISVELOBACKWARD ) @ F.PVTRACKS @ F.BPV(v2_pvs),
+                                        })
+
+    parent_variables = FunctorCollection({ 'DOCA': F.DOCA(Child1=1, Child2=2), 
+                                           'DOCACHI2': F.DOCACHI2(Child1=1, Child2=2),
+                                           'SDOCA': F.SDOCA(Child1=1, Child2=2), 
+                                           'SDOCACHI2': F.SDOCACHI2(Child1=1, Child2=2),
+                                           'END_VX': F.END_VX, 
+                                           'END_VY': F.END_VY, 
+                                           'END_VZ': F.END_VZ, 
+                                           'END_VRHO': F.END_VRHO,
+                                           'BPVFDCHI2': F.BPVFDCHI2(v2_pvs),
+                                           'BPVLTIME': F.BPVLTIME(v2_pvs),
+                                           'BPVFD': F.BPVFD(v2_pvs), 
+                                           'BPVDIRA': F.BPVDIRA(v2_pvs),
+                                           })
+    
+    children_variables = FunctorCollection({ 'PIDE':F.PID_E, 
+                                             'PIDK':F.PID_K, 
+                                             'PIDMU':F.PID_MU, 
+                                             'PIDP':F.PID_P, 
+                                             'PIDPI':F.PID_PI,
+                                             'PROBNNE':F.PROBNN_E, 
+                                             'PROBNNK':F.PROBNN_K, 
+                                             'PROBNNMU':F.PROBNN_MU, 
+                                             'PROBNNP':F.PROBNN_P, 
+                                             'PROBNNPI':F.PROBNN_PI,
+                                             'PROBNNGHOST':F.PROBNN_GHOST, 
+                                             'PROBNND':F.PROBNN_D, 
+                                             'GHOSTPROB':F.GHOSTPROB, 
+                                             'ISMUON':F.ISMUON,
+                                             'IS_NOT_H': F.IS_NOT_H, 
+                                             'IS_PHOTON': F.IS_PHOTON,
+                                             'TRACK_NVPHITS':F.VALUE_OR(-1) @ F.NVPHITS @ F.TRACK,
+                                             'TRACK_NFTHITS':F.VALUE_OR(-1) @ F.NFTHITS @ F.TRACK,
+                                             'TRACK_NUTHITS':F.VALUE_OR(-1) @ F.NUTHITS @ F.TRACK,
+                                             #'TRACK_INECAL':F.INECAL @ F.TRACK, 'TRACK_INHCAL':F.INHCAL @ F.TRACK, 'TRACK_INMUON':F.INMUON @ F.TRACK,
+                                             "TRACK_POS_CLOSESTTOBEAM_X"        : F.POSITION_X @ F.STATE_AT("ClosestToBeam")   @ F.TRACK,
+                                             "TRACK_POS_CLOSESTTOBEAM_Y"        : F.POSITION_Y @ F.STATE_AT("ClosestToBeam")   @ F.TRACK,
+                                             "TRACK_POS_CLOSESTTOBEAM_Z"        : F.POSITION_Z @ F.STATE_AT("ClosestToBeam")   @ F.TRACK,
+                                             })
+
+    evt_vars = FunctorCollection(
+        {   "FILLNUMBER":   F.VALUE_OR(-1) @ F.FILL_NUMBER,
+            "nLongTracks":  F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nLongTracks"),
+            'nUpTracks':    F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nUpstreamTracks"),
+            'nDownTracks':  F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nDownstreamTracks"),
+            'nBackTracks':  F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nBackTracks"),
+            "nVeloTracks":  F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nVeloTracks"),
+            "nMuonTracks":  F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nMuonTracks"),
+            "nTracks":      F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nTracks"),
+            "nTTracks":     F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nTTracks"), 
+
+            "nVeloClusters":F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nVeloClusters"),
+            "nVPClusters":  F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nVPClusters"),
+            "nFTClusters":  F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nFTClusters"),
+            "nRich1Hits":   F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nRich1Hits"),
+            "nRich2Hits":   F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nRich2Hits"),
+            "eCalTot":      F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "eCalTot"),
+            "hCalTot":      F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "hCalTot"),
+            "nEcalClusters":F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nEcalClusters"),
+            "nMuonCoordsS0":F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nMuonCoordsS0"),
+            "nMuonCoordsS1":F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nMuonCoordsS1"),
+            "nMuonCoordsS2":F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nMuonCoordsS2"),
+            "nMuonCoordsS3":F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nMuonCoordsS3"),
+            "nMuonCoordsS4":F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nMuonCoordsS4"),
+            
+            "nPVs":         F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nPVs"),
+            "PVZ[nPV]":          F.VALUE_OR(-1) @ F.ALLPVZ(v2_pvs),
+            "PVX[nPV]":          F.VALUE_OR(-1) @ F.ALLPVX(v2_pvs),
+            "PVY[nPV]":          F.VALUE_OR(-1) @ F.ALLPVY(v2_pvs),
+            "ALLPVX_ERR[nPV]":   F.VALUE_OR(-1) @ F.MAP(F.SQRT @ F.CALL(0, 0) @ F.POS_COV_MATRIX) @ F.TES(v2_pvs),
+            "ALLPVY_ERR[nPV]":   F.VALUE_OR(-1) @ F.MAP(F.SQRT @ F.CALL(1, 1) @ F.POS_COV_MATRIX) @ F.TES(v2_pvs),
+            "ALLPVZ_ERR[nPV]":   F.VALUE_OR(-1) @ F.MAP(F.SQRT @ F.CALL(2, 2) @ F.POS_COV_MATRIX) @ F.TES(v2_pvs),
+            "PVCHI2NDOF[nPV]":   F.VALUE_OR(-1) @ F.MAP( F.CHI2DOF ) @ F.TES(v2_pvs),
+            "PVCHI2[nPV]":       F.VALUE_OR(-1) @ F.MAP( F.CHI2 ) @ F.TES(v2_pvs),
+            "PVNDOF[nPV]":       F.VALUE_OR(-1) @ F.MAP( F.NDOF ) @ F.TES(v2_pvs),
+            'nPVTracks[nPV]':    F.VALUE_OR(-1) @ F.MAP( F.CAST_TO_INT @ F.SIZE_OF @ F.PVTRACKS ) @ F.TES(v2_pvs),
+            'nPVbackTracks[nPV]':F.VALUE_OR(-1) @ F.MAP( F.CAST_TO_INT @ F.COUNT_IF( F.TRACKISVELOBACKWARD ) @ F.PVTRACKS ) @ F.TES(v2_pvs),
+        }
+    )
+
+    evt_vars += FC.EventInfo()
+    evt_vars += FC.SMOGInfo()
+    evt_vars += FC.SelectionInfo( selection_type="Hlt1", trigger_lines=Hlt1_decisions ) # hlt1 trigger decisions
+
+    d_input_data, d_variables, d_mytuple = {},{},{}
+
+    for line in full_line_list:
+
+        d_input_data[line] = get_particles('/Event/Spruce/'+line+'/Particles')
+        
+        TisTos_variables = FC.HltTisTos( selection_type="Hlt1", trigger_lines=Hlt1_decisions, data=d_input_data[line] )
+        Hlt2_TisTos_variables = FC.HltTisTos( selection_type="Hlt2", trigger_lines=Hlt2_TISTOS, data=d_input_data[line] )
+
+        if line in lines_nocomposite: 
+            d_variables[line] = { parts[line][0]:all_variables+TisTos_variables+Hlt2_TisTos_variables+children_variables }
+        else: 
+            d_variables[line] = { parts[line][0]:all_variables+TisTos_variables+Hlt2_TisTos_variables+parent_variables }
+
+        for ichildren in range( 1, len(parts[line]) ): 
+            if line in lines_intermediate_daughters  and ichildren==1:
+                d_variables[line][parts[line][ichildren]] = all_variables+TisTos_variables+parent_variables
+            else: 
+                d_variables[line][parts[line][ichildren]] = all_variables+TisTos_variables+children_variables
+
+        d_mytuple[line] = Funtuple( names[line], 
+                                    'DecayFunTuple',
+                                    fields=fields[line], 
+                                    variables=d_variables[line], 
+                                    event_variables=evt_vars, 
+                                    inputs=d_input_data[line] )
+    
+    alg_list = []
+    for line in full_line_list: alg_list += [ d_mytuple[line] ]
+
+    config = make_config( options, alg_list ) 
+    return config
\ No newline at end of file
diff --git a/ift_spruce_validation/full_SMOG2_val_tuple.py b/ift_spruce_validation/full_SMOG2_val_tuple.py
new file mode 100644
index 0000000000000000000000000000000000000000..984f2273497ff72924821dbc81569b0267266b9b
--- /dev/null
+++ b/ift_spruce_validation/full_SMOG2_val_tuple.py
@@ -0,0 +1,526 @@
+from DaVinci import Options, make_config
+from DaVinci.algorithms import create_lines_filter
+from PyConf.reading import get_particles, get_pvs, get_rec_summary
+from Hlt2Conf.algorithms_thor import ParticleCombiner, ParticleFilter
+
+import Functors as F
+from Functors.math import in_range
+from FunTuple import FunctorCollection 
+import FunTuple.functorcollections as FC
+from FunTuple import FunTuple_Particles as Funtuple
+
+import Functors.math as fmath
+
+import sys
+from GaudiKernel.SystemOfUnits import MeV, mm, picosecond
+
+__MASS_Lc = 2286.46 * MeV
+__MASSWin_Lc = 80 * MeV
+
+def in_smog2(functor, min_z=-541 * mm, max_z=-341 * mm):
+    """
+    Filter defining the z range of SMOG2
+    """
+
+    return in_range(min_z, functor, max_z)
+
+
+def sv_in_smog2():
+    """
+    Filter requiring a composite particle to have a DV within in a z range
+    """
+
+    return in_smog2(functor=F.END_VZ)
+
+
+def bpv_in_smog2(pvs):
+    """
+    Filter requiring a particle to have a Best Primary Vertex (BPV) within the SMOG2 z range
+    """
+
+    return in_smog2(functor=F.BPVZ(pvs))
+
+def make_charm3hadrons(name, 
+                       pvs, 
+                       decay,
+                       protons, 
+                       kaons,
+                       pions,
+                       mass=__MASS_Lc,
+                       masswin=__MASSWin_Lc,
+                       min_child_pt=800 * MeV,
+                       max_sdoca=0.5 * mm,
+                       vchi2pdof_max=25,
+                       min_bpvltime=0.1 * picosecond
+                       ):
+    """Return a decay maker for:
+    Lambda_c+ -> p+ K- pi+
+    """
+    code = F.require_all(
+        F.MASS > (mass-masswin),
+        F.MASS < (mass+masswin))
+
+    combination_code = F.require_all(
+        in_range(mass-masswin,
+                 F.MASS,
+                 mass+masswin),
+        F.SUM(F.PT > min_child_pt) > 0)
+
+    if max_sdoca is not None:
+        combination_code &= F.MAXSDOCACUT(max_sdoca)
+
+    vertex_code = F.require_all(
+        F.CHI2DOF < vchi2pdof_max, sv_in_smog2(),
+        bpv_in_smog2(pvs))
+
+    if min_bpvltime is not None:
+        vertex_code &= F.BPVLTIME(pvs) > min_bpvltime
+
+    trihadron = ParticleCombiner(
+        Inputs=[protons, kaons, pions],
+        DecayDescriptor=decay,
+        CombinationCut=combination_code,
+        CompositeCut=vertex_code,
+        PrimaryVertices=pvs)
+
+    return ParticleFilter(trihadron, F.FILTER(code), name=name)
+
+
+def main(options: Options):
+
+    full_line_list = [  'SpruceIFT_SMOG2KS2PiPiLL',
+                        'SpruceIFT_SMOG2Lambda02PPiLL',
+                        'SpruceIFT_SMOG2Phi2kk',
+                        'SpruceIFT_SMOG2D02KPi', 
+                        'SpruceIFT_SMOG2Dpm2kpipi',
+                        'SpruceIFT_SMOG2DsToKKPi',
+                        'SpruceIFT_SMOG2LcTopKPi',
+                        'SpruceIFT_SMOG2SingleTrackHighPT',
+                        'SpruceIFT_SMOG2LowDiMuon',
+                        'SpruceIFT_SMOG2LowDiMuonSS',
+                        'SpruceIFT_SMOG2Jpsi2MuMu',
+                        'SpruceIFT_SMOG2Jpsi2MuMuSS',
+                        'SpruceIFT_SMOG2Xi2Lambda0pi_lll',
+                        'SpruceIFT_SMOG2Xi2Lambda0pi_ddl',
+                        'SpruceIFT_SMOG2Xi2Lambda0pi_ddd',
+                        'SpruceIFT_SMOG2Omega2Lambda0K_lll',
+                        'SpruceIFT_SMOG2Omega2Lambda0K_ddl',
+                        'SpruceIFT_SMOG2Omega2Lambda0K_ddd',
+                        'SpruceIFT_SMOG2DY2MuMuExcludeCCBarLow',
+                        'SpruceIFT_SMOG2DY2MuMuExcludeCCBarHigh',
+                        'SpruceIFT_5GeVIsolatedGamma',
+                        'SpruceIFT_10GeVIsolatedGamma',
+                        'SpruceIFT_20GeVIsolatedGamma',
+                        #For testing container persistency
+                        'TestPersistency_LcTopKPi',
+                        'TestPersistency_DstarToDsGamma'
+                    ]
+
+    lines_intermediate_daughters = ['SpruceIFT_SMOG2Xi2Lambda0pi_lll', 'SpruceIFT_SMOG2Omega2Lambda0K_lll',
+                                    'SpruceIFT_SMOG2Xi2Lambda0pi_ddl', 'SpruceIFT_SMOG2Omega2Lambda0K_ddl',
+                                    'SpruceIFT_SMOG2Xi2Lambda0pi_ddd', 'SpruceIFT_SMOG2Omega2Lambda0K_ddd']
+
+    lines_nocomposite = ['SpruceIFT_SMOG2SingleTrackHighPT', 'SpruceIFT_5GeVIsolatedGamma', 'SpruceIFT_10GeVIsolatedGamma', 'SpruceIFT_20GeVIsolatedGamma']
+
+    lines_frompersist = ['TestPersistency_LcTopKPi', 'TestPersistency_DstarToDsGamma']
+
+    Hlt2_TISTOS = [
+        "Hlt2IFTFull_SMOG2LowDiMuon",
+        "Hlt2IFTFull_SMOG2LowDiMuonSS",
+        "Hlt2IFTFull_SMOG2Jpsi2MuMu",
+        "Hlt2IFTFull_SMOG2Jpsi2MuMuSS"
+        ]
+    
+    #Test container persistency
+
+    v2_pvs      = get_pvs()
+
+    charm_kaons = get_particles(f"/Event/Spruce/SpruceIFT_SMOG2D02KPi/CharmKaons/Particles")
+    charm_pions = get_particles(f"/Event/Spruce/SpruceIFT_SMOG2D02KPi/CharmPions/Particles")
+    charm_protons = get_particles(f"/Event/Spruce/SpruceIFT_SMOG2D02KPi/CharmProtons/Particles")
+
+    smog2_testLc= make_charm3hadrons("smog2_testLc", v2_pvs, "[Lambda_c+ -> p+ K- pi+]cc", charm_protons, charm_kaons, charm_pions)
+
+    charm_photons = get_particles(f"/Event/Spruce/SpruceIFT_SMOG2DsToKKPi/Photons/Particles") 
+    ds_cands = get_particles(f"/Event/Spruce/SpruceIFT_SMOG2DsToKKPi/Particles")
+
+    smog2_testDstar = ParticleCombiner( Inputs=[ds_cands, charm_photons], 
+                                        DecayDescriptor="[D*_s+ -> D_s+ gamma]cc",
+                                        name="smog2_testDstar",
+                                        ParticleCombiner="ParticleAdder",
+                                    )
+
+    input_data_frompersist = {'TestPersistency_LcTopKPi': smog2_testLc,
+                              'TestPersistency_DstarToDsGamma': smog2_testDstar,
+    }
+
+    parts = { 'SpruceIFT_SMOG2KS2PiPiLL':["KS0","pip", "pim"], 
+              'SpruceIFT_SMOG2Lambda02PPiLL':["Lambda", "pbar", "pim"],
+              'SpruceIFT_SMOG2Phi2kk':["Phi", "kp", "km"],
+              'SpruceIFT_SMOG2D02KPi':["D0", "km", "pip" ],
+              'SpruceIFT_SMOG2Dpm2kpipi':["Dp", "km", "pip", "pip2"],
+              'SpruceIFT_SMOG2DsToKKPi':["Ds", "km", "kp", "pip"],
+              'SpruceIFT_SMOG2LcTopKPi':["Lc", "pbar", "km","pip"],
+              'SpruceIFT_SMOG2SingleTrackHighPT':["pi"],
+              'SpruceIFT_SMOG2LowDiMuon':["Jpsi", "mup", "mum"],
+              'SpruceIFT_SMOG2LowDiMuonSS':["Jpsi", "mu1", "mu2"],
+              'SpruceIFT_SMOG2Jpsi2MuMu':["Jpsi", "mup", "mum"],
+              'SpruceIFT_SMOG2Jpsi2MuMuSS':["Jpsi", "mu1", "mu2"],
+              'SpruceIFT_SMOG2Xi2Lambda0pi_lll':[ "Xim", "Lambda", "pbar", "Lambda_pim", "Xi_pim"],
+              'SpruceIFT_SMOG2Xi2Lambda0pi_ddl':[ "Xim", "Lambda", "pbar", "Lambda_pim", "Xi_pim"],
+              'SpruceIFT_SMOG2Xi2Lambda0pi_ddd':[ "Xim", "Lambda", "pbar", "Lambda_pim", "Xi_pim"],
+              'SpruceIFT_SMOG2Omega2Lambda0K_lll':["Omegam", "Lambda", "pbar", "pim", "km"],
+              'SpruceIFT_SMOG2Omega2Lambda0K_ddl':["Omegam", "Lambda", "pbar", "pim", "km"],
+              'SpruceIFT_SMOG2Omega2Lambda0K_ddd':["Omegam", "Lambda", "pbar", "pim", "km"],
+              'SpruceIFT_SMOG2DY2MuMuExcludeCCBarLow':["Jpsi", "mup", "mum"],
+              'SpruceIFT_SMOG2DY2MuMuExcludeCCBarHigh':["Jpsi", "mup", "mum"],
+              'SpruceIFT_5GeVIsolatedGamma': ["gamma"],
+              'SpruceIFT_10GeVIsolatedGamma': ["gamma"],
+              'SpruceIFT_20GeVIsolatedGamma': ["gamma"],
+              #For testing container persistency
+              'TestPersistency_LcTopKPi': ["Lc", "pbar", "km","pip"],
+              'TestPersistency_DstarToDsGamma': ["D*_s+", "D_s+", "gamma"] 
+            }
+
+    hlt1lines_muon = [ "Hlt1SMOG2SingleMuonDecision", "Hlt1SMOG2DiMuonHighMassDecision"]
+    hlt1lines_BE = [ "Hlt1SMOG2BENoBiasDecision", "Hlt1SMOG2PassThroughLowMult5Decision", "Hlt1SMOG2BELowMultElectronsDecision"]
+    hlt1lines_MB = [ "Hlt1SMOG2MinimumBiasDecision", "Hlt1PassthroughPVinSMOG2Decision"]
+        
+    hlt1lines_track = [ "Hlt1SMOG2SingleTrackHighPtDecision", "Hlt1SMOG2SingleTrackVeryHighPtDecision", "Hlt1SMOG22BodyGenericDecision", "Hlt1SMOG22BodyGenericPromptDecision"]
+    hlt1lines_hadron = [ "Hlt1SMOG2etacToppDecision", "Hlt1SMOG2D2KpiDecision"]
+    hlt1lines_longlived = [ "Hlt1SMOG2L0ToppiDecision", "Hlt1SMOG2KsTopipiDecision"]
+    hlt1lines_pp = [ "Hlt1TrackMVADecision", "Hlt1TrackMuonMVADecision", "Hlt1TwoTrackMVADecision"]
+
+    hlt1lines = []
+    hlt1lines += hlt1lines_muon
+    hlt1lines += hlt1lines_BE
+    hlt1lines += hlt1lines_MB
+    hlt1lines += hlt1lines_track
+    hlt1lines += hlt1lines_hadron
+    hlt1lines += hlt1lines_longlived
+    hlt1lines += hlt1lines_pp
+    Hlt1_decisions = hlt1lines
+
+    names = { "SpruceIFT_SMOG2KS2PiPiLL":"Ks0pipi",
+              "SpruceIFT_SMOG2Lambda02PPiLL":"Lambdappi",
+              "SpruceIFT_SMOG2Phi2kk":"Phi2kk",
+              'SpruceIFT_SMOG2D02KPi':"D02KPi",
+              'SpruceIFT_SMOG2Dpm2kpipi': "Dpm2Kpipi",
+              'SpruceIFT_SMOG2DsToKKPi': "Ds2KKpi",
+              'SpruceIFT_SMOG2LcTopKPi':"Lc2pkpi",
+              'SpruceIFT_SMOG2SingleTrackHighPT': 'SingleTrackHighPT',
+              'SpruceIFT_SMOG2LowDiMuon': 'LowDiMuon', 
+              'SpruceIFT_SMOG2LowDiMuonSS': 'LowDiMuonSS',
+              'SpruceIFT_SMOG2Jpsi2MuMu':"Jpsi2MuMu",
+              'SpruceIFT_SMOG2Jpsi2MuMuSS':"Jpsi2MuMuSS",
+              'SpruceIFT_SMOG2DY2MuMuExcludeCCBarLow':"qq2MuMulow",
+              'SpruceIFT_SMOG2DY2MuMuExcludeCCBarHigh':"qq2MuMuhigh",
+              'SpruceIFT_SMOG2Xi2Lambda0pi_lll':"Xi2Lambdaplll",
+              'SpruceIFT_SMOG2Xi2Lambda0pi_ddl':"Xi2Lambdapddl",
+              'SpruceIFT_SMOG2Xi2Lambda0pi_ddd':"Xi2Lambdapddd",
+              'SpruceIFT_SMOG2Omega2Lambda0K_lll':"Omega2LambdaKlll",
+              'SpruceIFT_SMOG2Omega2Lambda0K_ddl':"Omega2LambdaKddl", 
+              'SpruceIFT_SMOG2Omega2Lambda0K_ddd':"Omega2LambdaKddd",
+              'SpruceIFT_5GeVIsolatedGamma': "5GeVGamma",
+              'SpruceIFT_10GeVIsolatedGamma': "10GeVGamma",
+              'SpruceIFT_20GeVIsolatedGamma': "20GeVGamma",
+              'TestPersistency_LcTopKPi': "LcfromD0Line",
+              'TestPersistency_DstarToDsGamma': "DstarfromDsLine"
+              }
+
+    fields = { 'SpruceIFT_SMOG2KS2PiPiLL':{"KS0": "KS0 -> pi+ pi-",
+                                           "pip": "KS0 ->^pi+ pi-",
+                                           "pim": "KS0 -> pi+ ^pi-",
+                },
+               'SpruceIFT_SMOG2Lambda02PPiLL':{"Lambda": "[Lambda0 -> p+ pi-]CC",
+                                               "pbar": "[Lambda0 -> ^p+ pi-]CC",
+                                               "pim": "[Lambda0 -> p+ ^pi-]CC",
+                },
+               'SpruceIFT_SMOG2Phi2kk':{"Phi":'phi(1020) -> K+ K-', 
+                                        "kp":'phi(1020) -> ^K+ K-',
+                                        "km":'phi(1020) -> K+ ^K-',
+                },
+               'SpruceIFT_SMOG2D02KPi':{"D0":'[ D0 -> K- pi+ ]CC', 
+                                        "km":'[ D0 -> ^K- pi+ ]CC', 
+                                        "pip":'[ D0 -> K- ^pi+ ]CC',  
+                },
+               'SpruceIFT_SMOG2Dpm2kpipi':{"Dp": '[D+ -> K- pi+ pi+]CC',
+                                           "km": '[D+ -> ^K- pi+ pi+]CC',
+                                           "pip": '[D+ -> K- ^pi+ pi+]CC',
+                                           "pip2": '[D+ -> K- pi+ ^pi+]CC', 
+                },
+               'SpruceIFT_SMOG2DsToKKPi':{"Ds": "[D_s+ -> K- K+ pi+]CC",
+                                          "km": "[D_s+ -> ^K- K+ pi+]CC",
+                                          "kp": "[D_s+ -> K- ^K+ pi+]CC",
+                                          "pip": "[D_s+ -> K- K+ ^pi+]CC",
+               },
+               'SpruceIFT_SMOG2LcTopKPi':{"Lc": "[Lambda_c+ -> p+ K- pi+]CC",
+                                            "pbar": "[Lambda_c+ -> ^p+ K- pi+]CC",
+                                            "km": "[Lambda_c+ -> p+ ^K- pi+]CC",
+                                            "pip": "[Lambda_c+ -> p+ K- ^pi+]CC",
+               },
+               'SpruceIFT_SMOG2SingleTrackHighPT':{"pi": "[pi+]CC"},
+               'SpruceIFT_SMOG2LowDiMuon':{"Jpsi":'J/psi(1S) -> mu- mu+',
+                                           "mum":'J/psi(1S) -> ^mu- mu+',
+                                           "mup":'J/psi(1S) -> mu- ^mu+',                       
+               },
+               'SpruceIFT_SMOG2LowDiMuonSS':{"Jpsi":'[J/psi(1S) -> mu+ mu+]CC',
+                                           "mu1":'[J/psi(1S) -> ^mu+ mu+]CC',
+                                           "mu2":'[J/psi(1S) -> mu+ ^mu+]CC',                       
+               },
+               'SpruceIFT_SMOG2Jpsi2MuMu':{"Jpsi":'J/psi(1S) -> mu- mu+',
+                                           "mum":'J/psi(1S) -> ^mu- mu+',
+                                           "mup":'J/psi(1S) -> mu- ^mu+',                       
+               },
+               'SpruceIFT_SMOG2Jpsi2MuMuSS':{"Jpsi":'[J/psi(1S) -> mu+ mu+]CC',
+                                           "mu1":'[J/psi(1S) -> ^mu+ mu+]CC',
+                                           "mu2":'[J/psi(1S) -> mu+ ^mu+]CC',                       
+               },
+               'SpruceIFT_SMOG2DY2MuMuExcludeCCBarLow':{ "Jpsi":'J/psi(1S) -> mu- mu+',
+                                                         "mum":'J/psi(1S) -> ^mu- mu+',
+                                                         "mup":'J/psi(1S) -> mu- ^mu+',                       
+               },
+               'SpruceIFT_SMOG2DY2MuMuExcludeCCBarHigh':{ "Jpsi":'J/psi(1S) -> mu- mu+',
+                                                          "mum":'J/psi(1S) -> ^mu- mu+',
+                                                          "mup":'J/psi(1S) -> mu- ^mu+',                       
+               },
+               'SpruceIFT_SMOG2Xi2Lambda0pi_lll':{"Xim":"[Xi- -> (Lambda0 -> p+ pi-) pi-]CC",
+                                                  "Lambda":"[Xi- -> ^(Lambda0 -> p+ pi-) pi-]CC",
+                                                  "pbar":"[Xi- -> (Lambda0 -> ^p+ pi-) pi-]CC",
+                                                  "Lambda_pim":"[Xi- -> (Lambda0 -> p+ ^pi-) pi-]CC",
+                                                  "Xi_pim":"[Xi- -> (Lambda0 -> p+ pi-) ^pi-]CC",
+               },
+               'SpruceIFT_SMOG2Xi2Lambda0pi_ddl':{"Xim":"[Xi- -> (Lambda0 -> p+ pi-) pi-]CC",
+                                                  "Lambda":"[Xi- -> ^(Lambda0 -> p+ pi-) pi-]CC",
+                                                  "pbar":"[Xi- -> (Lambda0 -> ^p+ pi-) pi-]CC",
+                                                  "Lambda_pim":"[Xi- -> (Lambda0 -> p+ ^pi-) pi-]CC",
+                                                  "Xi_pim":"[Xi- -> (Lambda0 -> p+ pi-) ^pi-]CC",
+               },
+               'SpruceIFT_SMOG2Xi2Lambda0pi_ddd':{"Xim":"[Xi- -> (Lambda0 -> p+ pi-) pi-]CC",
+                                                  "Lambda":"[Xi- -> ^(Lambda0 -> p+ pi-) pi-]CC",
+                                                  "pbar":"[Xi- -> (Lambda0 -> ^p+ pi-) pi-]CC",
+                                                  "Lambda_pim":"[Xi- -> (Lambda0 -> p+ ^pi-) pi-]CC",
+                                                  "Xi_pim":"[Xi- -> (Lambda0 -> p+ pi-) ^pi-]CC",
+               },
+               'SpruceIFT_SMOG2Omega2Lambda0K_lll':{"Omegam": "[Omega- -> (Lambda0 -> p+ pi-) K-]CC",
+                                                    "Lambda": "[Omega- -> ^(Lambda0 -> p+ pi-) K-]CC",
+                                                    "pbar": "[Omega- -> (Lambda0 -> ^p+ pi-) K-]CC",
+                                                    "pim": "[Omega- -> (Lambda0 -> p+ ^pi-) K-]CC",
+                                                    "km": "[Omega- -> (Lambda0 -> p+ pi-) ^K-]CC", 
+               },
+               'SpruceIFT_SMOG2Omega2Lambda0K_ddl':{"Omegam": "[Omega- -> (Lambda0 -> p+ pi-) K-]CC",
+                                                    "Lambda": "[Omega- -> ^(Lambda0 -> p+ pi-) K-]CC",
+                                                    "pbar": "[Omega- -> (Lambda0 -> ^p+ pi-) K-]CC",
+                                                    "pim": "[Omega- -> (Lambda0 -> p+ ^pi-) K-]CC",
+                                                    "km": "[Omega- -> (Lambda0 -> p+ pi-) ^K-]CC", 
+               },
+               'SpruceIFT_SMOG2Omega2Lambda0K_ddd':{"Omegam": "[Omega- -> (Lambda0 -> p+ pi-) K-]CC",
+                                                    "Lambda": "[Omega- -> ^(Lambda0 -> p+ pi-) K-]CC",
+                                                    "pbar": "[Omega- -> (Lambda0 -> ^p+ pi-) K-]CC",
+                                                    "pim": "[Omega- -> (Lambda0 -> p+ ^pi-) K-]CC",
+                                                    "km": "[Omega- -> (Lambda0 -> p+ pi-) ^K-]CC", 
+               },
+              'SpruceIFT_5GeVIsolatedGamma': {"gamma": "gamma"},
+              'SpruceIFT_10GeVIsolatedGamma': {"gamma": "gamma"},
+              'SpruceIFT_20GeVIsolatedGamma': {"gamma": "gamma"},
+              'TestPersistency_LcTopKPi':{"Lc": "[Lambda_c+ -> p+ K- pi+]CC",
+                                          "pbar": "[Lambda_c+ -> ^p+ K- pi+]CC",
+                                          "km": "[Lambda_c+ -> p+ ^K- pi+]CC",
+                                          "pip": "[Lambda_c+ -> p+ K- ^pi+]CC",
+               },
+               'TestPersistency_DstarToDsGamma': {"D*_s+": "[D*_s+ -> D_s+ gamma]CC",
+                                                  "D_s+": "[D*_s+ -> ^D_s+ gamma]CC",
+                                                  "gamma" : "[D*_s+ -> D_s+ ^gamma]CC"}
+    }
+
+    rec_summary = get_rec_summary()
+    all_variables = FunctorCollection({ 'ID': F.PARTICLE_ID, 
+                                        'KEY': F.OBJECT_KEY, 
+                                        'CHARGE': F.CHARGE, 
+                                        'PT': F.PT, 
+                                        'PX': F.PX, 
+                                        'PY': F.PY,
+                                        'PZ': F.PZ,
+                                        'ETA': F.ETA,
+                                        'PHI': F.PHI,
+                                        'YSTAR':0.5*fmath.log( (F.ENERGY+F.PZ)/(F.ENERGY-F.PZ))-4.79,
+                                        'Y':0.5*fmath.log( (F.ENERGY+F.PZ)/(F.ENERGY-F.PZ)),
+                                        'MASS':F.MASS, 
+                                        'ENERGY': F.ENERGY,
+                                        'P': F.P,
+                                        'FOURMOMENTUM': F.FOURMOMENTUM,
+                                        'CHI2': F.CHI2, 
+                                        'CHI2DOF': F.CHI2DOF,
+                                        'B_PV_Z':F.BPVZ(v2_pvs),
+                                        'B_PV_X':F.BPVX(v2_pvs),
+                                        'B_PV_Y':F.BPVY(v2_pvs),
+                                        'BPVIP': F.BPVIP(v2_pvs),
+                                        'BPVIPCHI2': F.BPVIPCHI2(v2_pvs),
+                                        'nBestPVTracks': F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.SIZE_OF @ F.PVTRACKS @ F.BPV(v2_pvs),
+                                        'nBestPVbackTracks': F.VALUE_OR(-1) @ F.CAST_TO_INT @ F.COUNT_IF( F.TRACKISVELOBACKWARD ) @ F.PVTRACKS @ F.BPV(v2_pvs),
+                                        })
+
+    variables_without_vertex = FunctorCollection({ 'ID': F.PARTICLE_ID, 
+                                        'KEY': F.OBJECT_KEY, 
+                                        'CHARGE': F.CHARGE, 
+                                        'PT': F.PT, 
+                                        'PX': F.PX, 
+                                        'PY': F.PY,
+                                        'PZ': F.PZ,
+                                        'ETA': F.ETA,
+                                        'PHI': F.PHI,
+                                        'YSTAR':0.5*fmath.log( (F.ENERGY+F.PZ)/(F.ENERGY-F.PZ))-4.79,
+                                        'Y':0.5*fmath.log( (F.ENERGY+F.PZ)/(F.ENERGY-F.PZ)),
+                                        'MASS':F.MASS, 
+                                        'ENERGY': F.ENERGY,
+                                        'P': F.P,
+                                        'FOURMOMENTUM': F.FOURMOMENTUM,
+                                        'CHI2': F.CHI2, 
+                                        'CHI2DOF': F.CHI2DOF,
+                                        'DOCA': F.DOCA(Child1=1, Child2=2), 
+                                        'DOCACHI2': F.DOCACHI2(Child1=1, Child2=2),
+                                        'SDOCA': F.SDOCA(Child1=1, Child2=2), 
+                                        'SDOCACHI2': F.SDOCACHI2(Child1=1, Child2=2)
+                                    })
+
+    variables_without_vertex_children = FunctorCollection({ 'ID': F.PARTICLE_ID, 
+                                        'KEY': F.OBJECT_KEY, 
+                                        'CHARGE': F.CHARGE, 
+                                        'PT': F.PT, 
+                                        'PX': F.PX, 
+                                        'PY': F.PY,
+                                        'PZ': F.PZ,
+                                        'ETA': F.ETA,
+                                        'PHI': F.PHI,
+                                        'YSTAR':0.5*fmath.log( (F.ENERGY+F.PZ)/(F.ENERGY-F.PZ))-4.79,
+                                        'Y':0.5*fmath.log( (F.ENERGY+F.PZ)/(F.ENERGY-F.PZ)),
+                                        'MASS':F.MASS, 
+                                        'ENERGY': F.ENERGY,
+                                        'P': F.P,
+                                        'FOURMOMENTUM': F.FOURMOMENTUM,
+                                        'CHI2': F.CHI2, 
+                                        'CHI2DOF': F.CHI2DOF,
+                                    })
+
+    parent_variables = FunctorCollection({ 'DOCA': F.DOCA(Child1=1, Child2=2), 
+                                           'DOCACHI2': F.DOCACHI2(Child1=1, Child2=2),
+                                           'SDOCA': F.SDOCA(Child1=1, Child2=2), 
+                                           'SDOCACHI2': F.SDOCACHI2(Child1=1, Child2=2),
+                                           'END_VX': F.END_VX, 
+                                           'END_VY': F.END_VY, 
+                                           'END_VZ': F.END_VZ, 
+                                           'END_VRHO': F.END_VRHO,
+                                           'BPVFDCHI2': F.BPVFDCHI2(v2_pvs),
+                                           'BPVLTIME': F.BPVLTIME(v2_pvs),
+                                           'BPVFD': F.BPVFD(v2_pvs), 
+                                           'BPVDIRA': F.BPVDIRA(v2_pvs),
+                                           })
+    
+    children_variables = FunctorCollection({ 'PIDE':F.PID_E, 
+                                             'PIDK':F.PID_K, 
+                                             'PIDMU':F.PID_MU, 
+                                             'PIDP':F.PID_P, 
+                                             'PIDPI':F.PID_PI,
+                                             'PROBNNE':F.PROBNN_E, 
+                                             'PROBNNK':F.PROBNN_K, 
+                                             'PROBNNMU':F.PROBNN_MU, 
+                                             'PROBNNP':F.PROBNN_P, 
+                                             'PROBNNPI':F.PROBNN_PI,
+                                             'PROBNNGHOST':F.PROBNN_GHOST, 
+                                             'PROBNND':F.PROBNN_D, 
+                                             'GHOSTPROB':F.GHOSTPROB, 
+                                             'ISMUON':F.ISMUON,
+                                             'IS_NOT_H': F.IS_NOT_H, 
+                                             'IS_PHOTON': F.IS_PHOTON,
+                                             'TRACK_NVPHITS':F.VALUE_OR(-1) @ F.NVPHITS @ F.TRACK,
+                                             'TRACK_NFTHITS':F.VALUE_OR(-1) @ F.NFTHITS @ F.TRACK,
+                                             'TRACK_NUTHITS':F.VALUE_OR(-1) @ F.NUTHITS @ F.TRACK,
+                                             #'TRACK_INECAL':F.INECAL @ F.TRACK, 'TRACK_INHCAL':F.INHCAL @ F.TRACK, 'TRACK_INMUON':F.INMUON @ F.TRACK,
+                                             "TRACK_POS_CLOSESTTOBEAM_X"        : F.POSITION_X @ F.STATE_AT("ClosestToBeam")   @ F.TRACK,
+                                             "TRACK_POS_CLOSESTTOBEAM_Y"        : F.POSITION_Y @ F.STATE_AT("ClosestToBeam")   @ F.TRACK,
+                                             "TRACK_POS_CLOSESTTOBEAM_Z"        : F.POSITION_Z @ F.STATE_AT("ClosestToBeam")   @ F.TRACK,
+                                             })
+
+    evt_vars = FunctorCollection(
+        {   "FILLNUMBER":   F.VALUE_OR(-1) @ F.FILL_NUMBER,
+            "nLongTracks":  F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nLongTracks"),
+            'nUpTracks':    F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nUpstreamTracks"),
+            'nDownTracks':  F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nDownstreamTracks"),
+            'nBackTracks':  F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nBackTracks"),
+            "nVeloTracks":  F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nVeloTracks"),
+            "nMuonTracks":  F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nMuonTracks"),
+            "nTracks":      F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nTracks"),
+            "nTTracks":     F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nTTracks"), 
+
+            "nVeloClusters":F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nVeloClusters"),
+            "nVPClusters":  F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nVPClusters"),
+            "nFTClusters":  F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nFTClusters"),
+            "nRich1Hits":   F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nRich1Hits"),
+            "nRich2Hits":   F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nRich2Hits"),
+            "eCalTot":      F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "eCalTot"),
+            "hCalTot":      F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "hCalTot"),
+            "nEcalClusters":F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nEcalClusters"),
+            "nMuonCoordsS0":F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nMuonCoordsS0"),
+            "nMuonCoordsS1":F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nMuonCoordsS1"),
+            "nMuonCoordsS2":F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nMuonCoordsS2"),
+            "nMuonCoordsS3":F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nMuonCoordsS3"),
+            "nMuonCoordsS4":F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nMuonCoordsS4"),
+            
+            "nPVs":         F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, "nPVs"),
+            "PVZ[nPV]":          F.VALUE_OR(-1) @ F.ALLPVZ(v2_pvs),
+            "PVX[nPV]":          F.VALUE_OR(-1) @ F.ALLPVX(v2_pvs),
+            "PVY[nPV]":          F.VALUE_OR(-1) @ F.ALLPVY(v2_pvs),
+            "ALLPVX_ERR[nPV]":   F.VALUE_OR(-1) @ F.MAP(F.SQRT @ F.CALL(0, 0) @ F.POS_COV_MATRIX) @ F.TES(v2_pvs),
+            "ALLPVY_ERR[nPV]":   F.VALUE_OR(-1) @ F.MAP(F.SQRT @ F.CALL(1, 1) @ F.POS_COV_MATRIX) @ F.TES(v2_pvs),
+            "ALLPVZ_ERR[nPV]":   F.VALUE_OR(-1) @ F.MAP(F.SQRT @ F.CALL(2, 2) @ F.POS_COV_MATRIX) @ F.TES(v2_pvs),
+            "PVCHI2NDOF[nPV]":   F.VALUE_OR(-1) @ F.MAP( F.CHI2DOF ) @ F.TES(v2_pvs),
+            "PVCHI2[nPV]":       F.VALUE_OR(-1) @ F.MAP( F.CHI2 ) @ F.TES(v2_pvs),
+            "PVNDOF[nPV]":       F.VALUE_OR(-1) @ F.MAP( F.NDOF ) @ F.TES(v2_pvs),
+            'nPVTracks[nPV]':    F.VALUE_OR(-1) @ F.MAP( F.CAST_TO_INT @ F.SIZE_OF @ F.PVTRACKS ) @ F.TES(v2_pvs),
+            'nPVbackTracks[nPV]':F.VALUE_OR(-1) @ F.MAP( F.CAST_TO_INT @ F.COUNT_IF( F.TRACKISVELOBACKWARD ) @ F.PVTRACKS ) @ F.TES(v2_pvs),
+        }
+    )
+
+    evt_vars += FC.EventInfo()
+    evt_vars += FC.SMOGInfo()
+    evt_vars += FC.SelectionInfo( selection_type="Hlt1", trigger_lines=Hlt1_decisions ) # hlt1 trigger decisions
+
+    d_input_data, d_variables, d_mytuple = {},{},{}
+
+    for line in full_line_list:
+
+        if line in lines_frompersist:
+            d_input_data[line] = input_data_frompersist[line]
+        else:
+            d_input_data[line] = get_particles('/Event/Spruce/'+line+'/Particles')
+        
+        TisTos_variables = FC.HltTisTos( selection_type="Hlt1", trigger_lines=Hlt1_decisions, data=d_input_data[line] )
+        Hlt2_TisTos_variables = FC.HltTisTos( selection_type="Hlt2", trigger_lines=Hlt2_TISTOS, data=d_input_data[line] )
+
+        if line in lines_nocomposite: 
+            d_variables[line] = { parts[line][0]:all_variables+TisTos_variables+Hlt2_TisTos_variables+children_variables }
+        elif line == 'TestPersistency_DstarToDsGamma':
+            d_variables[line] = { parts[line][0]:variables_without_vertex+TisTos_variables+Hlt2_TisTos_variables+children_variables } 
+        else: 
+            d_variables[line] = { parts[line][0]:all_variables+TisTos_variables+Hlt2_TisTos_variables+parent_variables }
+
+        for ichildren in range( 1, len(parts[line]) ): 
+            if line in lines_intermediate_daughters  and ichildren==1:
+                d_variables[line][parts[line][ichildren]] = all_variables+TisTos_variables+parent_variables
+            elif line == 'TestPersistency_DstarToDsGamma':
+                d_variables[line][parts[line][ichildren]] = variables_without_vertex_children+TisTos_variables+children_variables
+            else: 
+                d_variables[line][parts[line][ichildren]] = all_variables+TisTos_variables+children_variables
+
+        d_mytuple[line] = Funtuple( names[line], 
+                                    'DecayFunTuple',
+                                    fields=fields[line], 
+                                    variables=d_variables[line], 
+                                    event_variables=evt_vars, 
+                                    inputs=d_input_data[line] )
+    
+    alg_list = []
+    for line in full_line_list: alg_list += [ d_mytuple[line] ]
+
+    config = make_config( options, alg_list ) 
+    return config
\ No newline at end of file
diff --git a/ift_spruce_validation/info.yaml b/ift_spruce_validation/info.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..feab2c7145d01d4d39a2962268bff425d797a31b
--- /dev/null
+++ b/ift_spruce_validation/info.yaml
@@ -0,0 +1,77 @@
+defaults:
+  inform:
+    - kara.mattioli@cern.ch
+  wg: IFT
+
+{%- set datasets = [
+  ('24', 'Sprucing24r1', '-Excl-UT', 'Down'),
+  ('24', 'Sprucing24r1', '-Excl-UT', 'Up'),
+  ('24', 'Sprucing24r1', '', 'Down'),
+  ('24', 'Sprucing24r1', '', 'Up'),
+]%}
+
+{%- for year, sprucingver, use_ut, polarity in datasets %}
+
+SMOG2Commissioning_DaVinci_{{year}}_Magnet{{polarity}}{{use_ut}}_{{sprucingver}}_FULL:
+  application: DaVinci/v64r12@x86_64_v2-el9-clang16-opt
+  input:
+    bk_query: /validation/Collision{{year}}/Beam6800GeV-VeloClosed-Mag{{polarity}}{{use_ut}}/Real Data/{{sprucingver}}/90000000/IFT.DST
+    dq_flags:
+      - UNCHECKED
+      - OK
+    smog2_state:
+      - Argon
+      - Helium
+      - Hydrogen
+      - Neon
+      - ArgonUnstable
+      - HeliumUnstable
+      - HydrogenUnstable
+      - NeonUnstable
+    keep_running: True
+    n_test_lfns: 5
+  output: IFT_EoYSpruceValidation_FULL.root
+  options:
+    entrypoint: ift_spruce_validation.full{{use_ut}}_SMOG2_val_tuple:main
+    extra_options:
+      input_raw_format: 0.5
+      input_type: ROOT # ROOT for SprucingPass, RAW for RAW data (Hlt2 output)
+      simulation: False
+      data_type: "Upgrade"
+      geometry_version: run3/2024.Q1.2-v00.00
+      conditions_version: master
+      input_process: "Spruce" 
+      input_stream: "ift"
+
+SMOG2Commissioning_DaVinci_{{year}}_Magnet{{polarity}}{{use_ut}}_{{sprucingver}}_MINBIAS:
+  application: DaVinci/v64r12@x86_64_v2-el9-clang16-opt
+  input:
+    bk_query: /validation/Collision{{year}}/Beam6800GeV-VeloClosed-Mag{{polarity}}{{use_ut}}/Real Data/{{sprucingver}}/90000000/IFT.DST
+    dq_flags:
+      - UNCHECKED
+      - OK
+    smog2_state:
+      - Argon
+      - Helium
+      - Hydrogen
+      - Neon
+      - ArgonUnstable
+      - HeliumUnstable
+      - HydrogenUnstable
+      - NeonUnstable
+    keep_running: True
+    n_test_lfns: 3
+  output: IFT_EoYSpruceValidation_MINBIAS.root
+  options:
+    entrypoint: ift_spruce_validation.MB_SMOG2_val_tuple:main
+    extra_options:
+      input_raw_format: 0.5
+      input_type: ROOT # ROOT for SprucingPass, RAW for RAW data (Hlt2 output)
+      simulation: False
+      data_type: "Upgrade"
+      geometry_version: run3/2024.Q1.2-v00.00
+      conditions_version: master
+      input_process: "Spruce" 
+      input_stream: "ift"
+
+{%- endfor %}