Belle II Software light-2406-ragdoll
TauDecayModeModule.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9#include <analysis/modules/TauDecayMode/TauDecayModeModule.h>
10#include <framework/datastore/StoreArray.h>
11#include <framework/datastore/StoreObjPtr.h>
12#include <framework/logging/Logger.h>
13#include <framework/particledb/EvtGenDatabasePDG.h>
14#include <iostream>
15#include <vector>
16#include <algorithm>
17#include <TParticlePDG.h>
18#include <map>
19#include <fstream>
20#include <set>
21using namespace std;
22using namespace Belle2;
23
24std::map<std::string, int> make_map(const std::string& file, int chg)
25{
26 std::string fileName;
27 if (file == "") {
28 if (chg < 0) {
29 B2INFO("Missing input mapping file: use mp_file_minus=basf2.find_file('data/analysis/modules/TauDecayMode/map_tauminus.txt') TauDecayMode.param('file_minus', mp_file_minus) to classify with default mapping.");
30 } else {
31 B2INFO("Missing input mapping file: use mp_file_plus=basf2.find_file('data/analysis/modules/TauDecayMode/map_tauplus.txt') TauDecayMode.param('file_plus', mp_file_plus) to classify with default mapping.");
32 }
33 } else {
34 fileName = file;
35 }
36
37 ifstream f;
38 f.open(fileName);
39 std::string line;
40 std::string key;
41 int value;
42 std::map <std::string, int> map_tau;
43 while (f.good()) {
44 getline(f, line);
45 istringstream ss(line);
46 ss >> key >> value;
47 map_tau[key] = value;
48 }
49 f.close();
50 return map_tau;
51}
52
53//-----------------------------------------------------------------
54// Register the Module
55//-----------------------------------------------------------------
56REG_MODULE(TauDecayMode);
57//-----------------------------------------------------------------
58// Implementation
59//-----------------------------------------------------------------
60
61TauDecayModeModule::TauDecayModeModule() : Module(), m_taum_no(0), m_taup_no(0), m_mmode(-2), m_pmode(-2),
62 m_mprong(0), m_pprong(0), tauPair(false), numOfTauMinus(0), numOfTauPlus(0), idOfTauMinus(-1), idOfTauPlus(-1),
63 m_isEtaPizPizPizFromTauMinus(false), m_isEtaPizPizPizFromTauPlus(false),
64 m_isOmegaPimPipFromTauMinus(false), m_isOmegaPimPipFromTauPlus(false)
65{
66 // Set module properties
67 setDescription("Module to identify generated tau pair decays, using MCParticle information."
68 "By default, each tau decay is numbered as TauolaBelle2DecayMode [Ref: BELLE2-NOTE-PH-2020-055]");
69 //Parameter definition
70 addParam("printmode", m_printmode, "Printout more information from each event", std::string("default"));
71 addParam("file_minus", m_file_minus, "Path for an alternative mapping for tau- decays", std::string(""));
72 addParam("file_plus", m_file_plus, "Path for an alternative mapping for tau+ decays", std::string(""));
73}
74
75//
77{
78 mode_decay_minus = make_map(m_file_minus, -1);
79 mode_decay_plus = make_map(m_file_plus, 1);
80 m_tauDecay.registerInDataStore();
81 m_event_metadata.isRequired();
82}
83
84//
86{
87
89 if (tauPair) {
90
92
93 if (m_printmode == "missing") {
94 if (m_mmode == -1) {
95 B2INFO("TauDecayMode:: EventNumber = " << m_event_metadata->getEvent()
96 << " Decay: tau- -> " << m_tauminusdecaymode << " Mode = " << m_mmode);
97 }
98 if (m_pmode == -1) {
99 B2INFO("TauDecayMode:: EventNumber = " << m_event_metadata->getEvent()
100 << " Decay: tau+ -> " << m_tauplusdecaymode << " Mode = " << m_pmode);
101 }
102 }
103
104 if (m_printmode == "all") {
105 B2INFO("TauDecayMode:: EventNumber = " << m_event_metadata->getEvent()
106 << " Decay: tau- -> " << m_tauminusdecaymode << " Mode = " << m_mmode);
107 B2INFO("TauDecayMode:: EventNumber = " << m_event_metadata->getEvent()
108 << " Decay: tau+ -> " << m_tauplusdecaymode << " Mode = " << m_pmode);
109 }
110
111 //
112 if (m_mmode == -1) {
113 m_taum_no = m_taum_no - 1;
115 }
116 if (m_pmode == -1) {
117 m_taup_no = m_taup_no - 1;
119 }
120
123
124 } else {
125 m_pmode = -1;
126 m_mmode = -1;
127 m_pprong = -1;
128 m_mprong = -1;
129 }
130
131 if (!m_tauDecay) m_tauDecay.create();
132 m_tauDecay->addTauMinusIdMode(m_mmode);
133 m_tauDecay->addTauPlusIdMode(m_pmode);
134
135 m_tauDecay->addTauPlusMcProng(m_pprong);
136 m_tauDecay->addTauMinusMcProng(m_mprong);
137
138}
139
141{
142 // Clear local vectors
143 vec_nut.clear();
144 vec_anut.clear();
145 vec_numu.clear();
146 vec_anumu.clear();
147 vec_nue.clear();
148 vec_anue.clear();
149 vec_em.clear();
150 vec_ep.clear();
151 vec_mum.clear();
152 vec_mup.clear();
153 vec_pim.clear();
154 vec_pip.clear();
155 vec_km.clear();
156 vec_kp.clear();
157 vec_apro.clear();
158 vec_pro.clear();
159 vec_pi0.clear();
160 vec_k0s.clear();
161 vec_k0l.clear();
162 vec_eta.clear();
163 vec_omega.clear();
164 vec_etapr.clear();
165 vec_phi.clear();
166 vec_rhom.clear();
167 vec_rhop.clear();
168 vec_rho0.clear();
169 vec_kstarm.clear();
170 vec_kstarp.clear();
171 vec_kstar0.clear();
172 vec_kstar0_br.clear();
173 vec_a1m.clear();
174 vec_a1p.clear();
175 vec_a00_980.clear();
176 vec_a0m_980.clear();
177 vec_a0p_980.clear();
178 vec_a00_1450.clear();
179 vec_a0m_1450.clear();
180 vec_a0p_1450.clear();
181 vec_b1m.clear();
182 vec_b1p.clear();
183 vec_f1.clear();
184 vec_f0.clear();
185 vec_lambda.clear();
186 vec_lmb_br.clear();
187 vec_alpha.clear();
188 vec_gam.clear();
189 //
190 map<int, std::vector<int>> map_vec;
191 //
192 map_vec[11] = vec_em;
193 map_vec[-11] = vec_ep;
194 map_vec[12] = vec_nue;
195 map_vec[-12] = vec_anue;
196 map_vec[13] = vec_mum;
197 map_vec[-13] = vec_mup;
198 map_vec[14] = vec_numu;
199 map_vec[-14] = vec_anumu;
200 map_vec[16] = vec_nut;
201 map_vec[-16] = vec_anut;
202 map_vec[-211] = vec_pim;
203 map_vec[211] = vec_pip;
204 map_vec[-321] = vec_km;
205 map_vec[321] = vec_kp;
206 map_vec[-2212] = vec_apro;
207 map_vec[2212] = vec_pro;
208 map_vec[111] = vec_pi0;
209 map_vec[310] = vec_k0s;
210 map_vec[130] = vec_k0l;
211 map_vec[221] = vec_eta;
212 map_vec[223] = vec_omega;
213 map_vec[331] = vec_etapr;
214 map_vec[333] = vec_phi;
215 map_vec[-213] = vec_rhom;
216 map_vec[213] = vec_rhop;
217 map_vec[113] = vec_rho0;
218 map_vec[-323] = vec_kstarm;
219 map_vec[323] = vec_kstarp;
220 map_vec[313] = vec_kstar0;
221 map_vec[-313] = vec_kstar0_br;
222 map_vec[-20213] = vec_a1m;
223 map_vec[20213] = vec_a1p;
224 map_vec[-9000211] = vec_a0m_980;
225 map_vec[9000211] = vec_a0p_980;
226 map_vec[9000111] = vec_a00_980;
227 map_vec[-10211] = vec_a0m_1450;
228 map_vec[10211] = vec_a0p_1450;
229 map_vec[10111] = vec_a00_1450;
230 map_vec[-10213] = vec_b1m;
231 map_vec[10213] = vec_b1p;
232 map_vec[20223] = vec_f1;
233 map_vec[9010221] = vec_f0;
234 map_vec[3122] = vec_lambda;
235 map_vec[-3122] = vec_lmb_br;
236 map_vec[94144] = vec_alpha;
237 map_vec[22] = vec_gam;
238
239 bool elecFirst = true;
240 bool muonFirst = true;
241
242 bool isPiPizGamTauMinusFirst = true;
243 bool isPiPizGamTauPlusFirst = true;
244
245 bool isLFVTauMinus2BodyDecayFirst = true;
246 bool isLFVTauPlus2BodyDecayFirst = true;
247
248 bool isChargedRhoFromTauMinusFirst = true;
249 bool isChargedRhoFromTauPlusFirst = true;
250
251 bool isChargedA1FromTauMinusFirst = true;
252 bool isChargedA1FromTauPlusFirst = true;
253
254 bool isEtaPPGFromTauMinusFirst = true;
255 bool isEtaPPGFromTauPlusFirst = true;
256
257 bool isOmegaPizGamFromTauMinusFirst = true;
258 bool isOmegaPizGamFromTauPlusFirst = true;
259
260 bool isEtaPizPizPizFromTauMinusFirst = true;
261 bool isEtaPizPizPizFromTauPlusFirst = true;
262
265
266 bool isOmegaPimPipFromTauMinusFirst = true;
267 bool isOmegaPimPipFromTauPlusFirst = true;
268
271
272 // Loop of MCParticles
273 for (int i = 0; i < MCParticles.getEntries(); i++) {
274
275 MCParticle& p = *MCParticles[i];
276
277 int pdgid = p.getPDG();
278
279 if (pdgid == -Const::Klong.getPDGCode()) pdgid = Const::Klong.getPDGCode(); // Strange feature in TauolaBelle2
280
281 if (!p.hasStatus(MCParticle::c_PrimaryParticle))
282 continue; // only consider particles coming from generator, e.g. discard particles added by Geant4
283 if (p.isInitial()) continue; // pick e- e+, but not from the incoming beams
284
285 if (pdgid == Const::electron.getPDGCode() && elecFirst) {
286 elecFirst = false;
287 const MCParticle* mother = p.getMother();
288 if (not mother) continue; // In some low multiplicity generators there may be no mother
289 const vector<MCParticle*> daughters = mother->getDaughters();
290 int nElMinus = 0;
291 int nElPlus = 0;
292 stringstream elec_ss;
293 for (MCParticle* d : daughters) {
294 if (!d->hasStatus(MCParticle::c_PrimaryParticle)) continue;
295 elec_ss << d->getPDG() << " ";
296 if (d->getPDG() == Const::electron.getPDGCode()) nElMinus++;
297 if (d->getPDG() == -Const::electron.getPDGCode()) nElPlus++;
298 }
299 if (nElMinus == 1 && nElPlus == 1) { // use this information in getRecursiveMotherCharge
300 B2DEBUG(1, "Mother of elec pair is = " << mother->getPDG() << " which has daughters : " << elec_ss.str());
301 }
302 }
303
304 if (pdgid == Const::muon.getPDGCode() && muonFirst) {
305 muonFirst = false;
306 const MCParticle* mother = p.getMother();
307 if (not mother) continue; // In some low multiplicity generators there may be no mother
308 const vector<MCParticle*> daughters = mother->getDaughters();
309 int nMuMinus = 0;
310 int nMuPlus = 0;
311 stringstream muon_ss;
312 for (MCParticle* d : daughters) {
313 if (!d->hasStatus(MCParticle::c_PrimaryParticle)) continue;
314 muon_ss << d->getPDG() << " ";
315 if (d->getPDG() == Const::muon.getPDGCode()) nMuMinus++;
316 if (d->getPDG() == -Const::muon.getPDGCode()) nMuPlus++;
317 }
318 if (nMuMinus == 1 && nMuPlus == 1) { // use this information in getRecursiveMotherCharge
319 B2DEBUG(1, "Mother of muon pair is = " << mother->getPDG() << " which has daughters : " << muon_ss.str());
320 }
321 }
322
323 // Special treatment for photons
324 bool accept_photon = false;
325 if (pdgid == Const::photon.getPDGCode()) {
326 const MCParticle* mother = p.getMother();
327 if (not mother) continue; // In some low multiplicity generators there may be no mother
328 int mothid = abs(mother->getPDG());
329
330 // check if the gamma comes from final state charged particles {e, mu, pi, K, p, b_1}
331 bool isRadiationfromFinalStateChargedParticle = false;
332 if (mothid == 11 ||
333 mothid == 13 ||
334 mothid == 211 ||
335 mothid == 321 ||
336 mothid == 2212 ||
337 mothid == 10213) {
338 isRadiationfromFinalStateChargedParticle = true;
339 }
340
341 // check if the gamma from ChargedRho
342 bool isRadiationFromChargedRho = false;
343 if (mothid == 213) {
344 int chg = getRecursiveMotherCharge(mother);
345 if (chg < 0 && isChargedRhoFromTauMinusFirst) {
346 isChargedRhoFromTauMinusFirst = false;
347 isRadiationFromChargedRho = true;
348 }
349 if (chg > 0 && isChargedRhoFromTauPlusFirst) {
350 isChargedRhoFromTauPlusFirst = false;
351 isRadiationFromChargedRho = true;
352 }
353 }
354
355 // check if the gamma from ChargedA1
356 bool isRadiationFromChargedA1 = false;
357 if (mothid == 20213) {
358 int chg = getRecursiveMotherCharge(mother);
359 if (chg < 0 && isChargedA1FromTauMinusFirst) {
360 isChargedA1FromTauMinusFirst = false;
361 isRadiationFromChargedA1 = true;
362 }
363 if (chg > 0 && isChargedA1FromTauPlusFirst) {
364 isChargedA1FromTauPlusFirst = false;
365 isRadiationFromChargedA1 = true;
366 }
367 }
368
369 // check if the gamma comes from intermediate W+- boson
370 bool isRadiationfromIntermediateWBoson = false;
371 if (mothid == 24) isRadiationfromIntermediateWBoson = true;
372
373 // check if it is a tau- -> pi- omega nu, omega -> pi0 gamma decay
374 // Note: TauolaBelle2 generator treats this a coherent production
375 // e.g. includes omega in the form factor but not as an explicit final state particle
376 bool isPiPizGam = false;
377 if (isRadiationfromIntermediateWBoson) {
378 if (p.get4Vector().E() > 0.050) { // 50 MeV threshold
379 const vector<MCParticle*> daughters = mother->getDaughters();
380 int nPiSisters = 0;
381 int nPizSisters = 0;
382 int nTotSisters = 0;
383 int nOtherSisters = 0;
384 for (MCParticle* d : daughters) {
385 if (!d->hasStatus(MCParticle::c_PrimaryParticle)) continue;
386 nTotSisters++;
387 if (abs(d->getPDG()) == 211) {
388 nPiSisters++;
389 } else if (abs(d->getPDG()) == 111) {
390 nPizSisters++;
391 } else if (abs(d->getPDG()) != 22) {
392 nOtherSisters++;
393 }
394 }
395 // allow final state radiation from the tau lepton, but ignore information on number of photons for decay mode classifiction
396 if (nTotSisters >= 3 && nPiSisters == 1 && nPizSisters == 1 && nOtherSisters == 0) {
397 int chg = getRecursiveMotherCharge(mother);
398 if (chg < 0 && isPiPizGamTauMinusFirst) {
399 isPiPizGamTauMinusFirst = false;
400 isPiPizGam = true;
401 }
402 if (chg > 0 && isPiPizGamTauPlusFirst) {
403 isPiPizGamTauPlusFirst = false;
404 isPiPizGam = true;
405 }
406 }
407 }
408 }
409
410 // check if the gamma comes from tau
411 bool isRadiationfromTau = false;
412 if (mothid == 15) isRadiationfromTau = true;
413
414 // check if the gamma comes from 2 body LFV decays of tau, e.g. tau- -> e-/mu- gamma with arbitrary number of extra photon radiations from PHOTOS/FSR
415 bool isLFVTau2BodyDecay = false;
416 if (isRadiationfromTau) {
417 bool hasNeutrinoAsSister = false;
418 int numChargedSister = 0;
419 int numNeutralNonNeutrinoNonPhotonSister = 0;
420 const vector<MCParticle*> daughters = mother->getDaughters();
421 for (MCParticle* d : daughters) {
422 if (!d->hasStatus(MCParticle::c_PrimaryParticle)) continue;
423 hasNeutrinoAsSister = find(begin(Neutrinos), end(Neutrinos), abs(d->getPDG())) != end(Neutrinos);
424 if (hasNeutrinoAsSister) break;
425 }
426 if (!hasNeutrinoAsSister) {
427 for (MCParticle* d : daughters) {
428 if (!d->hasStatus(MCParticle::c_PrimaryParticle)) continue;
429 bool isChargedFinalState = find(begin(finalStatePDGs), end(finalStatePDGs), abs(d->getPDG())) != end(finalStatePDGs);
430 if (isChargedFinalState) {
431 numChargedSister++;
432 } else if (d->getPDG() != 22) {
433 numNeutralNonNeutrinoNonPhotonSister++;
434 }
435 }
436 if (numChargedSister == 1 && numNeutralNonNeutrinoNonPhotonSister == 0) {
437 if (mother->getPDG() == 15 && isLFVTauMinus2BodyDecayFirst) {
438 isLFVTauMinus2BodyDecayFirst = false;
439 isLFVTau2BodyDecay = true;
440 }
441 if (mother->getPDG() == -15 && isLFVTauPlus2BodyDecayFirst) {
442 isLFVTauPlus2BodyDecayFirst = false;
443 isLFVTau2BodyDecay = true;
444 }
445 }
446 }
447 B2DEBUG(1, "hasNeutrinoAsSister = " << hasNeutrinoAsSister
448 << " numChargedSister = " << numChargedSister
449 << " numNeutralNonNeutrinoNonPhotonSister = " << numNeutralNonNeutrinoNonPhotonSister
450 << " isLFVTau2BodyDecay = " << isLFVTau2BodyDecay);
451 }
452
453 bool isPi0GG = false;
454 bool isEtaGG = false;
455 bool isEtpGG = false;
456 bool isPi0GEE = false;
457 bool isEtaPPG = false;
458 bool isOmPizG = false;
459 if (mothid == 111 || mothid == 221 || mothid == 331 || mothid == 223) {
460 const vector<MCParticle*> daughters = mother->getDaughters();
461 int numberofTotalDaughters = 0;
462 int numberOfPhotonDaughters = 0;
463 int numberOfElectronDaughters = 0;
464 int numberOfPionDaughters = 0;
465 int numberOfPizDaughters = 0;
466 for (MCParticle* d : daughters) {
467 if (!d->hasStatus(MCParticle::c_PrimaryParticle)) continue;
468 numberofTotalDaughters ++;
469 if (abs(d->getPDG()) == 22) numberOfPhotonDaughters++;
470 if (abs(d->getPDG()) == 11) numberOfElectronDaughters++;
471 if (abs(d->getPDG()) == 211) numberOfPionDaughters++;
472 if (abs(d->getPDG()) == 111) numberOfPizDaughters++;
473 }
474 if (numberofTotalDaughters == 2 && numberOfPhotonDaughters == 2) {
475 if (mothid == 111) isPi0GG = true;
476 if (mothid == 221) isEtaGG = true;
477 if (mothid == 331) isEtpGG = true;
478 }
479 if (numberofTotalDaughters >= 3 && numberOfPhotonDaughters >= 1 && numberOfElectronDaughters == 2 && numberOfPionDaughters == 0
480 && numberOfPizDaughters == 0) {
481 if (mothid == 111) isPi0GEE = true;
482 }
483 if (numberofTotalDaughters >= 3 && numberOfPhotonDaughters >= 1 && numberOfPizDaughters == 0 && numberOfPionDaughters == 2) {
484 if (mothid == 221) {
485 int chg = getRecursiveMotherCharge(mother);
486 if (chg < 0 && isEtaPPGFromTauMinusFirst) {
487 isEtaPPGFromTauMinusFirst = false;
488 isEtaPPG = true;
489 }
490 if (chg > 0 && isEtaPPGFromTauPlusFirst) {
491 isEtaPPGFromTauPlusFirst = false;
492 isEtaPPG = true;
493 }
494 }
495 }
496 if (numberofTotalDaughters >= 2 && numberOfPhotonDaughters >= 1 && numberOfPizDaughters == 1 && numberOfPionDaughters == 0) {
497 if (mothid == 223) {
498 int chg = getRecursiveMotherCharge(mother);
499 if (chg < 0 && isOmegaPizGamFromTauMinusFirst) {
500 isOmegaPizGamFromTauMinusFirst = false;
501 isOmPizG = true;
502 }
503 if (chg > 0 && isOmegaPizGamFromTauPlusFirst) {
504 isOmegaPizGamFromTauPlusFirst = false;
505 isOmPizG = true;
506 }
507 }
508 }
509 }
510
511 B2DEBUG(1, "isRadiationfromFinalStateChargedParticle = " << isRadiationfromFinalStateChargedParticle);
512 B2DEBUG(1, "isRadiationFromChargedRho = " << isRadiationFromChargedRho);
513 B2DEBUG(1, "isRadiationFromChargedA1 = " << isRadiationFromChargedA1);
514 B2DEBUG(1, "isRadiationfromIntermediateWBoson = " << isRadiationfromIntermediateWBoson << " isPiPizGam = " << isPiPizGam);
515 B2DEBUG(1, "isRadiationfromTau = " << isRadiationfromTau << " isLFVTau2BodyDecay = " << isLFVTau2BodyDecay);
516 B2DEBUG(1, "isPi0GG = " << isPi0GG << " isEtaGG = " << isEtaGG << " isEtpGG = " << isEtpGG << " isPi0GEE = " << isPi0GEE);
517 B2DEBUG(1, "isEtaPPG = " << isEtaPPG << " isOmPizG = " << isOmPizG);
518
519 // accept photons if (isRadiationfromFinalStateChargedParticle is false) or
520 // if (isRadiationfromIntermediateWBoson is false) or
521 // if (isRadiationfromTau is true) {gamma is from 2 body LFV decays of tau} or
522 // if the radiation is coming from any other decay [except pi0 -> gamma gamma, eta-> gamma gamma, eta' -> gamma gamma]
523 if (isRadiationfromFinalStateChargedParticle) {
524 } else if (isRadiationFromChargedRho) {
525 accept_photon = true;
526 } else if (isRadiationFromChargedA1) {
527 accept_photon = true;
528 } else if (isRadiationfromIntermediateWBoson) {
529 if (isPiPizGam) {
530 accept_photon = true;
531 }
532 } else if (isRadiationfromTau) { // accept one photon from tau -> (charged particle) + gamma [no neutrinos]
533 if (isLFVTau2BodyDecay) {
534 accept_photon = true;
535 }
536 } else if (isPi0GG) {
537 } else if (isEtaGG) {
538 } else if (isEtpGG) {
539 } else if (isPi0GEE) {
540 } else if (isEtaPPG) {
541 accept_photon = true;
542 } else if (isOmPizG) {
543 accept_photon = true;
544 }
545 }
546
547 // Without further analysis, it is NOT possible to separate
548 // tau- -> pi- 2pi0 eta (-> pi- pi+ pi0) nu decays [Mode 39] from
549 // tau- -> 2pi- pi+ eta (-> pi0 pi0 pi0) nu decays [Mode 42]
550
551 if (pdgid == 111 && (isEtaPizPizPizFromTauMinusFirst || isEtaPizPizPizFromTauPlusFirst)) {
552 const MCParticle* mother = p.getMother();
553 // In some low multiplicity generators there may be no mother
554 if (mother and (mother->getPDG() == 221)) { // eta -> pi0 pi0 pi0
555 const vector<MCParticle*> daughters = mother->getDaughters();
556 int nPizSisters = 0;
557 for (MCParticle* d : daughters) {
558 if (!d->hasStatus(MCParticle::c_PrimaryParticle)) continue;
559 if (d->getPDG() == 111) nPizSisters++;
560 }
561 B2DEBUG(1, "nPizSisters = " << nPizSisters);
562 if (nPizSisters == 3) {
563 int chg = getRecursiveMotherCharge(mother);
564 if (chg < 0 && isEtaPizPizPizFromTauMinusFirst) {
565 isEtaPizPizPizFromTauMinusFirst = false;
567 }
568 if (chg > 0 && isEtaPizPizPizFromTauPlusFirst) {
569 isEtaPizPizPizFromTauPlusFirst = false;
571 }
572 }
573 }
574 }
575 B2DEBUG(1,
576 "isEtaPizPizPizFromTauMinusFirst = " << isEtaPizPizPizFromTauMinusFirst << " "
577 "m_isEtaPizPizPizFromTauMinus = " << m_isEtaPizPizPizFromTauMinus << " "
578 "isEtaPizPizPizFromTauPlusFirst = " << isEtaPizPizPizFromTauPlusFirst << " "
579 "m_isEtaPizPizPizFromTauPlus = " << m_isEtaPizPizPizFromTauPlus
580 );
581
582 // Without further analysis, it is NOT possible to separate
583 // tau- -> pi- 2pi0 omega (-> pi- pi+) nu decays [Mode 49] from
584 // tau- -> 2pi- pi+ 2pi0 nu decays [Mode 66]
585 // Note: TauolaBelle2 treats Mode 66 is coherent production,
586 // e.g. includes omega in the form factor but not as an explicit final state particle.
587 // Note2: omega is explicitly included in following mode:
588 // tau- -> pi- pi0 omega (-> pi- pi+ pi0) nu decays [Mode 130]
589 // which is where Mode 49 is mapped to if there is no omega->pi-pi+ decay
590
591 // Same confusion can also happen for
592 // tau- -> pi- pi0 omega (-> pi- pi+) nu decays [Mode 131]
593 // tau- -> pi- omega (-> pi- pi+ pi0) nu decays [Mode 236]
594
595 if (pdgid == -211 && (isOmegaPimPipFromTauMinusFirst || isOmegaPimPipFromTauPlusFirst)) {
596 const MCParticle* mother = p.getMother();
597 // In some low multiplicity generators there may be no mother
598 if (mother and (mother->getPDG() == 223)) { // omega -> pi- pi+
599 const vector<MCParticle*> daughters = mother->getDaughters();
600 int nOmegaDaughters = 0;
601 int nPimSisters = 0;
602 int nPipSisters = 0;
603 int nPizSisters = 0;
604 for (MCParticle* d : daughters) {
605 if (!d->hasStatus(MCParticle::c_PrimaryParticle)) continue;
606 nOmegaDaughters++;
607 if (d->getPDG() == -211) nPimSisters++;
608 if (d->getPDG() == 211) nPipSisters++;
609 if (d->getPDG() == 111) nPizSisters++;
610 }
611 B2DEBUG(1,
612 "nOmegaDaughters = " << nOmegaDaughters << " "
613 "nPimSisters = " << nPimSisters << " "
614 "nPipSisters = " << nPipSisters << " "
615 "nPizSisters = " << nPizSisters);
616 if (nOmegaDaughters >= 2 && nPimSisters == 1 && nPipSisters == 1 && nPizSisters == 0) { // allow omega->pi-pi+gama
617 int chg = getRecursiveMotherCharge(mother);
618 if (chg < 0 && isOmegaPimPipFromTauMinusFirst) {
619 isOmegaPimPipFromTauMinusFirst = false;
621 }
622 if (chg > 0 && isOmegaPimPipFromTauPlusFirst) {
623 isOmegaPimPipFromTauPlusFirst = false;
625 }
626 }
627 }
628 }
629 B2DEBUG(1,
630 "isOmegaPimPipFromTauMinusFirst = " << isOmegaPimPipFromTauMinusFirst << " "
631 "m_isOmegaPimPipFromTauMinus = " << m_isOmegaPimPipFromTauMinus << " "
632 "isOmegaPimPipFromTauPlusFirst = " << isOmegaPimPipFromTauPlusFirst << " "
633 "m_isOmegaPimPipFromTauPlus = " << m_isEtaPizPizPizFromTauPlus
634 );
635
636 // Fill up all the vector of particles
637 map<int, std::vector<int>>::iterator ite ;
638 for (ite = map_vec.begin(); ite != map_vec.end(); ++ite) {
639 if (pdgid == ite->first) {
640 if (pdgid == 22) {
641 if (accept_photon) {
642 B2DEBUG(1, "Photon accepted");
643 ite-> second.push_back(i);
644 }
645 } else {
646 ite-> second.push_back(i);
647 }
648 break;
649 }
650 }
651
652 } // End of loop over MCParticles
653
654 vec_dau_tauminus.clear();
655 vec_dau_tauplus.clear();
656
657 map<int, std::vector<int>>::iterator itr ;
658 for (itr = map_vec.begin(); itr != map_vec.end(); ++itr) {
659 for (unsigned int i = 0; i < itr-> second.size(); i++) {
660 int ii = itr-> second[i];
662 if (chg < 0) vec_dau_tauminus.push_back(ii);
663 if (chg > 0) vec_dau_tauplus.push_back(ii);
664 }
665 }
666
668 std::string pdgname;
669
670 //make decay string for tau-
672 for (unsigned iorder = 0; iorder < 46; ++iorder) {
673 int ii = OrderedList[iorder];
674 //
675 for (unsigned int i = 0; i < vec_dau_tauminus.size(); i++) {
677 int pdg = p->getPDG();
678 if (pdg == -130) pdg = 130; // Strange Feature in TauolaBelle2
679 if (pdg != ii) continue;
680 m_tauminusdecaymode.append(".");
681 if (pdg == 94144) {
682 pdgname = "alpha";
683 } else {
684 pdgname = databasePDG->GetParticle(pdg)->GetName();
685 }
686 m_tauminusdecaymode.append(pdgname);
687 }
688 }
689 //
691
692 //make decay string for tau+
694 for (unsigned iorder = 0; iorder < 46; ++iorder) {
695 int ii = OrderedList[iorder];
696 //
697 for (unsigned int i = 0; i < vec_dau_tauplus.size(); i++) {
699 int pdg = p->getPDG();
700 if (pdg == -130) pdg = 130; // Strange Feature in TauolaBelle2
701 if (pdg != ii) continue;
702 m_tauplusdecaymode.append(".");
703 if (pdg == 94144) {
704 pdgname = "alpha";
705 } else {
706 pdgname = databasePDG->GetParticle(pdg)->GetName();
707 }
708 m_tauplusdecaymode.append(pdgname);
709 }
710 }
711 //
713
714}
715
716//
717int TauDecayModeModule::TauolaBelle2DecayMode(const std::string& state, int chg)
718{
719 std::map<std::string, int> mode_decay = (chg < 0) ? mode_decay_minus : mode_decay_plus;
720 map<std::string, int>::iterator itr ;
721 for (itr = mode_decay.begin(); itr != mode_decay.end(); ++itr) {
722 if (state == itr-> first) {
723 int mode = itr-> second;
724 if (mode == 39) {
725 if (chg < 0 && m_isEtaPizPizPizFromTauMinus) mode = 42;
726 if (chg > 0 && m_isEtaPizPizPizFromTauPlus) mode = 42;
727 }
728 if (mode == 49) {
729 if (chg < 0 && !m_isOmegaPimPipFromTauMinus) mode = 130;
730 if (chg > 0 && !m_isOmegaPimPipFromTauPlus) mode = 130;
731 }
732 if (mode == 131) {
733 if (chg < 0 && !m_isOmegaPimPipFromTauMinus) mode = 236;
734 if (chg > 0 && !m_isOmegaPimPipFromTauPlus) mode = 236;
735 }
736 if (mode == 247) {
737 if (chg < 0 && !m_isEtaPizPizPizFromTauMinus) mode = 15;
738 if (chg > 0 && !m_isEtaPizPizPizFromTauPlus) mode = 15;
739 }
740 return mode;
741 }
742 }
743 return -1;
744}
745
746//
748{
749 const MCParticle* mother = p->getMother();
750 if (mother == nullptr) {
751 return 0;
752 } else if (abs(p->getPDG()) == 11 && mother->getPDG() == 111) { // pi0 -> e-e+ gamma
753 return 0;
754 } else if (abs(p->getPDG()) == 11 && mother->getPDG() == 221) { // eta -> e-e+ gamma
755 return 0;
756 } else if (abs(p->getPDG()) == 11 && mother->getPDG() == 113) { // rho0 -> e-e+
757 return 0;
758 } else if (abs(p->getPDG()) == 11 && mother->getPDG() == 223) { // omega -> e- e+
759 return 0;
760 } else if (abs(p->getPDG()) == 11 && mother->getPDG() == 333) { // phi -> e- e+
761 return 0;
762 } else if (abs(p->getPDG()) == 13 && mother->getPDG() == 221) { // eta -> mu-mu+ gamma
763 return 0;
764 } else if (abs(p->getPDG()) == 13 && mother->getPDG() == 113) { // rho0 -> mu-mu+
765 return 0;
766 } else if (abs(p->getPDG()) == 13 && mother->getPDG() == 333) { // phi -> mu-mu+
767 return 0;
768 } else if (mother->getPDG() == 15) {
769 return -1;
770 } else if (mother->getPDG() == -15) {
771 return 1;
772 } else {
773 return getRecursiveMotherCharge(mother);
774 }
775}
776
777//
779{
780 numOfTauPlus = 0;
781 numOfTauMinus = 0;
782 idOfTauPlus = 0;
783 idOfTauMinus = 0;
784 for (int i = 0; i < MCParticles.getEntries(); i++) {
785 MCParticle& p = *MCParticles[i];
786
787 if (p.getStatus() == 1 && p.getPDG() == 15) {
789 idOfTauMinus = p.getIndex();
790 }
791 if (p.getStatus() == 1 && p.getPDG() == -15) {
792 numOfTauPlus++;
793 idOfTauPlus = p.getIndex();
794 }
795 }
796 if (numOfTauPlus == 1 && numOfTauMinus == 1) {
797 tauPair = true;
798 } else tauPair = false;
799}
800
801//
803{
804 int ret = 0;
805 const vector<MCParticle*> daughters = p.getDaughters();
806 if (daughters.empty()) return ret;
807 for (MCParticle* d : daughters) {
808 if (!d->hasStatus(MCParticle::c_PrimaryParticle)) continue;
809 // TODO: Improve how to identify a final state particle.
810 bool isChargedFinalState = find(begin(finalStatePDGs),
811 end(finalStatePDGs),
812 abs(d->getPDG())) != end(finalStatePDGs);
813 if (isChargedFinalState) ret++;
814 else ret += getProngOfDecay(*d);
815 }
816 return ret;
817}
int getPDGCode() const
PDG code.
Definition: Const.h:473
static const ChargedStable muon
muon particle
Definition: Const.h:660
static const ParticleType Klong
K^0_L particle.
Definition: Const.h:678
static const ParticleType photon
photon particle
Definition: Const.h:673
static const ChargedStable electron
electron particle
Definition: Const.h:659
Replacement for TDatabasePDG that is filled from EvtGen's evt.pdl.
static EvtGenDatabasePDG * Instance()
Instance method that loads the EvtGen table.
A Class to store the Monte Carlo particle information.
Definition: MCParticle.h:32
@ c_PrimaryParticle
bit 0: Particle is primary particle.
Definition: MCParticle.h:47
std::vector< Belle2::MCParticle * > getDaughters() const
Get vector of all daughter particles, empty vector if none.
Definition: MCParticle.cc:52
int getPDG() const
Return PDG code of particle.
Definition: MCParticle.h:112
Base class for Modules.
Definition: Module.h:72
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
std::vector< int > vec_numu
Variable name of the vector where particles identified in the event are stored.
std::vector< int > vec_em
Variable name of the vector where particles identified in the event are stored.
std::vector< int > vec_omega
Variable name of the vector where particles identified in the event are stored.
std::vector< int > vec_k0s
Variable name of the vector where particles identified in the event are stored.
Int_t m_mprong
Prong of the decay channel of tau-.
std::vector< int > vec_b1p
Variable name of the vector where particles identified in the event are stored.
std::vector< int > vec_f1
Variable name of the vector where particles identified in the event are stored.
int numOfTauPlus
Number of tau+ in the event.
Int_t m_pprong
Prong of the decay channel of tau+.
StoreObjPtr< EventMetaData > m_event_metadata
event number
void IdentifyTauPair()
Identifies if the event is a generated tau pair.
std::vector< int > vec_apro
Variable name of the vector where particles identified in the event are stored.
std::vector< int > vec_pi0
Variable name of the vector where particles identified in the event are stored.
std::vector< int > vec_alpha
Variable name of the vector where particles identified in the event are stored.
StoreArray< MCParticle > MCParticles
StoreArray of MCParticles.
std::vector< int > vec_anue
Variable name of the vector where particles identified in the event are stored.
std::vector< int > vec_nue
Variable name of the vector where particles identified in the event are stored.
virtual void initialize() override
Initializes the module.
std::vector< int > vec_a0p_980
Variable name of the vector where particles identified in the event are stored.
std::string m_file_plus
Alternative mapping for tau+.
std::vector< int > vec_a0m_1450
Variable name of the vector where particles identified in the event are stored.
virtual void event() override
Method is called for each event.
bool m_isEtaPizPizPizFromTauMinus
Flag for eta->pi0pi0pi0 decays from tau-.
std::vector< int > vec_lmb_br
Variable name of the vector where particles identified in the event are stored.
Int_t m_mmode
ID of the decay channel of tau-.
void AnalyzeTauPairEvent()
Analyze a generated tau pair event.
bool m_isOmegaPimPipFromTauMinus
Flag for omega->pi-pi+ decays from tau-.
int getRecursiveMotherCharge(const MCParticle *mc)
Identifies particles coming from tau decays.
std::vector< int > vec_phi
Variable name of the vector where particles identified in the event are stored.
static constexpr int Neutrinos[3]
PDG codes of neutrinos in final state particles in generation: {nu_e, nu_mu, mu_tau}.
int m_taum_no
number of tau- unclassified events
std::string m_tauminusdecaymode
Variable name for the decay mode of the tau-.
std::vector< int > vec_a1p
Variable name of the vector where particles identified in the event are stored.
bool m_isOmegaPimPipFromTauPlus
Flag for omega->pi-pi+ decays from tau+.
bool tauPair
Boolean variable used to identify tau event.
int TauolaBelle2DecayMode(const std::string &s, int chg)
Classifies the decays of the event and assigns a decay mode.
int idOfTauMinus
Index of the generated tau-.
std::vector< int > vec_lambda
Variable name of the vector where particles identified in the event are stored.
std::vector< int > vec_anut
Variable name of the vector where particles identified in the event are stored.
std::vector< int > vec_f0
Variable name of the vector where particles identified in the event are stored.
std::vector< int > vec_mum
Variable name of the vector where particles identified in the event are stored.
Int_t m_pmode
ID of the decay channel of tau+.
static constexpr int OrderedList[46]
PDG codes of ORDERED particles.
int numOfTauMinus
Number of tau- in the event.
std::vector< int > vec_nut
Variable name of the vector where particles identified in the event are stored.
std::vector< int > vec_kstar0_br
Variable name of the vector where particles identified in the event are stored.
std::vector< int > vec_a00_1450
Variable name of the vector where particles identified in the event are stored.
std::vector< int > vec_kstar0
Variable name of the vector where particles identified in the event are stored.
std::vector< int > vec_a0m_980
Variable name of the vector where particles identified in the event are stored.
std::vector< int > vec_a00_980
Variable name of the vector where particles identified in the event are stored.
int getProngOfDecay(const MCParticle &mc)
Identifies the number of charged final state particles in the decay.
std::vector< int > vec_a1m
Variable name of the vector where particles identified in the event are stored.
int idOfTauPlus
Index of the generated tau+.
StoreObjPtr< TauPairDecay > m_tauDecay
pointer to tau pair decay objects
std::vector< int > vec_rhop
Variable name of the vector where particles identified in the event are stored.
std::string m_printmode
Parameter passed by the user to indicated the informationt to be printed.
std::vector< int > vec_pro
Variable name of the vector where particles identified in the event are stored.
bool m_isEtaPizPizPizFromTauPlus
Flag for eta->pi0pi0pi0 decays from tau+.
std::string m_tauplusdecaymode
Variable name for the decay mode of the tau+.
std::vector< int > vec_pim
Variable name of the vector where particles identified in the event are stored.
std::vector< int > vec_mup
Variable name of the vector where particles identified in the event are stored.
std::vector< int > vec_pip
Variable name of the vector where particles identified in the event are stored.
std::vector< int > vec_kstarp
Variable name of the vector where particles identified in the event are stored.
std::vector< int > vec_kstarm
Variable name of the vector where particles identified in the event are stored.
std::vector< int > vec_etapr
Variable name of the vector where particles identified in the event are stored.
std::vector< int > vec_ep
Variable name of the vector where particles identified in the event are stored.
TauDecayModeModule()
Constructor: Sets the description, the properties and the parameters of the module.
std::vector< int > vec_k0l
Variable name of the vector where particles identified in the event are stored.
static constexpr int finalStatePDGs[5]
PDG codes accepted as charged final state particles in generation: {e, mu, pi, K, p}.
std::vector< int > vec_eta
Variable name of the vector where particles identified in the event are stored.
std::vector< int > vec_km
Variable name of the vector where particles identified in the event are stored.
std::vector< int > vec_anumu
Variable name of the vector where particles identified in the event are stored.
std::vector< int > vec_dau_tauplus
Variable name of the vector where particles identified in the event are stored.
std::vector< int > vec_rhom
Variable name of the vector where particles identified in the event are stored.
std::vector< int > vec_gam
Variable name of the vector where particles identified in the event are stored.
std::string m_file_minus
Alternative mapping for tau-.
int m_taup_no
number of tau+ unclassified events
std::vector< int > vec_dau_tauminus
Variable name of the vector where particles identified in the event are stored.
std::vector< int > vec_kp
Variable name of the vector where particles identified in the event are stored.
std::vector< int > vec_b1m
Variable name of the vector where particles identified in the event are stored.
std::vector< int > vec_rho0
Variable name of the vector where particles identified in the event are stored.
std::map< std::string, int > mode_decay_minus
Mapping for tau- decays.
std::map< std::string, int > mode_decay_plus
Mapping for tau+ decays.
std::vector< int > vec_a0p_1450
Variable name of the vector where particles identified in the event are stored.
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition: Module.h:560
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
Abstract base class for different kinds of events.
Definition: ClusterUtils.h:24
STL namespace.