Substitute PID
There are many situations where you may want to change the hypothesis on PID or swap the PID of two particles. For the decay \(D_s^- \to K^- \pi^+ \pi^-\), the \(K^-\) and the \(pi^-\) may be misidentified. Swapping the PID of \(K^-\) and \(\pi^-\) allows us to recover the misidentified case. In this example,
we show how to swap the PID of two particles,
store the result in different trees,
and merge two particle containers to tuple the swapped decay and the original decay in the same tree.
from Gaudi.Configuration import INFO
from FunTuple import FunTuple_Particles as Funtuple
from FunTuple import FunctorCollection
from DaVinci.algorithms import create_lines_filter
from PyConf.reading import get_particles
from DaVinciTools import SubstitutePID
from PyConf.Algorithms import ParticleContainerMerger
import FunTuple.functorcollections as FC
from DaVinci import Options, make_config
import Functors as F
def main(options: Options):
# Define the input
B_Line = "SpruceB2OC_BdToDsmK_DsmToHHH_FEST"
B_Data = get_particles(f"/Event/Spruce/{B_Line}/Particles")
# Filter
my_filter = create_lines_filter(name="HDRFilter_BdToDsmK", lines=[f"{B_Line}"])
# Define the swap
Swapped_Data = SubstitutePID(
"Subs_SwapKpi", # name of the algorithm
B_Data, # input particle container
substitutions=[
"[ B0 -> ( D_s- -> K-{{pi-}} pi+ pi-{{K-}} ) K+ ]CC",
],
).Particles
# Merge the swapped decays and the original decays
MergedContainer = ParticleContainerMerger(
name="HypothesisMerger",
InputContainers=[B_Data, Swapped_Data],
OutputLevel=INFO,
).OutputContainer
# Prepare output for funtuple
fields = {
"B": "[B0 -> ( D_s- -> K- pi+ pi- ) K+]CC",
"Ds": "[B0 -> ^( D_s- -> K- pi+ pi- ) K+]CC",
"Kminus": "[B0 -> ( D_s- -> ^K- pi+ pi- ) K+]CC",
"piplus": "[B0 -> ( D_s- -> K- ^pi+ pi- ) K+]CC",
"piminus": "[B0 -> ( D_s- -> K- pi+ ^pi- ) K+]CC",
"Kplus": "[B0 -> ( D_s- -> K- pi+ pi- ) ^K+]CC",
}
variables_all = FunctorCollection(
{
"ID": F.PARTICLE_ID,
"M": F.MASS,
"P": F.P,
"PT": F.PT,
"ENERGY": F.ENERGY,
}
)
variables = {"ALL": variables_all}
# Get event information
evt_vars = FC.EventInfo()
#
# Configure Funtuple algorithms
#
# 1. Original decays
tuple_original = Funtuple(
name="OriginalTuple",
tuple_name="DecayTree",
fields=fields,
variables=variables,
event_variables=evt_vars,
inputs=B_Data,
)
# 2. Swapped decays
tuple_swapped = Funtuple(
name="SwappedTuple",
tuple_name="DecayTree",
fields=fields,
variables=variables,
event_variables=evt_vars,
inputs=Swapped_Data,
)
# 3. Original decays + Swapped decays (Merged)
tuple_merged = Funtuple(
name="MergedTuple",
tuple_name="DecayTree",
fields=fields,
variables=variables,
event_variables=evt_vars,
inputs=MergedContainer,
)
# Run
algs = {
"Bd2DsmK": [my_filter, tuple_original, tuple_swapped, tuple_merged],
}
return make_config(options, algs)
To run the example:
lbexec DaVinciExamples.tupling.option_davinci_tupling_substitutePID:main $DAVINCIEXAMPLESROOT/example_data/Spruce_all_lines_dst.yaml
For reference, these are the options of this example
input_files:
- root://eoslhcb.cern.ch//eos/lhcb/wg/dpa/wp3/tests/spruce_all_lines_realtimereco_newPacking_newDst.dst
input_manifest_file: root://eoslhcb.cern.ch//eos/lhcb/wg/dpa/wp3/tests/spruce_all_lines_realtime_newPacking_newDst.tck.json
input_type: ROOT
simulation: true
conddb_tag: sim-20171127-vc-md100
dddb_tag: dddb-20171126
conditions_version: master
geometry_version: run3/trunk
lumi: False
write_fsr: False
histo_file: sprucing_histos.root
ntuple_file: sprucing_tuple.root
input_raw_format: 0.5
input_process: Spruce
persistreco_version: 0.0