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