Belle II Software development
EvtGenDecays.h
1// This file is a copy of Pythia8Plugins/EvtGen.h from Pythia 8,
2// but slightly modified in basf2 for extended EvtGen models
3
4// EvtGen.h is a part of the PYTHIA event generator.
5// Copyright (C) 2016 Torbjorn Sjostrand.
6// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
7// Please respect the MCnet Guidelines, see GUIDELINES for details.
8// Author: Philip Ilten.
9
10// This file contains an EvtGen interface. HepMC and EvtGen must be enabled.
11
12#pragma once
13
14#include <generators/utilities/GeneratorConst.h>
15#include "Pythia8/Pythia.h"
16#include "EvtGen/EvtGen.hh"
17#include "EvtGenBase/EvtRandomEngine.hh"
18#include "EvtGenBase/EvtParticle.hh"
19#include "EvtGenBase/EvtParticleFactory.hh"
20#include "EvtGenBase/EvtPDL.hh"
21#include "EvtGenBase/EvtDecayTable.hh"
22#include "EvtGenBase/EvtParticleDecayList.hh"
23#include "EvtGenBase/EvtDecayBase.hh"
24#include "EvtGenExternal/EvtExternalGenList.hh"
25
26//==========================================================================
27
29class EvtGenRandom : public EvtRandomEngine {
30
31public:
32
34 explicit EvtGenRandom(Pythia8::Rndm* rndmPtrIn) {rndmPtr = rndmPtrIn;}
35
37 double random() {if (rndmPtr) return rndmPtr->flat(); else return -1.0;}
38
40 Pythia8::Rndm* rndmPtr;
41
42};
43
44//==========================================================================
45
89
90public:
91
93 EvtGenDecays(Pythia8::Pythia* pythiaPtrIn, EvtGen* evtGen, bool limit = true);
94
96 EvtGenDecays(Pythia8::Pythia* pythiaPtrIn, std::string decayFile, std::string particleDataFile,
97 EvtExternalGenList* extPtrIn = 0, EvtAbsRadCorr* fsrPtrIn = 0,
98 int mixing = 1, bool xml = false, bool limit = true,
99 bool extUse = true, bool fsrUse = true);
100
103 {
104 if (evtgen) delete evtgen;
105 if (extOwner && extPtr) delete extPtr;
106 if (fsrOwner && fsrPtr) delete fsrPtr;
107 }
108
110 EvtGenDecays(const EvtGenDecays&) = delete;
111
114
116 void getDecayLimits(bool limit);
117
119 double decay();
120
122 void exclude(int id) {excIds.insert(id);}
123
125 void updatePythia();
126
128 void updateEvtGen();
129
131 void readDecayFile(std::string decayFile, bool xml = false)
132 {
133 evtgen->readUDecay(decayFile.c_str(), xml); updateData();
134 }
135
136 bool extOwner;
137 bool fsrOwner;
138 EvtExternalGenList* extPtr;
139 EvtAbsRadCorr* fsrPtr;
140 std::list<EvtDecayBase*> models;
141
143 struct Signal {
144 int status;
145 EvtId egId;
146 std::vector<double> bfs;
147 std::vector<int> map;
148 EvtParticleDecayList modes;
149 };
150
151 std::map<int, Signal> signals;
152
154 std::string signalSuffix;
155
156protected:
157
159 void updateData(bool final = false);
160
162 void updateEvent(Pythia8::Particle* pyPro, EvtParticle* egPro,
163 std::vector<int>* pySigs = 0, std::vector<EvtParticle*>* egSigs = 0,
164 std::vector<double>* bfs = 0, double* wgt = 0);
165
167 bool checkVertex(Pythia8::Particle* pyPro);
168
170 bool checkSignal(Pythia8::Particle* pyPro);
171
173 bool checkOsc(EvtParticle* egPro);
174
176 static constexpr int NTRYDECAY = 1000;
177
179 Pythia8::Pythia* pythiaPtr;
180
183
185 EvtGen* evtgen;
186
187 std::set<int> incIds;
188 std::set<int> excIds;
189
192
194 std::map<int, Signal>::iterator signal;
195
200 double tau0Max;
201 double tauMax;
202 double rMax;
203 double xyMax;
204 double zMax;
206 bool limitTau;
210};
211
212//--------------------------------------------------------------------------
213
214// The constructor.
215
216// The EvtGenDecays object is associated with a single Pythia
217// instance. This is to ensure a consistent random number generator
218// across the two, as well as any updates to particle data, etc. Note
219// that if multiple EvtGenDecays objects exist, that they will modify
220// one another particle databases due to the design of EvtGen.
221
222// This constructor also sets all particles to be decayed by EvtGen as
223// stable within Pythia. The parameters within Pythia used to check if
224// a particle should be decayed, as described in the "Particle Decays"
225// section of the Pythia manual, are set. Note that if the variable
226// "limit" is set to "false", then no check will be made before
227// decaying a particle with EvtGen.
228
229// The constructor is designed to have the exact same form as the
230// EvtGen constructor except for these five differences.
231// (1) The first variable is the pointer to the Pythia object.
232// (2) The third last argument is a flag to limit decays based on the
233// Pythia criteria (based on the particle decay vertex).
234// (3) The second last argument is a flag if external models should be
235// passed to EvtGen (default is true).
236// (4) The last argument is a flag if an FSR model should be passed
237// to EvtGen (default is true).
238// (5) No random engine pointer is passed, as this is obtained from
239// Pythia.
240
241// pythiaPtrIn: the pointer to the associated Pythia object.
242// decayFile: the name of the decay file to pass to EvtGen.
243// particleDataFile: the name of the particle data file to pass to EvtGen.
244// extPtrIn: the optional EvtExternalGenList pointer, this must be
245// be provided if fsrPtrIn is provided to avoid double
246// initializations.
247// fsrPtrIn: the EvtAbsRadCorr pointer to pass to EvtGen.
248// mixing: the mixing type to pass to EvtGen.
249// xml: flag to use XML files to pass to EvtGen.
250// limit: flag to limit particle decays based on Pythia criteria.
251// extUse: flag to use external models with EvtGen.
252// fsrUse: flag to use radiative correction engine with EvtGen.
253
254
255EvtGenDecays::EvtGenDecays(Pythia8::Pythia* pythiaPtrIn, EvtGen* evtGen, bool limit):
256 extOwner(false), fsrOwner(false), extPtr(nullptr), fsrPtr(nullptr),
257 signalSuffix("_SIGNAL"), pythiaPtr(pythiaPtrIn), rndm(nullptr),
258 evtgen(evtGen), updated(false)
259{
260 getDecayLimits(limit);
261}
262
263EvtGenDecays::EvtGenDecays(Pythia8::Pythia* pythiaPtrIn, std::string decayFile,
264 std::string particleDataFile, EvtExternalGenList* extPtrIn,
265 EvtAbsRadCorr* fsrPtrIn, int mixing, bool xml, bool limit,
266 bool extUse, bool fsrUse) : extPtr(extPtrIn), fsrPtr(fsrPtrIn),
267 signalSuffix("_SIGNAL"), pythiaPtr(pythiaPtrIn), rndm(&pythiaPtr->rndm),
268 updated(false)
269{
270
271 // Initialize EvtGen.
272 if (!extPtr && fsrPtr) {
273 B2ERROR("Error in EvtGenDecays::EvtGenDecays: extPtr is null but fsrPtr is provided");
274 return;
275 }
276 if (extPtr) extOwner = false;
277 else {extOwner = true; extPtr = new EvtExternalGenList();}
278 if (fsrPtr) fsrOwner = false;
279 else {fsrOwner = true; fsrPtr = extPtr->getPhotosModel();}
280 models = extPtr->getListOfModels();
281 evtgen = new EvtGen(decayFile.c_str(), particleDataFile.c_str(),
282 &rndm, fsrUse ? fsrPtr : 0, extUse ? &models : 0, mixing, xml);
283 getDecayLimits(limit);
284}
285
287{
288 // Get the Pythia decay limits.
289 if (!pythiaPtr) return;
290 limitTau0 = pythiaPtr->settings.flag("ParticleDecays:limitTau0");
291 tau0Max = pythiaPtr->settings.parm("ParticleDecays:tau0Max");
292 limitTau = pythiaPtr->settings.flag("ParticleDecays:limitTau");
293 tauMax = pythiaPtr->settings.parm("ParticleDecays:tauMax");
294 limitRadius = pythiaPtr->settings.flag("ParticleDecays:limitRadius");
295 rMax = pythiaPtr->settings.parm("ParticleDecays:rMax");
296 limitCylinder = pythiaPtr->settings.flag("ParticleDecays:limitCylinder");
297 xyMax = pythiaPtr->settings.parm("ParticleDecays:xyMax");
298 zMax = pythiaPtr->settings.parm("ParticleDecays:zMax");
299 limitDecay = limit && (limitTau0 || limitTau ||
301
302}
303
304//--------------------------------------------------------------------------
305
306// Perform all decays and return the event weight.
307
308// All particles in the event record that can be decayed by EvtGen are
309// decayed. If a particle is a signal particle, then this is stored in
310// a vector of signal particles. A signal particle is only stored if
311// its status is the same as the status provided in the signals map. A
312// negative status in the signal map indicates that all statuses
313// should be accepted. After all signal particles are identified, one
314// is randomly chosen and decayed as signal. The remainder are decayed
315// normally.
316
317// Forcing a signal decay changes the weight of an event from unity,
318// and so the relative event weight is returned, given the forced
319// signal decay. A weight of 0 indicates no signal in the event, while
320// a weight of -1 indicates something is wrong, e.g. either the Pythia
321// or EvtGen pointers are not available or the number of tries has
322// been exceeded. For the event weight to be valid, one should not
323// change the absolute branching fractions in the signal and inclusive
324// definitions, but rather just remove the unwanted decay channels
325// from the signal decay definition.
326
328{
329
330 // Reset the signal and signal counters.
331 if (!pythiaPtr || !evtgen) return -1;
332 if (!updated) updateData(true);
333
334 // Loop over all particles in the Pythia event.
335 Pythia8::Event& event = pythiaPtr->event;
336 std::vector<int> pySigs; std::vector<EvtParticle*> egSigs, egPrts;
337 std::vector<double> bfs; double wgt(1.);
338 for (int iPro = 0; iPro < event.size(); ++iPro) {
339
340 // Check particle is final and can be decayed by EvtGen.
341 Pythia8::Particle* pyPro = &event[iPro];
342 if (!pyPro->isFinal()) continue;
343 if (incIds.find(pyPro->id()) == incIds.end()) continue;
344 if (pyPro->status() == 93 || pyPro->status() == 94) continue;
345
346 // Decay the progenitor with EvtGen.
347 EvtParticle* egPro = EvtParticleFactory::particleFactory
348 (EvtPDL::evtIdFromStdHep(pyPro->id()),
349 EvtVector4R(pyPro->e(), pyPro->px(), pyPro->py(), pyPro->pz()));
350 egPrts.push_back(egPro);
351 egPro->setDiagonalSpinDensity();
352 evtgen->generateDecay(egPro);
353 pyPro->tau(egPro->getLifetime());
354 if (!checkVertex(pyPro)) continue;
355
356 // Add oscillations to event record.
357 if (checkOsc(egPro))
358 updateEvent(pyPro, egPro, &pySigs, &egSigs, &bfs, &wgt);
359
360 // Undo decay if signal (duplicate to stop oscillations).
361 else if (checkSignal(pyPro)) {
362 pySigs.push_back(pyPro->index());
363 egSigs.push_back(egPro);
364 bfs.push_back(signal->second.bfs[0]);
365 wgt *= 1 - bfs.back();
366 egPro->deleteDaughters();
367 // The following problematic part of the Pythia's code was removed, see
368 // https://gitlab.com/Pythia8/releases/
369 // -/blob/pythia8310/include/Pythia8Plugins/EvtGen.h?ref_type=tags#L321-325
370
371 // If not signal, add to event record.
372 } else updateEvent(pyPro, egPro, &pySigs, &egSigs, &bfs, &wgt);
373 }
374 if (pySigs.size() == 0) {
375 for (int iPrt = 0; iPrt < (int)egPrts.size(); ++iPrt)
376 egPrts[iPrt]->deleteTree();
377 return 0;
378 }
379
380 // Determine the decays of the signal particles (signal or background).
381 std::vector<int> modes; int force(-1);
382 for (int iTry = 1; iTry <= NTRYDECAY; ++iTry) {
383 int n(0);
384
385 modes.clear(); force = pythiaPtr->rndm.pick(bfs); n = 0;
386 for (int iSig = 0; iSig < (int)pySigs.size(); ++iSig) {
387 if (iSig == force) modes.push_back(0);
388 else modes.push_back(pythiaPtr->rndm.flat() > bfs[iSig]);
389 if (modes.back() == 0) ++n;
390 }
391 if (pythiaPtr->rndm.flat() <= 1.0 / n) break;
392 if (iTry == NTRYDECAY) {
393 wgt = 2.;
394 B2WARNING("Warning in EvtGenDecays::decay: maximum number of signal decay attempts exceeded"
395 << LogVar("maxTries", NTRYDECAY));
396 }
397 }
398
399 // Decay the signal particles and mark forced decay.
400 for (int iSig = 0; iSig < (int)pySigs.size(); ++iSig) {
401 EvtParticle* egSig = egSigs[iSig];
402 Pythia8::Particle* pySig = &event[pySigs[iSig]];
403 signal = signals.find(pySig->id());
404 if (egSig->getNDaug() > 0) egSig = egSig->getDaug(0);
405 if (modes[iSig] == 0) egSig->setId(signal->second.egId);
406 else {
407 signal->second.modes.getDecayModel(egSig);
408 egSig->setChannel(signal->second.map[egSig->getChannel()]);
409 }
410 if (iSig == force)
411 pySig->status(pySig->status() == 92 || pySig->status() == 94 ? 96 : 95);
412 evtgen->generateDecay(egSig);
413 updateEvent(pySig, egSigs[iSig]);
414 }
415
416 // Delete all EvtGen particles and return weight.
417 for (int iPrt = 0; iPrt < (int)egPrts.size(); ++iPrt)
418 egPrts[iPrt]->deleteTree();
419 return 1. - wgt;
420
421}
422
423//--------------------------------------------------------------------------
424
425// Update the Pythia particle database from EvtGen.
426
427// Note that only the particle spin type, charge type, nominal mass,
428// width, minimum mass, maximum mass, and nominal lifetime are
429// set. The name string is not set.
430
432{
433 if (!pythiaPtr || !evtgen) return;
434 for (int entry = 0; entry < (int)EvtPDL::entries(); ++entry) {
435 EvtId egId = EvtPDL::getEntry(entry);
436 int pyId = EvtPDL::getStdHep(egId);
437 pythiaPtr->particleData.spinType(pyId, EvtPDL::getSpinType(egId));
438 pythiaPtr->particleData.chargeType(pyId, EvtPDL::chg3(egId));
439 pythiaPtr->particleData.m0(pyId, EvtPDL::getMass(egId));
440 pythiaPtr->particleData.mWidth(pyId, EvtPDL::getWidth(egId));
441 pythiaPtr->particleData.mMin(pyId, EvtPDL::getMinMass(egId));
442 pythiaPtr->particleData.mMax(pyId, EvtPDL::getMaxMass(egId));
443 pythiaPtr->particleData.tau0(pyId, EvtPDL::getctau(egId));
444 }
445}
446
447//--------------------------------------------------------------------------
448
449// Update the EvtGen particle database from Pythia.
450
451// The particle update database between Pythia and EvtGen is not
452// symmetric. Particularly, it is not possible to update the spin
453// type, charge, or nominal lifetime in the EvtGen particle database.
454
456{
457 if (!pythiaPtr || !evtgen) return;
458 int pyId = pythiaPtr->particleData.nextId(0);
459 while (pyId != 0) {
460 EvtId egId = EvtPDL::evtIdFromStdHep(pyId);
461 EvtPDL::reSetMass(egId, pythiaPtr->particleData.m0(pyId));
462 EvtPDL::reSetWidth(egId, pythiaPtr->particleData.mWidth(pyId));
463 EvtPDL::reSetMassMin(egId, pythiaPtr->particleData.mMin(pyId));
464 EvtPDL::reSetMassMax(egId, pythiaPtr->particleData.mMax(pyId));
465 pyId = pythiaPtr->particleData.nextId(pyId);
466 }
467}
468
469//--------------------------------------------------------------------------
470
471// Update the particles to decay with EvtGen, and the selected signals.
472
473// If final is false, then only signals are initialized in the signal
474// map. Any particle or alias that ends with signalSuffix is taken as
475// a signal particle. If final is true all particle entries in EvtGen
476// are checked to see if they should be set stable in Pythia. If an
477// EvtGen particle has no decay modes, then Pythia is still allowed to
478// decay the particle. Additionally, the signal decay channels are
479// turned off for the non-aliased signal particle.
480
482{
483
484 // Loop over the EvtGen entries.
485 if (!pythiaPtr) return;
486 EvtDecayTable* egTable = EvtDecayTable::getInstance();
487 if (!egTable) return;
488 for (int iEntry = 0; iEntry < (int)EvtPDL::entries(); ++iEntry) {
489 EvtId egId = EvtPDL::getEntry(iEntry);
490 int pyId = EvtPDL::getStdHep(egId);
491 if (egTable->getNModes(egId) == 0) continue;
492 if (excIds.find(pyId) != excIds.end()) continue;
493
494 // Stop Pythia from decaying the particle and include in decay set.
495 if (final) {
496 incIds.insert(pyId);
497 pythiaPtr->particleData.mayDecay(pyId, false);
498 }
499
500 // Check for signal.
501 std::string egName = EvtPDL::name(egId);
502 if (egName.size() <= signalSuffix.size() || egName.substr
503 (egName.size() - signalSuffix.size()) != signalSuffix) continue;
504 signal = signals.find(pyId);
505 if (signal == signals.end()) {
506 signals[pyId].status = -1;
507 signal = signals.find(pyId);
508 }
509 signal->second.egId = egId;
510 signal->second.bfs = std::vector<double>(2, 0);
511 if (!final) continue;
512
513 // Get the signal and background decay modes.
514 std::vector<EvtParticleDecayList> egList = egTable->getDecayTable();
515 int sigIdx = egId.getAlias();
516 int bkgIdx = EvtPDL::evtIdFromStdHep(pyId).getAlias();
517 if (sigIdx > (int)egList.size() || bkgIdx > (int)egList.size()) continue;
518 EvtParticleDecayList sigModes = egList[sigIdx];
519 EvtParticleDecayList bkgModes = egList[bkgIdx];
520 EvtParticleDecayList allModes = egList[bkgIdx];
521 double sum(0);
522
523 // Sum signal branching fractions.
524 for (int iMode = 0; iMode < sigModes.getNMode(); ++iMode) {
525 EvtDecayBase* mode = sigModes.getDecayModel(iMode);
526 if (!mode) continue;
527 signal->second.bfs[0] += mode->getBranchingFraction();
528 sum += mode->getBranchingFraction();
529 }
530
531 // Sum remaining background branching fractions.
532 for (int iMode = 0; iMode < allModes.getNMode(); ++iMode) {
533 EvtDecayBase* mode = allModes.getDecayModel(iMode);
534 if (!mode) continue;
535 bool match(false);
536 for (int jMode = 0; jMode < sigModes.getNMode(); ++jMode)
537 if (mode->matchingDecay(*(sigModes.getDecayModel(jMode)))) {
538 match = true; break;
539 }
540 if (match) bkgModes.removeMode(mode);
541 else {
542 signal->second.map.push_back(iMode);
543 signal->second.bfs[1] += mode->getBranchingFraction();
544 sum += mode->getBranchingFraction();
545 }
546 }
547 signal->second.modes = bkgModes;
548 for (int iBf = 0; iBf < (int)signal->second.bfs.size(); ++iBf)
549 signal->second.bfs[iBf] /= sum;
550 }
551 if (final) updated = true;
552
553}
554
555//--------------------------------------------------------------------------
556
557// Update the Pythia event record with an EvtGen decay tree.
558
559// The production vertex of each particle (which can also be obtained
560// in EvtGen via EvtParticle::get4Pos()) is set by the decay vertex of
561// its mother, which in turn is calculated from the mother's
562// lifetime. The status code 93 is used to indicate an external decay,
563// while the status code 94 is used to indicate an oscillated external
564// decay. If the progenitor has a single daughter with the same ID,
565// this daughter is used as the progenitor. This is used to prevent
566// double oscillations.
567
568// If the arguments after egPro are no NULL and a particle in the
569// decay tree is a signal particle, the decay for this particle is
570// removed and the particle is stored as a signal candidate in the
571// pySigs and egSigs vectors, to be decayed later. However, if any of
572// these arguments is NULL then the entire tree is written.
573
574void EvtGenDecays::updateEvent(Pythia8::Particle* pyPro, EvtParticle* egPro,
575 std::vector<int>* pySigs, std::vector<EvtParticle*>* egSigs,
576 std::vector<double>* bfs, double* wgt)
577{
578
579 // Set up the mother vector.
580 if (!pythiaPtr) return;
581 EvtParticle* egMom = egPro;
582 if (egPro->getNDaug() == 1 && egPro->getPDGId() ==
583 egPro->getDaug(0)->getPDGId()) egMom = egPro->getDaug(0);
584 Pythia8::Event& event = pythiaPtr->event;
585 std::vector< std::pair<EvtParticle*, int> >
586 moms(1, std::pair<EvtParticle*, int>(egMom, pyPro->index()));
587
588 // Loop over the mothers.
589 while (moms.size() != 0) {
590
591 // Check if particle can decay.
592 egMom = moms.back().first;
593 int iMom = moms.back().second;
594 Pythia8::Particle* pyMom = &event[iMom];
595 moms.pop_back();
596 if (!checkVertex(pyMom)) continue;
597 bool osc(checkOsc(egMom));
598
599 // Set the children of the mother.
600 pyMom->daughters(event.size(), event.size() + egMom->getNDaug() - 1);
601 pyMom->statusNeg();
602 Pythia8::Vec4 vProd = pyMom->vDec();
603 for (int iDtr = 0 ; iDtr < (int)egMom->getNDaug(); ++iDtr) {
604 EvtParticle* egDtr = egMom->getDaug(iDtr);
605 int id = egDtr->getPDGId();
606 EvtVector4R p = egDtr->getP4Lab();
607 int idx = event.append(id, 93, iMom, 0, 0, 0, 0, 0, p.get(1),
608 p.get(2), p.get(3), p.get(0), egDtr->mass());
609 Pythia8::Particle* pyDtr = &event.back();
610 pyDtr->vProd(vProd);
611 pyDtr->tau(egDtr->getLifetime());
612 if (pySigs && egSigs && bfs && wgt && checkSignal(pyDtr)) {
613 pySigs->push_back(pyDtr->index());
614 egSigs->push_back(egDtr);
615 bfs->push_back(signal->second.bfs[0]);
616 (*wgt) *= 1 - bfs->back();
617 egDtr->deleteDaughters();
618 }
619 if (osc) pyDtr->status(94);
620 if (egDtr->getAttribute("FSR"))
621 pyDtr->status(Belle2::GeneratorConst::FSR_STATUS_CODE);
622 if (egDtr->getNDaug() > 0)
623 moms.push_back(std::pair<EvtParticle*, int>(egDtr, idx));
624 }
625 }
626
627}
628
629//--------------------------------------------------------------------------
630
631// Check if a particle can decay.
632
633// Modified slightly from ParticleDecays::checkVertex.
634
635bool EvtGenDecays::checkVertex(Pythia8::Particle* pyPro)
636{
637 using ::Pythia8::pow2;
638
639 if (!limitDecay) return true;
640 if (limitTau0 && pyPro->tau0() > tau0Max) return false;
641 if (limitTau && pyPro->tau() > tauMax) return false;
642 if (limitRadius && pow2(pyPro->xDec()) + pow2(pyPro->yDec())
643 + pow2(pyPro->zDec()) > pow2(rMax)) return false;
644 if (limitCylinder && (pow2(pyPro->xDec()) + pow2(pyPro->yDec())
645 > pow2(xyMax) || abs(pyPro->zDec()) > zMax)) return false;
646 return true;
647}
648
649//--------------------------------------------------------------------------
650
651// Check if a particle is signal.
652
653bool EvtGenDecays::checkSignal(Pythia8::Particle* pyPro)
654{
655 signal = signals.find(pyPro->id());
656 if (signal != signals.end() && (signal->second.status < 0 ||
657 signal->second.status == pyPro->status())) return true;
658 else return false;
659}
660
661//--------------------------------------------------------------------------
662
663// Check if an EvtGen particle has oscillated.
664
665// The criteria defined here for oscillation is a single daughter but
666// with a different ID from the mother.
667
668bool EvtGenDecays::checkOsc(EvtParticle* egPro)
669{
670 if (egPro && egPro->getNDaug() == 1 &&
671 egPro->getPDGId() != egPro->getDaug(0)->getPDGId()) return true;
672 else return false;
673}
674
675//==========================================================================
EvtGen * evtgen
The EvtGen object.
void updateData(bool final=false)
Update the particles to decay with EvtGen, and the selected signals.
EvtAbsRadCorr * fsrPtr
FSR model pointer.
void exclude(int id)
Stop EvtGen decaying a particle.
double tauMax
the pythia parameter ParticleDecays:tauMax
bool limitCylinder
the pythia parameter ParticleDecays:limitCylinder
~EvtGenDecays()
Destructor.
EvtGenDecays(Pythia8::Pythia *pythiaPtrIn, EvtGen *evtGen, bool limit=true)
Expert constructor which takes an already initialized EvtGen instance.
bool fsrOwner
bool has FSR model
std::map< int, Signal > signals
signal particles and statuses
std::set< int > incIds
Set of particle IDs to include decays with EvtGen.
std::list< EvtDecayBase * > models
list of model pointers
bool checkSignal(Pythia8::Particle *pyPro)
Check if a particle is signal.
bool updated
Flag whether the final particle update has been performed.
EvtGenDecays(const EvtGenDecays &)=delete
forbid copy
EvtExternalGenList * extPtr
External model pointer.
bool checkVertex(Pythia8::Particle *pyPro)
Check if a particle can decay.
double zMax
the pythia parameter ParticleDecays:zMax
void updatePythia()
Update the Pythia particle database from EvtGen.
bool checkOsc(EvtParticle *egPro)
Check if an EvtGen particle has oscillated.
double xyMax
the pythia parameter ParticleDecays:xyMax
std::set< int > excIds
Set of particle IDs to exclude decays with EvtGen.
bool limitTau
the pythia parameter ParticleDecays:limitTau
double rMax
the pythia parameter ParticleDecays:rMax
static constexpr int NTRYDECAY
Number of times to try a decay sampling (constant).
void updateEvtGen()
Update the EvtGen particle database from Pythia.
bool limitRadius
the pythia parameter ParticleDecays:limitRadius
bool limitDecay
is the decay limited
void readDecayFile(std::string decayFile, bool xml=false)
Read an EvtGen user decay file.
bool extOwner
bool has external model
void getDecayLimits(bool limit)
Get the Decay limits from Pythia.
std::string signalSuffix
The suffix indicating an EvtGen particle or alias is signal.
EvtGenDecays & operator=(const EvtGenDecays &)=delete
forbid assignment
void updateEvent(Pythia8::Particle *pyPro, EvtParticle *egPro, std::vector< int > *pySigs=0, std::vector< EvtParticle * > *egSigs=0, std::vector< double > *bfs=0, double *wgt=0)
Update the Pythia event record with an EvtGen decay tree.
EvtGenRandom rndm
Random number wrapper for EvtGen.
double decay()
Perform all decays and return the event weight.
bool limitTau0
the pythia parameter ParticleDecays:limitTau0
Pythia8::Pythia * pythiaPtr
The pointer to the associated Pythia object.
double tau0Max
Parameters used to check if a particle should decay (as set via Pythia).
std::map< int, Signal >::iterator signal
The selected signal iterator.
A class to wrap the Pythia random number generator for use by EvtGen.
double random()
Return a random number.
EvtGenRandom(Pythia8::Rndm *rndmPtrIn)
Constructor.
Pythia8::Rndm * rndmPtr
The random number pointer.
Class to store variables with their name which were sent to the logging service.
Map of signal particle info.
std::vector< int > map
the map for statuses
EvtId egId
the Lund ID
int status
status needed to consider a particle a signal
EvtParticleDecayList modes
list of decay modes &
std::vector< double > bfs
branching fractions