Matching example on data

This example shows how to read an HLT2 file and create an ntuple, containing a matching between particles in the line and persistreco particles based on the VELO IDs.

from PyConf.reading import get_particles
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

from PyConf.Algorithms import FlattenDecayTree, VeloIDOverlapRelationTable
from Hlt2Conf.algorithms_thor import ParticleFilter

from Hlt2Conf.standard_particles import make_long_electrons_with_brem
from GaudiKernel.SystemOfUnits import MeV

from PyConf.reading import get_pvs


def main(options: Options):
    fields = {
        "D0": "[D0 -> K- pi+]CC",
        "Kminus": "[D0 -> ^K- pi+]CC",
        "piplus": "[D0 -> K- ^pi+]CC",
    }

    # other particles from PersistReco, get electrons (that have Bremsstrahlung added)
    long_electrons = make_long_electrons_with_brem()
    pvs = get_pvs()

    d0_variables = FunctorCollection(
        {
            "ID": F.PARTICLE_ID,
            "KEY": F.OBJECT_KEY,
            "PT": F.PT,
            "PX": F.PX,
            "PY": F.PY,
            "PZ": F.PZ,
            "ENERGY": F.ENERGY,
            "P": F.P,
            "FOURMOMENTUM": F.FOURMOMENTUM,
            "BPVDIRA": F.BPVDIRA(pvs),
            "BPVFDCHI2": F.BPVFDCHI2(pvs),
            "BPVIPCHI2": F.BPVIPCHI2(pvs),
        }
    )

    daughter_variables = FunctorCollection(
        {
            "ID": F.PARTICLE_ID,
            "PT": F.PT,
            "PX": F.PX,
            "PY": F.PY,
            "PZ": F.PZ,
            "ENERGY": F.ENERGY,
            "P": F.P,
            "FOURMOMENTUM": F.FOURMOMENTUM,
        }
    )

    variables = {
        "D0": d0_variables,
        "Kminus": daughter_variables,
        "piplus": daughter_variables,
    }

    line_name = "Hlt2Commissioning_D0ToKmPip"
    d02kpi_data = get_particles(f"/Event/HLT2/{line_name}/Particles")

    flattened_input_decay_tree = FlattenDecayTree(
        InputParticles=d02kpi_data, name="FlattenedDzToKPiData"
    )
    basic_particles_dz_to_kpi = ParticleFilter(
        flattened_input_decay_tree.OutputParticles, F.FILTER(F.ISBASICPARTICLE)
    )

    relation_table_match_by_veloid = VeloIDOverlapRelationTable(
        MatchFrom=basic_particles_dz_to_kpi, MatchTo=long_electrons
    ).OutputRelations

    # make electrons with some cuts
    long_electrons_tight_cuts = ParticleFilter(
        Input=make_long_electrons_with_brem(),
        Cut=F.FILTER(F.require_all(F.PT > 500.0 * MeV, F.PID_E > 1.0)),
    )
    # make a test relation table
    relation_table_match_by_veloid_tight_cuts = VeloIDOverlapRelationTable(
        MatchFrom=basic_particles_dz_to_kpi, MatchTo=long_electrons_tight_cuts
    ).OutputRelations

    my_filter = create_lines_filter(name="HDRFilter_D0Kpi", lines=[f"{line_name}"])

    variables["piplus"] += FunctorCollection(
        {
            "Matched_to_Electron_P[nMatchTracks]": F.MAP_INPUT_ARRAY(
                Functor=F.P, Relations=relation_table_match_by_veloid
            ),
            "Matched_to_Electron_Weight[nMatchTracks]": F.MAP_WEIGHT(
                Relations=relation_table_match_by_veloid
            ),
            "Matched_to_Electron_P_tight_cuts[nMatchTracks_tight_cuts]": F.MAP_INPUT_ARRAY(
                Functor=F.P, Relations=relation_table_match_by_veloid_tight_cuts
            ),
            "Matched_to_Electron_ID_tight_cuts[nMatchTracks_tight_cuts]": F.MAP_INPUT_ARRAY(
                Functor=F.PARTICLE_ID,
                Relations=relation_table_match_by_veloid_tight_cuts,
            ),
        }
    )

    evt_variables = FC.SelectionInfo(selection_type="Hlt2", trigger_lines=[line_name])

    # define FunTuple instance
    my_tuple = Funtuple(
        name="DecayTreeTuple",
        tuple_name="DecayTree",
        fields=fields,
        variables=variables,
        event_variables=evt_variables,
        inputs=d02kpi_data,
    )

    return make_config(options, [my_filter, my_tuple])

To run the example:

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

For reference, these are the options of this example

input_files:
 - mdf:root://eoslhcb.cern.ch//eos/lhcb/wg/dpa/wp3/Commissioning2022/Run255620/255620_00150000_0000.raw
 - mdf:root://eoslhcb.cern.ch//eos/lhcb/wg/dpa/wp3/Commissioning2022/Run255620/255620_00150000_0001.raw
 - mdf:root://eoslhcb.cern.ch//eos/lhcb/wg/dpa/wp3/Commissioning2022/Run255620/255620_00150000_0002.raw
 - mdf:root://eoslhcb.cern.ch//eos/lhcb/wg/dpa/wp3/Commissioning2022/Run255620/255620_00150000_0003.raw
 - mdf:root://eoslhcb.cern.ch//eos/lhcb/wg/dpa/wp3/Commissioning2022/Run255620/255620_00150011_0001.raw
input_type: 'RAW'
simulation: False
input_raw_format: 0.5
input_process: Hlt2
conditions_version: AlignmentV14_2024_04_05
geometry_version: run3/trunk
python_logging_level: 3
persistreco_version: 0.0
lumi: False
write_fsr: False