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();
96 SERVICEEV.
ipdg = encoding;
98 ComprCodePyth=SERVICEEV.
KC;
99 Delta = SERVICEEV.
delta;
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());
189 p1.Pos(parentBW.Pos());
190 p1.Mom(parent.Mom());
191 p1.SetLastMotherPdg(parentBW.Encoding());
192 p1.SetLastMotherDecayCoor(parentBW.Pos());
193 p1.SetLastMotherDecayMom(parentBW.Mom());
195 p1.SetPythiaStatusCode(parent.GetPythiaStatusCode());
198 int parentIndex = parent.GetIndex();
199 int p1Index = p1.SetIndex();
200 p1.SetMother(parentIndex);
201 parent.SetFirstDaughterIndex(p1Index);
202 parent.SetLastDaughterIndex(p1Index);
210 p1.Pos(parentBW.Pos());
212 p2.Pos(parentBW.Pos());
215 MomAntiMom(p1.Mom(), p1.TableMass(), p2.Mom(), p2.TableMass(), BWmass);
218 p1.Mom().Boost(velocityBW);
219 p2.Mom().Boost(velocityBW);
222 p1.SetLastMotherPdg(parentBW.Encoding());
223 p1.SetLastMotherDecayCoor(parentBW.Pos());
224 p1.SetLastMotherDecayMom(parentBW.Mom());
225 p2.SetLastMotherPdg(parentBW.Encoding());
226 p2.SetLastMotherDecayCoor(parentBW.Pos());
227 p2.SetLastMotherDecayMom(parentBW.Mom());
231 p1.SetPythiaStatusCode(parent.GetPythiaStatusCode());
232 p2.SetPythiaStatusCode(parent.GetPythiaStatusCode());
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();
259 p1.SetMother(parentIndex);
260 p2.SetMother(parentIndex);
261 parent.SetFirstDaughterIndex(p1.GetIndex());
262 parent.SetLastDaughterIndex(p2.GetIndex());
272 p1.Pos(parentBW.Pos());
274 p2.Pos(parentBW.Pos());
276 p3.Pos(parentBW.Pos());
278 double pAbs1 = 0., pAbs2 = 0., pAbs3 = 0., sumPabs = 0., maxPabs = 0.;
279 double mass1 = p1.TableMass(), mass2 = p2.TableMass(), mass3 = p3.TableMass();
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);
345 p1.SetLastMotherPdg(parentBW.Encoding());
346 p1.SetLastMotherDecayCoor(parentBW.Pos());
347 p1.SetLastMotherDecayMom(parentBW.Mom());
348 p2.SetLastMotherPdg(parentBW.Encoding());
349 p2.SetLastMotherDecayCoor(parentBW.Pos());
350 p2.SetLastMotherDecayMom(parentBW.Mom());
351 p3.SetLastMotherPdg(parentBW.Encoding());
352 p3.SetLastMotherDecayCoor(parentBW.Pos());
353 p3.SetLastMotherDecayMom(parentBW.Mom());
359 p1.SetPythiaStatusCode(parent.GetPythiaStatusCode());
360 p2.SetPythiaStatusCode(parent.GetPythiaStatusCode());
361 p3.SetPythiaStatusCode(parent.GetPythiaStatusCode());
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();
388 p1.SetMother(parentIndex);
389 p2.SetMother(parentIndex);
390 p3.SetMother(parentIndex);
391 parent.SetFirstDaughterIndex(p1.GetIndex());
392 parent.SetLastDaughterIndex(p3.GetIndex());
ParticlePDG * GetPDGParticle(int pdg)
void Decay(List_t &output, Particle &parent, ParticleAllocator &allocator, DatabasePDG *database)
static const double slope[3]
DecayChannel * GetDecayChannel(int i)
std::list< Particle > List_t
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
double GetDecayTime(const Particle &parent, double weakDecayLimit)
int GetDaughterPDG(int i)
CLHEP::HepRandomEngine * hjRandomEngine
void MomAntiMom(TLorentzVector &mom, double mass, TLorentzVector &antiMom, double antiMass, double initialMass)
void AddParticle(const Particle &particle, List_t &list)
double GetFullBranching()
int GetNAllowedChannels(ParticlePDG *particle, double motherMass)