25#include "HepPDT/ParticleDataTable.hh"
27#include "CLHEP/Random/RandomEngine.h"
33 double r = engine->flat();
34 return ((-ct)*std::log(1.-
r));
40 double r = engine->flat();
96 double e = genpart->momentum().e();
97 double theta = genpart->momentum().theta();
98 double phi = genpart->momentum().phi();
100 double p2 = e*e - newMass*newMass;
102 ATH_MSG_FATAL(
"ParticleDecayer::fillEvt: -- you have generated a tachyon!");
103 return StatusCode::FAILURE;
106 double p = std::sqrt(p2);
107 double px = p*std::sin(
theta)*std::cos(
phi);
108 double py = p*std::sin(
theta)*std::sin(
phi);
109 double pz = p*std::cos(
theta);
111 const CLHEP::HepLorentzVector updatedLV(px,py,pz,e);
112 genpart->set_momentum(
HepMC::FourVector(updatedLV.x(),updatedLV.y(),updatedLV.z(),updatedLV.e()));
113 genpart->set_generated_mass(newMass);
114 return StatusCode::SUCCESS;
122 ATH_MSG_FATAL(
"ParticleDecayer::fillEvt: -- no production vertex position found!");
123 return StatusCode::FAILURE;
128 end_vtx->set_position(vtxp->position());
129 end_vtx->add_particle_in(std::move(genpart));
130 event->add_vertex(std::move(end_vtx));
131 return StatusCode::SUCCESS;
135 double gamma = genpart->momentum().e()/genpart->momentum().m();
137 double theta = genpart->momentum().theta();
153 double distanceToEdge = -999.;
165 return StatusCode::FAILURE;
167 double Limit = distanceToEdge / gamma;
172 while ( ctau > Limit )
185 double decayRadius = -999.;
189 double outerRadius = outerLength*std::sin(
theta);
196 double decayLength = decayRadius/std::sin(
theta);
197 ctau = decayLength/gamma;
200 ATH_MSG_FATAL(
"have to pick uniform or exponential decay distance");
201 return StatusCode::FAILURE;
204 double ctg = gamma * ctau;
205 double px = genpart->momentum().px();
206 double py = genpart->momentum().py();
207 double pz = genpart->momentum().pz();
208 double p = std::sqrt(px*px + py*py + pz*pz);
210 const CLHEP::HepLorentzVector posLV(((ctg*px/p)+(vtxp->position().x())), ((ctg*py/p)+(vtxp->position().y())), ((ctg*pz/p)+(vtxp->position().z())), ((ctg)+(vtxp->position().t())));
214 ATH_MSG_DEBUG(
"ParticleDecayer::fillEvt: -- set the decay vertex");
216 end_vtx->set_position(
HepMC::FourVector(posLV.x(),posLV.y(),posLV.z(),posLV.t()));
217 end_vtx->add_particle_in(std::move(genpart));
218 event->add_vertex(std::move(end_vtx));
219 return StatusCode::SUCCESS;
263 ATH_MSG_FATAL(
"Cannot configure exponential and uniform decay at the same time.");
264 return StatusCode::FAILURE;
268 if (TOTBR>1.0000001) {
269 ATH_MSG_FATAL(
"ParticleDecayer::genInitialize: -- Branching Ratio sum is larger than 1!! Please check the values in your jobOption.");
273 ATH_MSG_FATAL(
"ParticleDecayer::genInitialize: -- Total Branching Ratio " << TOTBR);
274 return StatusCode::FAILURE;
283 return StatusCode::FAILURE;
287 return StatusCode::SUCCESS;
295 const EventContext& ctx = Gaudi::Hive::currentContext();
296 CLHEP::HepRandomEngine* engine = this->
getRandomEngine(
"ParticleDecayer", ctx);
298 StatusCode status = StatusCode::SUCCESS;
303 ATH_MSG_DEBUG(
"ParticleDecayer::fillEvt: -- Found an McEventCollection for ParticleDecayer");
306 status = StatusCode::FAILURE;
310 event = mcEvtColl->
back();
313 ATH_MSG_FATAL(
"ParticleDecayer::fillEvt: -- McEvent was not successfully created");
314 status = StatusCode::FAILURE;
318 for (
auto genpart : *event) {
320 const bool hasRightPDG = (genpart->pdg_id() ==
m_particleID);
321 const bool isStable = (genpart->status() == 1);
322 const bool hasEndVtx = (genpart->end_vertex() !=
nullptr);
329 if (!isStable || hasEndVtx) {
330 ATH_MSG_DEBUG(
"ParticleDecayer::fillEvt: -- skip particle with PDG ID = "
332 <<
" status = " << genpart->status()
333 <<
" end_vertex = " << (hasEndVtx ?
"yes" :
"no"));
342 ATH_MSG_DEBUG(
"ParticleDecayer::fillEvt: -- only one dark photon per LeptonJet");
343 ATH_MSG_DEBUG(
"ParticleDecayer::fillEvt: -- found MC particle with PDG ID = " << genpart->pdg_id());
358 ATH_MSG_DEBUG(
"ParticleDecayer::fillEvt: -- set the new status = 2");
359 genpart->set_status(2);
362 ATH_MSG_DEBUG(
"ParticleDecayer::fillEvt: -- set the new momentum");
372 ATH_MSG_DEBUG(
"ParticleDecayer::fillEvt: -- two dark photons per LeptonJet");
373 ATH_MSG_DEBUG(
"ParticleDecayer::fillEvt: -- found MC particle with PDG ID = " << genpart->pdg_id());
386 ATH_MSG_DEBUG(
"ParticleDecayer::fillEvt: -- set the new status = 2");
387 genpart->set_status(2);
394 ATH_MSG_DEBUG(
"ParticleDecayer::fillEvt: -- allow the two-body decay of the dark scalar to dark photons...");
397 std::vector<CLHEP::HepLorentzVector> darkPhotonLVs;
398 CHECK(
getDecayProducts( engine, CLHEP::HepLorentzVector( genpart->momentum().px(), genpart->momentum().py(), genpart->momentum().pz(), genpart->momentum().e() ),
403 auto v0=darkPhotonLVs.at(0).vect();
406 auto v1=darkPhotonLVs.at(1).vect();
410 int polarizationSwitch = 1;
411 const std::vector<HepMC::GenParticlePtr>& particlesOut = genpart->end_vertex()->particles_out();
412 std::vector<HepMC::GenParticlePtr>::const_iterator pItBegin = particlesOut.begin();
413 std::vector<HepMC::GenParticlePtr>::const_iterator pItEnd = particlesOut.end();
414 for (
auto pIt=pItBegin ; pIt != pItEnd; ++pIt )
420 ATH_MSG_DEBUG(
"ParticleDecayer::fillEvt: -- Now allow the two-body decay of the dark photons");
424 polarizationSwitch = -polarizationSwitch;
432 return StatusCode::FAILURE;
440 if (event->weights().empty()) {
441 event->weights().push_back(1.);
462 double energy=std::sqrt(std::pow(momentum.x(),2)+std::pow(momentum.y(),2)+std::pow(momentum.z(),2)+mass*mass);
466 prod_vtx->add_particle_out(std::move(aParticle));
472 SmartIF<IPartPropSvc> partPropSvc(Gaudi::svcLocator()->service(
"PartPropSvc"));
473 if (!partPropSvc)
throw GaudiException(
"PartPropSvc error",
"I_ParticleDecayer", StatusCode::FAILURE);
476 const HepPDT::ParticleData* particle =
m_particleTable->particle(HepPDT::ParticleID(std::abs(pid)));
477 return particle->mass().value();
485 ATH_MSG_DEBUG(
"ParticleDecayer::fillEvt: -- allow the two-body decay of the dark photon...");
488 CLHEP::HepLorentzVector boostDF( genpart->momentum().px(), genpart->momentum().py(), genpart->momentum().pz(), genpart->momentum().e() );
500 ATH_MSG_DEBUG(
"ParticleDecayer::fillEvt: -- decayMode = " << ModeOfDecay);
508 if(Polarization==0) {
510 }
else if(Polarization==-1 && (ModeOfDecay==11 || ModeOfDecay==13)) {
512 }
else if(Polarization==1 && (ModeOfDecay==11 || ModeOfDecay==13)) {
514 }
else if(Polarization==-1 && ModeOfDecay==211) {
516 }
else if(Polarization==1 && ModeOfDecay==211) {
519 ATH_MSG_FATAL(
"ParticleDecayer::fillEvt: -- wrong polarization value... please check!");
520 return StatusCode::FAILURE;
524 std::vector<CLHEP::HepLorentzVector> daughterLVs;
528 ATH_MSG_DEBUG(
"ParticleDecayer::fillEvt: -- Add the daughters to the pool file");
529 auto end_vtx = genpart->end_vertex();
530 auto v0=daughterLVs.at(0).vect();
532 auto v1=daughterLVs.at(1).vect();
535 return StatusCode::SUCCESS;
540 double decayPartMass,
541 std::vector<CLHEP::HepLorentzVector>& daughterLVs,
544 double parentMass = parentLV.m();
545 CLHEP::Hep3Vector boostVec = parentLV.boostVector();
547 if( decayPartMass > parentMass/2.)
549 ATH_MSG_FATAL(
"Decay particle has more than half the mass of parent.");
550 return StatusCode::FAILURE;
554 double ct_rf =
cosgen(engine, decayType);
555 double theta_rf = std::acos(ct_rf);
558 double p1_rf = std::sqrt(parentMass*parentMass/4. - decayPartMass*decayPartMass);
559 double px_rf = p1_rf*std::cos(phi_rf)*std::sin(theta_rf);
560 double py_rf = p1_rf*std::sin(phi_rf)*std::sin(theta_rf);
561 double pz_rf = p1_rf*ct_rf;
562 CLHEP::HepLorentzVector hlv1( px_rf, py_rf, pz_rf, parentMass/2.);
563 CLHEP::HepLorentzVector hlv2( -px_rf, -py_rf, -pz_rf, parentMass/2.);
566 hlv1.rotateUz((parentLV.vect()).unit());
567 hlv2.rotateUz((parentLV.vect()).unit());
570 hlv1.boost(boostVec);
571 hlv2.boost(boostVec);
573 daughterLVs.push_back(hlv1);
574 daughterLVs.push_back(hlv2);
576 return StatusCode::SUCCESS;
Scalar phi() const
phi method
Scalar theta() const
theta method
#define CHECK(...)
Evaluate an expression and check for errors.
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
ServiceHandle< StoreGateSvc > & evtStore()
const T * back() const
Access the last element in the collection as an rvalue.
GenModule(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
CLHEP::HepRandomEngine * getRandomEngine(const std::string &streamName, const EventContext &ctx) const
This defines the McEventCollection, which is really just an ObjectVector of McEvent objectsFile: Gene...
double getParticleMass(int pdgID)
bool m_doExponentialDecay
StatusCode changeMass(HepMC::GenParticlePtr, double)
bool m_expDecayDoVariableLifetime
HepPDT::ParticleDataTable * m_particleTable
StatusCode DFTwoBodyDecay(CLHEP::HepRandomEngine *engine, HepMC::GenParticlePtr, int)
StatusCode getDecayProducts(CLHEP::HepRandomEngine *engine, CLHEP::HepLorentzVector, double, std::vector< CLHEP::HepLorentzVector > &, int decayType=0)
StatusCode setDecayPosition(CLHEP::HepRandomEngine *engine, HepMC::GenParticlePtr, HepMC::GenEvent *, bool doScalarDecay=false)
double rnd_DoubleRange(CLHEP::HepRandomEngine *engine, double a, double b)
std::string m_truthParticleContainerName
void addParticle(HepMC::GenVertexPtr, int pdg, HepMC::FourVector, int statusCode)
ParticleDecayer(const std::string &name, ISvcLocator *pSvcLocator)
double m_particleLifeTime
bool m_oppositePolarization
double m_thetaEndCapBarrel
double cosgen(CLHEP::HepRandomEngine *engine, int itype)
int m_particlePolarization
double m_expDecayFractionToKeep
StatusCode fillEvt(HepMC::GenEvent *)
For filling the HepMC event object.
bool m_expDecayDoTruncateLongDecays
StatusCode genInitialize()
For initializing the generator, if required.
double rnd_ExpLifetime(CLHEP::HepRandomEngine *engine, double ct)
bool contains(const std::string &s, const std::string ®x)
does a string contain the substring
HepMC3::FourVector FourVector
GenParticlePtr newGenParticlePtr(const HepMC3::FourVector &mom=HepMC3::FourVector::ZERO_VECTOR(), int pid=0, int status=0)
HepMC3::GenParticlePtr GenParticlePtr
GenVertexPtr newGenVertexPtr(const HepMC3::FourVector &pos=HepMC3::FourVector::ZERO_VECTOR(), const int i=0)
HepMC3::GenVertexPtr GenVertexPtr
HepMC3::GenEvent GenEvent