Particle refitting on data
This example shows how to read data, refit the decay tree with the updated alignment parameters, and tuple the new particles.
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.reading import get_pvs, get_rec_summary
from RecoConf import track_refitting
def main(options: Options):
line_name = "Hlt2Charm_DstpToD0Pip_D0ToKmPip"
original_particles = get_particles(f"/Event/HLT2/{line_name}/Particles")
my_filter = create_lines_filter(name="HDRFilter_D0Kpi", lines=[f"{line_name}"])
""" Next, the original PVs are read from the DST file.
Because an updated VELO alignment impacts the positions of these vertices,
these also need changing:"""
pvs = get_pvs()
updated_pvs = track_refitting.update_vertex_positions(input_pvs=pvs).OutputVertices
""" Note: the refit_decay_tree needs PVs, as Particles in LHCb are
associated to Primary Vertices when they are created. By giving
the PVs, the association is performed with the updated particles,
and (possibly) updated PVs. """
refitted_data = track_refitting.refit_decay_tree(
input_particles=original_particles, input_pvs=updated_pvs
)
refitted_particles = refitted_data.OutputParticles
fields = {
"Dst": "[D*(2010)+ -> (D0 -> K- pi+) pi+]CC",
"Dzero": "[D*(2010)+ -> ^(D0 -> K- pi+) pi+]CC",
"Km": "[D*(2010)+ -> (D0 -> ^K- pi+) pi+]CC",
"Pip": "[D*(2010)+ -> (D0 -> K- ^pi+) pi+]CC",
"TagPi": "[D*(2010)+ -> (D0 -> K- pi+) ^pi+]CC",
}
composite_variables = FunctorCollection(
{
"M": F.MASS,
"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(updated_pvs),
"BPVFDCHI2": F.BPVFDCHI2(updated_pvs),
"BPVIPCHI2": F.BPVIPCHI2(updated_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,
}
)
# we also have access to the previous iteration of the decay tree,
# which can be compared to candidate-per-candidate through a relation table
refitted_decay_tree_relations = refitted_data.OutputRelationsNewToOld
PRE_REFIT_FUNCTOR = lambda n: F.VALUE_OR(-1) @ F.MAP_INPUT(
Functor=n, Relations=refitted_decay_tree_relations
)
pre_refit_variables = FunctorCollection(
{
"Refitting_OLD_M": PRE_REFIT_FUNCTOR(F.MASS),
"Refitting_OLD_PT": PRE_REFIT_FUNCTOR(F.PT),
"Refitting_OLD_P": PRE_REFIT_FUNCTOR(F.P),
"Refitting_OLD_BPVIPCHI2": PRE_REFIT_FUNCTOR(F.BPVIPCHI2(pvs)),
}
)
composite_variables += pre_refit_variables
variables = {
"Dst": composite_variables,
"Dzero": composite_variables,
"Km": daughter_variables,
"Pip": daughter_variables,
"TagPi": daughter_variables,
}
rec_summary = get_rec_summary()
evt_variables = FC.RecSummary(rec_summary) + FC.AllPrimaryVertexInfo(
updated_pvs, extra_info=True
)
my_tuple = Funtuple(
name="DecayTreeTuple",
tuple_name="DecayTree",
fields=fields,
variables=variables,
event_variables=evt_variables,
inputs=refitted_particles,
)
return make_config(options, [my_filter, my_tuple])
To run the example:
lb-run DaVinci/vXXrY lbexec DaVinciExamples.tupling.option_davinci_tupling_from_spruced_turbo_with_refitting:main $DAVINCIEXAMPLESROOT/example_data/2024_sprucing24c2_charm_turbo_data.yaml
For reference, these are the options of this example
testfiledb_key: 2024_Sprucing24c2
input_raw_format: 0.5
input_process: TurboPass
input_stream: charm
python_logging_level: 3
persistreco_version: 1.0
lumi: False
write_fsr: False
ntuple_file: 2024_data.root
evt_max: 300