Tupling from Spruce data output

This example shows how to run on spruced output with 2023 commissioning data.

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


def main(options: Options):
    line_B0Dspi = "SpruceB2OC_BdToDsmPi_DsmToKpKmPim"
    bd2dspi_line = get_particles(f"/Event/Spruce/{line_B0Dspi}/Particles")

    fields_dspi = {
        "B0": "[B0 -> D_s- pi+]CC",
        "Ds": "[B0 -> ^D_s- pi+]CC",
        "pip": "[B0 -> D_s- ^pi+]CC",
    }

    v2_pvs = get_pvs()

    #
    # Variables for B0.
    # BPVLTIME sometimes gets the right solution, sometimes nan and sometimes nonsense.
    # Reported as Rec#421.
    #
    variables = FunctorCollection(
        {
            "BPVFDCHI2": F.BPVFDCHI2(v2_pvs),
            "BPVFD": F.BPVFD(v2_pvs),
            "BPVLTIME": F.BPVLTIME(v2_pvs),
            "BPVIP": F.BPVIP(v2_pvs),
            "BPVIPCHI2": F.BPVIPCHI2(v2_pvs),
            "CHI2": F.CHI2,
            "END_VX": F.END_VX,
            "END_VY": F.END_VY,
            "END_VZ": F.END_VZ,
            "BPVX": F.BPVX(v2_pvs),
            "BPVY": F.BPVY(v2_pvs),
            "BPVZ": F.BPVZ(v2_pvs),
        }
    )

    # FunTuple: make functor collection from the imported functor library Kinematics
    variables_all = FC.Kinematics()

    #
    # Variables for pions.
    # PID is uncalibrated and many PID variables return 0.
    # PROBNN_D and PROBNN_MU presently returns nan.
    #
    all_vars = {}
    all_vars["PID_E"] = F.PID_E
    all_vars["PID_K"] = F.PID_K
    all_vars["PID_MU"] = F.PID_MU
    all_vars["PID_P"] = F.PID_P
    all_vars["PID_PI"] = F.PID_PI
    # POD
    all_vars["PROBNN_E"] = F.PROBNN_E
    all_vars["PROBNN_GHOST"] = F.PROBNN_GHOST
    all_vars["PROBNN_K"] = F.PROBNN_K
    all_vars["PROBNN_P"] = F.PROBNN_P
    all_vars["PROBNN_PI"] = F.PROBNN_PI

    variables_extra = FunctorCollection(all_vars)
    # FunTuple: associate functor collections to field (branch) name
    variables_B0Dspi = {
        "ALL": variables_all,  # adds variables to all fields
        "B0": variables,
        "Ds": variables,
        "pip": variables_extra,
    }

    #
    # Event variables
    #
    evt_vars = FC.EventInfo()
    evt_vars["PV_SIZE"] = F.SIZE(v2_pvs)

    tuple_B0Dspi = Funtuple(
        name="B0Dspi_Tuple",
        tuple_name="DecayTree",
        fields=fields_dspi,
        variables=variables_B0Dspi,
        event_variables=evt_vars,
        inputs=bd2dspi_line,
    )

    filter_B0Dspi = create_lines_filter(
        name="HDRFilter_B0Dspi", lines=[f"{line_B0Dspi}"]
    )

    algs = {
        "B0Dspi": [filter_B0Dspi, tuple_B0Dspi],
    }

    return make_config(options, algs)

To run the example:

lbexec DaVinciExamples.tupling.option_davinci_tupling_from_spruce_data:main $DAVINCIEXAMPLESROOT/example_data/test_spruced_data.yaml

For reference, these are the options of this example

input_files:
- root://eoslhcb.cern.ch//eos/lhcb/wg/dpa/wp1/data/lumi/test3/spruce_all_lines_production_1.b2oc.dst
input_manifest_file: root://eoslhcb.cern.ch//eos/lhcb/wg/dpa/wp1/data/lumi/test3/spruce_all_lines_production.tck.json
input_type: ROOT
simulation: False
conddb_tag: md_VP_SciFi_macromicrosurvey_from20220923
dddb_tag: upgrade/dddb-20221004
conditions_version: master
geometry_version: run3/trunk
output_level: 3
input_raw_format: 0.5
input_process: Spruce
input_stream: b2oc