Re-using particles from a decay tree

This example shows how to extract particles from a decay tree and form new combinations with them.


import Functors as F
from DaVinci import Options, make_config
from DaVinci.algorithms import create_lines_filter
from FunTuple import FunctorCollection
from FunTuple import FunTuple_Particles as Funtuple
from PyConf.reading import get_particles, get_pvs
from RecoConf.event_filters import require_pvs

from PyConf.Algorithms import ThOrParticleSelection
from RecoConf.algorithms_thor import ParticleCombiner
from GaudiKernel.SystemOfUnits import MeV


def main(options: Options):

    line = "Hlt2BnoC_BdsToKSKpPim_LL"  # The original line, which has the decay B0->KS K+ pi-
    data = get_particles(f"/Event/HLT2/{line}/Particles")
    line_prefilter = create_lines_filter(name=f"PreFilter_{line}", lines=[line])

    pvs = get_pvs()

    fields = {
        "B": "[B0 -> (KS0 -> pi+ pi-) (K*(892)0 -> K+ pi-)]CC",
        "KS0": "[B0 -> ^(KS0 -> pi+ pi-) (K*(892)0 -> K+ pi-)]CC",
        "KS0Pip": "[B0 -> (KS0 -> ^pi+ pi-) (K*(892)0 -> K+ pi-)]CC",
        "KS0Pim": "[B0 -> (KS0 -> pi+ ^pi-) (K*(892)0 -> K+ pi-)]CC",
        "Kst": "[B0 -> (KS0 -> pi+ pi-) ^(K*(892)0 -> K+ pi-)]CC",
        "KstKp": "[B0 -> (KS0 -> pi+ pi-) (K*(892)0 -> ^K+ pi-)]CC",
        "KstPim": "[B0 -> (KS0 -> pi+ pi-) (K*(892)0 -> K+ ^pi-)]CC",
    }

    # Grab the particles from the decay tree with the GET_CHILDREN functor and select the ones we want
    child_KS0 = F.FILTER(F.IS_ABS_ID("KS0")) @ F.GET_CHILDREN()
    child_K = F.FILTER(F.IS_ABS_ID("K+")) @ F.GET_CHILDREN()
    child_pi = F.FILTER(F.IS_ABS_ID("pi+")) @ F.GET_CHILDREN()

    KS_from_B = ThOrParticleSelection(
        InputParticles=data, Functor=child_KS0
    ).OutputSelection

    kaons_from_B = ThOrParticleSelection(
        InputParticles=data, Functor=child_K
    ).OutputSelection

    pions_from_B = ThOrParticleSelection(
        InputParticles=data, Functor=child_pi
    ).OutputSelection

    # Make a K*(892)0 with the selected K+ and pi- from the original line

    am_min = 630 * MeV
    am_max = 1300 * MeV

    asumpt_min = 1000 * MeV
    vchi2pdof_max = 16
    bpvfdchi2_min = 16

    descriptor = "[K*(892)0 -> K+ pi-]cc"

    combination_code = F.require_all(
        F.math.in_range(am_min, F.MASS, am_max), F.SUM(F.PT) > asumpt_min
    )

    vertex_code = F.require_all(
        F.CHI2DOF < vchi2pdof_max, F.BPVFDCHI2(pvs) > bpvfdchi2_min
    )

    my_kstar0 = ParticleCombiner(
        [kaons_from_B, pions_from_B],
        name="Kstar_combiner_{hash}",
        DecayDescriptor=descriptor,
        CombinationCut=combination_code,
        CompositeCut=vertex_code,
    )

    """
    Make a B0 with the Kstar and KS
    """

    am_min = 4900 * MeV
    am_max = 6000 * MeV
    asumpt_min = 1000 * MeV
    bpvfdchi2_min = 36
    bpvdira_min = 0.999
    vchi2pdof_max = 10
    pt_min = 1500 * MeV

    combination_code = F.require_all(
        F.math.in_range(am_min - 100 * MeV, F.MASS, am_max + 100 * MeV),
        F.SUM(F.PT) > asumpt_min,
    )

    vertex_code = F.require_all(
        F.PT > pt_min,
        F.math.in_range(am_min, F.MASS, am_max),
        F.CHI2DOF < vchi2pdof_max,
        F.BPVDIRA(pvs) > bpvdira_min,
        F.BPVFDCHI2(pvs) > bpvfdchi2_min,
    )

    descriptor = "[B0 -> KS0 K*(892)0]cc"
    my_B0 = ParticleCombiner(
        [KS_from_B, my_kstar0],
        name="B0_combiner_{hash}",
        DecayDescriptor=descriptor,
        CombinationCut=combination_code,
        CompositeCut=vertex_code,
    )

    all_vars = FunctorCollection({"M": F.MASS, "P": F.P, "PT": F.PT})

    variables = {"ALL": all_vars}

    funtuple = Funtuple(
        name=line,
        tuple_name="DecayTree",
        fields=fields,
        variables=variables,
        inputs=my_B0,
    )

    algs = {line: [line_prefilter, require_pvs(pvs), funtuple]}

    return make_config(options, algs)

To run the example:

lb-run DaVinci/vXXrY lbexec DaVinciExamples.tupling.option_davinci_tupling_reuse_particles:main  $DAVINCIEXAMPLESROOT/example_data/test_spruced_data_bnoc.yaml

For reference, these are the options of this example

testfiledb_key: DaVinciExample_ReuseParticles_BnoC_data
evt_max: 300
input_raw_format: 0.5
print_freq: 1000
ntuple_file: B2KSKst_tuple.root
input_process: "TurboPass"
input_stream: bnoC
dddb_tag: default
conddb_tag: default