Replace a mass hypothesis
Learning Objectives
-
Create a new selection starting from the stripping line output
-
Change the particle hypothesis made by the stripping line
In certain situations, we may want to swap the mass hypothesis or PID of two particles. Take the case of \(D_s^-\to K^-K^+\pi^-\), where the \(K^-\) and the \(\pi^-\) sometimes are mis-identified. In this case, we would be interested in both \(D_s^-\to K^-K^+\pi^-\) and \(D_s^-\to \pi^-K^+ K^-\), since the order of the input particles in the decay descriptor matters.
This is precisely the case this lesson will cover, where we will create three nTuples, one for the \(D_s^-\to K^-K^+\pi^-\) case, another for the \(D_s^-\to \pi^-K^+ K^-\) case, and a third one combining the two previous cases.
We have a sprucing line selecting these candidates, in which the \(D_s^-\) comes from
a \(B^0\). We can cover the swapped-mass case by selecting candidates through the
sprucing line, and using the SubstitutePID
function to create a second Funtuple
in which we swap the two mass hypothesis.
The \(D_s^-\to K^-K^+\pi^-\) candidates are inside the B_Data
container here:
from PyConf.reading import get_particles
B_Line = "SpruceB2OC_BdToDsmK_DsmToKpKmPim_LTU"
B_Data = get_particles(f"/Event/Spruce/{B_Line}/Particles")
We can now apply SubstitutePID
to change the decay descriptor on a new Funtuple
:
from DaVinciTools import SubstitutePID
Swapped_Data = SubstitutePID(
"Subs_SwapKpi", # name of the algorithm
B_Data, # input particle container
substitutions=[
"[ B0 -> ( D_s- -> K-{{pi-}} K+ pi-{{K-}} ) K+ ]CC",
],
).Particles
tuple_swapped = Funtuple(
name="SwappedTuple",
tuple_name="DecayTree",
fields=fields,
variables=variables,
event_variables=evt_vars,
inputs=Swapped_Data,
)
fields
, variables
and evt_vars
are provided in the full example here.
In this example, we are assigning the first charged kaon a pion mass hypothesis,
and the charged pion from the \(D_s^-\), a kaon mass hypothesis.
Furthermore, we can also create another tuple in which we combine both cases: the right PID case and the 'wrong' PID case. For this, we create a container which merges both data containers so far:
from PyConf.Algorithms import ParticleContainerMerger
MergedContainer = ParticleContainerMerger(
name="HypothesisMerger",
InputContainers=[B_Data, Swapped_Data],
OutputLevel=INFO,
).OutputContainer
tuple_merged = Funtuple(
name="MergedTuple",
tuple_name="DecayTree",
fields=fields,
variables=variables,
event_variables=evt_vars,
inputs=MergedContainer,
)
We can run this example over simulation samples from the B2OC
working group
using the following options file:
input_files:
- root://eoslhcb.cern.ch//eos/lhcb/wg/dpa/wp7/Run3SK/exampleDST/my_spruce_output-B2OCstream.dst
input_type: ROOT
output_type: ROOT
input_raw_format: 0.5
simulation: true
input_process: Spruce
conddb_tag: sim10-2024.W37.39-v00.00-md100
dddb_tag: dddb-20240427
lumi: false
data_type: '2024'
evt_max: 10000
print_freq: 2000
ntuple_file: tuple.root
The code can be run with the following command:
$ lb-run -c x86_64_v3-el9-gcc13+detdesc-opt+g DaVinci/v65r0 lbexec DVoptions:main options.yaml
The result will be a tuple.root
file with three TTree
objects. OriginalTuple
contains
the candidates passing the sprucing line and satisfying the original decay descriptor.
Here is what the \(D_s^-\) invariant mass distribution looks like:
SwappedTuple
contains the candidates satisfying the decay descriptor
where the pion and the kaon are swapped. As you can see in the histogram below,
the peak is much broader. This is because we are swapping the mass hypothesis applied
to the pion and kaon tracks, but not the requirements. Therefore, the track that we
are now identifying as a pion still has a PID_K>5
from the sprucing line,
and the track that we are identifying as a kaon has a PID_K<5
.
Finally, MergedTuple
contains the addition of the two tuples: