30 #include "CLHEP/Random/RandomEngine.h"
31 #include "CLHEP/Random/RandBreitWigner.h"
42 LogDebug(
"HadronDecayer") <<
"GetDecayTime(): WARNING!!! The full branching for specie " << pDef->
GetPDG() <<
" is less than 100% ("
43 << fullBranching*100 <<
"%) and decay channels exist!";
46 if(width > weakDecayLimit) {
48 return -slope * TMath::Log(CLHEP::RandFlat::shoot(
hjRandomEngine));
63 if(pDef->
GetWidth()>0 && nDecayChannel==0) {
64 LogDebug(
"HadronDecayer") <<
"Decay(): WARNING!! Particle " << pDef->
GetPDG() <<
" has finite width (" << pDef->
GetWidth()
65 <<
") but NO decay channels specified in the database. Check it out!!";
73 if(fullBranching < 0.00001)
77 double PDGmass = pDef->
GetMass();
86 LogDebug(
"HadronDecayer") <<
"Decay(): WARNING!!! iterations to decay "
87 << pDef->
GetPDG() <<
" : " << iterations <<
" Check it out!!!";
95 int encoding = pDef->
GetPDG();
102 if(ComprCodePyth==0){
108 if(ComprCodePyth==254){
120 if(ComprCodePyth!=0 && Delta>0 && (BWmass<PDGmass-Delta || BWmass>PDGmass+Delta)){
126 LogDebug(
"HadronDecayer") <<
"Decay(): Breit-Wigner mass > 5GeV for encoding: "<< encoding
127 <<
"; PDG mass: "<< PDGmass <<
"; delta: " << Delta <<
"; width: "
128 << pDef->
GetWidth() <<
"; mass: " << BWmass <<
"; ComprCodePyth: " << ComprCodePyth;
133 if(nAllowedChannels==0) {
138 std::vector<Particle> apDaughter;
139 std::vector<double> dMass;
140 std::vector<double> dMom;
141 std::vector<double> sm;
142 std::vector<double> rd;
145 double randValue = CLHEP::RandFlat::shoot(
hjRandomEngine) * fullBranching;
147 int chosenChannel = 1000;
149 int channelIterations = 0;
151 if(channelIterations > 1000) {
152 LogDebug(
"HadronDecayer") <<
"Decay(): More than 1000 iterations to choose a decay channel. Check it out !!";
154 for(
int nChannel = 0; nChannel < nDecayChannel; ++nChannel) {
156 if(randValue <= 0. && database->IsChannelAllowed(pDef->
GetDecayChannel(nChannel), BWmass)) {
157 chosenChannel = nChannel;
171 parentBW.
Pos(parent.
Pos());
172 double BWenergy = TMath::Sqrt(parent.
Mom().X()*parent.
Mom().X() +
173 parent.
Mom().Y()*parent.
Mom().Y() +
174 parent.
Mom().Z()*parent.
Mom().Z() +
177 int NB = (int)parent.
GetType();
179 TLorentzVector MomparentBW(parent.
Mom().X(), parent.
Mom().Y(), parent.
Mom().Z(), BWenergy);
180 parentBW.
Mom(MomparentBW);
182 TVector3 velocityBW(parentBW.
Mom().BoostVector());
198 int parentIndex = parent.
GetIndex();
218 p1.
Mom().Boost(velocityBW);
219 p2.
Mom().Boost(velocityBW);
235 double deltaS = TMath::Sqrt((parentBW.
Mom().X()-p1.
Mom().X()-p2.
Mom().X())*(parentBW.
Mom().X()-p1.
Mom().X()-p2.
Mom().X())+
236 (parentBW.
Mom().Y()-p1.
Mom().Y()-p2.
Mom().Y())*(parentBW.
Mom().Y()-p1.
Mom().Y()-p2.
Mom().Y())+
237 (parentBW.
Mom().Z()-p1.
Mom().Z()-p2.
Mom().Z())*(parentBW.
Mom().Z()-p1.
Mom().Z()-p2.
Mom().Z())+
238 (parentBW.
Mom().E()-p1.
Mom().E()-p2.
Mom().E())*(parentBW.
Mom().E()-p1.
Mom().E()-p2.
Mom().E()));
244 LogDebug(
"HadronDecayer|deltaS") <<
"2-body decay kinematic check in lab system: " << pDef->
GetPDG() <<
" >>> " << p1.
Encoding() <<
" + " << p2.
Encoding() << endl
245 <<
" Mother (e,px,py,pz): " << parentBW.
Mom().E() <<
" : " << parentBW.
Mom().X() <<
" : " << parentBW.
Mom().Y() <<
" : " << parentBW.
Mom().Z() << endl
246 <<
" Mother (x,y,z,t): " << parentBW.
Pos().X() <<
" : " << parentBW.
Pos().Y() <<
" : " << parentBW.
Pos().Z() <<
" : " << parentBW.
Pos().T() << endl
247 <<
" Daughter1 (e,px,py,pz): " << p1.
Mom().E() <<
" : " << p1.
Mom().X() <<
" : " << p1.
Mom().Y() <<
" : " << p1.
Mom().Z() << endl
248 <<
" Daughter2 (e,px,py,pz): " << p2.
Mom().E() <<
" : " << p2.
Mom().X() <<
" : " << p2.
Mom().Y() <<
" : " << p2.
Mom().Z() << endl
249 <<
" 2-body decay delta(sqrtS): " << deltaS << endl
250 <<
" Repeating the decay algorithm";
256 int parentIndex = parent.
GetIndex();
278 double pAbs1 = 0., pAbs2 = 0., pAbs3 = 0., sumPabs = 0., maxPabs = 0.;
280 TLorentzVector &mom1 = p1.
Mom(), &mom2 = p2.
Mom(), &mom3 = p3.
Mom();
281 double deltaMass = BWmass - mass1 - mass2 - mass3;
289 double e = rd2*deltaMass;
290 pAbs1 = TMath::Sqrt(e*e + 2*e*mass1);
294 e = (1-rd1)*deltaMass;
295 pAbs2 = TMath::Sqrt(e*e + 2*e*mass2);
302 e = (rd1-rd2)*deltaMass;
303 pAbs3 = TMath::Sqrt(e*e + 2*e*mass3);
308 }
while(maxPabs > sumPabs - maxPabs);
312 double sinTheta = TMath::Sqrt(1 - cosTheta*cosTheta);
314 double sinPhi = TMath::Sin(phi);
315 double cosPhi = TMath::Cos(phi);
317 mom1.SetPxPyPzE(sinTheta*cosPhi, sinTheta*sinPhi, cosTheta, 0);
320 double cosThetaN = (pAbs2*pAbs2 - pAbs3*pAbs3 - pAbs1*pAbs1)/(2*pAbs1*pAbs3);
321 double sinThetaN = TMath::Sqrt(1 - cosThetaN*cosThetaN);
323 double sinPhiN = TMath::Sin(phiN);
324 double cosPhiN = TMath::Cos(phiN);
326 mom3.SetPxPyPzE(sinThetaN*cosPhiN*cosTheta*cosPhi - sinThetaN*sinPhiN*sinPhi + cosThetaN*sinTheta*cosPhi,
327 sinThetaN*cosPhiN*cosTheta*sinPhi + sinThetaN*sinPhiN*cosPhi + cosThetaN*sinTheta*sinPhi,
328 -sinThetaN*cosPhiN*sinTheta + cosThetaN*cosTheta,
331 mom3 *= pAbs3*mom3.P();
336 mom1.SetE(TMath::Sqrt(mom1.P()*mom1.P() + mass1*mass1));
337 mom2.SetE(TMath::Sqrt(mom2.P()*mom2.P() + mass2*mass2));
338 mom3.SetE(TMath::Sqrt(mom3.P()*mom3.P() + mass3*mass3));
341 mom1.Boost(velocityBW);
342 mom2.Boost(velocityBW);
343 mom3.Boost(velocityBW);
364 double deltaS = TMath::Sqrt((parentBW.
Mom().X()-p1.
Mom().X()-p2.
Mom().X()-p3.
Mom().X())*(parentBW.
Mom().X()-p1.
Mom().X()-p2.
Mom().X()-p3.
Mom().X()) +
365 (parentBW.
Mom().Y()-p1.
Mom().Y()-p2.
Mom().Y()-p3.
Mom().Y())*(parentBW.
Mom().Y()-p1.
Mom().Y()-p2.
Mom().Y()-p3.
Mom().Y()) +
366 (parentBW.
Mom().Z()-p1.
Mom().Z()-p2.
Mom().Z()-p3.
Mom().Z())*(parentBW.
Mom().Z()-p1.
Mom().Z()-p2.
Mom().Z()-p3.
Mom().Z()) +
367 (parentBW.
Mom().E()-p1.
Mom().E()-p2.
Mom().E()-p3.
Mom().E())*(parentBW.
Mom().E()-p1.
Mom().E()-p2.
Mom().E()-p3.
Mom().E()));
371 LogDebug(
"HadronDecayer|deltaS") <<
"3-body decay kinematic check in lab system: " << pDef->
GetPDG() <<
" >>> " << p1.
Encoding() <<
" + " << p2.
Encoding() <<
" + " << p3.
Encoding() << endl
372 <<
"Mother (e,px,py,pz): " << parentBW.
Mom().E() <<
" : " << parentBW.
Mom().X() <<
" : " << parentBW.
Mom().Y() <<
" : " << parentBW.
Mom().Z() << endl
373 <<
"Daughter1 (e,px,py,pz): " << p1.
Mom().E() <<
" : " << p1.
Mom().X() <<
" : " << p1.
Mom().Y() <<
" : " << p1.
Mom().Z() << endl
374 <<
"Daughter2 (e,px,py,pz): " << p2.
Mom().E() <<
" : " << p2.
Mom().X() <<
" : " << p2.
Mom().Y() <<
" : " << p2.
Mom().Z() << endl
375 <<
"Daughter3 (e,px,py,pz): " << p3.
Mom().E() <<
" : " << p3.
Mom().X() <<
" : " << p3.
Mom().Y() <<
" : " << p3.
Mom().Z() << endl
376 <<
"3-body decay delta(sqrtS): " << deltaS << endl
377 <<
"Repeating the decay algorithm";
384 int parentIndex = parent.
GetIndex();
TLorentzVector & SetLastMotherDecayCoor(const TLorentzVector &val)
void SetLastDaughterIndex(int index)
TLorentzVector & SetLastMotherDecayMom(const TLorentzVector &val)
ParticlePDG * Def() const
ParticlePDG * GetPDGParticle(int pdg)
void SetPythiaStatusCode(int code)
static const double slope[3]
void SetMother(int value)
DecayChannel * GetDecayChannel(int i)
int GetPythiaStatusCode()
std::list< Particle > List_t
void SetLastMotherPdg(int value)
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
void Decay(List_t &output, Particle &p, ParticleAllocator &allocator, DatabasePDG *database)
int GetDaughterPDG(int i)
CLHEP::HepRandomEngine * hjRandomEngine
void MomAntiMom(TLorentzVector &mom, double mass, TLorentzVector &antiMom, double antiMass, double initialMass)
double GetDecayTime(const Particle &p, double weakDecayLimit)
void AddParticle(const Particle &particle, List_t &list)
double GetFullBranching()
void SetFirstDaughterIndex(int index)
int GetNAllowedChannels(ParticlePDG *particle, double motherMass)