From 42e9d22434f462ef68cf39fe1624fcb80b20eda7 Mon Sep 17 00:00:00 2001
From: Tommaso Fulghesu <tommaso.fulghesu@cern.ch>
Date: Tue, 14 Jan 2025 13:51:35 +0100
Subject: [PATCH 1/6] Add files for minbias production

---
 slb-minbias-sprucing/davinci.py  | 610 +++++++++++++++++++++
 slb-minbias-sprucing/fields.json | 913 +++++++++++++++++++++++++++++++
 slb-minbias-sprucing/info.yaml   |  69 +++
 3 files changed, 1592 insertions(+)
 create mode 100644 slb-minbias-sprucing/davinci.py
 create mode 100644 slb-minbias-sprucing/fields.json
 create mode 100644 slb-minbias-sprucing/info.yaml

diff --git a/slb-minbias-sprucing/davinci.py b/slb-minbias-sprucing/davinci.py
new file mode 100644
index 0000000000..0508fadcf4
--- /dev/null
+++ b/slb-minbias-sprucing/davinci.py
@@ -0,0 +1,610 @@
+from PyConf.reading import get_pvs, get_particles, get_odin
+import Functors as F
+from FunTuple import FunctorCollection, FunTuple_Particles as Funtuple
+from DaVinci.algorithms import create_lines_filter
+from DaVinci import Options, make_config
+import FunTuple.functorcollections as FC
+from GaudiConf.LbExec import HltSourceID
+#from .field_lines import make_decay_descriptor, make_fields
+from Hlt2Conf.lines.semileptonic.spruce_semileptonic import all_lines as spruce_line_names
+from Hlt2Conf.lines.semileptonic.isolationMVA import combine_iso_pions, extract_parent_name, mva_functor_inclusive
+from DaVinciTools import SubstitutePID
+from DaVinciMCTools import MCTruthAndBkgCat
+from PyConf.Algorithms import DeterministicPrescaler
+import os
+import json
+
+#read the data from fields.json
+ap_base = os.environ['ANALYSIS_PRODUCTIONS_BASE']
+json_path = f'{ap_base}/slb_central_analysis_production/fields.json'
+with open(json_path, 'r') as f:
+    spruce_fields = json.load(f)
+
+# Hlt1 decisions + TISTOS
+Hlt1_decisions = [
+    #Charm
+    #"Hlt1D2KK",
+    "Hlt1D2KPi",
+    #"Hlt1D2PiPi",
+    "Hlt1Dst2D0Pi",
+    ##DiMuon (RJpsi)
+    #"Hlt1DiMuonDisplaced",
+    #"Hlt1DiMuonHighMass",
+    #"Hlt1DiMuonNoIP",
+    #"Hlt1DiMuonSoft",
+    ##DiElectron (RJpsi)
+    #"Hlt1DiElectronDisplaced",
+    #"Hlt1DiElectronHighMass",
+    #"Hlt1DiElectronSoft",
+    ##DiPhoton
+    #"Hlt1DiPhotonHighMass",
+    #Downstream
+    "Hlt1DownstreamKsToPiPi",
+    "Hlt1DownstreamLambdaToPPi",
+    #"Hlt1KsToPiPi",
+    #"Hlt1LambdaLLDetachedTrack",
+    #"Hlt1TwoTrackKs",
+    #Pi0
+    #"Hlt1Pi02GammaGamma",
+    #SingleElectron
+    "Hlt1SingleHighPtElectron",
+    "Hlt1TrackElectronMVA",
+    #SingleMuon
+    "Hlt1OneMuonTrackLine",
+    "Hlt1SingleHighPtMuon",
+    "Hlt1SingleHighPtMuonNoMuID",
+    #Generic track
+    "Hlt1TrackMVA",
+    "Hlt1TrackMuonMVA",
+    "Hlt1TwoTrackMVA",
+]
+
+# Hlt2 decisions + TISTOS
+Hlt2_decisions = [
+    "Hlt2Topo2BodyDecision",
+    "Hlt2Topo3BodyDecision",
+    "Hlt2TopoMu2BodyDecision",
+    "Hlt2TopoMu3BodyDecision",
+]
+
+# define spruce lines names and for which blocks the extra particles are NOT available
+# Empty list means that the extra particles are available for all blocks
+spruce_lines_with_extra_particles = {
+    "SpruceSLB_BuToD0MuNu_D0ToKPi": [],
+    "SpruceSLB_BuToD0MuNu_D0ToKPi_FakeMuon": [],
+    "SpruceSLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu": [],
+    "SpruceSLB_BuToD0TauNu_D0ToKPi_FakeMuon": [],
+    "SpruceSLB_BuToD0TauNu_D0ToKPi_TauToPiPiPiNu": [],
+    "SpruceSLB_LbToLcMuNu_LcToPKPi": [],
+    "SpruceSLB_LbToLcMuNu_LcToPKPi_FakeMuon": [],
+    "SpruceSLB_LbToLcTauNu_LcToPKPi_TauToMuNuNu": [],
+    "SpruceSLB_LbToLcTauNu_LcToPKPi_FakeMuon": [],
+    "SpruceSLB_LbToLcTauNu_LcTopKPi_TauToPiPiPiNu": [],
+    "SpruceSLB_LbToPMuNu": [],
+    "SpruceSLB_LbToPMuNu_FakeMuon": [],
+    "SpruceSLB_LbToPMuNu_FakeP": [],
+    "SpruceSLB_LbToPMuNu_WS": [],
+    "SpruceSLB_LbToPMuNu_WS_FakeMuon": [],
+    "SpruceSLB_LbToPMuNu_WS_FakeP": [],
+    "SpruceSLB_B2XuMuNuBs2K": [],
+    "SpruceSLB_B2XuMuNuBs2K_NoPIDMu": [],
+    "SpruceSLB_B2XuMuNuBs2K_NoPIDK": [],
+    "SpruceSLB_BsToDsMuNu_DsToKKPi": [],
+    "SpruceSLB_BsToDsMuNu_DsToKKPi_FakeMuon": [],
+    "SpruceSLB_BuToD0ENu_D0ToKPi": [],
+    "SpruceSLB_BuToD0ENu_D0ToKPi_FakeElectron": [],
+    "SpruceSLB_B0ToDpENu_DpToKPiPi": [],
+    "SpruceSLB_B0ToDpENu_DpToKPiPi_FakeElectron": [],
+    "SpruceSLB_B0ToDpTauNu_DpToKPiPi_TauToENuNu": [],
+    "SpruceSLB_B0ToDpTauNu_DpToKPiPi_FakeElectron": [],
+    "SpruceSLB_BuToD0TauNu_D0ToKPi_TauToENuNu": [],
+    "SpruceSLB_BuToD0TauNu_D0ToKPi_FakeElectron": [],
+    "SpruceSLB_BuToD0MuNu_D0ToK3Pi": [],
+    "SpruceSLB_BuToD0MuNu_D0ToK3Pi_FakeMuon": [],
+    "SpruceSLB_BuToD0TauNu_D0ToK3Pi_TauToMuNuNu": [],
+    "SpruceSLB_BuToD0TauNu_D0ToK3Pi_FakeMuon": [],
+    "SpruceSLB_BuToD0TauNu_D0ToK3Pi_TauToPiPiPiNu": [],
+}
+#spruce line names for which parent names cannot be extracted
+spruce_lines_with_no_parent_names = {
+    "SpruceSLB_B2XuMuNuBs2K": ("B_s0", "B_s~0"),
+    "SpruceSLB_B2XuMuNuBs2K_NoPIDMu": ("B_s0", "B_s~0"),
+    "SpruceSLB_B2XuMuNuBs2K_NoPIDK": ("B_s0", "B_s~0"),
+}
+
+# Extra variables that need to be set to NaN
+extravars_that_need_nan = []
+extravars_that_need_nan += ['TRUEP']
+extravars_that_need_nan += ['TRUEPT']
+extravars_that_need_nan += ['TRUEPX']
+extravars_that_need_nan += ['TRUEPY']
+extravars_that_need_nan += ['TRUEPZ']
+extravars_that_need_nan += ['TRUEENERGY']
+extravars_that_need_nan += ['TRUEETA']
+extravars_that_need_nan += ['TRUEPHI']
+extravars_that_need_nan += ['TRACKPX']
+extravars_that_need_nan += ['TRACKPY']
+extravars_that_need_nan += ['TRACKPZ']
+extravars_that_need_nan += ['TRACKGHOSTPROB']
+extravars_that_need_nan += ['TRACKCHI2']
+extravars_that_need_nan += ['TRACKCHI2DOF']
+extravars_that_need_nan += ['TRUEORIGINVERTEX_X']
+extravars_that_need_nan += ['TRUEORIGINVERTEX_Y']
+extravars_that_need_nan += ['TRUEORIGINVERTEX_Z']
+extravars_that_need_nan += ['CaloTrackMatchChi2']
+extravars_that_need_nan += ['CaloNeutralShowerShape']
+extravars_that_need_nan += ['CaloClusterMass']
+extravars_that_need_nan += ['CaloNeutralEcalEnergy']
+extravars_that_need_nan += ['CaloNeutral1To9EnergyRatio']
+extravars_that_need_nan += ['CaloNeutral4To9EnergyRatio']
+extravars_that_need_nan += ['CaloNeutralHcal2EcalEnergyRatio']
+extravars_that_need_nan += ['CaloNumSaturatedCells']
+extravars_that_need_nan += ['CaloNeutralArea']
+extravars_that_need_nan += ['CaloNeutralID']
+extravars_that_need_nan += ['CaloNeutralRow']
+extravars_that_need_nan += ['CaloNeutralCol']
+
+# Prescale lines
+prescale_lines = [
+    'SpruceSLB_BuToD0TauNu_D0ToKPi_TauToPiPiPiNu',
+    'SpruceSLB_LbToLcTauNu_LcTopKPi_TauToPiPiPiNu',
+    'SpruceSLB_B2XuTauNu_HadronicBs2K',
+    'SpruceSLB_BuToD0TauNu_D0ToK3Pi_TauToPiPiPiNu',
+    'SpruceSLB_LbTopTauNu_TauToPiPiPiNu', 'SpruceSLB_B2XuTauNu_HadronicB02Pi',
+    'SpruceSLB_Xib0ToXicplusTauNu_XicplusTopKPi_TauToMuNuNu',
+    'SpruceSLB_BcToBsPi_BsToDsPi', 'SpruceSLB_BcToBsPi_BsToDsK',
+    'SpruceSLB_BsToDsTauNu_DsToKKPi_TauToPiPiPiNu',
+    'SpruceSLB_BcToBsK_BsToDsPi', 'SpruceSLB_B2XuTauNu_MuonicBs2K',
+    'SpruceSLB_B2EEENu', 'SpruceSLB_BcToBsK_BsToDsK',
+    'SpruceSLB_BuToD0ENu_D0ToKPi', 'SpruceSLB_BuToD0TauNu_D0ToKPi_TauToENuNu',
+    'SpruceSLB_B0ToDpTauNu_DpToKPiPi_TauToPiPiPiNu',
+    'SpruceSLB_LbToLcENu_LcToPKPi',
+    'SpruceSLB_LbToLcTauNu_LcToPKPi_TauToENuNu',
+    'SpruceSLB_LbToLcTauNu_LcToPKSDD_TautoENuNu',
+    'SpruceSLB_LbToLcTauNu_LcToLambdaPiLL_TautoENuNu'
+]
+
+
+def combine_with_extra_charged_particle(b_parts, extra_parts, line_name, pvs):
+    # Get old parent names
+    if line_name in spruce_lines_with_no_parent_names:
+        parent_name, anti_parent_name = spruce_lines_with_no_parent_names[
+            line_name]
+    else:
+        parent_name, anti_parent_name = extract_parent_name(line_name)
+
+    # Set new parent names
+    new_parent_name, anti_new_parent_name = 'B*+', 'B*-'
+
+    # Do the PID substitution of old parent names with new parent names
+    substitutions = [
+        f"{parent_name}{{{{{new_parent_name}}}}}",
+        f"{anti_parent_name}{{{{{anti_new_parent_name}}}}}"
+    ]
+    new_b_cands = SubstitutePID(name=f'PIDSubstitute_{line_name}',
+                                input_particles=b_parts,
+                                substitutions=substitutions).Particles
+
+    # Do the combination with extra particles
+    return combine_iso_pions(new_b_cands, extra_parts, line_name, pvs)
+
+
+def get_common(pvs, b_parts, mctruth_b=None):
+    #define common variables for all fields (composite and basic)
+    vars_common = FunctorCollection()
+
+    #best pv: x, y, z, ip, ipchi2
+    vars_common['BPV_X'] = F.BPVX(pvs)
+    vars_common['BPV_Y'] = F.BPVY(pvs)
+    vars_common['BPV_Z'] = F.BPVZ(pvs)
+    vars_common['BPV_IP'] = F.BPVIP(pvs)
+    vars_common['BPV_IPCHI2'] = F.BPVIPCHI2(pvs)
+    #vars_common['BPV_CHI2'] = F.CHI2 @ F.BPV(pvs)
+    #vars_common['BPV_CHI2DOF'] = F.CHI2DOF @ F.BPV(pvs)
+
+    #particle id, key, truekey. The trueid is stored in MCHierarchy
+    vars_common['ID'] = F.PARTICLE_ID
+    vars_common['KEY'] = F.OBJECT_KEY
+
+    #get charge, min ip and min ipchi2
+    vars_common['CHARGE'] = F.CHARGE
+    #vars_common['MINIP'] = F.MINIP(pvs)
+    #vars_common['MINIPCHI2'] = F.MINIPCHI2(pvs)
+
+    #reco kinematics
+    vars_common += FC.Kinematics()
+    #vars_common['ETA'] = F.ETA
+    #vars_common['PHI'] = F.PHI
+    #vars_common['MASS'] = F.MASS
+
+    if mctruth_b is not None:
+        vars_common['TRUEID'] = mctruth_b(F.VALUE_OR(0) @ F.PARTICLE_ID)
+        vars_common['TRUEKEY'] = mctruth_b(F.VALUE_OR(-1) @ F.OBJECT_KEY)
+        vars_common['BKGCAT'] = mctruth_b.BkgCat
+        ## prompt decay ancestor ID
+        #vars_common += FC.MCPromptDecay(mctruth_alg=mctruth_b)
+        # Add true kinematics
+        vars_common += FC.MCKinematics(mctruth_alg=mctruth_b)
+        vars_common['TRUEETA'] = mctruth_b(F.ETA)
+        vars_common['TRUEPHI'] = mctruth_b(F.PHI)
+        ## Add MCVertexInfo and MCPromptDecay
+        #vars_common['MC_VTX_TYPE'] = mctruth_b(
+        #    F.VALUE_OR(-1) @ F.MC_VTX_TYPE @ F.MC_ORIGINVERTEX)
+        hierarchy = FC.MCHierarchy(mctruth_alg=mctruth_b)
+        hierarchy.pop('TRUEID')
+        vars_common += hierarchy
+
+    # Add HltTisTos for HLT1 and HLT2
+    vars_common += FC.HltTisTos(selection_type=HltSourceID.Hlt1,
+                                trigger_lines=Hlt1_decisions,
+                                data=b_parts)
+    vars_common += FC.HltTisTos(selection_type=HltSourceID.Hlt2,
+                                trigger_lines=Hlt2_decisions,
+                                data=b_parts)
+    return vars_common
+
+
+def get_composite(pvs, mctruth_b=None):
+    # variables for composite particles
+    vars_composite = FunctorCollection()
+
+    #end vertex position and end vertex chi2
+    vars_composite['ENDVERTEX_POS_'] = F.ENDVERTEX_POS
+    vars_composite['ENDVERTEX_CHI2'] = F.CHI2 @ F.ENDVERTEX
+    vars_composite['ENDVERTEX_CHI2DOF'] = F.CHI2DOF @ F.ENDVERTEX
+
+    #best pv: dira, fd, fdchi2, corrm, ltime, dls
+    vars_composite['BPV_DIRA'] = F.BPVDIRA(pvs)
+    vars_composite['BPV_FD_'] = F.BPVFDVEC(pvs)
+    vars_composite['BPV_FDCHI2'] = F.BPVFDCHI2(pvs)
+    vars_composite['BPV_CORRM'] = F.BPVCORRM(pvs)
+    #vars_composite['BPV_LTIME'] = F.BPVLTIME(pvs)
+    #vars_composite['BPV_DLS'] = F.BPVDLS(pvs)
+    vars_composite['BPV_VDDZ'] = F.BPVVDZ(pvs)
+
+    #mc composite vertex information
+    if mctruth_b is not None:
+        vars_composite += FC.MCVertexInfo(mctruth_alg=mctruth_b)
+
+    #Compute maximum DOCA and maximum DOCACHI2.
+    vars_composite['MAX_DOCA'] = F.MAXDOCA
+    vars_composite['MAX_DOCACHI2'] = F.MAXDOCACHI2
+    return vars_composite
+
+
+def get_basic(mctruth_b=None):
+    # variables for basics
+    vars_basic = FunctorCollection()
+    vars_basic += FC.ParticleID(extra_info=True)  #PROBNN and DLL
+    vars_basic.pop('PID_PI')
+    #vars_basic['PPHASMUONINFO'] = F.PPHASMUONINFO @ F.PROTOPARTICLE
+    vars_basic['INMUON'] = F.INMUON
+    vars_basic['ISMUON'] = F.ISMUON
+
+    # track level quantities
+    #vars_basic['TRACKPX'] = F.PX @ F.TRACK
+    #vars_basic['TRACKPY'] = F.PY @ F.TRACK
+    #vars_basic['TRACKPZ'] = F.PZ @ F.TRACK
+    vars_basic['TRACKGHOSTPROB'] = F.GHOSTPROB
+    vars_basic['TRACKCHI2'] = F.CHI2 @ F.TRACK
+    vars_basic['TRACKCHI2DOF'] = F.CHI2DOF @ F.TRACK
+    vars_basic['TRACKISCLONE'] = F.VALUE_OR(-1) @ F.TRACKISCLONE @ F.TRACK
+    vars_basic["NHITS"] = F.VALUE_OR(-1) @ F.NHITS @ F.TRACK
+    vars_basic["NFTHITS"] = F.VALUE_OR(-1) @ F.NFTHITS @ F.TRACK
+    vars_basic["NUTHITS"] = F.VALUE_OR(-1) @ F.NUTHITS @ F.TRACK
+    vars_basic["NVPHITS"] = F.VALUE_OR(-1) @ F.NVPHITS @ F.TRACK
+    vars_basic['TRACKTYPE'] = F.VALUE_OR(
+        -1) @ F.CAST_TO_INT @ F.TRACKTYPE @ F.TRACK
+    if mctruth_b is not None:
+        vars_basic['TRUEORIGINVERTEX_X'] = mctruth_b(F.ORIGIN_VX)
+        vars_basic['TRUEORIGINVERTEX_Y'] = mctruth_b(F.ORIGIN_VY)
+        vars_basic['TRUEORIGINVERTEX_Z'] = mctruth_b(F.ORIGIN_VZ)
+
+    return vars_basic
+
+
+def get_brem():
+    # Variables to keep from functorcollection
+    brem_info = [
+        "INECAL", "INHCAL", "INBREM", "HASBREM", "HASBREMADDED", "BREMENERGY",
+        "BREMPIDE", "ELECTRONSHOWEREOP", "ELECTRONSHOWERDLL", "ELECTRONENERGY",
+        "BREMHYPOENERGY"]
+    charge_info = FC.ChargedCaloInfo(extra_info=True)
+
+    # Variables for bremsstrahlung photons
+    vars_brem = FunctorCollection()
+    for key in brem_info: vars_brem[key] = charge_info.functor_dict[key]
+    vars_brem += charge_info
+    vars_brem['P_WITH_BREM'] = F.P_WITH_BREM
+    vars_brem['PT_WITH_BREM'] = F.PT_WITH_BREM
+    vars_brem['MASS_WITH_BREM'] = F.MASS_WITH_BREM
+    # vars_brem["SHOWER_SHAPE"] = F.CALO_NEUTRAL_SHOWER_SHAPE
+    return vars_brem
+
+
+def get_extra_charged_vars(pvs, charged_parts, mctruth_charged=None):
+    #TODO: The extra charged particles will be duplicated in case of multiple B candidates.
+    # The solution around this is to store the ID and KEY of the B candidate (to match with the B in the main tuple)
+    # Plus the ID and KEY of extra particles to remove duplicates offline.
+    # We also store charm candidate momentum info to quick combinations with extra particles
+
+    #define helper function
+    map_func = lambda func: F.MAP(func) @ F.TES(charged_parts)
+    map_func_bcand = lambda func: F.MAP(func @ F.CHILD(1, F.FORWARDARGS)
+                                        ) @ F.TES(charged_parts)
+    map_func_extra_part = lambda func: F.MAP(func @ F.CHILD(2, F.FORWARDARGS)
+                                             ) @ F.TES(charged_parts)
+    map_func_bcand_charm = lambda func: F.MAP(func @ F.CHILD(
+        1, F.FORWARDARGS) @ F.CHILD(1, F.FORWARDARGS)) @ F.TES(charged_parts)
+
+    # get the MVA functor
+    MVA_functor, _ = mva_functor_inclusive(pvs)
+
+    # define functor collection for extra charged particles
+    extra_charged_vars = FunctorCollection()
+    #!!!Note: We have to use here map_func instead of map_func_extra_part
+    extra_charged_vars["EXTRA_PARTS_MVA[indx_extra_parts]"] = map_func(
+        MVA_functor)
+    common_fc = get_common(pvs, charged_parts, mctruth_charged)
+    basic_fc = get_basic(mctruth_charged)
+    extra_fc = common_fc + basic_fc
+    for key, value in extra_fc.functor_dict.items():
+        if key in extravars_that_need_nan:
+            extra_charged_vars[
+                f"EXTRA_PARTS_{key}[indx_extra_parts]"] = map_func_extra_part(
+                    F.VALUE_OR(F.NaN) @ value)
+        else:
+            extra_charged_vars[
+                f"EXTRA_PARTS_{key}[indx_extra_parts]"] = map_func_extra_part(
+                    value)
+
+    #get the hierarchy for the extra charged particles
+    hierarchy = FC.MCHierarchy(mctruth_alg=mctruth_charged)
+    hierarchy.pop('TRUEID')
+
+    ## add BPLUSEXTRA ID, key and momentum so that we can identify which B in the event it has been combined with
+    #extra_charged_vars["Bst_PX[indx_extra_parts]"] = map_func(F.PX)
+    #extra_charged_vars["Bst_PY[indx_extra_parts]"] = map_func(F.PY)
+    #extra_charged_vars["Bst_PZ[indx_extra_parts]"] = map_func(F.PZ)
+    #extra_charged_vars["Bst_MASS[indx_extra_parts]"] = map_func(F.MASS)
+    #extra_charged_vars["Bst_ID[indx_extra_parts]"] = map_func(F.PARTICLE_ID)
+    #extra_charged_vars["Bst_KEY[indx_extra_parts]"] = map_func(F.OBJECT_KEY)
+    #if mctruth_charged is not None:
+    #    extra_charged_vars["Bst_TRUEID[indx_extra_parts]"] = map_func(
+    #        mctruth_charged(F.VALUE_OR(0) @ F.PARTICLE_ID))
+    #    extra_charged_vars["Bst_TRUEKEY[indx_extra_parts]"] = map_func(
+    #        mctruth_charged(F.VALUE_OR(-1) @ F.OBJECT_KEY))
+    #    for key, value in hierarchy.functor_dict.items():
+    #        extra_charged_vars[f"Bst_{key}[indx_extra_parts]"] = map_func(
+    #            value)
+
+    # add B ID, key and momentum so that we can identify which B in the event it has been combined with
+    extra_charged_vars["DMU_PX[indx_extra_parts]"] = map_func_bcand(F.PX)
+    extra_charged_vars["DMU_PY[indx_extra_parts]"] = map_func_bcand(F.PY)
+    extra_charged_vars["DMU_PZ[indx_extra_parts]"] = map_func_bcand(F.PZ)
+    extra_charged_vars["DMU_MASS[indx_extra_parts]"] = map_func_bcand(F.MASS)
+    extra_charged_vars["DMU_ID[indx_extra_parts]"] = map_func_bcand(
+        F.PARTICLE_ID)
+    extra_charged_vars["DMU_KEY[indx_extra_parts]"] = map_func_bcand(
+        F.OBJECT_KEY)
+    if mctruth_charged is not None:
+        extra_charged_vars["DMU_TRUEP[indx_extra_parts]"] = map_func_bcand(
+            mctruth_charged(F.VALUE_OR(F.NaN) @ F.P))
+        extra_charged_vars["DMU_TRUEPT[indx_extra_parts]"] = map_func_bcand(
+            mctruth_charged(F.VALUE_OR(F.NaN) @ F.PT))
+        extra_charged_vars["DMU_TRUEID[indx_extra_parts]"] = map_func_bcand(
+            mctruth_charged(F.VALUE_OR(0) @ F.PARTICLE_ID))
+        extra_charged_vars["DMU_TRUEKEY[indx_extra_parts]"] = map_func_bcand(
+            mctruth_charged(F.VALUE_OR(-1) @ F.OBJECT_KEY))
+        for key, value in hierarchy.functor_dict.items():
+            extra_charged_vars[
+                f"DMU_{key}[indx_extra_parts]"] = map_func_bcand(value)
+
+    ## add charm(less) candidate ID, key and momentum for quick combinations with extra particles
+    #extra_charged_vars["D_PX[indx_extra_parts]"] = map_func_bcand_charm(F.PX)
+    #extra_charged_vars["D_PY[indx_extra_parts]"] = map_func_bcand_charm(F.PY)
+    #extra_charged_vars["D_PZ[indx_extra_parts]"] = map_func_bcand_charm(F.PZ)
+    #extra_charged_vars["D_MASS[indx_extra_parts]"] = map_func_bcand_charm(
+    #    F.MASS)
+    #extra_charged_vars["D_ID[indx_extra_parts]"] = map_func_bcand_charm(
+    #    F.PARTICLE_ID)
+    #extra_charged_vars["D_KEY[indx_extra_parts]"] = map_func_bcand_charm(
+    #    F.OBJECT_KEY)
+    #if mctruth_charged is not None:
+    #    extra_charged_vars[
+    #        "D_TRUEID[indx_extra_parts]"] = map_func_bcand_charm(
+    #            mctruth_charged(F.VALUE_OR(0) @ F.PARTICLE_ID))
+    #    extra_charged_vars[
+    #        "D_TRUEKEY[indx_extra_parts]"] = map_func_bcand_charm(
+    #            mctruth_charged(F.VALUE_OR(-1) @ F.OBJECT_KEY))
+    #    for key, value in hierarchy.functor_dict.items():
+    #        extra_charged_vars[
+    #            f"D_{key}[indx_extra_parts]"] = map_func_bcand_charm(value)
+
+    return extra_charged_vars
+
+
+def get_extra_neutral_vars(pvs, neutral_parts, mctruth_neutral=None):
+    #TODO: Cannot add NeutralCaloInfo because get error "'allocate' declared as a pointer to a reference of type 'const unsigned int &'"
+
+    #define helper function
+    map_func_neutral = lambda func: F.MAP(func) @ F.TES(neutral_parts)
+
+    # define functor collection for extra neutral particles
+    extra_neutral_vars = FunctorCollection()
+    #get common variables for neutral particles
+    common_fc = get_common(pvs, neutral_parts, mctruth_neutral)
+    #Get basic functor collection for extra charged particles
+    basic_fc = get_basic(mctruth_neutral)
+    #get the brem variables for neutral particles
+    vars_neutral = FC.NeutralCaloInfo(
+        extra_info=False)  #Turn this to True (high memory usage)
+    #add all the fc
+    extra_fc = common_fc + basic_fc + vars_neutral
+    #Add these to the event variables
+    for key, value in extra_fc.functor_dict.items():
+        if key in extravars_that_need_nan:
+            extra_neutral_vars[
+                f"EXTRA_NEUTRALS_{key}[indx_extra_neutrals]"] = map_func_neutral(
+                    F.VALUE_OR(F.NaN) @ value)
+        else:
+            extra_neutral_vars[
+                f"EXTRA_NEUTRALS_{key}[indx_extra_neutrals]"] = map_func_neutral(
+                    value)
+
+    return extra_neutral_vars
+
+
+def get_event_vars(pvs,
+                   line_name,
+                   charged_parts=None,
+                   neutral_parts=None,
+                   mctruth_charged=None,
+                   mctruth_neutral=None):
+    #variables for event
+    evt_vars = FunctorCollection()
+
+    # Add RecSummary functor collection
+    evt_vars += FC.RecSummary(detector_info=True)
+
+    # Add event decision and TCK for HLT1
+    evt_vars += FC.SelectionInfo(selection_type=HltSourceID.Hlt1,
+                                 trigger_lines=Hlt1_decisions)
+
+    # Add event decision for Hlt2 lines
+    evt_vars += FC.SelectionInfo(selection_type=HltSourceID.Hlt2,
+                                 trigger_lines=Hlt2_decisions +
+                                 [line_name.replace("Spruce", "Hlt2")])
+
+    ## Add event decision for spruce  (useless?)
+    #evt_vars += FC.SelectionInfo(selection_type = HltSourceID.Spruce, trigger_lines = [line_name])
+
+    # Add information about the charged particles
+    if charged_parts is not None:
+        evt_vars += get_extra_charged_vars(pvs, charged_parts, mctruth_charged)
+
+    ## Add information about the neutral particles
+    #if neutral_parts is not None:
+    #    evt_vars += get_extra_neutral_vars(pvs, neutral_parts, mctruth_neutral)
+
+    return evt_vars
+
+
+def get_neutral():
+    # variables for neutral particles
+    vars_neutral = FunctorCollection()
+    vars_neutral += FC.NeutralCaloInfo(extra_info=False)  # Turn extra info off
+    return vars_neutral
+
+
+def tuple_b_had(pvs,
+                line_name,
+                b_parts,
+                charged_parts,
+                neutral_parts,
+                mctruth_b=None,
+                mctruth_charged=None,
+                mctruth_neutral=None):
+    # Get functors
+    vars_common = get_common(pvs, b_parts, mctruth_b)
+    vars_composite = get_composite(pvs, mctruth_b)
+    vars_basic = get_basic(mctruth_b)
+    vars_brem = get_brem()
+    vars_neutral = get_neutral()
+    evt_vars = get_event_vars(pvs, line_name, charged_parts, neutral_parts,
+                              mctruth_charged, mctruth_neutral)
+
+    ## Define fields
+    #decay_descriptor = make_decay_descriptor(line_name)
+    #fields = make_fields(decay_descriptor)
+    fields = spruce_fields[line_name]
+
+    # Map fields to variables
+    variables = {"ALL": vars_common}
+    for field in fields:
+        if (field.startswith("B") and "_" not in field) or "_b" in field:
+            variables[field] = vars_composite
+        elif any(substring in field
+                 for substring in ["_p", "_K", "_pi", "_mu"]):
+            variables[field] = vars_basic
+        elif "_e" in field:
+            variables[field] = vars_basic + vars_brem
+        elif "_gamma" in field:
+            variables[field] = vars_composite + vars_neutral
+        else:
+            variables[field] = vars_composite
+
+    # Define tuple
+    return Funtuple(name=f"Tuple_{line_name}",
+                    tuple_name="DecayTree",
+                    fields=fields,
+                    variables=variables,
+                    event_variables=evt_vars,
+                    store_multiple_cand_info=True,
+                    inputs=b_parts)
+
+
+def main(options: Options, isMC: bool, block: str):
+    user_algorithms = {}
+    for line_name in spruce_line_names:
+        if any(substring in line_name
+               for substring in ["Fake", "SS", "WS", "NoPID"]):
+            continue
+
+        # get the primary vertices
+        pvs = get_pvs()
+
+        # get the B particles
+        b_parts = get_particles(f"/Event/Spruce/{line_name}/Particles")
+
+        # get charged and neutral particles in the event
+        charged_parts = None
+        neutral_parts = None
+        if line_name in spruce_lines_with_extra_particles and block not in spruce_lines_with_extra_particles[
+                line_name]:
+            # get the charged particles in the event
+            extra_charged_part = get_particles(
+                f"/Event/Spruce/{line_name}/{line_name}_extra_tracks/Particles"
+            )
+            # Note now we combine with the b_parts so as to get MVA score (i.e. how isolated the extra charged particle is)
+            # naming it here charged_parts is a bit misleading bcos it really is the "B + Extra particle" combination
+            charged_parts = combine_with_extra_charged_particle(
+                b_parts, extra_charged_part, line_name, pvs)
+            # get the neutral particles in the event
+            neutral_parts = get_particles(
+                f"/Event/Spruce/{line_name}/{line_name}_extra_neutrals/Particles"
+            )
+
+        # make truth matching algorithms
+        mctruth_b = MCTruthAndBkgCat(b_parts,
+                                     name='mctruth_b_{hash}') if isMC else None
+        mctruth_charged = MCTruthAndBkgCat(
+            charged_parts,
+            name='mctruth_charged_{hash}') if isMC and charged_parts else None
+        mctruth_neutral = MCTruthAndBkgCat(
+            neutral_parts,
+            name='mctruth_neutral_{hash}') if isMC and neutral_parts else None
+
+        # Create tuple
+        tuple_file = tuple_b_had(pvs, line_name, b_parts, charged_parts,
+                                 neutral_parts, mctruth_b, mctruth_charged,
+                                 mctruth_neutral)
+
+        # Define filter
+        my_filter = create_lines_filter(name=f"Filter_{line_name}",
+                                        lines=[line_name])
+
+        # prescale if need be
+        if line_name in prescale_lines:
+            prescale = 0.05
+            prescaler = DeterministicPrescaler(name="Prescaler",
+                                               AcceptFraction=prescale,
+                                               SeedName="PrescaleSeed",
+                                               ODINLocation=get_odin())
+            alg_list = [my_filter, prescaler, tuple_file]
+        else:
+            alg_list = [my_filter, tuple_file]
+
+        user_algorithms[line_name] = alg_list
+
+    return make_config(options, user_algorithms)
diff --git a/slb-minbias-sprucing/fields.json b/slb-minbias-sprucing/fields.json
new file mode 100644
index 0000000000..b783d18cd9
--- /dev/null
+++ b/slb-minbias-sprucing/fields.json
@@ -0,0 +1,913 @@
+{
+  "SpruceSLB_BuToD0TauNu_D0ToK3Pi_TauToPiPiPiNu": {
+      "B": "[B+ -> ([D0 -> K- pi+ pi- pi+]CC) ([tau+ -> pi+ pi+ pi-]CC)]CC",
+      "B_D0": "[B+ -> ^([D0 -> K- pi+ pi- pi+]CC) ([tau+ -> pi+ pi+ pi-]CC)]CC",
+      "D0_Km": "[B+ -> ([D0 -> ^K- pi+ pi- pi+]CC) ([tau+ -> pi+ pi+ pi-]CC)]CC",
+      "D0_pip": "[B+ -> ([D0 -> K- ^pi+ pi- pi+]CC) ([tau+ -> pi+ pi+ pi-]CC)]CC",
+      "D0_pim": "[B+ -> ([D0 -> K- pi+ ^pi- pi+]CC) ([tau+ -> pi+ pi+ pi-]CC)]CC",
+      "D0_pip2": "[B+ -> ([D0 -> K- pi+ pi- ^pi+]CC) ([tau+ -> pi+ pi+ pi-]CC)]CC",
+      "B_tau": "[B+ -> ([D0 -> K- pi+ pi- pi+]CC) ^([tau+ -> pi+ pi+ pi-]CC)]CC",
+      "tau_pip": "[B+ -> ([D0 -> K- pi+ pi- pi+]CC) ([tau+ -> ^pi+ pi+ pi-]CC)]CC",
+      "tau_pip2": "[B+ -> ([D0 -> K- pi+ pi- pi+]CC) ([tau+ -> pi+ ^pi+ pi-]CC)]CC",
+      "tau_pim": "[B+ -> ([D0 -> K- pi+ pi- pi+]CC) ([tau+ -> pi+ pi+ ^pi-]CC)]CC"
+  },
+  "SpruceSLB_BcToJpsiTauNu_JpsiToMuMu_TauToMuNuNu": {
+      "Bc": "[B_c+ -> (J/psi(1S) -> mu+ mu-) [mu+]CC]CC",
+      "Bc_Jpsi": "[B_c+ -> ^(J/psi(1S) -> mu+ mu-) [mu+]CC]CC",
+      "Jpsi_mup": "[B_c+ -> (J/psi(1S) -> ^mu+ mu-) [mu+]CC]CC",
+      "Jpsi_mum": "[B_c+ -> (J/psi(1S) -> mu+ ^mu-) [mu+]CC]CC",
+      "Bc_mu": "[B_c+ -> (J/psi(1S) -> mu+ mu-) ^[mu+]CC]CC"
+  },
+  "SpruceSLB_BcToJpsiTauNu_JpsiToMuMu_TauToENuNu": {
+      "Bc": "[B_c+ -> (J/psi(1S) -> mu+ mu-) [e+]CC]CC",
+      "Bc_Jpsi": "[B_c+ -> ^(J/psi(1S) -> mu+ mu-) [e+]CC]CC",
+      "Jpsi_mup": "[B_c+ -> (J/psi(1S) -> ^mu+ mu-) [e+]CC]CC",
+      "Jpsi_mum": "[B_c+ -> (J/psi(1S) -> mu+ ^mu-) [e+]CC]CC",
+      "Bc_ep": "[B_c+ -> (J/psi(1S) -> mu+ mu-) ^[e+]CC]CC"
+  },
+  "SpruceSLB_B0ToDpTauNu_DpToKPiPi_TauToMuNuNu": {
+      "Bz": "[B0 -> ([D+ -> K- pi+ pi+]CC) [mu-]CC]CC",
+      "Bz_Dp": "[B0 -> ^([D+ -> K- pi+ pi+]CC) [mu-]CC]CC",
+      "Dp_Km": "[B0 -> ([D+ -> ^K- pi+ pi+]CC) [mu-]CC]CC",
+      "Dp_pip": "[B0 -> ([D+ -> K- ^pi+ pi+]CC) [mu-]CC]CC",
+      "Dp_pip2": "[B0 -> ([D+ -> K- pi+ ^pi+]CC) [mu-]CC]CC",
+      "Bz_mum": "[B0 -> ([D+ -> K- pi+ pi+]CC) ^[mu-]CC]CC"
+  },
+  "SpruceSLB_B0ToDpTauNu_DpToKPiPi_TauToENuNu": {
+      "Bz": "[B0 -> ([D+ -> K- pi+ pi+]CC) [e-]CC]CC",
+      "Bz_Dp": "[B0 -> ^([D+ -> K- pi+ pi+]CC) [e-]CC]CC",
+      "Dp_Km": "[B0 -> ([D+ -> ^K- pi+ pi+]CC) [e-]CC]CC",
+      "Dp_pip": "[B0 -> ([D+ -> K- ^pi+ pi+]CC) [e-]CC]CC",
+      "Dp_pip2": "[B0 -> ([D+ -> K- pi+ ^pi+]CC) [e-]CC]CC",
+      "Bz_em": "[B0 -> ([D+ -> K- pi+ pi+]CC) ^[e-]CC]CC"
+  },
+  "SpruceSLB_BuToD0TauNu_D0ToKPi_TauToMuNuNu": {
+      "B": "[B+ -> ([D0 -> K- pi+]CC) [mu+]CC]CC",
+      "B_D0": "[B+ -> ^([D0 -> K- pi+]CC) [mu+]CC]CC",
+      "D0_Km": "[B+ -> ([D0 -> ^K- pi+]CC) [mu+]CC]CC",
+      "D0_pip": "[B+ -> ([D0 -> K- ^pi+]CC) [mu+]CC]CC",
+      "B_mup": "[B+ -> ([D0 -> K- pi+]CC) ^[mu+]CC]CC"
+  },
+  "SpruceSLB_BuToD0TauNu_D0ToKPi_TauToENuNu": {
+      "B": "[B+ -> ([D0 -> K- pi+]CC) [e+]CC]CC",
+      "B_D0": "[B+ -> ^([D0 -> K- pi+]CC) [e+]CC]CC",
+      "D0_Km": "[B+ -> ([D0 -> ^K- pi+]CC) [e+]CC]CC",
+      "D0_pip": "[B+ -> ([D0 -> K- ^pi+]CC) [e+]CC]CC",
+      "B_ep": "[B+ -> ([D0 -> K- pi+]CC) ^[e+]CC]CC"
+  },
+  "SpruceSLB_BuToD0TauNu_D0ToK3Pi_TauToMuNuNu": {
+      "B": "[B+ -> ([D0 -> K- pi+ pi- pi+]CC) [mu+]CC]CC",
+      "B_D0": "[B+ -> ^([D0 -> K- pi+ pi- pi+]CC) [mu+]CC]CC",
+      "D0_Km": "[B+ -> ([D0 -> ^K- pi+ pi- pi+]CC) [mu+]CC]CC",
+      "D0_pip": "[B+ -> ([D0 -> K- ^pi+ pi- pi+]CC) [mu+]CC]CC",
+      "D0_pim": "[B+ -> ([D0 -> K- pi+ ^pi- pi+]CC) [mu+]CC]CC",
+      "D0_pip2": "[B+ -> ([D0 -> K- pi+ pi- ^pi+]CC) [mu+]CC]CC",
+      "B_mup": "[B+ -> ([D0 -> K- pi+ pi- pi+]CC) ^[mu+]CC]CC"
+  },
+  "SpruceSLB_BuToD0TauNu_D0ToK3Pi_TauToENuNu": {
+      "B": "[B+ -> ([D0 -> K- pi+ pi- pi+]CC) [e+]CC]CC",
+      "B_D0": "[B+ -> ^([D0 -> K- pi+ pi- pi+]CC) [e+]CC]CC",
+      "D0_Km": "[B+ -> ([D0 -> ^K- pi+ pi- pi+]CC) [e+]CC]CC",
+      "D0_pip": "[B+ -> ([D0 -> K- ^pi+ pi- pi+]CC) [e+]CC]CC",
+      "D0_pim": "[B+ -> ([D0 -> K- pi+ ^pi- pi+]CC) [e+]CC]CC",
+      "D0_pip2": "[B+ -> ([D0 -> K- pi+ pi- ^pi+]CC) [e+]CC]CC",
+      "B_ep": "[B+ -> ([D0 -> K- pi+ pi- pi+]CC) ^[e+]CC]CC"
+  },
+  "SpruceSLB_BsToDsTauNu_DsToKKPi_TauToMuNuNu": {
+      "Bs": "[B_s0 -> ([D_s- -> K+ K- pi-]CC) [mu+]CC]CC",
+      "Bs_Dsm": "[B_s0 -> ^([D_s- -> K+ K- pi-]CC) [mu+]CC]CC",
+      "Dsm_Kp": "[B_s0 -> ([D_s- -> ^K+ K- pi-]CC) [mu+]CC]CC",
+      "Dsm_Km": "[B_s0 -> ([D_s- -> K+ ^K- pi-]CC) [mu+]CC]CC",
+      "Dsm_pim": "[B_s0 -> ([D_s- -> K+ K- ^pi-]CC) [mu+]CC]CC",
+      "Bs_mup": "[B_s0 -> ([D_s- -> K+ K- pi-]CC) ^[mu+]CC]CC"
+  },
+  "SpruceSLB_BsToDsTauNu_DsToKKPi_TauToENuNu": {
+      "Bs": "[B_s0 -> ([D_s- -> K+ K- pi-]CC) [e+]CC]CC",
+      "Bs_Dsm": "[B_s0 -> ^([D_s- -> K+ K- pi-]CC) [e+]CC]CC",
+      "Dsm_Kp": "[B_s0 -> ([D_s- -> ^K+ K- pi-]CC) [e+]CC]CC",
+      "Dsm_Km": "[B_s0 -> ([D_s- -> K+ ^K- pi-]CC) [e+]CC]CC",
+      "Dsm_pim": "[B_s0 -> ([D_s- -> K+ K- ^pi-]CC) [e+]CC]CC",
+      "Bs_ep": "[B_s0 -> ([D_s- -> K+ K- pi-]CC) ^[e+]CC]CC"
+  },
+  "SpruceSLB_LbToLcMuNu_LcToPKPi": {
+      "Lb": "[Lambda_b0 -> ([Lambda_c+ -> p+ K- pi+]CC) mu-]CC",
+      "Lb_Lc": "[Lambda_b0 -> ^([Lambda_c+ -> p+ K- pi+]CC) mu-]CC",
+      "Lc_p": "[Lambda_b0 -> ([Lambda_c+ -> ^p+ K- pi+]CC) mu-]CC",
+      "Lc_Km": "[Lambda_b0 -> ([Lambda_c+ -> p+ ^K- pi+]CC) mu-]CC",
+      "Lc_pip": "[Lambda_b0 -> ([Lambda_c+ -> p+ K- ^pi+]CC) mu-]CC",
+      "Lb_mum": "[Lambda_b0 -> ([Lambda_c+ -> p+ K- pi+]CC) ^mu-]CC"
+  },
+  "SpruceSLB_LbToLcENu_LcToPKPi": {
+      "Lb": "[Lambda_b0 -> ([Lambda_c+ -> p+ K- pi+]CC) e-]CC",
+      "Lb_Lc": "[Lambda_b0 -> ^([Lambda_c+ -> p+ K- pi+]CC) e-]CC",
+      "Lc_p": "[Lambda_b0 -> ([Lambda_c+ -> ^p+ K- pi+]CC) e-]CC",
+      "Lc_Km": "[Lambda_b0 -> ([Lambda_c+ -> p+ ^K- pi+]CC) e-]CC",
+      "Lc_pip": "[Lambda_b0 -> ([Lambda_c+ -> p+ K- ^pi+]CC) e-]CC",
+      "Lb_em": "[Lambda_b0 -> ([Lambda_c+ -> p+ K- pi+]CC) ^e-]CC"
+  },
+  "SpruceSLB_LbToLcTauNu_LcToPKPi_TauToMuNuNu": {
+      "Lb": "[Lambda_b0 -> ([Lambda_c+ -> p+ K- pi+]CC) [mu-]CC]CC",
+      "Lb_Lc": "[Lambda_b0 -> ^([Lambda_c+ -> p+ K- pi+]CC) [mu-]CC]CC",
+      "Lc_p": "[Lambda_b0 -> ([Lambda_c+ -> ^p+ K- pi+]CC) [mu-]CC]CC",
+      "Lc_Km": "[Lambda_b0 -> ([Lambda_c+ -> p+ ^K- pi+]CC) [mu-]CC]CC",
+      "Lc_pip": "[Lambda_b0 -> ([Lambda_c+ -> p+ K- ^pi+]CC) [mu-]CC]CC",
+      "Lb_mum": "[Lambda_b0 -> ([Lambda_c+ -> p+ K- pi+]CC) ^[mu-]CC]CC"
+  },
+  "SpruceSLB_LbToLcTauNu_LcToPKPi_TauToENuNu": {
+      "Lb": "[Lambda_b0 -> ([Lambda_c+ -> p+ K- pi+]CC) [e-]CC]CC",
+      "Lb_Lc": "[Lambda_b0 -> ^([Lambda_c+ -> p+ K- pi+]CC) [e-]CC]CC",
+      "Lc_p": "[Lambda_b0 -> ([Lambda_c+ -> ^p+ K- pi+]CC) [e-]CC]CC",
+      "Lc_Km": "[Lambda_b0 -> ([Lambda_c+ -> p+ ^K- pi+]CC) [e-]CC]CC",
+      "Lc_pip": "[Lambda_b0 -> ([Lambda_c+ -> p+ K- ^pi+]CC) [e-]CC]CC",
+      "Lb_em": "[Lambda_b0 -> ([Lambda_c+ -> p+ K- pi+]CC) ^[e-]CC]CC"
+  },
+  "SpruceSLB_BcToJpsiMuNu_JpsiToMuMu": {
+      "Bc": "[B_c+ -> (J/psi(1S) -> mu+ mu-) mu+]CC",
+      "Bc_Jpsi": "[B_c+ -> ^(J/psi(1S) -> mu+ mu-) mu+]CC",
+      "Jpsi_mup": "[B_c+ -> (J/psi(1S) -> ^mu+ mu-) mu+]CC",
+      "Jpsi_mum": "[B_c+ -> (J/psi(1S) -> mu+ ^mu-) mu+]CC",
+      "Bc_mup": "[B_c+ -> (J/psi(1S) -> mu+ mu-) ^mu+]CC"
+  },
+  "SpruceSLB_BcToJpsiENu_JpsiToMuMu": {
+      "Bc": "[B_c+ -> (J/psi(1S) -> mu+ mu-) e+]CC",
+      "Bc_Jpsi": "[B_c+ -> ^(J/psi(1S) -> mu+ mu-) e+]CC",
+      "Jpsi_mup": "[B_c+ -> (J/psi(1S) -> ^mu+ mu-) e+]CC",
+      "Jpsi_mum": "[B_c+ -> (J/psi(1S) -> mu+ ^mu-) e+]CC",
+      "Bc_ep": "[B_c+ -> (J/psi(1S) -> mu+ mu-) ^e+]CC"
+  },
+  "SpruceSLB_BuToD0MuNu_D0ToKPi": {
+      "B": "[B+ -> ([D0 -> K- pi+]CC) mu+]CC",
+      "B_D0": "[B+ -> ^([D0 -> K- pi+]CC) mu+]CC",
+      "D0_Km": "[B+ -> ([D0 -> ^K- pi+]CC) mu+]CC",
+      "D0_pip": "[B+ -> ([D0 -> K- ^pi+]CC) mu+]CC",
+      "B_mup": "[B+ -> ([D0 -> K- pi+]CC) ^mu+]CC"
+  },
+  "SpruceSLB_BuToD0ENu_D0ToKPi": {
+      "B": "[B+ -> ([D0 -> K- pi+]CC) e+]CC",
+      "B_D0": "[B+ -> ^([D0 -> K- pi+]CC) e+]CC",
+      "D0_Km": "[B+ -> ([D0 -> ^K- pi+]CC) e+]CC",
+      "D0_pip": "[B+ -> ([D0 -> K- ^pi+]CC) e+]CC",
+      "B_ep": "[B+ -> ([D0 -> K- pi+]CC) ^e+]CC"
+  },
+  "SpruceSLB_BuToD0MuNu_D0ToK3Pi": {
+      "B": "[B+ -> ([D0 -> K- pi+ pi- pi+]CC) mu+]CC",
+      "B_D0": "[B+ -> ^([D0 -> K- pi+ pi- pi+]CC) mu+]CC",
+      "D0_Km": "[B+ -> ([D0 -> ^K- pi+ pi- pi+]CC) mu+]CC",
+      "D0_pip": "[B+ -> ([D0 -> K- ^pi+ pi- pi+]CC) mu+]CC",
+      "D0_pim": "[B+ -> ([D0 -> K- pi+ ^pi- pi+]CC) mu+]CC",
+      "D0_pip2": "[B+ -> ([D0 -> K- pi+ pi- ^pi+]CC) mu+]CC",
+      "B_mup": "[B+ -> ([D0 -> K- pi+ pi- pi+]CC) ^mu+]CC"
+  },
+  "SpruceSLB_BuToD0ENu_D0ToK3Pi": {
+      "B": "[B+ -> ([D0 -> K- pi+ pi- pi+]CC) e+]CC",
+      "B_D0": "[B+ -> ^([D0 -> K- pi+ pi- pi+]CC) e+]CC",
+      "D0_Km": "[B+ -> ([D0 -> ^K- pi+ pi- pi+]CC) e+]CC",
+      "D0_pip": "[B+ -> ([D0 -> K- ^pi+ pi- pi+]CC) e+]CC",
+      "D0_pim": "[B+ -> ([D0 -> K- pi+ ^pi- pi+]CC) e+]CC",
+      "D0_pip2": "[B+ -> ([D0 -> K- pi+ pi- ^pi+]CC) e+]CC",
+      "B_ep": "[B+ -> ([D0 -> K- pi+ pi- pi+]CC) ^e+]CC"
+  },
+  "SpruceSLB_B0ToDpMuNu_DpToKPiPi": {
+      "Bz": "[B0 -> ([D+ -> K- pi+ pi+]CC) mu-]CC",
+      "Bz_Dp": "[B0 -> ^([D+ -> K- pi+ pi+]CC) mu-]CC",
+      "Dp_Km": "[B0 -> ([D+ -> ^K- pi+ pi+]CC) mu-]CC",
+      "Dp_pip": "[B0 -> ([D+ -> K- ^pi+ pi+]CC) mu-]CC",
+      "Dp_pip2": "[B0 -> ([D+ -> K- pi+ ^pi+]CC) mu-]CC",
+      "Bz_mum": "[B0 -> ([D+ -> K- pi+ pi+]CC) ^mu-]CC"
+  },
+  "SpruceSLB_B0ToDpENu_DpToKPiPi": {
+      "Bz": "[B0 -> ([D+ -> K- pi+ pi+]CC) e-]CC",
+      "Bz_Dp": "[B0 -> ^([D+ -> K- pi+ pi+]CC) e-]CC",
+      "Dp_Km": "[B0 -> ([D+ -> ^K- pi+ pi+]CC) e-]CC",
+      "Dp_pip": "[B0 -> ([D+ -> K- ^pi+ pi+]CC) e-]CC",
+      "Dp_pip2": "[B0 -> ([D+ -> K- pi+ ^pi+]CC) e-]CC",
+      "Bz_em": "[B0 -> ([D+ -> K- pi+ pi+]CC) ^e-]CC"
+  },
+  "SpruceSLB_B0ToDpMuNu_DpToKKPi": {
+      "Bz": "[B0 -> ([D+ -> K- K+ pi+]CC) mu-]CC",
+      "Bz_Dp": "[B0 -> ^([D+ -> K- K+ pi+]CC) mu-]CC",
+      "Dp_Km": "[B0 -> ([D+ -> ^K- K+ pi+]CC) mu-]CC",
+      "Dp_Kp": "[B0 -> ([D+ -> K- ^K+ pi+]CC) mu-]CC",
+      "Dp_pip": "[B0 -> ([D+ -> K- K+ ^pi+]CC) mu-]CC",
+      "Bz_mum": "[B0 -> ([D+ -> K- K+ pi+]CC) ^mu-]CC"
+  },
+  "SpruceSLB_B0ToDpENu_DpToKKPi": {
+      "Bz": "[B0 -> ([D+ -> K- K+ pi+]CC) e-]CC",
+      "Bz_Dp": "[B0 -> ^([D+ -> K- K+ pi+]CC) e-]CC",
+      "Dp_Km": "[B0 -> ([D+ -> ^K- K+ pi+]CC) e-]CC",
+      "Dp_Kp": "[B0 -> ([D+ -> K- ^K+ pi+]CC) e-]CC",
+      "Dp_pip": "[B0 -> ([D+ -> K- K+ ^pi+]CC) e-]CC",
+      "Bz_em": "[B0 -> ([D+ -> K- K+ pi+]CC) ^e-]CC"
+  },
+  "SpruceSLB_BsToDsMuNu_DsToKKPi": {
+      "Bs": "[B_s0 -> ([D_s- -> K+ K- pi-]CC) mu+]CC",
+      "Bs_Dsm": "[B_s0 -> ^([D_s- -> K+ K- pi-]CC) mu+]CC",
+      "Dsm_Kp": "[B_s0 -> ([D_s- -> ^K+ K- pi-]CC) mu+]CC",
+      "Dsm_Km": "[B_s0 -> ([D_s- -> K+ ^K- pi-]CC) mu+]CC",
+      "Dsm_pim": "[B_s0 -> ([D_s- -> K+ K- ^pi-]CC) mu+]CC",
+      "Bs_mup": "[B_s0 -> ([D_s- -> K+ K- pi-]CC) ^mu+]CC"
+  },
+  "SpruceSLB_BsToDsstMuNu_DsstToDsGamma_DsToKKPi_Gamma2EE": {
+      "Bs": "[B_s0 -> ([D*_s- -> ([D_s- -> K+ K- pi-]CC) (gamma -> e+ e-)]CC) mu+]CC",
+      "Bs_Dsstm": "[B_s0 -> ^([D*_s- -> ([D_s- -> K+ K- pi-]CC) (gamma -> e+ e-)]CC) mu+]CC",
+      "Dsstm_Dsm": "[B_s0 -> ([D*_s- -> ^([D_s- -> K+ K- pi-]CC) (gamma -> e+ e-)]CC) mu+]CC",
+      "Dsm_Kp": "[B_s0 -> ([D*_s- -> ([D_s- -> ^K+ K- pi-]CC) (gamma -> e+ e-)]CC) mu+]CC",
+      "Dsm_Km": "[B_s0 -> ([D*_s- -> ([D_s- -> K+ ^K- pi-]CC) (gamma -> e+ e-)]CC) mu+]CC",
+      "Dsm_pim": "[B_s0 -> ([D*_s- -> ([D_s- -> K+ K- ^pi-]CC) (gamma -> e+ e-)]CC) mu+]CC",
+      "Dsstm_gamma": "[B_s0 -> ([D*_s- -> ([D_s- -> K+ K- pi-]CC) ^(gamma -> e+ e-)]CC) mu+]CC",
+      "gamma_ep": "[B_s0 -> ([D*_s- -> ([D_s- -> K+ K- pi-]CC) ([gamma -> ^e+ e-]CC)]CC) mu+]CC",
+      "gamma_em": "[B_s0 -> ([D*_s- -> ([D_s- -> K+ K- pi-]CC) ([gamma -> e+ ^e-]CC)]CC) mu+]CC",
+      "Dsstm_mup": "[B_s0 -> ([D*_s- -> ([D_s- -> K+ K- pi-]CC) (gamma -> e+ e-)]CC) ^mu+]CC"
+  },
+  "SpruceSLB_BsToDsENu_DsToKKPi": {
+      "Bs": "[B_s0 -> ([D_s- -> K+ K- pi-]CC) e+]CC",
+      "Bs_Dsm": "[B_s0 -> ^([D_s- -> K+ K- pi-]CC) e+]CC",
+      "Dsm_Kp": "[B_s0 -> ([D_s- -> ^K+ K- pi-]CC) e+]CC",
+      "Dsm_Km": "[B_s0 -> ([D_s- -> K+ ^K- pi-]CC) e+]CC",
+      "Dsm_pim": "[B_s0 -> ([D_s- -> K+ K- ^pi-]CC) e+]CC",
+      "Bs_ep": "[B_s0 -> ([D_s- -> K+ K- pi-]CC) ^e+]CC"
+  },
+  "SpruceSLB_Xib0ToXicplusMuNu_XicplusTopKPi": {
+      "Xibz": "[Xi_b0 -> ([Xi_c+ -> p+ K- pi+]CC) mu-]CC",
+      "Xibz_Xic": "[Xi_b0 -> ^([Xi_c+ -> p+ K- pi+]CC) mu-]CC",
+      "Xic_p": "[Xi_b0 -> ([Xi_c+ -> ^p+ K- pi+]CC) mu-]CC",
+      "Xic_Km": "[Xi_b0 -> ([Xi_c+ -> p+ ^K- pi+]CC) mu-]CC",
+      "Xic_pip": "[Xi_b0 -> ([Xi_c+ -> p+ K- ^pi+]CC) mu-]CC",
+      "Xibz_mum": "[Xi_b0 -> ([Xi_c+ -> p+ K- pi+]CC) ^mu-]CC"
+  },
+  "SpruceSLB_Xib0ToXicplusTauNu_XicplusTopKPi_TauToMuNuNu": {
+      "Xibz": "[Xi_b0 -> ([Xi_c+ -> p+ K- pi+]CC) [mu-]CC]CC",
+      "Xibz_Xic": "[Xi_b0 -> ^([Xi_c+ -> p+ K- pi+]CC) [mu-]CC]CC",
+      "Xic_p": "[Xi_b0 -> ([Xi_c+ -> ^p+ K- pi+]CC) [mu-]CC]CC",
+      "Xic_Km": "[Xi_b0 -> ([Xi_c+ -> p+ ^K- pi+]CC) [mu-]CC]CC",
+      "Xic_pip": "[Xi_b0 -> ([Xi_c+ -> p+ K- ^pi+]CC) [mu-]CC]CC",
+      "Xibz_mum": "[Xi_b0 -> ([Xi_c+ -> p+ K- pi+]CC) ^[mu-]CC]CC"
+  },
+  "SpruceSLB_XibminusToXic0MuNu_Xic0TopKKPi": {
+      "Xibm": "[Xi_b- -> ([Xi_c0 -> p+ K- K+ pi-]CC) mu-]CC",
+      "Xibm_Xi_c0": "[Xi_b- -> ^([Xi_c0 -> p+ K- K+ pi-]CC) mu-]CC",
+      "Xi_c0_p": "[Xi_b- -> ([Xi_c0 -> ^p+ K- K+ pi-]CC) mu-]CC",
+      "Xi_c0_Km": "[Xi_b- -> ([Xi_c0 -> p+ ^K- K+ pi-]CC) mu-]CC",
+      "Xi_c0_Kp": "[Xi_b- -> ([Xi_c0 -> p+ K- ^K+ pi-]CC) mu-]CC",
+      "Xi_c0_pim": "[Xi_b- -> ([Xi_c0 -> p+ K- K+ ^pi-]CC) mu-]CC",
+      "Xibm_mum": "[Xi_b- -> ([Xi_c0 -> p+ K- K+ pi-]CC) ^mu-]CC"
+  },
+  "SpruceSLB_XibminusToXic0TauNu_Xic0TopKKPi_TauToMuNuNu": {
+      "Xibm": "[Xi_b- -> ([Xi_c0 -> p+ K- K+ pi-]CC) [mu-]CC]CC",
+      "Xibm_Xi_c0": "[Xi_b- -> ^([Xi_c0 -> p+ K- K+ pi-]CC) [mu-]CC]CC",
+      "Xi_c0_p": "[Xi_b- -> ([Xi_c0 -> ^p+ K- K+ pi-]CC) [mu-]CC]CC",
+      "Xi_c0_Km": "[Xi_b- -> ([Xi_c0 -> p+ ^K- K+ pi-]CC) [mu-]CC]CC",
+      "Xi_c0_Kp": "[Xi_b- -> ([Xi_c0 -> p+ K- ^K+ pi-]CC) [mu-]CC]CC",
+      "Xi_c0_pim": "[Xi_b- -> ([Xi_c0 -> p+ K- K+ ^pi-]CC) [mu-]CC]CC",
+      "Xibm_mum": "[Xi_b- -> ([Xi_c0 -> p+ K- K+ pi-]CC) ^[mu-]CC]CC"
+  },
+  "SpruceSLB_BcToD0MuNu_D0ToKPi": {
+      "Bc": "[B_c+ -> ([D0 -> K- pi+]CC) mu+]CC",
+      "Bc_D0": "[B_c+ -> ^([D0 -> K- pi+]CC) mu+]CC",
+      "D0_Km": "[B_c+ -> ([D0 -> ^K- pi+]CC) mu+]CC",
+      "D0_pip": "[B_c+ -> ([D0 -> K- ^pi+]CC) mu+]CC",
+      "Bc_mup": "[B_c+ -> ([D0 -> K- pi+]CC) ^mu+]CC"
+  },
+  "SpruceSLB_BcToD0ENu_D0ToKPi": {
+      "Bc": "[B_c+ -> ([D0 -> K- pi+]CC) e+]CC",
+      "Bc_D0": "[B_c+ -> ^([D0 -> K- pi+]CC) e+]CC",
+      "D0_Km": "[B_c+ -> ([D0 -> ^K- pi+]CC) e+]CC",
+      "D0_pip": "[B_c+ -> ([D0 -> K- ^pi+]CC) e+]CC",
+      "Bc_ep": "[B_c+ -> ([D0 -> K- pi+]CC) ^e+]CC"
+  },
+  "SpruceSLB_B0ToDpTauNu_DpToKPiPi_TauToPiPiPiNu": {
+      "Bz": "[B0 -> ([D+ -> K- pi+ pi+]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Bz_Dp": "[B0 -> ^([D+ -> K- pi+ pi+]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Dp_Km": "[B0 -> ([D+ -> ^K- pi+ pi+]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Dp_pip": "[B0 -> ([D+ -> K- ^pi+ pi+]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Dp_pip2": "[B0 -> ([D+ -> K- pi+ ^pi+]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Bz_tau": "[B0 -> ([D+ -> K- pi+ pi+]CC) ^([tau- -> pi- pi+ pi-]CC)]CC",
+      "tau_pim": "[B0 -> ([D+ -> K- pi+ pi+]CC) ([tau- -> ^pi- pi+ pi-]CC)]CC",
+      "tau_pip": "[B0 -> ([D+ -> K- pi+ pi+]CC) ([tau- -> pi- ^pi+ pi-]CC)]CC",
+      "tau_pim2": "[B0 -> ([D+ -> K- pi+ pi+]CC) ([tau- -> pi- pi+ ^pi-]CC)]CC"
+  },
+  "SpruceSLB_BcToJpsiTauNu_JpsiToMuMu_TauToPiPiPiNu": {
+      "Bc": "[B_c+ -> (J/psi(1S) -> mu+ mu-) ([tau+ -> pi+ pi+ pi-]CC)]CC",
+      "Bc_Jpsi": "[B_c+ -> ^(J/psi(1S) -> mu+ mu-) ([tau+ -> pi+ pi+ pi-]CC)]CC",
+      "Jpsi_mup": "[B_c+ -> ([J/psi(1S) -> ^mu+ mu-]CC) ([tau+ -> pi+ pi+ pi-]CC)]CC",
+      "Jpsi_mum": "[B_c+ -> ([J/psi(1S) -> mu+ ^mu-]CC) ([tau+ -> pi+ pi+ pi-]CC)]CC",
+      "Bc_tau": "[B_c+ -> (J/psi(1S) -> mu+ mu-) ^([tau+ -> pi+ pi+ pi-]CC)]CC",
+      "tau_pip": "[B_c+ -> (J/psi(1S) -> mu+ mu-) ([tau+ -> ^pi+ pi+ pi-]CC)]CC",
+      "tau_pip2": "[B_c+ -> (J/psi(1S) -> mu+ mu-) ([tau+ -> pi+ ^pi+ pi-]CC)]CC",
+      "tau_pim": "[B_c+ -> (J/psi(1S) -> mu+ mu-) ([tau+ -> pi+ pi+ ^pi-]CC)]CC"
+  },
+  "SpruceSLB_LbToLcMuNu_LcToPKSLL": {
+      "Lb": "[Lambda_b0 -> ([Lambda_c+ -> p+ (KS0 -> pi+ pi-)]CC) mu-]CC",
+      "Lb_Lc": "[Lambda_b0 -> ^([Lambda_c+ -> p+ (KS0 -> pi+ pi-)]CC) mu-]CC",
+      "Lc_p": "[Lambda_b0 -> ([Lambda_c+ -> ^p+ (KS0 -> pi+ pi-)]CC) mu-]CC",
+      "Lc_KS0": "[Lambda_b0 -> ([Lambda_c+ -> p+ ^(KS0 -> pi+ pi-)]CC) mu-]CC",
+      "Lb_mum": "[Lambda_b0 -> ([Lambda_c+ -> p+ (KS0 -> pi+ pi-)]CC) ^mu-]CC"
+  },
+  "SpruceSLB_LbToLcENu_LcToPKSLL": {
+      "Lb": "[Lambda_b0 -> ([Lambda_c+ -> p+ (KS0 -> pi+ pi-)]CC) e-]CC",
+      "Lb_Lc": "[Lambda_b0 -> ^([Lambda_c+ -> p+ (KS0 -> pi+ pi-)]CC) e-]CC",
+      "Lc_p": "[Lambda_b0 -> ([Lambda_c+ -> ^p+ (KS0 -> pi+ pi-)]CC) e-]CC",
+      "Lc_KS0": "[Lambda_b0 -> ([Lambda_c+ -> p+ ^(KS0 -> pi+ pi-)]CC) e-]CC",
+      "Lb_em": "[Lambda_b0 -> ([Lambda_c+ -> p+ (KS0 -> pi+ pi-)]CC) ^e-]CC"
+  },
+  "SpruceSLB_LbToLcTauNu_LcToPKSLL_TautoMuNuNu": {
+      "Lb": "[Lambda_b0 -> ([Lambda_c+ -> p+ (KS0 -> pi+ pi-)]CC) [mu-]CC]CC",
+      "Lb_Lc": "[Lambda_b0 -> ^([Lambda_c+ -> p+ (KS0 -> pi+ pi-)]CC) [mu-]CC]CC",
+      "Lc_p": "[Lambda_b0 -> ([Lambda_c+ -> ^p+ (KS0 -> pi+ pi-)]CC) [mu-]CC]CC",
+      "Lc_KS0": "[Lambda_b0 -> ([Lambda_c+ -> p+ ^(KS0 -> pi+ pi-)]CC) [mu-]CC]CC",
+      "Lb_mum": "[Lambda_b0 -> ([Lambda_c+ -> p+ (KS0 -> pi+ pi-)]CC) ^[mu-]CC]CC"
+  },
+  "SpruceSLB_LbToLcTauNu_LcToLambdaPiLL_TauToPiPiPiNu": {
+      "Lb": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ pi-) pi+]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Lb_Lc": "[Lambda_b0 -> ^([Lambda_c+ -> (Lambda0 -> p+ pi-) pi+]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Lc_Lambda": "[Lambda_b0 -> ([Lambda_c+ -> ^(Lambda0 -> p+ pi-) pi+]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Lambda_p": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> ^p+ pi-) pi+]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Lambda_pim": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ ^pi-) pi+]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Lc_pip": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ pi-) ^pi+]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Lb_tau": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ pi-) pi+]CC) ^([tau- -> pi- pi+ pi-]CC)]CC",
+      "tau_pim1": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ pi-) pi+]CC) ([tau- -> ^pi- pi+ pi-]CC)]CC",
+      "tau_pip": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ pi-) pi+]CC) ([tau- -> pi- ^pi+ pi-]CC)]CC",
+      "tau_pim2": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ pi-) pi+]CC) ([tau- -> pi- pi+ ^pi-]CC)]CC"
+  },
+  "SpruceSLB_BcToBsMuNu_BsToKK": {
+      "Bc": "[B_c+ -> ([B_s0 -> K+ K-]CC) mu+]CC",
+      "Bc_Bs": "[B_c+ -> ^([B_s0 -> K+ K-]CC) mu+]CC",
+      "Bs_Kp": "[B_c+ -> ([B_s0 -> ^K+ K-]CC) mu+]CC",
+      "Bs_Km": "[B_c+ -> ([B_s0 -> K+ ^K-]CC) mu+]CC",
+      "Bc_mup": "[B_c+ -> ([B_s0 -> K+ K-]CC) ^mu+]CC"
+  },
+  "SpruceSLB_BcToBsENu_BsToKK": {
+      "Bc": "[B_c+ -> ([B_s0 -> K+ K-]CC) e+]CC",
+      "Bc_Bs": "[B_c+ -> ^([B_s0 -> K+ K-]CC) e+]CC",
+      "Bs_Kp": "[B_c+ -> ([B_s0 -> ^K+ K-]CC) e+]CC",
+      "Bs_Km": "[B_c+ -> ([B_s0 -> K+ ^K-]CC) e+]CC",
+      "Bc_ep": "[B_c+ -> ([B_s0 -> K+ K-]CC) ^e+]CC"
+  },
+  "SpruceSLB_BcToBsPi_BsToKK": {
+      "Bc": "[B_c+ -> ([B_s0 -> K+ K-]CC) pi+]CC",
+      "Bc_Bs": "[B_c+ -> ^([B_s0 -> K+ K-]CC) pi+]CC",
+      "Bs_Kp": "[B_c+ -> ([B_s0 -> ^K+ K-]CC) pi+]CC",
+      "Bs_Km": "[B_c+ -> ([B_s0 -> K+ ^K-]CC) pi+]CC",
+      "Bc_pip": "[B_c+ -> ([B_s0 -> K+ K-]CC) ^pi+]CC"
+  },
+  "SpruceSLB_BcToBsK_BsToKK": {
+      "Bc": "[B_c+ -> ([B_s0 -> K+ K-]CC) K+]CC",
+      "Bc_Bs": "[B_c+ -> ^([B_s0 -> K+ K-]CC) K+]CC",
+      "Bs_Kp": "[B_c+ -> ([B_s0 -> ^K+ K-]CC) K+]CC",
+      "Bs_Km": "[B_c+ -> ([B_s0 -> K+ ^K-]CC) K+]CC",
+      "Bc_Kp": "[B_c+ -> ([B_s0 -> K+ K-]CC) ^K+]CC"
+  },
+  "SpruceSLB_BcToBsMuNu_BsToPiPi": {
+      "Bc": "[B_c+ -> ([B_s0 -> pi+ pi-]CC) mu+]CC",
+      "Bc_Bs": "[B_c+ -> ^([B_s0 -> pi+ pi-]CC) mu+]CC",
+      "Bs_pip": "[B_c+ -> ([B_s0 -> ^pi+ pi-]CC) mu+]CC",
+      "Bs_pim": "[B_c+ -> ([B_s0 -> pi+ ^pi-]CC) mu+]CC",
+      "Bc_mup": "[B_c+ -> ([B_s0 -> pi+ pi-]CC) ^mu+]CC"
+  },
+  "SpruceSLB_BcToBsENu_BsToPiPi": {
+      "Bc": "[B_c+ -> ([B_s0 -> pi+ pi-]CC) e+]CC",
+      "Bc_Bs": "[B_c+ -> ^([B_s0 -> pi+ pi-]CC) e+]CC",
+      "Bs_pip": "[B_c+ -> ([B_s0 -> ^pi+ pi-]CC) e+]CC",
+      "Bs_pim": "[B_c+ -> ([B_s0 -> pi+ ^pi-]CC) e+]CC",
+      "Bc_ep": "[B_c+ -> ([B_s0 -> pi+ pi-]CC) ^e+]CC"
+  },
+  "SpruceSLB_BcToBsPi_BsToPiPi": {
+      "Bc": "[B_c+ -> ([B_s0 -> pi+ pi-]CC) pi+]CC",
+      "Bc_Bs": "[B_c+ -> ^([B_s0 -> pi+ pi-]CC) pi+]CC",
+      "Bs_pip": "[B_c+ -> ([B_s0 -> ^pi+ pi-]CC) pi+]CC",
+      "Bs_pim": "[B_c+ -> ([B_s0 -> pi+ ^pi-]CC) pi+]CC",
+      "Bc_pip": "[B_c+ -> ([B_s0 -> pi+ pi-]CC) ^pi+]CC"
+  },
+  "SpruceSLB_BcToBsK_BsToPiPi": {
+      "Bc": "[B_c+ -> ([B_s0 -> pi+ pi-]CC) K+]CC",
+      "Bc_Bs": "[B_c+ -> ^([B_s0 -> pi+ pi-]CC) K+]CC",
+      "Bs_pip": "[B_c+ -> ([B_s0 -> ^pi+ pi-]CC) K+]CC",
+      "Bs_pim": "[B_c+ -> ([B_s0 -> pi+ ^pi-]CC) K+]CC",
+      "Bc_Kp": "[B_c+ -> ([B_s0 -> pi+ pi-]CC) ^K+]CC"
+  },
+  "SpruceSLB_BcToBsMuNu_BsToKPi": {
+      "Bc": "[B_c+ -> ([B_s0 -> K- pi+]CC) mu+]CC",
+      "Bc_Bs": "[B_c+ -> ^([B_s0 -> K- pi+]CC) mu+]CC",
+      "Bs_Km": "[B_c+ -> ([B_s0 -> ^K- pi+]CC) mu+]CC",
+      "Bs_pip": "[B_c+ -> ([B_s0 -> K- ^pi+]CC) mu+]CC",
+      "Bc_mup": "[B_c+ -> ([B_s0 -> K- pi+]CC) ^mu+]CC"
+  },
+  "SpruceSLB_BcToBsENu_BsToKPi": {
+      "Bc": "[B_c+ -> ([B_s0 -> K- pi+]CC) e+]CC",
+      "Bc_Bs": "[B_c+ -> ^([B_s0 -> K- pi+]CC) e+]CC",
+      "Bs_Km": "[B_c+ -> ([B_s0 -> ^K- pi+]CC) e+]CC",
+      "Bs_pip": "[B_c+ -> ([B_s0 -> K- ^pi+]CC) e+]CC",
+      "Bc_ep": "[B_c+ -> ([B_s0 -> K- pi+]CC) ^e+]CC"
+  },
+  "SpruceSLB_BcToBsPi_BsToKPi": {
+      "Bc": "[B_c+ -> ([B_s0 -> K- pi+]CC) pi+]CC",
+      "Bc_Bs": "[B_c+ -> ^([B_s0 -> K- pi+]CC) pi+]CC",
+      "Bs_Km": "[B_c+ -> ([B_s0 -> ^K- pi+]CC) pi+]CC",
+      "Bs_pip": "[B_c+ -> ([B_s0 -> K- ^pi+]CC) pi+]CC",
+      "Bc_pip": "[B_c+ -> ([B_s0 -> K- pi+]CC) ^pi+]CC"
+  },
+  "SpruceSLB_BcToBsK_BsToKPi": {
+      "Bc": "[B_c+ -> ([B_s0 -> K- pi+]CC) K+]CC",
+      "Bc_Bs": "[B_c+ -> ^([B_s0 -> K- pi+]CC) K+]CC",
+      "Bs_Km": "[B_c+ -> ([B_s0 -> ^K- pi+]CC) K+]CC",
+      "Bs_pip": "[B_c+ -> ([B_s0 -> K- ^pi+]CC) K+]CC",
+      "Bc_Kp": "[B_c+ -> ([B_s0 -> K- pi+]CC) ^K+]CC"
+  },
+  "SpruceSLB_BuToD0TauNu_D0ToKPi_TauToPiPiPiNu": {
+      "B": "[B+ -> ([D0 -> K- pi+]CC) ([tau+ -> pi+ pi+ pi-]CC)]CC",
+      "B_D0": "[B+ -> ^([D0 -> K- pi+]CC) ([tau+ -> pi+ pi+ pi-]CC)]CC",
+      "D0_Km": "[B+ -> ([D0 -> ^K- pi+]CC) ([tau+ -> pi+ pi+ pi-]CC)]CC",
+      "D0_pip": "[B+ -> ([D0 -> K- ^pi+]CC) ([tau+ -> pi+ pi+ pi-]CC)]CC",
+      "B_tau": "[B+ -> ([D0 -> K- pi+]CC) ^([tau+ -> pi+ pi+ pi-]CC)]CC",
+      "tau_pip1": "[B+ -> ([D0 -> K- pi+]CC) ([tau+ -> ^pi+ pi+ pi-]CC)]CC",
+      "tau_pip2": "[B+ -> ([D0 -> K- pi+]CC) ([tau+ -> pi+ ^pi+ pi-]CC)]CC",
+      "tau_pim": "[B+ -> ([D0 -> K- pi+]CC) ([tau+ -> pi+ pi+ ^pi-]CC)]CC"
+  },
+  "SpruceSLB_BsToDsTauNu_DsToKKPi_TauToPiPiPiNu": {
+      "Bs": "[B_s0 -> ([D_s- -> K+ K- pi-]CC) ([tau+ -> pi+ pi+ pi-]CC)]CC",
+      "Bs_Dsm": "[B_s0 -> ^([D_s- -> K+ K- pi-]CC) ([tau+ -> pi+ pi+ pi-]CC)]CC",
+      "Dsm_Kp": "[B_s0 -> ([D_s- -> ^K+ K- pi-]CC) ([tau+ -> pi+ pi+ pi-]CC)]CC",
+      "Dsm_Km": "[B_s0 -> ([D_s- -> K+ ^K- pi-]CC) ([tau+ -> pi+ pi+ pi-]CC)]CC",
+      "Dsm_pim": "[B_s0 -> ([D_s- -> K+ K- ^pi-]CC) ([tau+ -> pi+ pi+ pi-]CC)]CC",
+      "Bs_tau": "[B_s0 -> ([D_s- -> K+ K- pi-]CC) ^([tau+ -> pi+ pi+ pi-]CC)]CC",
+      "tau_pip1": "[B_s0 -> ([D_s- -> K+ K- pi-]CC) ([tau+ -> ^pi+ pi+ pi-]CC)]CC",
+      "tau_pip2": "[B_s0 -> ([D_s- -> K+ K- pi-]CC) ([tau+ -> pi+ ^pi+ pi-]CC)]CC",
+      "tau_pim": "[B_s0 -> ([D_s- -> K+ K- pi-]CC) ([tau+ -> pi+ pi+ ^pi-]CC)]CC"
+  },
+  "SpruceSLB_LbToLcTauNu_LcTopKPi_TauToPiPiPiNu": {
+      "Lb": "[Lambda_b0 -> ([Lambda_c+ -> p+ K- pi+]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Lb_Lc": "[Lambda_b0 -> ^([Lambda_c+ -> p+ K- pi+]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Lc_p": "[Lambda_b0 -> ([Lambda_c+ -> ^p+ K- pi+]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Lc_Km": "[Lambda_b0 -> ([Lambda_c+ -> p+ ^K- pi+]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Lc_pip": "[Lambda_b0 -> ([Lambda_c+ -> p+ K- ^pi+]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Lb_tau": "[Lambda_b0 -> ([Lambda_c+ -> p+ K- pi+]CC) ^([tau- -> pi- pi+ pi-]CC)]CC",
+      "tau_pim1": "[Lambda_b0 -> ([Lambda_c+ -> p+ K- pi+]CC) ([tau- -> ^pi- pi+ pi-]CC)]CC",
+      "tau_pip": "[Lambda_b0 -> ([Lambda_c+ -> p+ K- pi+]CC) ([tau- -> pi- ^pi+ pi-]CC)]CC",
+      "tau_pim2": "[Lambda_b0 -> ([Lambda_c+ -> p+ K- pi+]CC) ([tau- -> pi- pi+ ^pi-]CC)]CC"
+  },
+  "SpruceSLB_LbTopTauNu_TauToPiPiPiNu": {
+      "Lb": "[Lambda_b0 -> p+ ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Lb_p": "[Lambda_b0 -> ^p+ ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Lb_tau": "[Lambda_b0 -> p+ ^([tau- -> pi- pi+ pi-]CC)]CC",
+      "tau_pim1": "[Lambda_b0 -> p+ ([tau- -> ^pi- pi+ pi-]CC)]CC",
+      "tau_pip": "[Lambda_b0 -> p+ ([tau- -> pi- ^pi+ pi-]CC)]CC",
+      "tau_pim2": "[Lambda_b0 -> p+ ([tau- -> pi- pi+ ^pi-]CC)]CC"
+  },
+  "SpruceSLB_B2XuMuNuB02Pi": {
+      "B": "[B0 -> [pi-]CC [mu+]CC ]CC",
+      "B_pim": "[B0 -> ^[pi-]CC [mu+]CC ]CC",
+      "B_mup": "[B0 -> [pi-]CC ^[mu+]CC ]CC"
+  },
+  "SpruceSLB_B2XuTauNu_HadronicB02Pi": {
+      "B": "[B0 -> [pi-]CC ([tau+ -> pi+ pi+ pi-]CC)]CC",
+      "B_pim": "[B0 -> ^[pi-]CC ([tau+ -> pi+ pi+ pi-]CC)]CC",
+      "B_tau": "[B0 -> [pi-]CC ^([tau+ -> pi+ pi+ pi-]CC)]CC",
+      "tau_pip1": "[B0 -> [pi-]CC ([tau+ -> ^pi+ pi+ pi-]CC)]CC",
+      "tau_pip2": "[B0 -> [pi-]CC ([tau+ -> pi+ ^pi+ pi-]CC)]CC",
+      "tau_pim": "[B0 -> [pi-]CC ([tau+ -> pi+ pi+ ^pi-]CC)]CC"
+  },
+  "SpruceSLB_LbToPMuNu": {
+      "Lb": "[Lambda_b0 -> [p+]CC [mu-]CC]CC",
+      "Lb_p": "[Lambda_b0 -> ^[p+]CC [mu-]CC]CC",
+      "Lb_mum": "[Lambda_b0 -> [p+]CC ^[mu-]CC]CC"
+  },
+  "SpruceSLB_B2XuMuNuBs2K": {
+      "Bs": "[B_s0 -> [K-]CC [mu+]CC]CC",
+      "Bs_Km": "[B_s0 -> ^[K-]CC [mu+]CC]CC",
+      "Bs_mup": "[B_s0 -> [K-]CC ^[mu+]CC]CC"
+  },
+  "SpruceSLB_B2XuTauNu_HadronicBs2K": {
+      "Bs": "[B_s0 -> [K-]CC ([tau+ -> pi+ pi+ pi-]CC)]CC",
+      "Bs_Km": "[B_s0 -> ^[K-]CC ([tau+ -> pi+ pi+ pi-]CC)]CC",
+      "Bs_tau": "[B_s0 -> [K-]CC ^([tau+ -> pi+ pi+ pi-]CC)]CC",
+      "tau_pip1": "[B_s0 -> [K-]CC ([tau+ -> ^pi+ pi+ pi-]CC)]CC",
+      "tau_pip2": "[B_s0 -> [K-]CC ([tau+ -> pi+ ^pi+ pi-]CC)]CC",
+      "tau_pim": "[B_s0 -> [K-]CC ([tau+ -> pi+ pi+ ^pi-]CC)]CC"
+  },
+  "SpruceSLB_B2XuTauNu_MuonicBs2K": {
+      "Bs": "[B_s0 -> [K-]CC [mu+]CC]CC",
+      "Bs_Km": "[B_s0 -> ^[K-]CC [mu+]CC]CC",
+      "Bs_mup": "[B_s0 -> [K-]CC ^[mu+]CC]CC"
+  },
+  "SpruceSLB_B2PPbarMuNu": {
+      "B": "[B0 -> [p+]CC [p~-]CC [mu+]CC]CC",
+      "B_p": "[B0 -> ^[p+]CC [p~-]CC [mu+]CC]CC",
+      "B_pbar": "[B0 -> [p+]CC ^[p~-]CC [mu+]CC]CC",
+      "B_mup": "[B0 -> [p+]CC [p~-]CC ^[mu+]CC]CC"
+  },
+  "SpruceSLB_B2PiPiMuNu": {
+      "B": "[B+ -> [pi+]CC [pi-]CC [mu+]CC]CC",
+      "B_pip": "[B+ -> ^[pi+]CC [pi-]CC [mu+]CC]CC",
+      "B_pim": "[B+ -> [pi+]CC ^[pi-]CC [mu+]CC]CC",
+      "B_mup": "[B+ -> [pi+]CC [pi-]CC ^[mu+]CC]CC"
+  },
+  "SpruceSLB_B2KKMuNu": {
+      "B": "[B+ -> [K+]CC [K-]CC [mu+]CC]CC",
+      "B_Kp": "[B+ -> ^[K+]CC [K-]CC [mu+]CC]CC",
+      "B_Km": "[B+ -> [K+]CC ^[K-]CC [mu+]CC]CC",
+      "B_mup": "[B+ -> [K+]CC [K-]CC ^[mu+]CC]CC"
+  },
+  "SpruceSLB_B2MuMuMuNu": {
+      "B": "[B+ -> [mu+]CC [mu-]CC [mu+]CC]CC",
+      "B_mup1": "[B+ -> ^[mu+]CC [mu-]CC [mu+]CC]CC",
+      "B_mum": "[B+ -> [mu+]CC ^[mu-]CC [mu+]CC]CC",
+      "B_mup2": "[B+ -> [mu+]CC [mu-]CC ^[mu+]CC]CC"
+  },
+  "SpruceSLB_B2EMuMuNu": {
+      "B": "[B+ -> [e+]CC [mu-]CC [mu+]CC]CC",
+      "B_ep": "[B+ -> ^[e+]CC [mu-]CC [mu+]CC]CC",
+      "B_mum": "[B+ -> [e+]CC ^[mu-]CC [mu+]CC]CC",
+      "B_mup": "[B+ -> [e+]CC [mu-]CC ^[mu+]CC]CC"
+  },
+  "SpruceSLB_B2MuEENu": {
+      "B": "[B+ -> [mu+]CC [e-]CC [e+]CC]CC",
+      "B_mup": "[B+ -> ^[mu+]CC [e-]CC [e+]CC]CC",
+      "B_em": "[B+ -> [mu+]CC ^[e-]CC [e+]CC]CC",
+      "B_ep": "[B+ -> [mu+]CC [e-]CC ^[e+]CC]CC"
+  },
+  "SpruceSLB_B2MuGammaNu_CNVLL": {
+      "B": "[B+ -> mu+ (gamma -> e+ e-)]CC",
+      "B_mup": "[B+ -> ^mu+ (gamma -> e+ e-)]CC",
+      "B_gamma": "[B+ -> mu+ ^(gamma -> e+ e-)]CC",
+      "gamma_ep": "[B+ -> mu+ ([gamma -> ^e+ e-]CC)]CC",
+      "gamma_em": "[B+ -> mu+ ([gamma -> e+ ^e-]CC)]CC"
+  },
+  "SpruceSLB_B2MuGammaNu_CNVDD": {
+      "B": "[B0 -> mu+ (gamma -> e+ e-)]CC",
+      "B_mup": "[B0 -> ^mu+ (gamma -> e+ e-)]CC",
+      "B_gamma": "[B0 -> mu+ ^(gamma -> e+ e-)]CC",
+      "gamma_ep": "[B0 -> mu+ ([gamma -> ^e+ e-]CC)]CC",
+      "gamma_em": "[B0 -> mu+ ([gamma -> e+ ^e-]CC)]CC"
+  },
+  "SpruceSLB_B2EGammaNu_CNVLL": {
+      "B": "[B+ -> e+ (gamma -> e+ e-)]CC",
+      "B_ep": "[B+ -> ^e+ (gamma -> e+ e-)]CC",
+      "B_gamma": "[B+ -> e+ ^(gamma -> e+ e-)]CC",
+      "gamma_ep": "[B+ -> e+ ([gamma -> ^e+ e-]CC)]CC",
+      "gamma_em": "[B+ -> e+ ([gamma -> e+ ^e-]CC)]CC"
+  },
+  "SpruceSLB_B2EGammaNu_CNVDD": {
+      "B": "[B0 -> e+ (gamma -> e+ e-)]CC",
+      "B_ep": "[B0 -> ^e+ (gamma -> e+ e-)]CC",
+      "B_gamma": "[B0 -> e+ ^(gamma -> e+ e-)]CC",
+      "gamma_ep": "[B0 -> e+ ([gamma -> ^e+ e-]CC)]CC",
+      "gamma_em": "[B0 -> e+ ([gamma -> e+ ^e-]CC)]CC"
+  },
+  "SpruceSLB_B2EEENu": {
+      "B": "[B+ -> e+ e- e+]CC",
+      "B_ep1": "[B+ -> ^e+ e- e+]CC",
+      "B_em": "[B+ -> e+ ^e- e+]CC",
+      "B_ep2": "[B+ -> e+ e- ^e+]CC"
+  },
+  "SpruceSLB_B2TauMuMuNu_3Pi": {
+      "B": "[B+ -> ([tau+ -> pi+ pi+ pi-]CC) mu+ mu-]CC",
+      "B_tau": "[B+ -> ^([tau+ -> pi+ pi+ pi-]CC) mu+ mu-]CC",
+      "tau_pip1": "[B+ -> ([tau+ -> ^pi+ pi+ pi-]CC) mu+ mu-]CC",
+      "tau_pip2": "[B+ -> ([tau+ -> pi+ ^pi+ pi-]CC) mu+ mu-]CC",
+      "tau_pim": "[B+ -> ([tau+ -> pi+ pi+ ^pi-]CC) mu+ mu-]CC",
+      "B_mup": "[B+ -> ([tau+ -> pi+ pi+ pi-]CC) ^mu+ mu-]CC",
+      "B_mum": "[B+ -> ([tau+ -> pi+ pi+ pi-]CC) mu+ ^mu-]CC"
+  },
+  "SpruceSLB_B2TauEENu_3Pi": {
+      "B": "[B+ -> ([tau+ -> pi+ pi+ pi-]CC) e+ e-]CC",
+      "B_tau": "[B+ -> ^([tau+ -> pi+ pi+ pi-]CC) e+ e-]CC",
+      "tau_pip1": "[B+ -> ([tau+ -> ^pi+ pi+ pi-]CC) e+ e-]CC",
+      "tau_pip2": "[B+ -> ([tau+ -> pi+ ^pi+ pi-]CC) e+ e-]CC",
+      "tau_pim": "[B+ -> ([tau+ -> pi+ pi+ ^pi-]CC) e+ e-]CC",
+      "B_ep": "[B+ -> ([tau+ -> pi+ pi+ pi-]CC) ^e+ e-]CC",
+      "B_em": "[B+ -> ([tau+ -> pi+ pi+ pi-]CC) e+ ^e-]CC"
+  },
+  "SpruceSLB_OmegabToOmegacMuNu_OmegacToPKKPi": {
+      "Omegab": "[Omega_b- -> ([Omega_c0 -> p+ K- K- pi+]CC) mu-]CC",
+      "Omegab_Omegac": "[Omega_b- -> ^([Omega_c0 -> p+ K- K- pi+]CC) mu-]CC",
+      "Omegac_p": "[Omega_b- -> ([Omega_c0 -> ^p+ K- K- pi+]CC) mu-]CC",
+      "Omegac_Km1": "[Omega_b- -> ([Omega_c0 -> p+ ^K- K- pi+]CC) mu-]CC",
+      "Omegac_Km2": "[Omega_b- -> ([Omega_c0 -> p+ K- ^K- pi+]CC) mu-]CC",
+      "Omegac_pip": "[Omega_b- -> ([Omega_c0 -> p+ K- K- ^pi+]CC) mu-]CC",
+      "Omegab_mum": "[Omega_b- -> ([Omega_c0 -> p+ K- K- pi+]CC) ^mu-]CC"
+  },
+  "SpruceSLB_OmegabToOmegacTauNu_OmegacToPKKPi_TauToMuNuNu": {
+      "Omegab": "[Omega_b- -> ([Omega_c0 -> p+ K- K- pi+]CC) [mu-]CC]CC",
+      "Omegab_Omegac": "[Omega_b- -> ^([Omega_c0 -> p+ K- K- pi+]CC) [mu-]CC]CC",
+      "Omegac_p": "[Omega_b- -> ([Omega_c0 -> ^p+ K- K- pi+]CC) [mu-]CC]CC",
+      "Omegac_Km1": "[Omega_b- -> ([Omega_c0 -> p+ ^K- K- pi+]CC) [mu-]CC]CC",
+      "Omegac_Km2": "[Omega_b- -> ([Omega_c0 -> p+ K- ^K- pi+]CC) [mu-]CC]CC",
+      "Omegac_pip": "[Omega_b- -> ([Omega_c0 -> p+ K- K- ^pi+]CC) [mu-]CC]CC",
+      "Omegab_mum": "[Omega_b- -> ([Omega_c0 -> p+ K- K- pi+]CC) ^[mu-]CC]CC"
+  },
+  "SpruceSLB_LbToLcMuNu_LcToPKSDD": {
+      "Lb": "[Lambda_b0 -> ([Lambda_c+ -> p+ (KS0 -> pi+ pi-)]CC) mu-]CC",
+      "Lb_Lc": "[Lambda_b0 -> ^([Lambda_c+ -> p+ (KS0 -> pi+ pi-)]CC) mu-]CC",
+      "Lc_p": "[Lambda_b0 -> ([Lambda_c+ -> ^p+ (KS0 -> pi+ pi-)]CC) mu-]CC",
+      "Lc_KS0": "[Lambda_b0 -> ([Lambda_c+ -> p+ ^(KS0 -> pi+ pi-)]CC) mu-]CC",
+      "Lb_mum": "[Lambda_b0 -> ([Lambda_c+ -> p+ (KS0 -> pi+ pi-)]CC) ^mu-]CC"
+  },
+  "SpruceSLB_LbToLcENu_LcToPKSDD": {
+      "Lb": "[Lambda_b0 -> ([Lambda_c+ -> p+ (KS0 -> pi+ pi-)]CC) e-]CC",
+      "Lb_Lc": "[Lambda_b0 -> ^([Lambda_c+ -> p+ (KS0 -> pi+ pi-)]CC) e-]CC",
+      "Lc_p": "[Lambda_b0 -> ([Lambda_c+ -> ^p+ (KS0 -> pi+ pi-)]CC) e-]CC",
+      "Lc_KS0": "[Lambda_b0 -> ([Lambda_c+ -> p+ ^(KS0 -> pi+ pi-)]CC) e-]CC",
+      "Lb_em": "[Lambda_b0 -> ([Lambda_c+ -> p+ (KS0 -> pi+ pi-)]CC) ^e-]CC"
+  },
+  "SpruceSLB_LbToLcTauNu_LcToPKSDD_TautoMuNuNu": {
+      "Lb": "[Lambda_b0 -> ([Lambda_c+ -> p+ (KS0 -> pi+ pi-)]CC) [mu-]CC]CC",
+      "Lb_Lc": "[Lambda_b0 -> ^([Lambda_c+ -> p+ (KS0 -> pi+ pi-)]CC) [mu-]CC]CC",
+      "Lc_p": "[Lambda_b0 -> ([Lambda_c+ -> ^p+ (KS0 -> pi+ pi-)]CC) [mu-]CC]CC",
+      "Lc_KS0": "[Lambda_b0 -> ([Lambda_c+ -> p+ ^(KS0 -> pi+ pi-)]CC) [mu-]CC]CC",
+      "Lb_mum": "[Lambda_b0 -> ([Lambda_c+ -> p+ (KS0 -> pi+ pi-)]CC) ^[mu-]CC]CC"
+  },
+  "SpruceSLB_LbToLcTauNu_LcToPKSLL_TautoENuNu": {
+      "Lb": "[Lambda_b0 -> ([Lambda_c+ -> p+ (KS0 -> pi+ pi-)]CC) [e-]CC]CC",
+      "Lb_Lc": "[Lambda_b0 -> ^([Lambda_c+ -> p+ (KS0 -> pi+ pi-)]CC) [e-]CC]CC",
+      "Lc_p": "[Lambda_b0 -> ([Lambda_c+ -> ^p+ (KS0 -> pi+ pi-)]CC) [e-]CC]CC",
+      "Lc_KS0": "[Lambda_b0 -> ([Lambda_c+ -> p+ ^(KS0 -> pi+ pi-)]CC) [e-]CC]CC",
+      "Lb_em": "[Lambda_b0 -> ([Lambda_c+ -> p+ (KS0 -> pi+ pi-)]CC) ^[e-]CC]CC"
+  },
+  "SpruceSLB_LbToLcTauNu_LcToPKSDD_TautoENuNu": {
+      "Lb": "[Lambda_b0 -> ([Lambda_c+ -> p+ (KS0 -> pi+ pi-)]CC) [e-]CC]CC",
+      "Lb_Lc": "[Lambda_b0 -> ^([Lambda_c+ -> p+ (KS0 -> pi+ pi-)]CC) [e-]CC]CC",
+      "Lc_p": "[Lambda_b0 -> ([Lambda_c+ -> ^p+ (KS0 -> pi+ pi-)]CC) [e-]CC]CC",
+      "Lc_KS0": "[Lambda_b0 -> ([Lambda_c+ -> p+ ^(KS0 -> pi+ pi-)]CC) [e-]CC]CC",
+      "Lb_em": "[Lambda_b0 -> ([Lambda_c+ -> p+ (KS0 -> pi+ pi-)]CC) ^[e-]CC]CC"
+  },
+  "SpruceSLB_LbToLcMuNu_LcToLambdaPiLL": {
+      "Lb": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ pi-) pi+]CC) mu-]CC",
+      "Lb_Lc": "[Lambda_b0 -> ^([Lambda_c+ -> (Lambda0 -> p+ pi-) pi+]CC) mu-]CC",
+      "Lc_Lambda": "[Lambda_b0 -> ([Lambda_c+ -> ^(Lambda0 -> p+ pi-) pi+]CC) mu-]CC",
+      "Lambda_p": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> ^p+ pi-) pi+]CC) mu-]CC",
+      "Lambda_pim": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ ^pi-) pi+]CC) mu-]CC",
+      "Lc_pip": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ pi-) ^pi+]CC) mu-]CC",
+      "Lb_mum": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ pi-) pi+]CC) ^mu-]CC"
+  },
+  "SpruceSLB_LbToLcMuNu_LcToLambdaPiDD": {
+      "Lb": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ pi-) pi+]CC) mu-]CC",
+      "Lb_Lc": "[Lambda_b0 -> ^([Lambda_c+ -> (Lambda0 -> p+ pi-) pi+]CC) mu-]CC",
+      "Lc_Lambda": "[Lambda_b0 -> ([Lambda_c+ -> ^(Lambda0 -> p+ pi-) pi+]CC) mu-]CC",
+      "Lambda_p": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> ^p+ pi-) pi+]CC) mu-]CC",
+      "Lambda_pim": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ ^pi-) pi+]CC) mu-]CC",
+      "Lc_pip": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ pi-) ^pi+]CC) mu-]CC",
+      "Lb_mum": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ pi-) pi+]CC) ^mu-]CC"
+  },
+  "SpruceSLB_LbToLcENu_LcToLambdaPiLL": {
+      "Lb": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ pi-) pi+]CC) e-]CC",
+      "Lb_Lc": "[Lambda_b0 -> ^([Lambda_c+ -> (Lambda0 -> p+ pi-) pi+]CC) e-]CC",
+      "Lc_Lambda": "[Lambda_b0 -> ([Lambda_c+ -> ^(Lambda0 -> p+ pi-) pi+]CC) e-]CC",
+      "Lambda_p": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> ^p+ pi-) pi+]CC) e-]CC",
+      "Lambda_pim": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ ^pi-) pi+]CC) e-]CC",
+      "Lc_pip": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ pi-) ^pi+]CC) e-]CC",
+      "Lb_em": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ pi-) pi+]CC) ^e-]CC"
+  },
+  "SpruceSLB_LbToLcENu_LcToLambdaPiDD": {
+      "Lb": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ pi-) pi+]CC) e-]CC",
+      "Lb_Lc": "[Lambda_b0 -> ^([Lambda_c+ -> (Lambda0 -> p+ pi-) pi+]CC) e-]CC",
+      "Lc_Lambda": "[Lambda_b0 -> ([Lambda_c+ -> ^(Lambda0 -> p+ pi-) pi+]CC) e-]CC",
+      "Lambda_p": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> ^p+ pi-) pi+]CC) e-]CC",
+      "Lambda_pim": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ ^pi-) pi+]CC) e-]CC",
+      "Lc_pip": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ pi-) ^pi+]CC) e-]CC",
+      "Lb_em": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ pi-) pi+]CC) ^e-]CC"
+  },
+  "SpruceSLB_LbToLcTauNu_LcToLambdaPiLL_TautoMuNuNu": {
+      "Lb": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ pi-) pi+]CC) [mu-]CC]CC",
+      "Lb_Lc": "[Lambda_b0 -> ^([Lambda_c+ -> (Lambda0 -> p+ pi-) pi+]CC) [mu-]CC]CC",
+      "Lc_Lambda": "[Lambda_b0 -> ([Lambda_c+ -> ^(Lambda0 -> p+ pi-) pi+]CC) [mu-]CC]CC",
+      "Lambda_p": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> ^p+ pi-) pi+]CC) [mu-]CC]CC",
+      "Lambda_pim": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ ^pi-) pi+]CC) [mu-]CC]CC",
+      "Lc_pip": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ pi-) ^pi+]CC) [mu-]CC]CC",
+      "Lb_mum": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ pi-) pi+]CC) ^[mu-]CC]CC"
+  },
+  "SpruceSLB_LbToLcTauNu_LcToLambdaPiDD_TautoMuNuNu": {
+      "Lb": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ pi-) pi+]CC) [mu-]CC]CC",
+      "Lb_Lc": "[Lambda_b0 -> ^([Lambda_c+ -> (Lambda0 -> p+ pi-) pi+]CC) [mu-]CC]CC",
+      "Lc_Lambda": "[Lambda_b0 -> ([Lambda_c+ -> ^(Lambda0 -> p+ pi-) pi+]CC) [mu-]CC]CC",
+      "Lambda_p": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> ^p+ pi-) pi+]CC) [mu-]CC]CC",
+      "Lambda_pim": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ ^pi-) pi+]CC) [mu-]CC]CC",
+      "Lc_pip": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ pi-) ^pi+]CC) [mu-]CC]CC",
+      "Lb_mum": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ pi-) pi+]CC) ^[mu-]CC]CC"
+  },
+  "SpruceSLB_LbToLcTauNu_LcToLambdaPiLL_TautoENuNu": {
+      "Lb": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ pi-) pi+]CC) [e-]CC]CC",
+      "Lb_Lc": "[Lambda_b0 -> ^([Lambda_c+ -> (Lambda0 -> p+ pi-) pi+]CC) [e-]CC]CC",
+      "Lc_Lambda": "[Lambda_b0 -> ([Lambda_c+ -> ^(Lambda0 -> p+ pi-) pi+]CC) [e-]CC]CC",
+      "Lambda_p": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> ^p+ pi-) pi+]CC) [e-]CC]CC",
+      "Lambda_pim": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ ^pi-) pi+]CC) [e-]CC]CC",
+      "Lc_pip": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ pi-) ^pi+]CC) [e-]CC]CC",
+      "Lb_em": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ pi-) pi+]CC) ^[e-]CC]CC"
+  },
+  "SpruceSLB_LbToLcTauNu_LcToLambdaPiDD_TautoENuNu": {
+      "Lb": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ pi-) pi+]CC) [e-]CC]CC",
+      "Lb_Lc": "[Lambda_b0 -> ^([Lambda_c+ -> (Lambda0 -> p+ pi-) pi+]CC) [e-]CC]CC",
+      "Lc_Lambda": "[Lambda_b0 -> ([Lambda_c+ -> ^(Lambda0 -> p+ pi-) pi+]CC) [e-]CC]CC",
+      "Lambda_p": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> ^p+ pi-) pi+]CC) [e-]CC]CC",
+      "Lambda_pim": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ ^pi-) pi+]CC) [e-]CC]CC",
+      "Lc_pip": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ pi-) ^pi+]CC) [e-]CC]CC",
+      "Lb_em": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ pi-) pi+]CC) ^[e-]CC]CC"
+  },
+  "SpruceSLB_BcToBsMuNu_BsToDsPi": {
+      "Bc": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ K- pi-]CC) pi+]CC) mu+]CC",
+      "Bc_Bs": "[B_c+ -> ^([B_s0 -> ([D_s- -> K+ K- pi-]CC) pi+]CC) mu+]CC",
+      "Bs_Dsm": "[B_c+ -> ([B_s0 -> ^([D_s- -> K+ K- pi-]CC) pi+]CC) mu+]CC",
+      "Dsm_Kp": "[B_c+ -> ([B_s0 -> ([D_s- -> ^K+ K- pi-]CC) pi+]CC) mu+]CC",
+      "Dsm_Km": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ ^K- pi-]CC) pi+]CC) mu+]CC",
+      "Dsm_pim": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ K- ^pi-]CC) pi+]CC) mu+]CC",
+      "Bs_pip": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ K- pi-]CC) ^pi+]CC) mu+]CC",
+      "Bc_mup": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ K- pi-]CC) pi+]CC) ^mu+]CC"
+  },
+  "SpruceSLB_BcToBsMuNu_BsToDsK": {
+      "Bc": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ K- pi-]CC) K+]CC) mu+]CC",
+      "Bc_Bs": "[B_c+ -> ^([B_s0 -> ([D_s- -> K+ K- pi-]CC) K+]CC) mu+]CC",
+      "Bs_Dsm": "[B_c+ -> ([B_s0 -> ^([D_s- -> K+ K- pi-]CC) K+]CC) mu+]CC",
+      "Dsm_Kp": "[B_c+ -> ([B_s0 -> ([D_s- -> ^K+ K- pi-]CC) K+]CC) mu+]CC",
+      "Dsm_Km": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ ^K- pi-]CC) K+]CC) mu+]CC",
+      "Dsm_pim": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ K- ^pi-]CC) K+]CC) mu+]CC",
+      "Bs_Kp": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ K- pi-]CC) ^K+]CC) mu+]CC",
+      "Bc_mup": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ K- pi-]CC) K+]CC) ^mu+]CC"
+  },
+  "SpruceSLB_BcToBsMuNu_BsToJpsiPhi": {
+      "Bc": "[B_c+ -> ([B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) -> K+ K-)]CC) mu+]CC",
+      "Bc_Bs": "[B_c+ -> ^([B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) -> K+ K-)]CC) mu+]CC",
+      "Bs_Jpsi": "[B_c+ -> ([B_s0 -> ^(J/psi(1S) -> mu+ mu-) (phi(1020) -> K+ K-)]CC) mu+]CC",
+      "Jpsi_mup": "[B_c+ -> ([B_s0 -> ([J/psi(1S) -> ^mu+ mu-]CC) (phi(1020) -> K+ K-)]CC) mu+]CC",
+      "Jpsi_mum": "[B_c+ -> ([B_s0 -> ([J/psi(1S) -> mu+ ^mu-]CC) (phi(1020) -> K+ K-)]CC) mu+]CC",
+      "Bs_phi": "[B_c+ -> ([B_s0 -> (J/psi(1S) -> mu+ mu-) ^(phi(1020) -> K+ K-)]CC) mu+]CC",
+      "phi_Kp": "[B_c+ -> ([B_s0 -> (J/psi(1S) -> mu+ mu-) ([phi(1020) -> ^K+ K-]CC)]CC) mu+]CC",
+      "phi_Km": "[B_c+ -> ([B_s0 -> (J/psi(1S) -> mu+ mu-) ([phi(1020) -> K+ ^K-]CC)]CC) mu+]CC",
+      "Bc_mup": "[B_c+ -> ([B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) -> K+ K-)]CC) ^mu+]CC"
+  },
+  "SpruceSLB_BcToBsENu_BsToDsPi": {
+      "Bc": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ K- pi-]CC) pi+]CC) e+]CC",
+      "Bc_Bs": "[B_c+ -> ^([B_s0 -> ([D_s- -> K+ K- pi-]CC) pi+]CC) e+]CC",
+      "Bs_Dsm": "[B_c+ -> ([B_s0 -> ^([D_s- -> K+ K- pi-]CC) pi+]CC) e+]CC",
+      "Dsm_Kp": "[B_c+ -> ([B_s0 -> ([D_s- -> ^K+ K- pi-]CC) pi+]CC) e+]CC",
+      "Dsm_Km": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ ^K- pi-]CC) pi+]CC) e+]CC",
+      "Dsm_pim": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ K- ^pi-]CC) pi+]CC) e+]CC",
+      "Bs_pip": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ K- pi-]CC) ^pi+]CC) e+]CC",
+      "Bc_ep": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ K- pi-]CC) pi+]CC) ^e+]CC"
+  },
+  "SpruceSLB_BcToBsENu_BsToDsK": {
+      "Bc": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ K- pi-]CC) K+]CC) e+]CC",
+      "Bc_Bs": "[B_c+ -> ^([B_s0 -> ([D_s- -> K+ K- pi-]CC) K+]CC) e+]CC",
+      "Bs_Dsm": "[B_c+ -> ([B_s0 -> ^([D_s- -> K+ K- pi-]CC) K+]CC) e+]CC",
+      "Dsm_Kp": "[B_c+ -> ([B_s0 -> ([D_s- -> ^K+ K- pi-]CC) K+]CC) e+]CC",
+      "Dsm_Km": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ ^K- pi-]CC) K+]CC) e+]CC",
+      "Dsm_pim": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ K- ^pi-]CC) K+]CC) e+]CC",
+      "Bs_Kp": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ K- pi-]CC) ^K+]CC) e+]CC",
+      "Bc_ep": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ K- pi-]CC) K+]CC) ^e+]CC"
+  },
+  "SpruceSLB_BcToBsENu_BsToJpsiPhi": {
+      "Bc": "[B_c+ -> ([B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) -> K+ K-)]CC) e+]CC",
+      "Bc_Bs": "[B_c+ -> ^([B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) -> K+ K-)]CC) e+]CC",
+      "Bs_Jpsi": "[B_c+ -> ([B_s0 -> ^(J/psi(1S) -> mu+ mu-) (phi(1020) -> K+ K-)]CC) e+]CC",
+      "Jpsi_mup": "[B_c+ -> ([B_s0 -> ([J/psi(1S) -> ^mu+ mu-]CC) (phi(1020) -> K+ K-)]CC) e+]CC",
+      "Jpsi_mum": "[B_c+ -> ([B_s0 -> ([J/psi(1S) -> mu+ ^mu-]CC) (phi(1020) -> K+ K-)]CC) e+]CC",
+      "Bs_phi": "[B_c+ -> ([B_s0 -> (J/psi(1S) -> mu+ mu-) ^(phi(1020) -> K+ K-)]CC) e+]CC",
+      "phi_Kp": "[B_c+ -> ([B_s0 -> (J/psi(1S) -> mu+ mu-) ([phi(1020) -> ^K+ K-]CC)]CC) e+]CC",
+      "phi_Km": "[B_c+ -> ([B_s0 -> (J/psi(1S) -> mu+ mu-) ([phi(1020) -> K+ ^K-]CC)]CC) e+]CC",
+      "Bc_ep": "[B_c+ -> ([B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) -> K+ K-)]CC) ^e+]CC"
+  },
+  "SpruceSLB_BcToBsPi_BsToDsPi": {
+      "Bc": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ K- pi-]CC) pi+]CC) pi+]CC",
+      "Bc_Bs": "[B_c+ -> ^([B_s0 -> ([D_s- -> K+ K- pi-]CC) pi+]CC) pi+]CC",
+      "Bs_Dsm": "[B_c+ -> ([B_s0 -> ^([D_s- -> K+ K- pi-]CC) pi+]CC) pi+]CC",
+      "Dsm_Kp": "[B_c+ -> ([B_s0 -> ([D_s- -> ^K+ K- pi-]CC) pi+]CC) pi+]CC",
+      "Dsm_Km": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ ^K- pi-]CC) pi+]CC) pi+]CC",
+      "Dsm_pim": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ K- ^pi-]CC) pi+]CC) pi+]CC",
+      "Bs_pip": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ K- pi-]CC) ^pi+]CC) pi+]CC",
+      "Bc_pip": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ K- pi-]CC) pi+]CC) ^pi+]CC"
+  },
+  "SpruceSLB_BcToBsPi_BsToDsK": {
+      "Bc": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ K- pi-]CC) K+]CC) pi+]CC",
+      "Bc_Bs": "[B_c+ -> ^([B_s0 -> ([D_s- -> K+ K- pi-]CC) K+]CC) pi+]CC",
+      "Bs_Dsm": "[B_c+ -> ([B_s0 -> ^([D_s- -> K+ K- pi-]CC) K+]CC) pi+]CC",
+      "Dsm_Kp": "[B_c+ -> ([B_s0 -> ([D_s- -> ^K+ K- pi-]CC) K+]CC) pi+]CC",
+      "Dsm_Km": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ ^K- pi-]CC) K+]CC) pi+]CC",
+      "Dsm_pim": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ K- ^pi-]CC) K+]CC) pi+]CC",
+      "Bs_Kp": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ K- pi-]CC) ^K+]CC) pi+]CC",
+      "Bc_pip": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ K- pi-]CC) K+]CC) ^pi+]CC"
+  },
+  "SpruceSLB_BcToBsPi_BsToJpsiPhi": {
+      "Bc": "[B_c+ -> ([B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) -> K+ K-)]CC) pi+]CC",
+      "Bc_Bs": "[B_c+ -> ^([B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) -> K+ K-)]CC) pi+]CC",
+      "Bs_Jpsi": "[B_c+ -> ([B_s0 -> ^(J/psi(1S) -> mu+ mu-) (phi(1020) -> K+ K-)]CC) pi+]CC",
+      "Jpsi_mup": "[B_c+ -> ([B_s0 -> ([J/psi(1S) -> ^mu+ mu-]CC) (phi(1020) -> K+ K-)]CC) pi+]CC",
+      "Jpsi_mum": "[B_c+ -> ([B_s0 -> ([J/psi(1S) -> mu+ ^mu-]CC) (phi(1020) -> K+ K-)]CC) pi+]CC",
+      "Bs_phi": "[B_c+ -> ([B_s0 -> (J/psi(1S) -> mu+ mu-) ^(phi(1020) -> K+ K-)]CC) pi+]CC",
+      "phi_Kp": "[B_c+ -> ([B_s0 -> (J/psi(1S) -> mu+ mu-) ([phi(1020) -> ^K+ K-]CC)]CC) pi+]CC",
+      "phi_Km": "[B_c+ -> ([B_s0 -> (J/psi(1S) -> mu+ mu-) ([phi(1020) -> K+ ^K-]CC)]CC) pi+]CC",
+      "Bc_pip": "[B_c+ -> ([B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) -> K+ K-)]CC) ^pi+]CC"
+  },
+  "SpruceSLB_BcToBsK_BsToDsPi": {
+      "Bc": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ K- pi-]CC) pi+]CC) K+]CC",
+      "Bc_Bs": "[B_c+ -> ^([B_s0 -> ([D_s- -> K+ K- pi-]CC) pi+]CC) K+]CC",
+      "Bs_Dsm": "[B_c+ -> ([B_s0 -> ^([D_s- -> K+ K- pi-]CC) pi+]CC) K+]CC",
+      "Dsm_Kp": "[B_c+ -> ([B_s0 -> ([D_s- -> ^K+ K- pi-]CC) pi+]CC) K+]CC",
+      "Dsm_Km": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ ^K- pi-]CC) pi+]CC) K+]CC",
+      "Dsm_pim": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ K- ^pi-]CC) pi+]CC) K+]CC",
+      "Bs_pip": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ K- pi-]CC) ^pi+]CC) K+]CC",
+      "Bc_Kp": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ K- pi-]CC) pi+]CC) ^K+]CC"
+  },
+  "SpruceSLB_BcToBsK_BsToDsK": {
+      "Bc": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ K- pi-]CC) K+]CC) K+]CC",
+      "Bc_Bs": "[B_c+ -> ^([B_s0 -> ([D_s- -> K+ K- pi-]CC) K+]CC) K+]CC",
+      "Bs_Dsm": "[B_c+ -> ([B_s0 -> ^([D_s- -> K+ K- pi-]CC) K+]CC) K+]CC",
+      "Dsm_Kp": "[B_c+ -> ([B_s0 -> ([D_s- -> ^K+ K- pi-]CC) K+]CC) K+]CC",
+      "Dsm_Km": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ ^K- pi-]CC) K+]CC) K+]CC",
+      "Dsm_pim": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ K- ^pi-]CC) K+]CC) K+]CC",
+      "Bs_Kp1": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ K- pi-]CC) ^K+]CC) K+]CC",
+      "Bc_Kp": "[B_c+ -> ([B_s0 -> ([D_s- -> K+ K- pi-]CC) K+]CC) ^K+]CC"
+  },
+  "SpruceSLB_BcToBsK_BsToJpsiPhi": {
+      "Bc": "[B_c+ -> ([B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) -> K+ K-)]CC) K+]CC",
+      "Bc_Bs": "[B_c+ -> ^([B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) -> K+ K-)]CC) K+]CC",
+      "Bs_Jpsi": "[B_c+ -> ([B_s0 -> ^(J/psi(1S) -> mu+ mu-) (phi(1020) -> K+ K-)]CC) K+]CC",
+      "Jpsi_mup": "[B_c+ -> ([B_s0 -> ([J/psi(1S) -> ^mu+ mu-]CC) (phi(1020) -> K+ K-)]CC) K+]CC",
+      "Jpsi_mum": "[B_c+ -> ([B_s0 -> ([J/psi(1S) -> mu+ ^mu-]CC) (phi(1020) -> K+ K-)]CC) K+]CC",
+      "Bs_phi": "[B_c+ -> ([B_s0 -> (J/psi(1S) -> mu+ mu-) ^(phi(1020) -> K+ K-)]CC) K+]CC",
+      "phi_Kp": "[B_c+ -> ([B_s0 -> (J/psi(1S) -> mu+ mu-) ([phi(1020) -> ^K+ K-]CC)]CC) K+]CC",
+      "phi_Km": "[B_c+ -> ([B_s0 -> (J/psi(1S) -> mu+ mu-) ([phi(1020) -> K+ ^K-]CC)]CC) K+]CC",
+      "Bc_Kp": "[B_c+ -> ([B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) -> K+ K-)]CC) ^K+]CC"
+  },
+  "SpruceSLB_BToTauNu_TauToPiPiPiNu_BTracking": {
+      "B": "[B- -> ([tau- -> pi- pi+ pi-]CC)]CC",
+      "B_tau": "[B- -> ^([tau- -> pi- pi+ pi-]CC)]CC",
+      "tau_pim1": "[B- -> ([tau- -> ^pi- pi+ pi-]CC)]CC",
+      "tau_pip": "[B- -> ([tau- -> pi- ^pi+ pi-]CC)]CC",
+      "tau_pim2": "[B- -> ([tau- -> pi- pi+ ^pi-]CC)]CC"
+  },
+  "SpruceSLB_BToDPiPi_DToKPiPi_BTracking": {
+      "B": "[B- -> ([D- -> K+ pi- pi-]CC) pi+ pi-]CC",
+      "B_Dm": "[B- -> ^([D- -> K+ pi- pi-]CC) pi+ pi-]CC",
+      "Dm_Kp": "[B- -> ([D- -> ^K+ pi- pi-]CC) pi+ pi-]CC",
+      "Dm_pim1": "[B- -> ([D- -> K+ ^pi- pi-]CC) pi+ pi-]CC",
+      "Dm_pim2": "[B- -> ([D- -> K+ pi- ^pi-]CC) pi+ pi-]CC",
+      "B_pip": "[B- -> ([D- -> K+ pi- pi-]CC) ^pi+ pi-]CC",
+      "B_pim": "[B- -> ([D- -> K+ pi- pi-]CC) pi+ ^pi-]CC"
+  },
+  "SpruceSLB_LbToLcTauNu_LcToPKSLL_TauToPiPiPiNu": {
+      "Lb": "[Lambda_b0 -> ([Lambda_c+ -> p+ (KS0 -> pi+ pi-)]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Lb_Lc": "[Lambda_b0 -> ^([Lambda_c+ -> p+ (KS0 -> pi+ pi-)]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Lc_p": "[Lambda_b0 -> ([Lambda_c+ -> ^p+ (KS0 -> pi+ pi-)]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Lc_KS0": "[Lambda_b0 -> ([Lambda_c+ -> p+ ^(KS0 -> pi+ pi-)]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Lb_tau": "[Lambda_b0 -> ([Lambda_c+ -> p+ (KS0 -> pi+ pi-)]CC) ^([tau- -> pi- pi+ pi-]CC)]CC",
+      "tau_pim1": "[Lambda_b0 -> ([Lambda_c+ -> p+ (KS0 -> pi+ pi-)]CC) ([tau- -> ^pi- pi+ pi-]CC)]CC",
+      "tau_pip": "[Lambda_b0 -> ([Lambda_c+ -> p+ (KS0 -> pi+ pi-)]CC) ([tau- -> pi- ^pi+ pi-]CC)]CC",
+      "tau_pim2": "[Lambda_b0 -> ([Lambda_c+ -> p+ (KS0 -> pi+ pi-)]CC) ([tau- -> pi- pi+ ^pi-]CC)]CC"
+  },
+  "SpruceSLB_LbToLcTauNu_LcToPKSDD_TauToPiPiPiNu": {
+      "Lb": "[Lambda_b0 -> ([Lambda_c+ -> p+ (KS0 -> pi+ pi-)]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Lb_Lc": "[Lambda_b0 -> ^([Lambda_c+ -> p+ (KS0 -> pi+ pi-)]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Lc_p": "[Lambda_b0 -> ([Lambda_c+ -> ^p+ (KS0 -> pi+ pi-)]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Lc_KS0": "[Lambda_b0 -> ([Lambda_c+ -> p+ ^(KS0 -> pi+ pi-)]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Lb_tau": "[Lambda_b0 -> ([Lambda_c+ -> p+ (KS0 -> pi+ pi-)]CC) ^([tau- -> pi- pi+ pi-]CC)]CC",
+      "tau_pim1": "[Lambda_b0 -> ([Lambda_c+ -> p+ (KS0 -> pi+ pi-)]CC) ([tau- -> ^pi- pi+ pi-]CC)]CC",
+      "tau_pip": "[Lambda_b0 -> ([Lambda_c+ -> p+ (KS0 -> pi+ pi-)]CC) ([tau- -> pi- ^pi+ pi-]CC)]CC",
+      "tau_pim2": "[Lambda_b0 -> ([Lambda_c+ -> p+ (KS0 -> pi+ pi-)]CC) ([tau- -> pi- pi+ ^pi-]CC)]CC"
+  },
+  "SpruceSLB_LbToLcTauNu_LcToLambdaPiDD_TauToPiPiPiNu": {
+      "Lb": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ pi-) pi+]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Lb_Lc": "[Lambda_b0 -> ^([Lambda_c+ -> (Lambda0 -> p+ pi-) pi+]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Lc_Lambda": "[Lambda_b0 -> ([Lambda_c+ -> ^(Lambda0 -> p+ pi-) pi+]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Lambda_p": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> ^p+ pi-) pi+]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Lambda_pim": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ ^pi-) pi+]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Lc_pip": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ pi-) ^pi+]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Lb_tau": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ pi-) pi+]CC) ^([tau- -> pi- pi+ pi-]CC)]CC",
+      "tau_pim1": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ pi-) pi+]CC) ([tau- -> ^pi- pi+ pi-]CC)]CC",
+      "tau_pip": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ pi-) pi+]CC) ([tau- -> pi- ^pi+ pi-]CC)]CC",
+      "tau_pim2": "[Lambda_b0 -> ([Lambda_c+ -> (Lambda0 -> p+ pi-) pi+]CC) ([tau- -> pi- pi+ ^pi-]CC)]CC"
+  },
+  "SpruceSLB_LbToLcTauNu_LcTopPhi_TauToPiPiPiNu": {
+      "Lb": "[Lambda_b0 -> ([Lambda_c+ -> p+ (phi(1020) -> K+ K-)]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Lb_Lc": "[Lambda_b0 -> ^([Lambda_c+ -> p+ (phi(1020) -> K+ K-)]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Lc_p": "[Lambda_b0 -> ([Lambda_c+ -> ^p+ (phi(1020) -> K+ K-)]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Lc_phi": "[Lambda_b0 -> ([Lambda_c+ -> p+ ^(phi(1020) -> K+ K-)]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "phi_Kp": "[Lambda_b0 -> ([Lambda_c+ -> p+ ([phi(1020) -> ^K+ K-]CC)]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "phi_Km": "[Lambda_b0 -> ([Lambda_c+ -> p+ ([phi(1020) -> K+ ^K-]CC)]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Lb_tau": "[Lambda_b0 -> ([Lambda_c+ -> p+ (phi(1020) -> K+ K-)]CC) ^([tau- -> pi- pi+ pi-]CC)]CC",
+      "tau_pim1": "[Lambda_b0 -> ([Lambda_c+ -> p+ (phi(1020) -> K+ K-)]CC) ([tau- -> ^pi- pi+ pi-]CC)]CC",
+      "tau_pip": "[Lambda_b0 -> ([Lambda_c+ -> p+ (phi(1020) -> K+ K-)]CC) ([tau- -> pi- ^pi+ pi-]CC)]CC",
+      "tau_pim2": "[Lambda_b0 -> ([Lambda_c+ -> p+ (phi(1020) -> K+ K-)]CC) ([tau- -> pi- pi+ ^pi-]CC)]CC"
+  },
+  "SpruceSLB_XibminusToXic0TauNu_Xic0TopKKPi_TauToPiPiPiNu": {
+      "Xibm": "[Xi_b- -> ([Xi_c0 -> p+ K- K+ pi-]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Xibm_Xi_c0": "[Xi_b- -> ^([Xi_c0 -> p+ K- K+ pi-]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Xi_c0_p": "[Xi_b- -> ([Xi_c0 -> ^p+ K- K+ pi-]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Xi_c0_Km": "[Xi_b- -> ([Xi_c0 -> p+ ^K- K+ pi-]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Xi_c0_Kp": "[Xi_b- -> ([Xi_c0 -> p+ K- ^K+ pi-]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Xi_c0_pim": "[Xi_b- -> ([Xi_c0 -> p+ K- K+ ^pi-]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Xibm_tau": "[Xi_b- -> ([Xi_c0 -> p+ K- K+ pi-]CC) ^([tau- -> pi- pi+ pi-]CC)]CC",
+      "tau_pim1": "[Xi_b- -> ([Xi_c0 -> p+ K- K+ pi-]CC) ([tau- -> ^pi- pi+ pi-]CC)]CC",
+      "tau_pip": "[Xi_b- -> ([Xi_c0 -> p+ K- K+ pi-]CC) ([tau- -> pi- ^pi+ pi-]CC)]CC",
+      "tau_pim2": "[Xi_b- -> ([Xi_c0 -> p+ K- K+ pi-]CC) ([tau- -> pi- pi+ ^pi-]CC)]CC"
+  },
+  "SpruceSLB_OmegabToOmegacTauNu_OmegacToPKKPi_TauToPiPiPiNu": {
+      "Omegab": "[Omega_b- -> ([Omega_c0 -> p+ K- K- pi+]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Omegab_Omegac": "[Omega_b- -> ^([Omega_c0 -> p+ K- K- pi+]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Omegac_p": "[Omega_b- -> ([Omega_c0 -> ^p+ K- K- pi+]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Omegac_Km1": "[Omega_b- -> ([Omega_c0 -> p+ ^K- K- pi+]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Omegac_Km2": "[Omega_b- -> ([Omega_c0 -> p+ K- ^K- pi+]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Omegac_pip": "[Omega_b- -> ([Omega_c0 -> p+ K- K- ^pi+]CC) ([tau- -> pi- pi+ pi-]CC)]CC",
+      "Omegab_tau": "[Omega_b- -> ([Omega_c0 -> p+ K- K- pi+]CC) ^([tau- -> pi- pi+ pi-]CC)]CC",
+      "tau_pim1": "[Omega_b- -> ([Omega_c0 -> p+ K- K- pi+]CC) ([tau- -> ^pi- pi+ pi-]CC)]CC",
+      "tau_pip": "[Omega_b- -> ([Omega_c0 -> p+ K- K- pi+]CC) ([tau- -> pi- ^pi+ pi-]CC)]CC",
+      "tau_pim2": "[Omega_b- -> ([Omega_c0 -> p+ K- K- pi+]CC) ([tau- -> pi- pi+ ^pi-]CC)]CC"
+  }
+}
diff --git a/slb-minbias-sprucing/info.yaml b/slb-minbias-sprucing/info.yaml
new file mode 100644
index 0000000000..72d29eb7ff
--- /dev/null
+++ b/slb-minbias-sprucing/info.yaml
@@ -0,0 +1,69 @@
+defaults:
+  wg: SL
+  inform:
+    - tfulghes@cern.ch
+
+{%- set platform           = 'x86_64_v2-el9-gcc13+detdesc-opt' %}
+{%- set dv_v               = 'v64r13' %}
+{%- set spruce_v           = 'v55r11' %}
+
+{%- set isMC = True %}
+
+{%- set datasets = [
+  ('Minbias', '300000000')
+]
+%}  
+
+{%- set polarity_variables = [
+  ('MagDown'  , 'sim-20201113-5-vc-mu100-Sim10','dddb-20220927-2015' ),
+  ('MagUp'    , 'sim-20201113-5-vc-md100-Sim10','dddb-20220927-2015' ),
+]
+%}
+
+{%- for polarity, conddb_tag , dddb_tag in polarity_variables %}
+{%- set mc_cond_path = '/MC/2024/Beam6800GeV-2024.W40.42-' + polarity + '-Nu7.6-25ns-Pythia8/Sim10d/HLT2-2024.W40.42' %}
+{%- for eventtype, event in datasets %}
+
+MC_{{polarity}}_{{event}}_SPRUCE:
+  application: "Moore/{{spruce_v}}@{{platform}}"
+  input:
+    bk_query: '{{mc_cond_path}}/{{eventtype}}/DST'    
+  output: Spruce.dst
+  options:
+    entrypoint : slb_central_analysis_production.mc_spruce_hackathon:main
+    extra_options:
+      input_raw_format: 0.5
+      conddb_tag: {{conddb_tag}}
+      dddb_tag: {{dddb_tag}}
+      input_type: ROOT
+      output_type: ROOT
+      output_manifest_file: "Spruce.tck.json"
+      input_process: "Hlt2"
+      simulation: True
+      process: Spruce
+      data_type: "Upgrade" 
+
+MC_{{polarity}}_{{event}}_DV:
+  application: "DaVinci/{{dv_v}}@{{platform}}"
+  input:
+    job_name: "MC_{{polarity}}_{{event}}_SPRUCE"
+  output: Tuple.root
+  options:
+    entrypoint : slb_central_analysis_production.mc_davinci_hackathon:main
+    extra_options:
+      input_raw_format: 0.5
+      conddb_tag: {{conddb_tag}}
+      dddb_tag: {{dddb_tag}}
+      input_type: ROOT
+      output_type: ROOT
+      input_manifest_file: "Spruce.tck.json"
+      input_process: "Spruce"
+      geometry_version: run3/2024.Q1.2-v00.00
+      ntuple_basketsize : 1024 
+      simulation: True
+      data_type: "Upgrade"
+    extra_args:
+      - {{isMC}}
+      
+  {%- endfor %}
+{%- endfor %}
\ No newline at end of file
-- 
GitLab


From ba74cd4b14029c7993615cf65119d1c223f4df03 Mon Sep 17 00:00:00 2001
From: Tommaso Fulghesu <tommaso.fulghesu@cern.ch>
Date: Tue, 14 Jan 2025 13:58:56 +0100
Subject: [PATCH 2/6] Fix eventtype

---
 slb-minbias-sprucing/info.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/slb-minbias-sprucing/info.yaml b/slb-minbias-sprucing/info.yaml
index 72d29eb7ff..7bae47bb18 100644
--- a/slb-minbias-sprucing/info.yaml
+++ b/slb-minbias-sprucing/info.yaml
@@ -10,7 +10,7 @@ defaults:
 {%- set isMC = True %}
 
 {%- set datasets = [
-  ('Minbias', '300000000')
+  ('Minbias', '30000000')
 ]
 %}  
 
-- 
GitLab


From 1cc0537a8f2869558793d129fd904cd37fd5a94b Mon Sep 17 00:00:00 2001
From: Tommaso Fulghesu <tommaso.fulghesu@cern.ch>
Date: Wed, 15 Jan 2025 10:07:05 +0100
Subject: [PATCH 3/6] Apply changes to the bkpath and DV script

---
 slb-minbias-sprucing/davinci.py |  5 ++---
 slb-minbias-sprucing/info.yaml  | 13 ++++---------
 2 files changed, 6 insertions(+), 12 deletions(-)

diff --git a/slb-minbias-sprucing/davinci.py b/slb-minbias-sprucing/davinci.py
index 0508fadcf4..009cee5db8 100644
--- a/slb-minbias-sprucing/davinci.py
+++ b/slb-minbias-sprucing/davinci.py
@@ -544,7 +544,7 @@ def tuple_b_had(pvs,
                     inputs=b_parts)
 
 
-def main(options: Options, isMC: bool, block: str):
+def main(options: Options, isMC: bool):
     user_algorithms = {}
     for line_name in spruce_line_names:
         if any(substring in line_name
@@ -560,8 +560,7 @@ def main(options: Options, isMC: bool, block: str):
         # get charged and neutral particles in the event
         charged_parts = None
         neutral_parts = None
-        if line_name in spruce_lines_with_extra_particles and block not in spruce_lines_with_extra_particles[
-                line_name]:
+        if line_name in spruce_lines_with_extra_particles:
             # get the charged particles in the event
             extra_charged_part = get_particles(
                 f"/Event/Spruce/{line_name}/{line_name}_extra_tracks/Particles"
diff --git a/slb-minbias-sprucing/info.yaml b/slb-minbias-sprucing/info.yaml
index 7bae47bb18..7b83c9301e 100644
--- a/slb-minbias-sprucing/info.yaml
+++ b/slb-minbias-sprucing/info.yaml
@@ -9,10 +9,7 @@ defaults:
 
 {%- set isMC = True %}
 
-{%- set datasets = [
-  ('Minbias', '30000000')
-]
-%}  
+{%- set eventtype = '30000000' %}  
 
 {%- set polarity_variables = [
   ('MagDown'  , 'sim-20201113-5-vc-mu100-Sim10','dddb-20220927-2015' ),
@@ -22,9 +19,8 @@ defaults:
 
 {%- for polarity, conddb_tag , dddb_tag in polarity_variables %}
 {%- set mc_cond_path = '/MC/2024/Beam6800GeV-2024.W40.42-' + polarity + '-Nu7.6-25ns-Pythia8/Sim10d/HLT2-2024.W40.42' %}
-{%- for eventtype, event in datasets %}
 
-MC_{{polarity}}_{{event}}_SPRUCE:
+MINBIAS_{{polarity}}_SPRUCE:
   application: "Moore/{{spruce_v}}@{{platform}}"
   input:
     bk_query: '{{mc_cond_path}}/{{eventtype}}/DST'    
@@ -43,10 +39,10 @@ MC_{{polarity}}_{{event}}_SPRUCE:
       process: Spruce
       data_type: "Upgrade" 
 
-MC_{{polarity}}_{{event}}_DV:
+MINBIAS_{{polarity}}_DV:
   application: "DaVinci/{{dv_v}}@{{platform}}"
   input:
-    job_name: "MC_{{polarity}}_{{event}}_SPRUCE"
+    job_name: "MINBIAS_{{polarity}}_SPRUCE"
   output: Tuple.root
   options:
     entrypoint : slb_central_analysis_production.mc_davinci_hackathon:main
@@ -65,5 +61,4 @@ MC_{{polarity}}_{{event}}_DV:
     extra_args:
       - {{isMC}}
       
-  {%- endfor %}
 {%- endfor %}
\ No newline at end of file
-- 
GitLab


From c40a1b919982e692a2072630838da3224ede7656 Mon Sep 17 00:00:00 2001
From: Tommaso Fulghesu <tommaso.fulghesu@cern.ch>
Date: Wed, 15 Jan 2025 10:39:34 +0100
Subject: [PATCH 4/6] Move to prod repository and add sprucing over all the
 lines

---
 {slb-minbias-sprucing => prod}/davinci.py  |  0
 {slb-minbias-sprucing => prod}/fields.json |  0
 {slb-minbias-sprucing => prod}/info.yaml   | 10 +++---
 prod/spruce.py                             | 41 ++++++++++++++++++++++
 4 files changed, 46 insertions(+), 5 deletions(-)
 rename {slb-minbias-sprucing => prod}/davinci.py (100%)
 rename {slb-minbias-sprucing => prod}/fields.json (100%)
 rename {slb-minbias-sprucing => prod}/info.yaml (80%)
 create mode 100644 prod/spruce.py

diff --git a/slb-minbias-sprucing/davinci.py b/prod/davinci.py
similarity index 100%
rename from slb-minbias-sprucing/davinci.py
rename to prod/davinci.py
diff --git a/slb-minbias-sprucing/fields.json b/prod/fields.json
similarity index 100%
rename from slb-minbias-sprucing/fields.json
rename to prod/fields.json
diff --git a/slb-minbias-sprucing/info.yaml b/prod/info.yaml
similarity index 80%
rename from slb-minbias-sprucing/info.yaml
rename to prod/info.yaml
index 7b83c9301e..339246ef9c 100644
--- a/slb-minbias-sprucing/info.yaml
+++ b/prod/info.yaml
@@ -12,8 +12,8 @@ defaults:
 {%- set eventtype = '30000000' %}  
 
 {%- set polarity_variables = [
-  ('MagDown'  , 'sim-20201113-5-vc-mu100-Sim10','dddb-20220927-2015' ),
-  ('MagUp'    , 'sim-20201113-5-vc-md100-Sim10','dddb-20220927-2015' ),
+  ('MagDown'  , 'sim10-2024.W40.42-v00.00-md100','dddb-20240427' ),
+  ('MagUp'    , 'sim10-2024.W40.42-v00.00-md100','dddb-20240427' ),
 ]
 %}
 
@@ -23,10 +23,10 @@ defaults:
 MINBIAS_{{polarity}}_SPRUCE:
   application: "Moore/{{spruce_v}}@{{platform}}"
   input:
-    bk_query: '{{mc_cond_path}}/{{eventtype}}/DST'    
+    bk_query: '{{mc_cond_path}}/{{eventtype}}/HLT2.DST'    
   output: Spruce.dst
   options:
-    entrypoint : slb_central_analysis_production.mc_spruce_hackathon:main
+    entrypoint : prod.spruce:main
     extra_options:
       input_raw_format: 0.5
       conddb_tag: {{conddb_tag}}
@@ -45,7 +45,7 @@ MINBIAS_{{polarity}}_DV:
     job_name: "MINBIAS_{{polarity}}_SPRUCE"
   output: Tuple.root
   options:
-    entrypoint : slb_central_analysis_production.mc_davinci_hackathon:main
+    entrypoint : prod.davinci:main
     extra_options:
       input_raw_format: 0.5
       conddb_tag: {{conddb_tag}}
diff --git a/prod/spruce.py b/prod/spruce.py
new file mode 100644
index 0000000000..203f7ea39c
--- /dev/null
+++ b/prod/spruce.py
@@ -0,0 +1,41 @@
+from Moore import Options, options, run_moore, config
+from Moore.lines import optimize_controlflow
+from Moore.config import SpruceLine,register_line_builder
+from Moore.streams import DETECTORS, Stream, Streams
+from PyConf.application import configure_input, configure, default_raw_event
+from RecoConf.global_tools import stateProvider_with_simplified_geom,trackMasterExtrapolator_with_simplified_geom
+from PyConf.Algorithms import VeloRetinaClusterTrackingSIMD
+from RecoConf.reconstruction_objects import reconstruction
+from RecoConf.legacy_rec_hlt1_tracking import (make_VeloClusterTrackingSIMD, make_RetinaClusters)
+from PyConf.reading import reconstruction as reco_spruce, upfront_reconstruction as upfront_spruce
+from RecoConf.decoders import default_ft_decoding_version,default_VeloCluster_source
+from Moore.persistence.hlt2_tistos import list_of_full_stream_lines
+from Hlt2Conf.lines.semileptonic import all_lines as slb_lines
+from Hlt2Conf.lines.topological_b import all_lines as topo_lines
+from Hlt2Conf.lines.semileptonic import sprucing_lines as slb_sprucing_lines
+from Moore.persistence.hlt2_tistos import list_of_full_stream_lines
+
+
+def lines_for_tistos():
+    return [linename for line_dict in [topo_lines] for linename in line_dict.keys()] + [linename for linename in slb_lines.keys()]
+
+def make_streams():
+    lines = [builder() for linename, builder in slb_sprucing_lines.items()] 
+    streams = [Stream(lines=lines, detectors=[])]
+    return Streams(streams=streams)
+
+def main(options: Options):
+    default_VeloCluster_source.global_bind(bank_type="VPRetinaCluster")
+    make_VeloClusterTrackingSIMD.global_bind(
+        algorithm=VeloRetinaClusterTrackingSIMD)
+
+    public_tools = [
+        trackMasterExtrapolator_with_simplified_geom(),
+        stateProvider_with_simplified_geom()
+    ]
+    with reconstruction.bind(from_file=True, spruce=True),\
+      reco_spruce.bind(simulation=True),\
+      upfront_spruce.bind(simulation=True),\
+      list_of_full_stream_lines.bind(lines=lines_for_tistos),\
+      optimize_controlflow.bind(optimization="default"):
+       return run_moore(options, make_streams, public_tools=public_tools)
-- 
GitLab


From c22a8144c30604697e124da6c4490d01fb3aa06b Mon Sep 17 00:00:00 2001
From: Tommaso Fulghesu <tommaso.fulghesu@cern.ch>
Date: Wed, 15 Jan 2025 12:18:36 +0100
Subject: [PATCH 5/6] Fix limiting the sprucing lines we run on

---
 prod/davinci.py |  9 ++++-----
 prod/info.yaml  | 17 ++++++++++++++---
 prod/spruce.py  | 15 ++++++++-------
 3 files changed, 26 insertions(+), 15 deletions(-)

diff --git a/prod/davinci.py b/prod/davinci.py
index 009cee5db8..1276936a16 100644
--- a/prod/davinci.py
+++ b/prod/davinci.py
@@ -16,7 +16,7 @@ import json
 
 #read the data from fields.json
 ap_base = os.environ['ANALYSIS_PRODUCTIONS_BASE']
-json_path = f'{ap_base}/slb_central_analysis_production/fields.json'
+json_path = f'{ap_base}/prod/fields.json'
 with open(json_path, 'r') as f:
     spruce_fields = json.load(f)
 
@@ -544,16 +544,15 @@ def tuple_b_had(pvs,
                     inputs=b_parts)
 
 
-def main(options: Options, isMC: bool):
+def main(options: Options, isMC: bool): 
     user_algorithms = {}
+
     for line_name in spruce_line_names:
         if any(substring in line_name
                for substring in ["Fake", "SS", "WS", "NoPID"]):
             continue
 
-        # get the primary vertices
-        pvs = get_pvs()
-
+    
         # get the B particles
         b_parts = get_particles(f"/Event/Spruce/{line_name}/Particles")
 
diff --git a/prod/info.yaml b/prod/info.yaml
index 339246ef9c..64ddbbdd95 100644
--- a/prod/info.yaml
+++ b/prod/info.yaml
@@ -5,19 +5,27 @@ defaults:
 
 {%- set platform           = 'x86_64_v2-el9-gcc13+detdesc-opt' %}
 {%- set dv_v               = 'v64r13' %}
-{%- set spruce_v           = 'v55r11' %}
+{%- set spruce_v           = 'v55r13p4' %}
 
 {%- set isMC = True %}
 
 {%- set eventtype = '30000000' %}  
 
+{%- set lines = [
+    'SpruceSLB_BcToD0ENu_D0ToKPi',
+    'SpruceSLB_BuToD0TauNu_D0ToKPi_TauToPiPiPiNu',
+    'SpruceSLB_BuToD0ENu_D0ToKPi',
+    'SpruceSLB_B0ToDpTauNu_DpToKPiPi_TauToPiPiPiNu',
+    'SpruceSLB_BuToD0TauNu_D0ToK3Pi_TauToPiPiPiNu'
+] %}
+
 {%- set polarity_variables = [
   ('MagDown'  , 'sim10-2024.W40.42-v00.00-md100','dddb-20240427' ),
   ('MagUp'    , 'sim10-2024.W40.42-v00.00-md100','dddb-20240427' ),
 ]
 %}
 
-{%- for polarity, conddb_tag , dddb_tag in polarity_variables %}
+{%- for polarity,conddb_tag,dddb_tag in polarity_variables %}
 {%- set mc_cond_path = '/MC/2024/Beam6800GeV-2024.W40.42-' + polarity + '-Nu7.6-25ns-Pythia8/Sim10d/HLT2-2024.W40.42' %}
 
 MINBIAS_{{polarity}}_SPRUCE:
@@ -37,7 +45,10 @@ MINBIAS_{{polarity}}_SPRUCE:
       input_process: "Hlt2"
       simulation: True
       process: Spruce
-      data_type: "Upgrade" 
+      data_type: "Upgrade"
+    extra_args:
+      - "{{lines}}"
+  
 
 MINBIAS_{{polarity}}_DV:
   application: "DaVinci/{{dv_v}}@{{platform}}"
diff --git a/prod/spruce.py b/prod/spruce.py
index 203f7ea39c..329414a398 100644
--- a/prod/spruce.py
+++ b/prod/spruce.py
@@ -16,15 +16,16 @@ from Hlt2Conf.lines.semileptonic import sprucing_lines as slb_sprucing_lines
 from Moore.persistence.hlt2_tistos import list_of_full_stream_lines
 
 
-def lines_for_tistos():
-    return [linename for line_dict in [topo_lines] for linename in line_dict.keys()] + [linename for linename in slb_lines.keys()]
 
-def make_streams():
-    lines = [builder() for linename, builder in slb_sprucing_lines.items()] 
+def lines_for_tistos(lines: list):
+    return [linename for line_dict in [topo_lines] for linename in line_dict.keys()] + [linename for linename in slb_lines.keys() if linename in lines]
+
+def make_full_streams(lines: list):
+    lines = [builder() for linename, builder in slb_sprucing_lines.items() if linename in lines] 
     streams = [Stream(lines=lines, detectors=[])]
     return Streams(streams=streams)
 
-def main(options: Options):
+def main(options: Options, lines: list):
     default_VeloCluster_source.global_bind(bank_type="VPRetinaCluster")
     make_VeloClusterTrackingSIMD.global_bind(
         algorithm=VeloRetinaClusterTrackingSIMD)
@@ -36,6 +37,6 @@ def main(options: Options):
     with reconstruction.bind(from_file=True, spruce=True),\
       reco_spruce.bind(simulation=True),\
       upfront_spruce.bind(simulation=True),\
-      list_of_full_stream_lines.bind(lines=lines_for_tistos),\
+      list_of_full_stream_lines.bind(lines=lines_for_tistos(lines)),\
       optimize_controlflow.bind(optimization="default"):
-       return run_moore(options, make_streams, public_tools=public_tools)
+        return run_moore(options, lambda: make_full_streams(lines), public_tools=public_tools)
-- 
GitLab


From 0a4bf99de3c74d9c9b9c8b81c166bc0698551608 Mon Sep 17 00:00:00 2001
From: Tommaso Fulghesu <tommaso.fulghesu@cern.ch>
Date: Wed, 15 Jan 2025 13:29:24 +0100
Subject: [PATCH 6/6] Add pvs definition

---
 prod/davinci.py | 1 +
 1 file changed, 1 insertion(+)

diff --git a/prod/davinci.py b/prod/davinci.py
index 1276936a16..39972abd23 100644
--- a/prod/davinci.py
+++ b/prod/davinci.py
@@ -552,6 +552,7 @@ def main(options: Options, isMC: bool):
                for substring in ["Fake", "SS", "WS", "NoPID"]):
             continue
 
+        pvs = get_pvs()
     
         # get the B particles
         b_parts = get_particles(f"/Event/Spruce/{line_name}/Particles")
-- 
GitLab