MC Truth of unreconstructed particles

This example reads an HLT2 simulated sample and creates an ntuple with truth information about unreconstructed particles

import Functors as F
from FunTuple import FunctorCollection
from FunTuple import FunTuple_Particles as Funtuple
from DaVinci.algorithms import create_lines_filter
from DaVinci import make_config, Options
from DaVinciMCTools import MCTruthAndBkgCat
from PyConf.reading import get_particles


def main(options: Options):
    # define fields
    fields = {"Lb": "[Lambda_b0 -> (Lambda_c+ -> p+ K- pi+) mu-]CC"}

    # get particles to run over
    line_name = "Hlt2SLB_LbToLcMuNu_LcToPKPi_Line"
    particles = get_particles(f"/Event/HLT2/{line_name}/Particles")
    my_filter = create_lines_filter(name="Myfilter", lines=[f"{line_name}"])

    # get configured "MCTruthAndBkgCatAlg" algorithm for HLT2 output
    MCTRUTH = MCTruthAndBkgCat(particles, name="MCTruthAndBkgCat_info")

    # define variables and add them to all fields
    #
    # In MCDecay case it is possible to use the simplified decay descriptor using
    # only the direct products of the parent decay and omitting other descendants
    # In this case we're interested into MC information about the unreconstructed neutrino
    #
    # A returning value of NaN is needed whenever the FIND_MCDECAY functor
    # is not able to find any MC particle from the decay, because either none or more
    # than one caret is passed to the DecayDescriptor
    lc_px = (
        F.VALUE_OR(F.NaN)
        @ F.PX
        @ F.FIND_MCDECAY("[ Lambda_b0 => ^Lambda_c+ mu- nu_mu~ ]CC")
    )
    mu_px = (
        F.VALUE_OR(F.NaN)
        @ F.PX
        @ F.FIND_MCDECAY("[ Lambda_b0 => Lambda_c+ ^mu- nu_mu~ ]CC")
    )
    nu_px = (
        F.VALUE_OR(F.NaN)
        @ F.PX
        @ F.FIND_MCDECAY("[ Lambda_b0 => Lambda_c+ mu- ^nu_mu~ ]CC")
    )
    lc_true_id = (
        F.VALUE_OR(-1)
        @ F.PARTICLE_ID
        @ F.FIND_MCDECAY("[ Lambda_b0 => ^Lambda_c+ mu- nu_mu~ ]CC")
    )
    mu_true_id = (
        F.VALUE_OR(-1)
        @ F.PARTICLE_ID
        @ F.FIND_MCDECAY("[ Lambda_b0 => Lambda_c+ ^mu- nu_mu~ ]CC")
    )
    nu_true_id = (
        F.VALUE_OR(-1)
        @ F.PARTICLE_ID
        @ F.FIND_MCDECAY("[ Lambda_b0 => Lambda_c+ mu- ^nu_mu~ ]CC")
    )

    # A returning value of NaN is needed whenever MCAssocTable is empty
    # i.e. has no relations inside
    lb_variables = FunctorCollection(
        {
            "TRUEPX": MCTRUTH(F.PX),
            "Lc_TRUEPX": F.VALUE_OR(F.NaN) @ MCTRUTH(lc_px),
            "Mu_TRUEPX": F.VALUE_OR(F.NaN) @ MCTRUTH(mu_px),
            "NuMu_TRUEPX": F.VALUE_OR(F.NaN) @ MCTRUTH(nu_px),
            "Lc_TRUEID": F.VALUE_OR(-1) @ MCTRUTH(lc_true_id),
            "Mu_TRUEID": F.VALUE_OR(-1) @ MCTRUTH(mu_true_id),
            "NuMu_TRUEID": F.VALUE_OR(-1) @ MCTRUTH(nu_true_id),
        }
    )

    variables = {"Lb": lb_variables}

    # define tupling algorithm
    my_tuple = Funtuple(
        name="Tuple",
        tuple_name="DecayTree",
        fields=fields,
        variables=variables,
        inputs=particles,
    )

    return make_config(options, [my_filter, my_tuple])

To run the example:

lbexec DaVinciExamples.tupling.option_davinci_tupling_unreconstructed_info:main $DAVINCIEXAMPLESROOT/example_data/Upgrade_LbToLcmunu.yaml

For reference, these are the options of this example

input_files:
   - root://eoslhcb.cern.ch//eos/lhcb/wg/dpa/wp3/tests/Upgrade_LbToLcmunu.dst
input_manifest_file: root://eoslhcb.cern.ch//eos/lhcb/wg/dpa/wp3/tests/Upgrade_LbToLcmunu.tck.json
input_type: ROOT
simulation: True
conddb_tag: sim-20210617-vc-mu100
dddb_tag: dddb-20210617
conditions_version: master
geometry_version: run3/trunk
input_raw_format: 0.5
ntuple_file: 'mytuple.root'
print_freq: 1
input_process: Hlt2
input_stream: default
evt_max: 7
persistreco_version: 0.0
lumi: False
write_fsr: False