9 #include "Pythia8/ParticleData.h"
10 #include "Pythia8/ResonanceWidths.h"
11 #include "Pythia8/StandardModel.h"
12 #include "Pythia8/SusyResonanceWidths.h"
13 #include "Pythia8/ResonanceWidthsDM.h"
29 bool DecayChannel::contains(
int id1)
const {
32 for (
int i = 0; i < nProd; ++i)
if (prod[i] == id1) found1 =
true;
42 bool DecayChannel::contains(
int id1,
int id2)
const {
46 for (
int i = 0; i < nProd; ++i) {
47 if (!found1 && prod[i] == id1) {found1 =
true;
continue;}
48 if (!found2 && prod[i] == id2) {found2 =
true;
continue;}
50 return found1 && found2;
59 bool DecayChannel::contains(
int id1,
int id2,
int id3)
const {
64 for (
int i = 0; i < nProd; ++i) {
65 if (!found1 && prod[i] == id1) {found1 =
true;
continue;}
66 if (!found2 && prod[i] == id2) {found2 =
true;
continue;}
67 if (!found3 && prod[i] == id3) {found3 =
true;
continue;}
69 return found1 && found2 && found3;
86 const int ParticleDataEntry::INVISIBLENUMBER = 62;
87 const int ParticleDataEntry::INVISIBLETABLE[80] = {
88 12, 14, 16, 18, 23, 25, 32, 33,
89 35, 36, 39, 41, 45, 46, 51, 52,
90 53, 54, 55, 56, 57, 58, 59, 60,
91 1000012, 1000014, 1000016, 1000018, 1000022, 1000023, 1000025, 1000035,
92 1000045, 1000039, 2000012, 2000014, 2000016, 2000018, 4900012, 4900014,
93 4900016, 4900021, 4900022, 4900101, 4900102, 4900103, 4900104, 4900105,
94 4900106, 4900107, 4900108, 4900111, 4900113, 4900211, 4900213, 4900991,
95 5000039, 5100039, 9900012, 9900014, 9900016, 9900023, 0, 0,
96 0, 0, 0, 0, 0, 0, 0, 0,
97 0, 0, 0, 0, 0, 0, 0, 0
102 const int ParticleDataEntry::KNOWNNOWIDTH[3] = {10313, 10323, 10333};
105 const double ParticleDataEntry::MAXTAU0FORDECAY = 1000.;
108 const double ParticleDataEntry::MINMASSRESONANCE = 20.;
111 const double ParticleDataEntry::NARROWMASS = 1e-6;
114 const double ParticleDataEntry::CONSTITUENTMASSTABLE[10]
115 = {0., 0.325, 0.325, 0.50, 1.60, 5.00, 0., 0., 0., 0.7};
121 ParticleDataEntry::~ParticleDataEntry() {
122 if (resonancePtr != 0)
delete resonancePtr;
129 void ParticleDataEntry::setDefaults() {
132 isResonanceSave = (m0Save > MINMASSRESONANCE);
135 mayDecaySave = (tau0Save < MAXTAU0FORDECAY);
141 doExternalDecaySave =
false;
144 isVisibleSave =
true;
145 for (
int i = 0; i < INVISIBLENUMBER; ++i)
146 if (idSave == INVISIBLETABLE[i]) isVisibleSave =
false;
149 doForceWidthSave =
false;
152 setConstituentMass();
165 bool ParticleDataEntry::isHadron()
const {
167 if (idSave <= 100 || (idSave >= 1000000 && idSave <= 9000000)
168 || idSave >= 9900000)
return false;
169 if (idSave == 130 || idSave == 310)
return true;
170 if (idSave%10 == 0 || (idSave/10)%10 == 0 || (idSave/100)%10 == 0)
181 bool ParticleDataEntry::isMeson()
const {
183 if (idSave <= 100 || (idSave >= 1000000 && idSave <= 9000000)
184 || idSave >= 9900000)
return false;
185 if (idSave == 130 || idSave == 310)
return true;
186 if (idSave%10 == 0 || (idSave/10)%10 == 0 || (idSave/100)%10 == 0
187 || (idSave/1000)%10 != 0)
return false;
197 bool ParticleDataEntry::isBaryon()
const {
199 if (idSave <= 1000 || (idSave >= 1000000 && idSave <= 9000000)
200 || idSave >= 9900000)
return false;
201 if (idSave%10 == 0 || (idSave/10)%10 == 0 || (idSave/100)%10 == 0
202 || (idSave/1000)%10 == 0)
return false;
211 bool ParticleDataEntry::isOnium()
const {
212 if (idSave%2 != 1)
return false;
213 if (idSave > 1000000)
return false;
214 if ((idSave/10)%10 < 4)
return false;
215 if ((idSave/10)%10 > 6)
return false;
216 if ((idSave/10)%10 != (idSave/100)%10)
return false;
217 if ((idSave/1000)%10 != 0)
return false;
226 int ParticleDataEntry::heaviestQuark(
int idIn)
const {
228 if (!isHadron())
return 0;
232 if ( (idSave/1000)%10 == 0 ) {
233 hQ = (idSave/100)%10;
234 if (idSave == 130) hQ = 3;
235 if (hQ%2 == 1) hQ = -hQ;
238 }
else hQ = (idSave/1000)%10;
241 return (idIn > 0) ? hQ : -hQ;
249 int ParticleDataEntry::baryonNumberType(
int idIn)
const {
252 if (isQuark())
return (idIn > 0) ? 1 : -1;
255 if (isDiquark())
return (idIn > 0) ? 2 : -2;
258 if (isBaryon())
return (idIn > 0) ? 3 : -3;
270 int ParticleDataEntry::nQuarksInCode(
int idQIn)
const {
273 int idQ = abs(idQIn);
274 int idNow = abs(idSave);
278 if (isQuark())
return (idQ == idNow) ? 1 : 0;
282 if ( (idNow/1000) % 10 == idQ) ++nQ;
283 if ( (idNow/100) % 10 == idQ) ++nQ;
289 if ( (idNow/100) % 10 == idQ) ++nQ;
290 if ( (idNow/10) % 10 == idQ) ++nQ;
296 if ( (idNow/1000) % 10 == idQ) ++nQ;
297 if ( (idNow/100) % 10 == idQ) ++nQ;
298 if ( (idNow/10) % 10 == idQ) ++nQ;
312 void ParticleDataEntry::initBWmass() {
316 if (modeTau0now == 0) modeTau0now = (particleDataPtr->setRapidDecayVertex
317 && tau0Save == 0. && channels.size() > 0) ? 2 : 1;
318 if (modeTau0now == 2) tau0Save = (mWidthSave > NARROWMASS)
319 ? HBARC * FM2MM / mWidthSave : particleDataPtr->intermediateTau0;
322 modeBWnow = particleDataPtr->modeBreitWigner;
323 if ( m0Save < NARROWMASS ) mWidthSave = 0.;
324 if ( mWidthSave < NARROWMASS || (mMaxSave > mMinSave
325 && mMaxSave - mMinSave < NARROWMASS) ) modeBWnow = 0;
326 if (modeBWnow == 0) {
327 mMinSave = mMaxSave = m0Save;
333 atanLow = atan( 2. * (mMinSave - m0Save) / mWidthSave );
334 double atanHigh = (mMaxSave > mMinSave)
335 ? atan( 2. * (mMaxSave - m0Save) / mWidthSave ) : 0.5 * M_PI;
336 atanDif = atanHigh - atanLow;
338 atanLow = atan( (pow2(mMinSave) - pow2(m0Save))
339 / (m0Save * mWidthSave) );
340 double atanHigh = (mMaxSave > mMinSave)
341 ? atan( (pow2(mMaxSave) - pow2(m0Save)) / (m0Save * mWidthSave) )
343 atanDif = atanHigh - atanLow;
347 if (modeBWnow%2 == 1)
return;
352 for (
int i = 0; i < int(channels.size()); ++i)
353 if (channels[i].onMode() > 0) {
354 bRatSum += channels[i].bRatio();
355 double mChannelSum = 0.;
356 for (
int j = 0; j < channels[i].multiplicity(); ++j)
357 mChannelSum += particleDataPtr->m0( channels[i].product(j) );
358 mThrSum += channels[i].bRatio() * mChannelSum;
360 mThr = (bRatSum == 0.) ? 0. : mThrSum / bRatSum;
363 if (mThr + NARROWMASS > m0Save && !isResonanceSave) {
365 bool knownProblem =
false;
366 for (
int i = 0; i < 3; ++i)
if (idSave == KNOWNNOWIDTH[i])
369 ostringstream osWarn;
370 osWarn <<
"for id = " << idSave;
371 particleDataPtr->infoPtr->errorMsg(
"Warning in ParticleDataEntry::"
372 "initBWmass: switching off width", osWarn.str(),
true);
383 double ParticleDataEntry::mSel()
const {
386 if (modeBWnow == 0 || mWidthSave < NARROWMASS)
return m0Save;
390 if (modeBWnow == 1) {
391 mNow = m0Save + 0.5 * mWidthSave
392 * tan( atanLow + atanDif * particleDataPtr->rndmPtr->flat() );
395 }
else if (modeBWnow == 2) {
396 double mWidthNow, fixBW, runBW;
397 double m0ThrS = m0Save*m0Save - mThr*mThr;
399 mNow = m0Save + 0.5 * mWidthSave
400 * tan( atanLow + atanDif * particleDataPtr->rndmPtr->flat() );
401 mWidthNow = mWidthSave * sqrtpos( (mNow*mNow - mThr*mThr) / m0ThrS );
402 fixBW = mWidthSave / (pow2(mNow - m0Save) + pow2(0.5 * mWidthSave));
403 runBW = mWidthNow / (pow2(mNow - m0Save) + pow2(0.5 * mWidthNow));
404 }
while (runBW < particleDataPtr->rndmPtr->flat()
405 * particleDataPtr->maxEnhanceBW * fixBW);
408 }
else if (modeBWnow == 3) {
409 m2Now = m0Save*m0Save + m0Save * mWidthSave
410 * tan( atanLow + atanDif * particleDataPtr->rndmPtr->flat() );
411 mNow = sqrtpos( m2Now);
415 double mwNow, fixBW, runBW;
416 double m2Ref = m0Save * m0Save;
417 double mwRef = m0Save * mWidthSave;
418 double m2Thr = mThr * mThr;
420 m2Now = m2Ref + mwRef * tan( atanLow + atanDif
421 * particleDataPtr->rndmPtr->flat() );
422 mNow = sqrtpos( m2Now);
423 mwNow = mNow * mWidthSave
424 * sqrtpos( (m2Now - m2Thr) / (m2Ref - m2Thr) );
425 fixBW = mwRef / (pow2(m2Now - m2Ref) + pow2(mwRef));
426 runBW = mwNow / (pow2(m2Now - m2Ref) + pow2(mwNow));
427 }
while (runBW < particleDataPtr->rndmPtr->flat()
428 * particleDataPtr->maxEnhanceBW * fixBW);
439 double ParticleDataEntry::mRun(
double mHat)
const {
442 if (idSave > 6)
return m0Save;
443 double mQRun = particleDataPtr->mQRun[idSave];
444 double Lam5 = particleDataPtr->Lambda5Run;
447 if (idSave < 4)
return mQRun * pow ( log(2. / Lam5)
448 / log(max(2., mHat) / Lam5), 12./23.);
451 return mQRun * pow ( log(mQRun / Lam5)
452 / log(max(mQRun, mHat) / Lam5), 12./23.);
460 void ParticleDataEntry::rescaleBR(
double newSumBR) {
463 double oldSumBR = 0.;
464 for (
int i = 0; i < int(channels.size()); ++ i)
465 oldSumBR += channels[i].bRatio();
466 double rescaleFactor = newSumBR / oldSumBR;
467 for (
int i = 0; i < int(channels.size()); ++ i)
468 channels[i].rescaleBR(rescaleFactor);
476 bool ParticleDataEntry::preparePick(
int idSgn,
double mHat,
int idInFlav) {
482 if (isResonanceSave && resonancePtr != 0) {
483 resonancePtr->widthStore(idSgn, mHat, idInFlav);
484 for (
int i = 0; i < int(channels.size()); ++i)
485 currentBRSum += channels[i].currentBR();
491 for (
int i = 0; i < int(channels.size()); ++i) {
492 onMode = channels[i].onMode();
494 if ( idSgn > 0 && (onMode == 1 || onMode == 2) )
495 currentBRNow = channels[i].bRatio();
496 else if ( idSgn < 0 && (onMode == 1 || onMode == 3) )
497 currentBRNow = channels[i].bRatio();
498 channels[i].currentBR(currentBRNow);
499 currentBRSum += currentBRNow;
504 return (currentBRSum > 0.);
512 DecayChannel& ParticleDataEntry::pickChannel() {
515 int size = channels.size();
516 double rndmBR = currentBRSum * particleDataPtr->rndmPtr->flat();
518 do rndmBR -= channels[++i].currentBR();
519 while (rndmBR > 0. && i < size);
522 if (i == size) i = 0;
532 void ParticleDataEntry::setResonancePtr(
533 ResonanceWidths* resonancePtrIn) {
534 if (resonancePtr == resonancePtrIn)
return;
535 if (resonancePtr != 0)
delete resonancePtr;
536 resonancePtr = resonancePtrIn;
539 void ParticleDataEntry::resInit(Info* infoPtr) {
540 if (resonancePtr != 0) resonancePtr->init(infoPtr);
543 double ParticleDataEntry::resWidth(
int idSgn,
double mHat,
int idIn,
544 bool openOnly,
bool setBR) {
545 return (resonancePtr != 0) ? resonancePtr->width( idSgn, mHat,
546 idIn, openOnly, setBR) : 0.;
549 double ParticleDataEntry::resWidthOpen(
int idSgn,
double mHat,
int idIn) {
550 return (resonancePtr != 0) ? resonancePtr->widthOpen( idSgn, mHat, idIn)
554 double ParticleDataEntry::resWidthStore(
int idSgn,
double mHat,
int idIn) {
555 return (resonancePtr != 0) ? resonancePtr->widthStore( idSgn, mHat, idIn)
559 double ParticleDataEntry::resOpenFrac(
int idSgn) {
560 return (resonancePtr != 0) ? resonancePtr->openFrac(idSgn) : 1.;
563 double ParticleDataEntry::resWidthRescaleFactor() {
564 return (resonancePtr != 0) ? resonancePtr->widthRescaleFactor() : 1.;
567 double ParticleDataEntry::resWidthChan(
double mHat,
int idAbs1,
569 return (resonancePtr != 0) ? resonancePtr->widthChan( mHat, idAbs1,
580 void ParticleDataEntry::setConstituentMass() {
583 constituentMassSave = m0Save;
586 if (idSave < 6) constituentMassSave = CONSTITUENTMASSTABLE[idSave];
587 if (idSave == 21) constituentMassSave = CONSTITUENTMASSTABLE[9];
590 if (idSave > 1000 && idSave < 10000 && (idSave/10)%10 == 0) {
591 int id1 = idSave/1000;
592 int id2 = (idSave/100)%10;
593 if (id1 <6 && id2 < 6) constituentMassSave
594 = CONSTITUENTMASSTABLE[id1] + CONSTITUENTMASSTABLE[id2];
612 void ParticleData::initCommon() {
615 modeBreitWigner = settingsPtr->mode(
"ParticleData:modeBreitWigner");
618 maxEnhanceBW = settingsPtr->parm(
"ParticleData:maxEnhanceBW");
621 mQRun[1] = settingsPtr->parm(
"ParticleData:mdRun");
622 mQRun[2] = settingsPtr->parm(
"ParticleData:muRun");
623 mQRun[3] = settingsPtr->parm(
"ParticleData:msRun");
624 mQRun[4] = settingsPtr->parm(
"ParticleData:mcRun");
625 mQRun[5] = settingsPtr->parm(
"ParticleData:mbRun");
626 mQRun[6] = settingsPtr->parm(
"ParticleData:mtRun");
629 double alphaSvalue = settingsPtr->parm(
"ParticleData:alphaSvalueMRun");
631 alphaS.init( alphaSvalue, 1, 5,
false);
632 Lambda5Run = alphaS.Lambda5();
635 setRapidDecayVertex = settingsPtr->flag(
"HadronLevel:Rescatter")
636 || ( settingsPtr->flag(
"Fragmentation:setVertices")
637 && settingsPtr->flag(
"HadronVertex:rapidDecays") );
638 intermediateTau0 = settingsPtr->parm(
"HadronVertex:intermediateTau0");
648 void ParticleData::initWidths( vector<ResonanceWidths*> resonancePtrs) {
655 ResonanceWidths* resonancePtr = 0;
656 for (map<int, ParticleDataEntry>::iterator pdtEntry = pdt.begin();
657 pdtEntry != pdt.end(); ++pdtEntry) {
658 ParticleDataEntry& pdtNow = pdtEntry->second;
662 resonancePtr = pdtNow.getResonancePtr();
663 if (resonancePtr != 0) pdtNow.setResonancePtr(0);
668 resonancePtr =
new ResonanceGmZ(23);
669 setResonancePtr( 23, resonancePtr);
670 resonancePtr =
new ResonanceW(24);
671 setResonancePtr( 24, resonancePtr);
672 resonancePtr =
new ResonanceTop(6);
673 setResonancePtr( 6, resonancePtr);
676 if (!settingsPtr->flag(
"Higgs:useBSM")) {
677 resonancePtr =
new ResonanceH(0, 25);
678 setResonancePtr( 25, resonancePtr);
682 resonancePtr =
new ResonanceH(1, 25);
683 setResonancePtr( 25, resonancePtr);
684 resonancePtr =
new ResonanceH(2, 35);
685 setResonancePtr( 35, resonancePtr);
686 resonancePtr =
new ResonanceH(3, 36);
687 setResonancePtr( 36, resonancePtr);
688 resonancePtr =
new ResonanceHchg(37);
689 setResonancePtr( 37, resonancePtr);
690 resonancePtr =
new ResonanceH(4, 45);
691 setResonancePtr( 45, resonancePtr);
692 resonancePtr =
new ResonanceH(5, 46);
693 setResonancePtr( 46, resonancePtr);
697 resonancePtr =
new ResonanceFour(7);
698 setResonancePtr( 7, resonancePtr);
699 resonancePtr =
new ResonanceFour(8);
700 setResonancePtr( 8, resonancePtr);
701 resonancePtr =
new ResonanceFour(17);
702 setResonancePtr( 17, resonancePtr);
703 resonancePtr =
new ResonanceFour(18);
704 setResonancePtr( 18, resonancePtr);
707 resonancePtr =
new ResonanceZprime(32);
708 setResonancePtr( 32, resonancePtr);
709 resonancePtr =
new ResonanceWprime(34);
710 setResonancePtr( 34, resonancePtr);
711 resonancePtr =
new ResonanceRhorizontal(41);
712 setResonancePtr( 41, resonancePtr);
715 resonancePtr =
new ResonanceLeptoquark(42);
716 setResonancePtr( 42, resonancePtr);
719 resonancePtr =
new ResonanceS(54);
720 setResonancePtr( 54, resonancePtr);
721 resonancePtr =
new ResonanceZp(55);
722 setResonancePtr( 55, resonancePtr);
723 resonancePtr =
new ResonanceSl(56);
724 setResonancePtr( 56, resonancePtr);
725 resonancePtr =
new ResonanceCha(57);
726 setResonancePtr( 57, resonancePtr);
727 resonancePtr =
new ResonanceDM2(58);
728 setResonancePtr( 58, resonancePtr);
729 resonancePtr =
new ResonanceChaD(59);
730 setResonancePtr( 59, resonancePtr);
734 resonancePtr =
new ResonanceGmZ(93);
735 setResonancePtr( 93, resonancePtr);
736 resonancePtr =
new ResonanceW(94);
737 setResonancePtr( 94, resonancePtr);
741 for(
int i = 1; i < 7; i++){
742 resonancePtr =
new ResonanceSquark(1000000 + i);
743 setResonancePtr( 1000000 + i, resonancePtr);
744 resonancePtr =
new ResonanceSquark(2000000 + i);
745 setResonancePtr( 2000000 + i, resonancePtr);
749 for(
int i = 1; i < 7; i++){
750 resonancePtr =
new ResonanceSlepton(1000010 + i);
751 setResonancePtr( 1000010 + i, resonancePtr);
752 resonancePtr =
new ResonanceSlepton(2000010 + i);
753 setResonancePtr( 2000010 + i, resonancePtr);
757 resonancePtr =
new ResonanceGluino(1000021);
758 setResonancePtr( 1000021, resonancePtr);
761 resonancePtr =
new ResonanceChar(1000024);
762 setResonancePtr( 1000024, resonancePtr);
763 resonancePtr =
new ResonanceChar(1000037);
764 setResonancePtr( 1000037, resonancePtr);
767 if (isResonance(1000022)) {
768 resonancePtr =
new ResonanceNeut(1000022);
769 setResonancePtr( 1000022, resonancePtr);
771 resonancePtr =
new ResonanceNeut(1000023);
772 setResonancePtr( 1000023, resonancePtr);
773 resonancePtr =
new ResonanceNeut(1000025);
774 setResonancePtr( 1000025, resonancePtr);
775 resonancePtr =
new ResonanceNeut(1000035);
776 setResonancePtr( 1000035, resonancePtr);
777 resonancePtr =
new ResonanceNeut(1000045);
778 setResonancePtr( 1000045, resonancePtr);
781 for (
int i = 1; i < 7; ++i) {
782 resonancePtr =
new ResonanceExcited(4000000 + i);
783 setResonancePtr( 4000000 + i, resonancePtr);
785 for (
int i = 11; i < 17; ++i) {
786 resonancePtr =
new ResonanceExcited(4000000 + i);
787 setResonancePtr( 4000000 + i, resonancePtr);
791 resonancePtr =
new ResonanceGraviton(5100039);
792 setResonancePtr( 5100039, resonancePtr);
793 resonancePtr =
new ResonanceKKgluon(5100021);
794 setResonancePtr( 5100021, resonancePtr);
798 resonancePtr =
new ResonanceNuRight(9900012);
799 setResonancePtr( 9900012, resonancePtr);
800 resonancePtr =
new ResonanceNuRight(9900014);
801 setResonancePtr( 9900014, resonancePtr);
802 resonancePtr =
new ResonanceNuRight(9900016);
803 setResonancePtr( 9900016, resonancePtr);
804 resonancePtr =
new ResonanceZRight(9900023);
805 setResonancePtr( 9900023, resonancePtr);
806 resonancePtr =
new ResonanceWRight(9900024);
807 setResonancePtr( 9900024, resonancePtr);
808 resonancePtr =
new ResonanceHchgchgLeft(9900041);
809 setResonancePtr( 9900041, resonancePtr);
810 resonancePtr =
new ResonanceHchgchgRight(9900042);
811 setResonancePtr( 9900042, resonancePtr);
814 for (
int i = 0; i < int(resonancePtrs.size()); ++i) {
815 int idNow = resonancePtrs[i]->id();
816 resonancePtrs[i]->initBasic(idNow);
817 setResonancePtr( idNow, resonancePtrs[i]);
821 vector<int> idOrdered;
822 vector<double> m0Ordered;
825 idOrdered.push_back(23);
826 m0Ordered.push_back(m0(23));
827 idOrdered.push_back(24);
828 m0Ordered.push_back(m0(24));
831 for (map<int, ParticleDataEntry>::iterator pdtEntry = pdt.begin();
832 pdtEntry != pdt.end(); ++pdtEntry) {
833 ParticleDataEntry& pdtNow = pdtEntry->second;
834 int idNow = pdtNow.id();
837 if (pdtNow.isResonance() && pdtNow.getResonancePtr() == 0) {
838 resonancePtr =
new ResonanceGeneric(idNow);
839 setResonancePtr( idNow, resonancePtr);
843 if (pdtNow.getResonancePtr() != 0 && idNow != 23 && idNow != 24) {
844 double m0Now = pdtNow.m0();
845 idOrdered.push_back(idNow);
846 m0Ordered.push_back(m0Now);
847 for (
int i =
int(idOrdered.size()) - 2; i > 1; --i) {
848 if (m0Ordered[i] < m0Now)
break;
849 swap( idOrdered[i], idOrdered[i + 1]);
850 swap( m0Ordered[i], m0Ordered[i + 1]);
856 for (
int i = 0; i < int(idOrdered.size()); ++i) {
857 resInit( idOrdered[i]);
858 ParticleDataEntry* pdtPtrNow = particleDataEntryPtr( idOrdered[i]);
859 pdtPtrNow->initBWmass();
868 bool ParticleData::readXML(
string inFile,
bool reset) {
871 if (!loadXML(inFile,reset))
return false;
874 if (!processXML(reset))
return false;
884 bool ParticleData::readXML(istream &inStr,
bool reset) {
887 if (!loadXML(inStr,reset))
return false;
890 if (!processXML(reset))
return false;
900 bool ParticleData::copyXML(
const ParticleData &particleDataIn) {
905 readStringHistory.resize(0);
906 readStringSubrun.clear();
908 xmlFileSav=particleDataIn.xmlFileSav;
911 if (!processXML(
true))
return false;
920 bool ParticleData::loadXML(istream& is,
bool reset) {
926 readStringHistory.resize(0);
927 readStringSubrun.clear();
933 infoPtr->errorMsg(
"Error in ParticleData::readXML:"
934 " did not find data");
941 while ( getline(is, line) ) {
944 istringstream getfirst(line);
949 if (word1 ==
"<file") {
950 string file = attributeValue(line,
"name");
955 xmlFileSav.push_back(line);
969 bool ParticleData::loadXML(
string inFile,
bool reset) {
971 const char* cstring = inFile.c_str();
972 ifstream is(cstring);
974 return loadXML(is, reset);
981 bool ParticleData::processXML(
bool reset) {
984 int nLines = xmlFileSav.size();
989 while (++i < nLines) {
992 string line = xmlFileSav[i];
995 istringstream getfirst(line);
1000 if (word1 ==
"<particle") {
1001 while (line.find(
">") == string::npos) {
1002 if (++i >= nLines)
break;
1003 string addLine = xmlFileSav[i];
1008 int idTmp = intAttributeValue( line,
"id");
1009 string nameTmp = attributeValue( line,
"name");
1010 string antiNameTmp = attributeValue( line,
"antiName");
1011 if (antiNameTmp ==
"") antiNameTmp =
"void";
1012 int spinTypeTmp = intAttributeValue( line,
"spinType");
1013 int chargeTypeTmp = intAttributeValue( line,
"chargeType");
1014 int colTypeTmp = intAttributeValue( line,
"colType");
1015 double m0Tmp = doubleAttributeValue( line,
"m0");
1016 double mWidthTmp = doubleAttributeValue( line,
"mWidth");
1017 double mMinTmp = doubleAttributeValue( line,
"mMin");
1018 double mMaxTmp = doubleAttributeValue( line,
"mMax");
1019 double tau0Tmp = doubleAttributeValue( line,
"tau0");
1020 bool varWidthTmp = boolAttributeValue( line,
"varWidth");
1023 if (isParticle(idTmp)) pdt.erase(idTmp);
1026 addParticle( idTmp, nameTmp, antiNameTmp, spinTypeTmp, chargeTypeTmp,
1027 colTypeTmp, m0Tmp, mWidthTmp, mMinTmp, mMaxTmp, tau0Tmp,
1029 particlePtr = particleDataEntryPtr(idTmp);
1032 }
else if (word1 ==
"<channel") {
1033 while (line.find(
">") == string::npos) {
1034 if (++i >= nLines)
break;
1035 string addLine = xmlFileSav[i];
1040 int onMode = intAttributeValue( line,
"onMode");
1041 double bRatio = doubleAttributeValue( line,
"bRatio");
1042 int meMode = intAttributeValue( line,
"meMode");
1043 string products = attributeValue( line,
"products");
1046 istringstream prodStream(products);
1047 int prod0 = 0;
int prod1 = 0;
int prod2 = 0;
int prod3 = 0;
1048 int prod4 = 0;
int prod5 = 0;
int prod6 = 0;
int prod7 = 0;
1049 prodStream >> prod0 >> prod1 >> prod2 >> prod3 >> prod4 >> prod5
1052 infoPtr->errorMsg(
"Error in ParticleData::readXML:"
1053 " incomplete decay channel", line);
1058 if (particlePtr == 0) {
1059 infoPtr->errorMsg(
"Error in ParticleData::readXML:"
1060 " orphan decay channel", line);
1063 particlePtr->addChannel(onMode, bRatio, meMode, prod0, prod1,
1064 prod2, prod3, prod4, prod5, prod6, prod7);
1071 if (reset)
for (map<int, ParticleDataEntry>::iterator pdtEntry
1072 = pdt.begin(); pdtEntry != pdt.end(); ++pdtEntry) {
1073 particlePtr = &pdtEntry->second;
1074 particlePtr->setHasChanged(
false);
1087 void ParticleData::listXML(
string outFile) {
1090 const char* cstring = outFile.c_str();
1091 ofstream os(cstring);
1094 for (map<int, ParticleDataEntry>::iterator pdtEntry
1095 = pdt.begin(); pdtEntry != pdt.end(); ++pdtEntry) {
1096 particlePtr = &pdtEntry->second;
1099 os <<
"<particle id=\"" << particlePtr->id() <<
"\""
1100 <<
" name=\"" << particlePtr->name() <<
"\"";
1101 if (particlePtr->hasAnti())
1102 os <<
" antiName=\"" << particlePtr->name(-1) <<
"\"";
1103 os <<
" spinType=\"" << particlePtr->spinType() <<
"\""
1104 <<
" chargeType=\"" << particlePtr->chargeType() <<
"\""
1105 <<
" colType=\"" << particlePtr->colType() <<
"\"\n";
1107 double m0Now = particlePtr->m0();
1108 if (m0Now == 0 || (m0Now > 0.1 && m0Now < 1000.))
1109 os << fixed << setprecision(5);
1110 else os << scientific << setprecision(3);
1111 os <<
" m0=\"" << m0Now <<
"\"";
1112 if (particlePtr->mWidth() > 0.)
1113 os <<
" mWidth=\"" << particlePtr->mWidth() <<
"\""
1114 <<
" mMin=\"" << particlePtr->mMin() <<
"\""
1115 <<
" mMax=\"" << particlePtr->mMax() <<
"\"";
1116 if (particlePtr->tau0() > 0.) os << scientific << setprecision(5)
1117 <<
" tau0=\"" << particlePtr->tau0() <<
"\"";
1121 if (particlePtr->sizeChannels() > 0) {
1122 for (
int i = 0; i < particlePtr->sizeChannels(); ++i) {
1123 const DecayChannel& channel = particlePtr->channel(i);
1124 int mult = channel.multiplicity();
1127 os <<
" <channel onMode=\"" << channel.onMode() <<
"\""
1128 << fixed << setprecision(7)
1129 <<
" bRatio=\"" << channel.bRatio() <<
"\"";
1130 if (channel.meMode() > 0)
1131 os <<
" meMode=\"" << channel.meMode() <<
"\"";
1132 os <<
" products=\"";
1133 for (
int j = 0; j < mult; ++j) {
1134 os << channel.product(j);
1135 if (j < mult - 1) os <<
" ";
1144 os <<
"</particle>\n\n";
1154 bool ParticleData::readFF(istream& is,
bool reset) {
1159 readStringHistory.resize(0);
1160 readStringSubrun.clear();
1165 infoPtr->errorMsg(
"Error in ParticleData::readFF:"
1166 " did not find stream");
1173 bool readParticle =
false;
1174 while ( getline(is, line) ) {
1177 if (line.find_first_not_of(
" \n\t\v\b\r\f\a") == string::npos) {
1178 readParticle =
true;
1183 istringstream readLine(line);
1190 string nameTmp, antiNameTmp;
1191 int spinTypeTmp, chargeTypeTmp, colTypeTmp;
1192 double m0Tmp, mWidthTmp, mMinTmp, mMaxTmp, tau0Tmp;
1197 readLine >> idTmp >> nameTmp >> antiNameTmp >> spinTypeTmp
1198 >> chargeTypeTmp >> colTypeTmp >> m0Tmp >> mWidthTmp
1199 >> mMinTmp >> mMaxTmp >> tau0Tmp >> varWidthTmp;
1203 infoPtr->errorMsg(
"Error in ParticleData::readFF:"
1204 " incomplete particle", line);
1209 if (isParticle(idTmp)) pdt.erase(idTmp);
1212 addParticle( idTmp, nameTmp, antiNameTmp, spinTypeTmp, chargeTypeTmp,
1213 colTypeTmp, m0Tmp, mWidthTmp, mMinTmp, mMaxTmp, tau0Tmp, varWidthTmp);
1214 particlePtr = particleDataEntryPtr(idTmp);
1215 readParticle =
false;
1224 int prod0 = 0;
int prod1 = 0;
int prod2 = 0;
int prod3 = 0;
1225 int prod4 = 0;
int prod5 = 0;
int prod6 = 0;
int prod7 = 0;
1228 readLine >> onMode >> bRatio >> meMode >> prod0;
1230 infoPtr->errorMsg(
"Error in ParticleData::readFF:"
1231 " incomplete decay channel", line);
1234 readLine >> prod1 >> prod2 >> prod3 >> prod4 >> prod5
1238 if (particlePtr == 0) {
1239 infoPtr->errorMsg(
"Error in ParticleData::readFF:"
1240 " orphan decay channel", line);
1243 particlePtr->addChannel(onMode, bRatio, meMode, prod0, prod1,
1244 prod2, prod3, prod4, prod5, prod6, prod7);
1263 bool ParticleData::readFF(
string inFile,
bool reset) {
1265 const char* cstring = inFile.c_str();
1266 ifstream is(cstring);
1268 return readFF(is,reset);
1275 void ParticleData::listFF(
string outFile) {
1278 const char* cstring = outFile.c_str();
1279 ofstream os(cstring);
1282 for (map<int, ParticleDataEntry>::iterator pdtEntry
1283 = pdt.begin(); pdtEntry != pdt.end(); ++pdtEntry) {
1284 particlePtr = &pdtEntry->second;
1287 double m0Now = particlePtr->m0();
1288 if (m0Now == 0 || (m0Now > 0.1 && m0Now < 1000.))
1289 os << fixed << setprecision(5);
1290 else os << scientific << setprecision(3);
1293 os <<
"\n" << setw(8) << particlePtr->id() <<
" "
1294 << left << setw(16) << particlePtr->name() <<
" "
1295 << setw(16) << particlePtr->name(-1) <<
" "
1296 << right << setw(2) << particlePtr->spinType() <<
" "
1297 << setw(2) << particlePtr->chargeType() <<
" "
1298 << setw(2) << particlePtr->colType() <<
" "
1299 << setw(10) << particlePtr->m0() <<
" "
1300 << setw(10) << particlePtr->mWidth() <<
" "
1301 << setw(10) << particlePtr->mMin() <<
" "
1302 << setw(10) << particlePtr->mMax() <<
" "
1303 << scientific << setprecision(5)
1304 << setw(12) << particlePtr->tau0() <<
"\n";
1307 if (particlePtr->sizeChannels() > 0) {
1308 for (
int i = 0; i < particlePtr->sizeChannels(); ++i) {
1309 const DecayChannel& channel = particlePtr->channel(i);
1310 os <<
" " << setw(6) << channel.onMode()
1311 <<
" " << fixed << setprecision(7) << setw(10)
1312 << channel.bRatio() <<
" "
1313 << setw(3) << channel.meMode() <<
" ";
1314 for (
int j = 0; j < channel.multiplicity(); ++j)
1315 os << setw(8) << channel.product(j) <<
" ";
1329 bool ParticleData::readString(
string lineIn,
bool warn) {
1332 if (lineIn.find_first_not_of(
" \n\t\v\b\r\f\a") == string::npos)
return true;
1335 string line = lineIn;
1338 int firstChar = line.find_first_not_of(
" \n\t\v\b\r\f\a");
1339 if (!isdigit(line[firstChar]))
return true;
1342 for (
int j = 0; j < int(line.size()); ++ j)
1343 if (line[j] ==
':' || line[j] ==
'=') line[j] =
' ';
1348 istringstream getWord(line);
1349 getWord >> idTmp >> property;
1350 toLowerRep(property);
1353 if ( (!isParticle(idTmp) && property !=
"all" && property !=
"new")
1355 if (warn) cout <<
"\n PYTHIA Error: input particle not found in Particle"
1356 <<
" Data Table:\n " << lineIn <<
"\n";
1357 readingFailedSave =
true;
1362 readStringHistory.push_back(line);
1363 int subrun = max( -1, settingsPtr->mode(
"Main:subrun"));
1364 if (readStringSubrun.find(subrun) == readStringSubrun.end())
1365 readStringSubrun[subrun] = vector<string>();
1366 readStringSubrun[subrun].push_back(line);
1369 if (property ==
"name") {
1372 pdt[idTmp].setName(nameTmp);
1375 if (property ==
"antiname") {
1377 getWord >> antiNameTmp;
1378 pdt[idTmp].setAntiName(antiNameTmp);
1381 if (property ==
"names") {
1382 string nameTmp, antiNameTmp;
1383 getWord >> nameTmp >> antiNameTmp;
1384 pdt[idTmp].setNames(nameTmp, antiNameTmp);
1387 if (property ==
"spintype") {
1389 getWord >> spinTypeTmp;
1390 pdt[idTmp].setSpinType(spinTypeTmp);
1393 if (property ==
"chargetype") {
1395 getWord >> chargeTypeTmp;
1396 pdt[idTmp].setChargeType(chargeTypeTmp);
1399 if (property ==
"coltype") {
1401 getWord >> colTypeTmp;
1402 pdt[idTmp].setColType(colTypeTmp);
1405 if (property ==
"m0") {
1408 pdt[idTmp].setM0(m0Tmp);
1411 if (property ==
"mwidth") {
1413 getWord >> mWidthTmp;
1414 pdt[idTmp].setMWidth(mWidthTmp);
1417 if (property ==
"mmin") {
1420 pdt[idTmp].setMMin(mMinTmp);
1423 if (property ==
"mmax") {
1426 pdt[idTmp].setMMax(mMaxTmp);
1429 if (property ==
"tau0") {
1432 pdt[idTmp].setTau0(tau0Tmp);
1435 if (property ==
"isresonance") {
1437 getWord >> isresTmp;
1438 bool isResonanceTmp = boolString(isresTmp);
1439 pdt[idTmp].setIsResonance(isResonanceTmp);
1442 if (property ==
"maydecay") {
1445 bool mayDecayTmp = boolString(mayTmp);
1446 pdt[idTmp].setMayDecay(mayDecayTmp);
1449 if (property ==
"taucalc") {
1452 bool tauCalcTmp = boolString(tauTmp);
1453 pdt[idTmp].setTauCalc(tauCalcTmp);
1456 if (property ==
"doexternaldecay") {
1458 getWord >> extdecTmp;
1459 bool doExternalDecayTmp = boolString(extdecTmp);
1460 pdt[idTmp].setDoExternalDecay(doExternalDecayTmp);
1463 if (property ==
"isvisible") {
1465 getWord >> isvisTmp;
1466 bool isVisibleTmp = boolString(isvisTmp);
1467 pdt[idTmp].setIsVisible(isVisibleTmp);
1470 if (property ==
"doforcewidth") {
1472 getWord >> doforceTmp;
1473 bool doForceWidthTmp = boolString(doforceTmp);
1474 pdt[idTmp].setDoForceWidth(doForceWidthTmp);
1477 if (property ==
"varwidth") {
1479 getWord >> varwidthTmp;
1480 bool varWidthTmp = boolString(varwidthTmp);
1481 pdt[idTmp].setVarWidth(varWidthTmp);
1486 if (property ==
"all" || property ==
"new") {
1489 string nameTmp =
"void";
1490 string antiNameTmp =
"void";
1491 int spinTypeTmp = 0;
1492 int chargeTypeTmp = 0;
1495 double mWidthTmp = 0.;
1496 double mMinTmp = 0.;
1497 double mMaxTmp = 0.;
1498 double tau0Tmp = 0.;
1499 bool varWidthTmp =
false;
1502 getWord >> nameTmp >> antiNameTmp >> spinTypeTmp >> chargeTypeTmp
1503 >> colTypeTmp >> m0Tmp >> mWidthTmp >> mMinTmp >> mMaxTmp
1504 >> tau0Tmp >> varWidthTmp;
1507 if (property ==
"all" && isParticle(idTmp)) {
1508 setAll( idTmp, nameTmp, antiNameTmp, spinTypeTmp, chargeTypeTmp,
1509 colTypeTmp, m0Tmp, mWidthTmp, mMinTmp, mMaxTmp, tau0Tmp, varWidthTmp);
1513 if (isParticle(idTmp)) pdt.erase(idTmp);
1514 addParticle( idTmp, nameTmp, antiNameTmp, spinTypeTmp, chargeTypeTmp,
1515 colTypeTmp, m0Tmp, mWidthTmp, mMinTmp, mMaxTmp, tau0Tmp, varWidthTmp);
1521 if (property ==
"onmode") {
1524 getWord >> onModeIn;
1526 if (isdigit(onModeIn[0])) {
1527 istringstream getOnMode(onModeIn);
1528 getOnMode >> onMode;
1529 }
else onMode = (boolString(onModeIn)) ? 1 : 0;
1530 for (
int i = 0; i < pdt[idTmp].sizeChannels(); ++i)
1531 pdt[idTmp].channel(i).onMode(onMode);
1537 if (property ==
"offifany" || property ==
"onifany" ||
1538 property ==
"onposifany" || property ==
"onnegifany") matchKind = 1;
1539 if (property ==
"offifall" || property ==
"onifall" ||
1540 property ==
"onposifall" || property ==
"onnegifall") matchKind = 2;
1541 if (property ==
"offifmatch" || property ==
"onifmatch" ||
1542 property ==
"onposifmatch" || property ==
"onnegifmatch") matchKind = 3;
1543 if (matchKind > 0) {
1545 if (property ==
"onifany" || property ==
"onifall"
1546 || property ==
"onifmatch") onMode = 1;
1547 if (property ==
"onposifany" || property ==
"onposifall"
1548 || property ==
"onposifmatch") onMode = 2;
1549 if (property ==
"onnegifany" || property ==
"onnegifall"
1550 || property ==
"onnegifmatch") onMode = 3;
1553 vector<int> idToMatch;
1557 if (!getWord)
break;
1558 idToMatch.push_back(abs(idRead));
1560 int nToMatch = idToMatch.size();
1563 for (
int i = 0; i < pdt[idTmp].sizeChannels(); ++i) {
1564 int multi = pdt[idTmp].channel(i).multiplicity();
1567 if (matchKind == 1) {
1568 bool foundMatch =
false;
1569 for (
int j = 0; j < multi; ++j) {
1570 int idNow = abs(pdt[idTmp].channel(i).product(j));
1571 for (
int k = 0; k < nToMatch; ++k)
1572 if (idNow == idToMatch[k]) {foundMatch =
true;
break;}
1573 if (foundMatch)
break;
1575 if (foundMatch) pdt[idTmp].channel(i).onMode(onMode);
1579 int nUnmatched = nToMatch;
1580 if (multi < nToMatch);
1581 else if (multi > nToMatch && matchKind == 3);
1583 vector<int> idUnmatched;
1584 for (
int k = 0; k < nToMatch; ++k)
1585 idUnmatched.push_back(idToMatch[k]);
1586 for (
int j = 0; j < multi; ++j) {
1587 int idNow = abs(pdt[idTmp].channel(i).product(j));
1588 for (
int k = 0; k < nUnmatched; ++k)
1589 if (idNow == idUnmatched[k]) {
1590 idUnmatched[k] = idUnmatched[--nUnmatched];
1593 if (nUnmatched == 0)
break;
1596 if (nUnmatched == 0) pdt[idTmp].channel(i).onMode(onMode);
1603 if (property ==
"rescalebr") {
1606 pdt[idTmp].rescaleBR(factor);
1611 if (property ==
"onechannel") pdt[idTmp].clearChannels();
1614 if (property ==
"addchannel" || property ==
"onechannel"
1615 || isdigit(property[0])) {
1617 if (property ==
"addchannel" || property ==
"onechannel") {
1618 pdt[idTmp].addChannel();
1619 channel = pdt[idTmp].sizeChannels() - 1;
1622 istringstream getChannel(property);
1623 getChannel >> channel;
1624 getWord >> property;
1625 toLowerRep(property);
1629 if (channel < 0 || channel >= pdt[idTmp].sizeChannels())
return false;
1633 if (property ==
"onmode" || property ==
"all") {
1636 getWord >> onModeIn;
1638 if (isdigit(onModeIn[0])) {
1639 istringstream getOnMode(onModeIn);
1640 getOnMode >> onMode;
1641 }
else onMode = (boolString(onModeIn)) ? 1 : 0;
1642 pdt[idTmp].channel(channel).onMode(onMode);
1643 if (property ==
"onmode")
return true;
1645 if (property ==
"bratio" || property ==
"all") {
1648 pdt[idTmp].channel(channel).bRatio(bRatio);
1649 if (property ==
"bratio")
return true;
1651 if (property ==
"memode" || property ==
"all") {
1654 pdt[idTmp].channel(channel).meMode(meMode);
1655 if (property ==
"memode")
return true;
1659 if (property ==
"products" || property ==
"all") {
1661 for (
int iProd = 0; iProd < 8; ++iProd) {
1664 if (!getWord)
break;
1665 pdt[idTmp].channel(channel).product(iProd, idProd);
1668 for (
int iProd = nProd; iProd < 8; ++iProd)
1669 pdt[idTmp].channel(channel).product(iProd, 0);
1670 pdt[idTmp].channel(channel).multiplicity(nProd);
1675 if (property ==
"rescalebr") {
1678 pdt[idTmp].channel(channel).rescaleBR(factor);
1684 if (warn) cout <<
"\n PYTHIA Error: input property not found in Particle"
1685 <<
" Data Table:\n " << lineIn <<
"\n";
1686 readingFailedSave =
true;
1695 void ParticleData::list(ostream& str,
bool changedOnly,
bool changedRes) {
1699 str <<
"\n -------- PYTHIA Particle Data Table (complete) --------"
1700 <<
"------------------------------------------------------------"
1701 <<
"--------------\n \n";
1704 str <<
"\n -------- PYTHIA Particle Data Table (changed only) ----"
1705 <<
"------------------------------------------------------------"
1706 <<
"--------------\n \n";
1708 str <<
" id name antiName spn chg col m0"
1709 <<
" mWidth mMin mMax tau0 res dec ext "
1710 <<
"vis wid\n no onMode bRatio meMode products \n";
1714 for (map<int, ParticleDataEntry>::iterator pdtEntry
1715 = pdt.begin(); pdtEntry != pdt.end(); ++pdtEntry) {
1716 particlePtr = &pdtEntry->second;
1717 if ( !changedOnly || particlePtr->hasChanged() ||
1718 ( changedRes && particlePtr->getResonancePtr() != 0 ) ) {
1721 double m0Now = particlePtr->m0();
1722 if (m0Now == 0 || (m0Now > 0.1 && m0Now < 1000.))
1723 str << fixed << setprecision(5);
1724 else str << scientific << setprecision(3);
1728 str <<
"\n" << setw(8) << particlePtr->id() <<
" " << left;
1729 if (particlePtr->name(-1) ==
"void")
1730 str << setw(33) << particlePtr->name() <<
" ";
1731 else str << setw(16) << particlePtr->name() <<
" "
1732 << setw(16) << particlePtr->name(-1) <<
" ";
1733 str << right << setw(2) << particlePtr->spinType() <<
" "
1734 << setw(2) << particlePtr->chargeType() <<
" "
1735 << setw(2) << particlePtr->colType() <<
" "
1736 << setw(10) << particlePtr->m0() <<
" "
1737 << setw(10) << particlePtr->mWidth() <<
" "
1738 << setw(10) << particlePtr->mMin() <<
" "
1739 << setw(10) << particlePtr->mMax() <<
" "
1740 << scientific << setprecision(5)
1741 << setw(12) << particlePtr->tau0() <<
" " << setw(2)
1742 << particlePtr->isResonance() <<
" " << setw(2)
1743 << (particlePtr->mayDecay() && particlePtr->canDecay())
1744 <<
" " << setw(2) << particlePtr->doExternalDecay() <<
" "
1745 << setw(2) << particlePtr->isVisible()<<
" "
1746 << setw(2) << particlePtr->doForceWidth() <<
"\n";
1749 if (particlePtr->sizeChannels() > 0) {
1750 for (
int i = 0; i < int(particlePtr->sizeChannels()); ++i) {
1751 const DecayChannel& channel = particlePtr->channel(i);
1752 str <<
" " << setprecision(7) << setw(5) << i
1753 << setw(6) << channel.onMode() << fixed<< setw(12)
1754 << channel.bRatio() << setw(5) << channel.meMode() <<
" ";
1755 for (
int j = 0; j < channel.multiplicity(); ++j)
1756 str << setw(8) << channel.product(j) <<
" ";
1765 if (changedOnly && nList == 0) cout <<
"\n no particle data has been "
1766 <<
"changed from its default value \n";
1767 cout <<
"\n -------- End PYTHIA Particle Data Table -----------------"
1768 <<
"--------------------------------------------------------------"
1769 <<
"----------\n" << endl;
1777 void ParticleData::list(vector<int> idList) {
1780 cout <<
"\n -------- PYTHIA Particle Data Table (partial) ---------"
1781 <<
"------------------------------------------------------------"
1782 <<
"--------------\n \n";
1783 cout <<
" id name antiName spn chg col m0"
1784 <<
" mWidth mMin mMax tau0 res dec ext "
1785 <<
"vis wid\n no onMode bRatio meMode products \n";
1788 for (
int i = 0; i < int(idList.size()); ++i) {
1789 particlePtr = particleDataEntryPtr(idList[i]);
1792 double m0Now = particlePtr->m0();
1793 if (m0Now == 0 || (m0Now > 0.1 && m0Now < 1000.))
1794 cout << fixed << setprecision(5);
1795 else cout << scientific << setprecision(3);
1798 cout <<
"\n" << setw(8) << particlePtr->id() <<
" " << left;
1799 if (particlePtr->name(-1) ==
"void")
1800 cout << setw(33) << particlePtr->name() <<
" ";
1801 else cout << setw(16) << particlePtr->name() <<
" "
1802 << setw(16) << particlePtr->name(-1) <<
" ";
1803 cout << right << setw(2) << particlePtr->spinType() <<
" "
1804 << setw(2) << particlePtr->chargeType() <<
" "
1805 << setw(2) << particlePtr->colType() <<
" "
1806 << setw(10) << particlePtr->m0() <<
" "
1807 << setw(10) << particlePtr->mWidth() <<
" "
1808 << setw(10) << particlePtr->mMin() <<
" "
1809 << setw(10) << particlePtr->mMax() <<
" "
1810 << scientific << setprecision(5)
1811 << setw(12) << particlePtr->tau0() <<
" " << setw(2)
1812 << particlePtr->isResonance() <<
" " << setw(2)
1813 << (particlePtr->mayDecay() && particlePtr->canDecay())
1814 <<
" " << setw(2) << particlePtr->doExternalDecay() <<
" "
1815 << setw(2) << particlePtr->isVisible() <<
" "
1816 << setw(2) << particlePtr->doForceWidth() <<
"\n";
1819 if (particlePtr->sizeChannels() > 0) {
1820 for (
int j = 0; j < int(particlePtr->sizeChannels()); ++j) {
1821 const DecayChannel& channel = particlePtr->channel(j);
1822 cout <<
" " << setprecision(7) << setw(5) << j
1823 << setw(6) << channel.onMode() << fixed << setw(12)
1824 << channel.bRatio() << setw(5) << channel.meMode() <<
" ";
1825 for (
int k = 0; k < channel.multiplicity(); ++k)
1826 cout << setw(8) << channel.product(k) <<
" ";
1834 cout <<
"\n -------- End PYTHIA Particle Data Table -----------------"
1835 <<
"--------------------------------------------------------------"
1836 <<
"----------\n" << endl;
1851 void ParticleData::checkTable(
int verbosity) {
1854 cout <<
"\n -------- PYTHIA Check of Particle Data Table ------------"
1859 for (map<int, ParticleDataEntry>::iterator pdtEntry
1860 = pdt.begin(); pdtEntry != pdt.end(); ++pdtEntry) {
1861 particlePtr = &pdtEntry->second;
1864 int idNow = particlePtr->id();
1865 bool hasAntiNow = particlePtr->hasAnti();
1866 int spinTypeNow = particlePtr->spinType();
1867 int chargeTypeNow = particlePtr->chargeType();
1868 int baryonTypeNow = particlePtr->baryonNumberType();
1869 double m0Now = particlePtr->m0();
1870 double mMinNow = particlePtr->mMin();
1871 double mMaxNow = particlePtr->mMax();
1872 double mWidthNow = particlePtr->mWidth();
1873 double tau0Now = particlePtr->tau0();
1874 bool isResonanceNow = particlePtr->isResonance();
1875 bool hasPrinted =
false;
1876 bool studyCloser = verbosity > 10 || !isResonanceNow;
1879 string particleName = particlePtr->name(1);
1880 if (particleName.size() > 16) {
1881 cout <<
" Warning: particle " << idNow <<
" has name " << particleName
1882 <<
" of length " << particleName.size() <<
"\n";
1888 for (
int i = 0; i < int(particleName.size()); ++i) {
1889 if (particleName[i] ==
'+') ++nPos;
1890 if (particleName[i] ==
'-') ++nNeg;
1892 if ( (nPos > 0 && nNeg > 0) || ( nPos + nNeg > 0
1893 && 3 * (nPos - nNeg) != chargeTypeNow )) {
1894 cout <<
" Warning: particle " << idNow <<
" has name " << particleName
1895 <<
" inconsistent with charge type " << chargeTypeNow <<
"\n";
1902 particleName = particlePtr->name(-1);
1903 if (particleName.size() > 16) {
1904 cout <<
" Warning: particle " << idNow <<
" has name " << particleName
1905 <<
" of length " << particleName.size() <<
"\n";
1911 for (
int i = 0; i < int(particleName.size()); ++i) {
1912 if (particleName[i] ==
'+') ++nPos;
1913 if (particleName[i] ==
'-') ++nNeg;
1915 if ( (nPos > 0 && nNeg > 0) || ( nPos + nNeg > 0
1916 && 3 * (nPos - nNeg) != -chargeTypeNow )) {
1917 cout <<
" Warning: particle " << -idNow <<
" has name "
1918 << particleName <<
" inconsistent with charge type "
1919 << -chargeTypeNow <<
"\n";
1926 if (particlePtr->useBreitWigner()) {
1927 if (mMinNow > m0Now) {
1928 cout <<
" Error: particle " << idNow <<
" has mMin "
1929 << fixed << setprecision(5) << mMinNow
1930 <<
" larger than m0 " << m0Now <<
"\n";
1934 if (mMaxNow > mMinNow && mMaxNow < m0Now) {
1935 cout <<
" Error: particle " << idNow <<
" has mMax "
1936 << fixed << setprecision(5) << mMaxNow
1937 <<
" smaller than m0 " << m0Now <<
"\n";
1941 if (mMaxNow > mMinNow && mMaxNow - mMinNow < mWidthNow) {
1942 cout <<
" Warning: particle " << idNow <<
" has mMax - mMin "
1943 << fixed << setprecision(5) << mMaxNow - mMinNow
1944 <<
" smaller than mWidth " << mWidthNow <<
"\n";
1951 if (mWidthNow > 0. && tau0Now > 0.) {
1952 cout <<
" Warning: particle " << idNow <<
" has both nonvanishing width "
1953 << scientific << setprecision(5) << mWidthNow <<
" and lifetime "
1960 if (particlePtr->sizeChannels() > 0) {
1963 double bRatioSum = 0.;
1964 double bRatioPos = 0.;
1965 double bRatioNeg = 0.;
1966 bool hasPosBR =
false;
1967 bool hasNegBR =
false;
1968 double threshMass = 0.;
1969 bool openChannel =
false;
1970 for (
int i = 0; i < particlePtr->sizeChannels(); ++i) {
1973 int onMode = particlePtr->channel(i).onMode();
1974 double bRatio = particlePtr->channel(i).bRatio();
1975 int meMode = particlePtr->channel(i).meMode();
1976 int mult = particlePtr->channel(i).multiplicity();
1978 for (
int j = 0; j < 8; ++j)
1979 prod[j] = particlePtr->channel(i).product(j);
1982 if (onMode == 0 || onMode == 1) bRatioSum += bRatio;
1983 else if (onMode == 2) {bRatioPos += bRatio; hasPosBR =
true;}
1984 else if (onMode == 3) {bRatioNeg += bRatio; hasNegBR =
true;}
1987 for (
int j = 0; j < 8; ++j) {
1988 if ( prod[j] != 0 && !isParticle(prod[j]) ) {
1989 cout <<
" Error: unknown decay product for " << idNow
1990 <<
" -> " << prod[j] <<
"\n";
1999 for (
int j = 0; j < 8; ++j)
2000 if (prod[j] != 0) nLast = j + 1;
2001 if (mult == 0 || mult != nLast) {
2002 cout <<
" Error: corrupted decay product list for "
2003 << particlePtr->id() <<
" -> ";
2004 for (
int j = 0; j < 8; ++j) cout << prod[j] <<
" ";
2012 int chargeTypeSum = -chargeTypeNow;
2013 int baryonTypeSum = -baryonTypeNow;
2014 double avgFinalMass = 0.;
2015 double minFinalMass = 0.;
2016 bool canHandle =
true;
2017 for (
int j = 0; j < mult; ++j) {
2018 chargeTypeSum += chargeType( prod[j] );
2019 baryonTypeSum += baryonNumberType( prod[j] );
2020 avgFinalMass += m0( prod[j] );
2021 minFinalMass += m0Min( prod[j] );
2022 if (prod[j] == 81 || prod[j] == 82 || prod[j] == 83)
2025 threshMass += bRatio * avgFinalMass;
2028 if (chargeTypeSum != 0 && canHandle) {
2029 cout <<
" Error: 3*charge changed by " << chargeTypeSum
2030 <<
" in " << idNow <<
" -> ";
2031 for (
int j = 0; j < mult; ++j) cout << prod[j] <<
" ";
2037 if ( baryonTypeSum != 0 && canHandle && particlePtr->isHadron() ) {
2038 cout <<
" Error: 3*baryon number changed by " << baryonTypeSum
2039 <<
" in " << idNow <<
" -> ";
2040 for (
int j = 0; j < mult; ++j) cout << prod[j] <<
" ";
2048 bool correctME =
true;
2051 if (meMode == 0 && !isResonanceNow) {
2052 bool hasPartons =
false;
2053 for (
int j = 0; j < mult; ++j) {
2054 int idAbs = abs(prod[j]);
2055 if ( idAbs < 10 || idAbs == 21 || idAbs == 81 || idAbs == 82
2056 || idAbs == 83 || (idAbs > 1000 && idAbs < 10000
2057 && (idAbs/10)%10 == 0) ) hasPartons =
true;
2059 if (hasPartons) correctME =
false;
2063 bool useME1 = ( mult == 3 && spinTypeNow == 3 && idNow > 100
2065 && particlePtr->channel(i).contains(211, -211, 111) );
2066 if ( meMode == 1 && !useME1 ) correctME =
false;
2067 if ( meMode != 1 && useME1 ) correctME =
false;
2070 bool useME2 = ( mult == 2 && spinTypeNow == 3 && idNow > 100
2071 && idNow < 1000 && spinType(prod[0]) == 1
2072 && spinType(prod[1]) == 1 );
2073 if ( meMode == 2 && !useME2 ) correctME =
false;
2074 if ( meMode != 2 && useME2 ) correctME =
false;
2079 bool useME11 = ( mult == 3 && !isResonanceNow
2080 && (prod[1] == 11 || prod[1] == 13 || prod[1] == 15)
2081 && prod[2] == -prod[1] );
2082 bool useME12 = ( mult > 3 && !isResonanceNow
2083 && (prod[mult - 2] == 11 || prod[mult - 2] == 13
2084 || prod[mult - 2] == 15) && prod[mult - 1] == -prod[mult - 2] );
2085 bool useME13 = ( mult == 4 && !isResonanceNow
2086 && (prod[0] == 11 || prod[0] == 13) && prod[1] == -prod[0]
2087 && (prod[2] == 11 || prod[2] == 13) && prod[3] == -prod[2] );
2088 if (useME13) useME12 =
false;
2089 if ( meMode == 11 && !useME11 ) correctME =
false;
2090 if ( meMode != 11 && useME11 ) correctME =
false;
2091 if ( meMode == 12 && !useME12 ) correctME =
false;
2092 if ( meMode != 12 && useME12 ) correctME =
false;
2093 if ( meMode == 13 && !useME13 ) correctME =
false;
2094 if ( meMode != 13 && useME13 ) correctME =
false;
2097 bool useME21 = (idNow == 15 && mult > 2 && prod[0] == 16
2098 && abs(prod[1]) > 100);
2099 if ( meMode == 21 && !useME21 ) correctME =
false;
2100 if ( meMode != 21 && useME21 ) correctME =
false;
2104 if ( isLepton(prod[0]) && isLepton(prod[1]) ) {
2105 bool useME22 =
false;
2109 if (particlePtr->isLepton()) {
2110 typeA = (idNow > 0) ? 1 + (idNow-1)%2 : -1 - (1-idNow)%2;
2111 }
else if (particlePtr->isHadron()) {
2112 int hQ = particlePtr->heaviestQuark();
2114 if (idNow == 541 && heaviestQuark(prod[2]) == -5) hQ = 4;
2115 typeA = (hQ > 0) ? 1 + (hQ-1)%2 : -1 - (1-hQ)%2;
2117 typeB = (prod[0] > 0) ? 1 + (prod[0]-1)%2 : -1 - (1-prod[0])%2;
2118 typeC = (prod[1] > 0) ? 1 + (prod[1]-1)%2 : -1 - (1-prod[1])%2;
2120 if ( (idNow == 130 || idNow == 310) && typeC * typeA < 0)
2122 if (mult == 3 && idNow == 2112 && prod[2] == 2212)
2124 if (mult == 3 && idNow == 3222 && prod[2] == 3122)
2126 if (mult > 2 && typeC == typeA && typeB * typeC < 0
2127 && (typeB + typeC)%2 != 0) useME22 =
true;
2128 if ( meMode == 22 && !useME22 ) correctME =
false;
2129 if ( meMode != 22 && useME22 ) correctME =
false;
2135 for (
int j = 0; j < mult; ++j)
if (prod[j] == 22) ++nGamma;
2136 if (nGamma != 1) correctME =
false;
2140 if ( !isResonanceNow && (meMode < 0 || (meMode > 2 && meMode <= 10)
2141 || (meMode > 13 && meMode <= 20) || (meMode > 23 && meMode <= 30)
2142 || (meMode > 31 && meMode <= 41) || meMode == 51 || meMode == 61
2143 || meMode == 71 || (meMode > 80 && meMode <= 90)
2144 || (!particlePtr->isOctetHadron() && meMode > 92) ) )
2149 cout <<
" Warning: meMode " << meMode <<
" used for "
2151 for (
int j = 0; j < mult; ++j) cout << prod[j] <<
" ";
2158 if ( studyCloser && verbosity > 0 && canHandle && onMode > 0
2159 && particlePtr->m0Min() - minFinalMass < 0. ) {
2160 if (particlePtr->m0Max() - minFinalMass < 0.)
2161 cout <<
" Error: decay never possible for ";
2162 else cout <<
" Warning: decay sometimes not possible for ";
2163 cout << idNow <<
" -> ";
2164 for (
int j = 0; j < mult; ++j) cout << prod[j] <<
" ";
2171 if (onMode > 0 && bRatio > 0.) openChannel =
true;
2175 if (verbosity%10 > 1 && particlePtr->useBreitWigner()) {
2176 threshMass /= bRatioSum;
2177 cout <<
" Info: particle " << idNow << fixed << setprecision(5)
2178 <<
" has average mass threshold " << threshMass
2179 <<
" while mMin is " << mMinNow <<
"\n";
2184 if (studyCloser && !openChannel) {
2185 cout <<
" Error: no acceptable decay channel found for particle "
2192 if (studyCloser && (!hasAntiNow || (!hasPosBR && !hasNegBR))
2193 && abs(bRatioSum + bRatioPos - 1.) > 1e-8) {
2194 cout <<
" Warning: particle " << idNow << fixed << setprecision(8)
2195 <<
" has branching ratio sum " << bRatioSum <<
"\n";
2198 }
else if (studyCloser && hasAntiNow
2199 && (abs(bRatioSum + bRatioPos - 1.) > 1e-8
2200 || abs(bRatioSum + bRatioNeg - 1.) > 1e-8)) {
2201 cout <<
" Warning: particle " << idNow << fixed << setprecision(8)
2202 <<
" has branching ratio sum " << bRatioSum + bRatioPos
2203 <<
" while its antiparticle has " << bRatioSum + bRatioNeg
2211 if (hasPrinted) cout <<
"\n";
2215 cout <<
" Total number of errors and warnings is " << nErr <<
"\n";
2216 cout <<
"\n -------- End PYTHIA Check of Particle Data Table --------"
2217 <<
"------\n" << endl;
2225 int ParticleData::nextId(
int idIn)
const {
2228 if (idIn < 0 || (idIn > 0 && !isParticle(idIn)))
return 0;
2229 if (idIn == 0)
return pdt.begin()->first;
2232 map<int, ParticleDataEntry>::const_iterator pdtIn = pdt.find(idIn);
2233 if (pdtIn == pdt.end())
return 0;
2235 if (pdtIn == pdt.end())
return 0;
2236 return pdtIn->first;
2244 double ParticleData::resOpenFrac(
int id1In,
int id2In,
int id3In) {
2250 if ( ParticleDataEntry* ptr = findParticle(id1In) )
2251 answer = ptr->resOpenFrac(id1In);
2254 if ( ParticleDataEntry* ptr = findParticle(id2In) )
2255 answer *= ptr->resOpenFrac(id2In);
2258 if ( ParticleDataEntry* ptr = findParticle(id3In) )
2259 answer *= ptr->resOpenFrac(id3In);
2270 string ParticleData::attributeValue(
string line,
string attribute) {
2272 if (line.find(attribute) == string::npos)
return "";
2273 int iBegAttri = line.find(attribute);
2274 int iBegQuote = line.find(
"\"", iBegAttri + 1);
2275 int iEndQuote = line.find(
"\"", iBegQuote + 1);
2276 return line.substr(iBegQuote + 1, iEndQuote - iBegQuote - 1);
2284 bool ParticleData::boolAttributeValue(
string line,
string attribute) {
2286 string valString = attributeValue(line, attribute);
2287 if (valString ==
"")
return false;
2288 return boolString(valString);
2296 int ParticleData::intAttributeValue(
string line,
string attribute) {
2297 string valString = attributeValue(line, attribute);
2298 if (valString ==
"")
return 0;
2299 istringstream valStream(valString);
2301 valStream >> intVal;
2310 double ParticleData::doubleAttributeValue(
string line,
string attribute) {
2311 string valString = attributeValue(line, attribute);
2312 if (valString ==
"")
return 0.;
2313 istringstream valStream(valString);
2315 valStream >> doubleVal;