|
| 1 | +--- |
| 2 | +layout: page |
| 3 | +title: Second steps in LHCb |
| 4 | +subtitle: Reuse particles from a decay tree |
| 5 | +minutes: 10 |
| 6 | +--- |
| 7 | + |
| 8 | +> ## Learning Objectives {.objectives} |
| 9 | +> |
| 10 | +> * Learn how to extract particles from a decay tree |
| 11 | +> * Build a new particle from the extracted particles |
| 12 | +
|
| 13 | +Sometimes we want to extract a portion of the decay tree in order to build a different decay. |
| 14 | +To do that, we need to put the particles we're interested in in a new container so they can afterwards be used as inputs to a `CombineParticles` instance (as we saw in [the selection framework lesson](https://lhcb.github.io/second-analysis-steps/01-building-decays.html)). |
| 15 | +To achieve this we can use the `FilterInTrees` algorithm, a simple variation of `FilterDesktop` ([doxygen](https://lhcb-release-area.web.cern.ch/LHCb-release-area/DOC/hlt/latest_doxygen/de/d8e/class_filter_in_trees.html)). |
| 16 | + |
| 17 | +Let's start from the example in [the selection framework lesson](https://lhcb.github.io/second-analysis-steps/01-building-decays.html) and let's check that the $\pi^-$ child of the $D^0$ does not come from a $\rho\to\pi^+\pi^-$. |
| 18 | +To do that, we have to extract the $\pi^-$ from `([D0 -> pi+ K-]CC)` and combine it with all pions in `Phys/StdAllNoPIDsPions/Particles`. |
| 19 | + |
| 20 | +Using `FilterInTrees` is done in the same way we would use `FilterDesktop`: |
| 21 | + |
| 22 | +```python |
| 23 | +from Configurables import FilterInTrees |
| 24 | +from PhysSelPython.Wrappers import Selection, DataOnDemand |
| 25 | + |
| 26 | +decay_tree_location = '/Event/AllStreams/Phys/D2hhCompleteEventPromptDst2D2RSLine/Particles' |
| 27 | +d0_from_dst = FilterInTrees('d0_from_dst_filter', Code="DECTREE('[Charm -> pi+ K-]CC')") |
| 28 | +d0_from_dst_sel = Selection("d0_from_dst_sel", |
| 29 | + Algorithm=d0_from_dst, |
| 30 | + RequiredSelections=[AutomaticData(Location=decay_tree_location)]) |
| 31 | +pions_from_d0 = FilterInTrees('pions_from_d0_filter',Code="('pi+' == ABSID)") |
| 32 | +pions_from_d0_sel = Selection("pions_from_d0_sel", |
| 33 | + Algorithm=pions_from_d0, |
| 34 | + RequiredSelections=[d0_from_dst_sel]) |
| 35 | +``` |
| 36 | + |
| 37 | +The output of `pions_from_d0_sel` is a container with all the pions coming from the $D^0$. |
| 38 | + |
| 39 | +> ## Question {.callout} |
| 40 | +> Do you see why we couldn't use something simple like |
| 41 | +> ```python |
| 42 | +pions_from_d0 = FilterInTrees('pions_from_d0_filter', Code="'pi+' == ABSID") |
| 43 | +``` |
| 44 | +> ? |
| 45 | +
|
| 46 | +Note how we had to do the process in two steps in order to avoid getting the soft pion from the $D^*$. |
| 47 | +Sometimes this makes things quite difficult, but almost all problems can be solved with a smart use of the `DECTREE` container in an intermediate step. |
| 48 | + |
| 49 | +> ## Selecting the soft pion {.challenge} |
| 50 | +> Can you find of a way of selecting the soft pion? |
| 51 | +> Hint: use the `FilterDecays` algorithm, in which you specify a decay descriptor as `Code`, marking the desired particle(s). |
| 52 | +
|
| 53 | +The final step is easy, very similar to [building your own decay](https://lhcb.github.io/second-analysis-steps/01-building-decays.html): |
| 54 | + |
| 55 | +```python |
| 56 | +from Configurables import CombineParticles |
| 57 | +from PhysSelPython.Wrappers import Selection, DataOnDemand |
| 58 | + |
| 59 | +Pions = DataOnDemand('Phys/StdAllNoPIDsPions/Particles') |
| 60 | +rho = CombineParticles('rho_particles', |
| 61 | + DecayDescriptor=['rho(770)0 -> pi+ pi-'], |
| 62 | + CombinationCut="ADAMASS('rho(770)0') < 300*MeV", |
| 63 | + MotherCut='(VFASPF(VCHI2/VDOF)< 9)') |
| 64 | +rho_sel = Selection('rho_sel', |
| 65 | + Algorithm=rho, |
| 66 | + RequiredSelections=[pions_from_d0_sel, Pions]) |
| 67 | +``` |
| 68 | + |
| 69 | +Unfortunately, the `CombineParticles` example we just wrote is not exactly what we meant, since it will actually build $\rho$ from all pions it gets as input, not using one from our `pions_from_d0` selection and one from `'Phys/StdAllNoPIDsPions/Particles'`. |
| 70 | +How to solve this? |
| 71 | +We have to get creative and use the tools at hand: |
| 72 | +for example, we could use `SubstitutePID` from the previous lesson to change the PID of the pions in the `pions_from_d0` selection to kaon and build `[rho(770)0 -> K+ pi-]CC` and then change again the PID of the kaon to a pion. |
| 73 | +Of course, if we were reconstructing $K^{*}(892)^{0} \to K^{-}\pi^{+}$ with `Phys/StdAllLooseKaons/Particles` instead, for example, we would already have everything we need since the ambiguity wouldn't exist. |
| 74 | + |
| 75 | +> ## An interesting detail {.callout} |
| 76 | +> One can use `FilterInTrees` and `FilterDecays` to select several particles at once and obtain a flattened list. |
| 77 | +> For example, if we had a Stripping line that builds `[B- -> (^D0 -> ^K- ^pi+) ^pi-]cc` and we wanted to combine the $D^0$ and $\pi^-$ with an external $\pi^0$ to build `[B- -> D0 pi- pi0]cc`, we could do |
| 78 | +> ```python |
| 79 | +flatlist = FilterInTrees ("FlatList", Code="('D0' == ABSID) | ('pi-' == ABSID)") |
| 80 | +from Configurables import CombineParticles |
| 81 | +add_pi0 = CombineParticles("MakeB", |
| 82 | + DecayDescriptor = "[B- -> D0 pi- pi0]cc", |
| 83 | + ... |
| 84 | + Inputs=[flatlist, resolvedPi0]) |
| 85 | +``` |
| 86 | +> `flatlist` contains both $D^0$ and $\pi^-$, which are then used to build the $B$. |
0 commit comments