]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PYTHIA8/pythia8170/src/ParticleData.cxx
Update to pythi8.170
[u/mrichter/AliRoot.git] / PYTHIA8 / pythia8170 / src / ParticleData.cxx
1 // ParticleData.cc is a part of the PYTHIA event generator.
2 // Copyright (C) 2012 Torbjorn Sjostrand.
3 // PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
4 // Please respect the MCnet Guidelines, see GUIDELINES for details.
5
6 // Function definitions (not found in the header) for the
7 // DecayChannel, ParticleDataEntry and ParticleData classes.
8
9 #include "ParticleData.h"
10 #include "StandardModel.h"
11 #include "SusyResonanceWidths.h"
12
13 // Allow string and character manipulation.
14 #include <cctype>
15
16 namespace Pythia8 {
17
18 //==========================================================================
19
20 // DecayChannel class.
21 // This class holds info on a single decay channel.
22
23 //--------------------------------------------------------------------------
24
25 // Check whether id1 occurs anywhere in product list.
26
27 bool DecayChannel::contains(int id1) const {
28   
29   bool found1 = false;
30   for (int i = 0; i < nProd; ++i) if (prod[i] == id1) found1 = true;
31   return found1;
32
33 }
34
35 //--------------------------------------------------------------------------
36
37 // Check whether id1 and id2 occur anywhere in product list.
38 // iF ID1 == ID2 then two copies of this particle must be present.
39
40 bool DecayChannel::contains(int id1, int id2) const {
41   
42   bool found1 = false;
43   bool found2 = false;
44   for (int i = 0; i < nProd; ++i) {
45     if (!found1 && prod[i] == id1) {found1 = true; continue;}
46     if (!found2 && prod[i] == id2) {found2 = true; continue;}
47   }
48   return found1 && found2;
49
50 }
51
52 //--------------------------------------------------------------------------
53
54 // Check whether id1, id2 and id3 occur anywhere in product list.
55 // iF ID1 == ID2 then two copies of this particle must be present, etc.
56
57 bool DecayChannel::contains(int id1, int id2, int id3) const {
58   
59   bool found1 = false;
60   bool found2 = false;
61   bool found3 = false;
62   for (int i = 0; i < nProd; ++i) {
63     if (!found1 && prod[i] == id1) {found1 = true; continue;}
64     if (!found2 && prod[i] == id2) {found2 = true; continue;}
65     if (!found3 && prod[i] == id3) {found3 = true; continue;}
66   }
67   return found1 && found2 && found3;
68
69 }
70
71 //==========================================================================
72
73 // ParticleDataEntry class.
74 // This class holds info on a single particle species.
75
76 //--------------------------------------------------------------------------
77
78 // Constants: could be changed here if desired, but normally should not.
79 // These are of technical nature, as described for each.
80
81 // A particle is invisible if it has neither strong nor electric charge,
82 // and is not made up of constituents that have it. Only relevant for
83 // long-lived particles. This list may need to be extended.
84 const int ParticleDataEntry::INVISIBLENUMBER = 50;
85 const int ParticleDataEntry::INVISIBLETABLE[50] = { 12, 14, 16, 18, 23, 25,
86   32, 33, 35, 36, 39, 41,    1000012, 1000014, 1000016, 1000018, 1000022, 
87   1000023, 1000025, 1000035, 1000045, 1000039, 2000012, 2000014, 2000016, 
88   2000018, 4900012, 4900014, 4900016, 4900021, 4900022, 4900101, 4900102,
89   4900103, 4900104, 4900105, 4900106, 4900107, 4900108, 4900111, 4900113, 
90   4900211, 4900213, 4900991, 5000039, 5100039, 9900012, 9900014, 9900016, 
91   9900023 };     
92
93 // For some particles we know it is necessary to switch off width,
94 // although they do have one, so do not warn.
95 const int ParticleDataEntry::KNOWNNOWIDTH[3] = {10313, 10323, 10333}; 
96
97 // Particles with a read-in tau0 (in mm/c) below this mayDecay by default.
98 const double ParticleDataEntry::MAXTAU0FORDECAY = 1000.;
99
100 // Particles with a read-in m0 above this isResonance by default.
101 const double ParticleDataEntry::MINMASSRESONANCE = 20.;
102
103 // Narrow states are assigned nominal mass.
104 const double ParticleDataEntry::NARROWMASS       = 1e-6;
105
106 // Constituent quark masses (d, u, s, c, b, -, -, -, g).
107 const double ParticleDataEntry::CONSTITUENTMASSTABLE[10] 
108   = {0., 0.325, 0.325, 0.50, 1.60, 5.00, 0., 0., 0., 0.7};
109
110 //--------------------------------------------------------------------------
111
112 // Destructor: delete any ResonanceWidths object.
113
114 ParticleDataEntry::~ParticleDataEntry() {
115   if (resonancePtr != 0) delete resonancePtr;
116 }
117
118 //--------------------------------------------------------------------------
119
120 // Set initial default values for some quantities. 
121
122 void ParticleDataEntry::setDefaults() {
123
124   // A particle is a resonance if it is heavy enough.
125   isResonanceSave     = (m0Save > MINMASSRESONANCE);
126
127   // A particle may decay if it is shortlived enough.
128   mayDecaySave        = (tau0Save < MAXTAU0FORDECAY); 
129
130   // A particle by default has no external decays.
131   doExternalDecaySave = false;
132
133   // A particle is invisible if in current table of such.
134   isVisibleSave = true;
135   for (int i = 0; i < INVISIBLENUMBER; ++i) 
136     if (idSave == INVISIBLETABLE[i]) isVisibleSave = false;  
137
138   // Normally a resonance should not have width forced to fixed value.
139   doForceWidthSave  = false; 
140
141   // Set up constituent masses.
142   setConstituentMass();
143
144   // No Breit-Wigner mass selection before initialized.
145   modeBWnow = 0;
146
147 }
148
149 //--------------------------------------------------------------------------
150
151 // Find out if a particle is a hadron.
152 // Only covers normal hadrons, not e.g. R-hadrons.
153
154 bool ParticleDataEntry::isHadron() const {
155
156   if (idSave <= 100 || (idSave >= 1000000 && idSave <= 9000000)
157     || idSave >= 9900000) return false;
158   if (idSave == 130 || idSave == 310) return true;  
159   if (idSave%10 == 0 || (idSave/10)%10 == 0 || (idSave/100)%10 == 0) 
160     return false;
161   return true;
162
163 }
164
165 //--------------------------------------------------------------------------
166
167 // Find out if a particle is a meson.
168 // Only covers normal hadrons, not e.g. R-hadrons.
169
170 bool ParticleDataEntry::isMeson() const {
171
172   if (idSave <= 100 || (idSave >= 1000000 && idSave <= 9000000)
173     || idSave >= 9900000) return false;
174   if (idSave == 130 || idSave == 310) return true;  
175   if (idSave%10 == 0 || (idSave/10)%10 == 0 || (idSave/100)%10 == 0 
176     || (idSave/1000)%10 != 0) return false;
177   return true;
178
179 }
180
181 //--------------------------------------------------------------------------
182
183 // Find out if a particle is a baryon.
184 // Only covers normal hadrons, not e.g. R-hadrons.
185
186 bool ParticleDataEntry::isBaryon() const {
187
188   if (idSave <= 1000 || (idSave >= 1000000 && idSave <= 9000000)
189     || idSave >= 9900000) return false;
190   if (idSave%10 == 0 || (idSave/10)%10 == 0 || (idSave/100)%10 == 0 
191     || (idSave/1000)%10 == 0) return false;
192   return true;
193   
194
195 }
196
197 //--------------------------------------------------------------------------
198
199 // Extract the heaviest (= largest id)  quark in a hadron.
200
201 int ParticleDataEntry::heaviestQuark(int idIn) const {
202
203   if (!isHadron()) return 0;
204   int hQ = 0;
205   
206   // Meson.
207   if ( (idSave/1000)%10 == 0 ) {
208     hQ = (idSave/100)%10;
209     if (idSave == 130) hQ = 3;
210     if (hQ%2 == 1) hQ = -hQ;
211
212   // Baryon.
213   } else hQ = (idSave/1000)%10;
214
215   // Done.
216   return (idIn > 0) ? hQ : -hQ;
217
218 }
219
220 //--------------------------------------------------------------------------
221
222 // Calculate three times baryon number, i.e. net quark - antiquark number.
223
224 int ParticleDataEntry::baryonNumberType(int idIn) const {
225
226   // Quarks.
227   if (isQuark()) return (idIn > 0) ? 1 : -1; 
228
229   // Diquarks
230   if (isDiquark()) return (idIn > 0) ? 2 : -2;  
231   
232   // Baryons.
233   if (isBaryon()) return (idIn > 0) ? 3 : -3; 
234
235   // Done.
236   return 0;
237
238 }
239
240 //--------------------------------------------------------------------------
241
242 // Prepare the Breit-Wigner mass selection by precalculating 
243 // frequently-used expressions.
244
245 void ParticleDataEntry::initBWmass() {
246
247   // Find Breit-Wigner mode for current particle.
248   modeBWnow = particleDataPtr->modeBreitWigner;
249   if ( mWidthSave < NARROWMASS || (mMaxSave > mMinSave      
250     && mMaxSave - mMinSave < NARROWMASS) ) modeBWnow = 0;
251   if (modeBWnow == 0) return;
252
253   // Find atan expressions to be used in random mass selection.
254   if (modeBWnow < 3) { 
255     atanLow = atan( 2. * (mMinSave - m0Save) / mWidthSave );
256     double atanHigh = (mMaxSave > mMinSave) 
257       ? atan( 2. * (mMaxSave - m0Save) / mWidthSave ) : 0.5 * M_PI;
258     atanDif = atanHigh - atanLow;
259   } else {
260     atanLow = atan( (pow2(mMinSave) - pow2(m0Save))
261       / (m0Save * mWidthSave) );
262     double atanHigh = (mMaxSave > mMinSave)
263       ? atan( (pow2(mMaxSave) - pow2(m0Save)) / (m0Save * mWidthSave) )
264       : 0.5 * M_PI;
265     atanDif = atanHigh - atanLow;
266   }
267
268   // Done if no threshold factor.
269   if (modeBWnow%2 == 1) return;
270
271   // Find average mass threshold for threshold-factor correction.
272   double bRatSum = 0.;
273   double mThrSum = 0;
274   for (int i = 0; i < int(channels.size()); ++i) 
275   if (channels[i].onMode() >= 0) {
276     bRatSum += channels[i].bRatio();
277     double mChannelSum = 0.;
278     for (int j = 0; j < channels[i].multiplicity(); ++j)
279       mChannelSum += particleDataPtr->m0( channels[i].product(j) );
280     mThrSum += channels[i].bRatio() * mChannelSum;
281   }
282   mThr = (bRatSum == 0.) ? 0. : mThrSum / bRatSum;
283
284   // Switch off Breit-Wigner if very close to threshold.
285   if (mThr + NARROWMASS > m0Save) {
286     modeBWnow = 0;
287     bool knownProblem = false;
288     for (int i = 0; i < 3; ++i) if (idSave == KNOWNNOWIDTH[i]) 
289       knownProblem = true;
290     if (!knownProblem) {
291       ostringstream osWarn;
292       osWarn << "for id = " << idSave;
293       particleDataPtr->infoPtr->errorMsg("Warning in ParticleDataEntry::"
294         "initBWmass: switching off width", osWarn.str(), true);
295     }
296   }
297
298 }
299
300 //--------------------------------------------------------------------------
301
302 // Function to give mass of a particle, either at the nominal value
303 // or picked according to a (linear or quadratic) Breit-Wigner. 
304
305 double ParticleDataEntry::mass() {
306
307   // Nominal value.
308   if (modeBWnow == 0) return m0Save;
309   double mNow, m2Now;
310
311   // Mass according to a Breit-Wigner linear in m.
312   if (modeBWnow == 1) {
313      mNow = m0Save + 0.5 * mWidthSave 
314        * tan( atanLow + atanDif * particleDataPtr->rndmPtr->flat() );
315
316   // Ditto, but make Gamma proportional to sqrt(m^2 - m_threshold^2).
317   } else if (modeBWnow == 2) {
318     double mWidthNow, fixBW, runBW;
319     double m0ThrS = m0Save*m0Save - mThr*mThr;
320     do {
321       mNow = m0Save + 0.5 * mWidthSave 
322         * tan( atanLow + atanDif * particleDataPtr->rndmPtr->flat() );
323       mWidthNow = mWidthSave * sqrtpos( (mNow*mNow - mThr*mThr) / m0ThrS ); 
324       fixBW = mWidthSave / (pow2(mNow - m0Save) + pow2(0.5 * mWidthSave));
325       runBW = mWidthNow / (pow2(mNow - m0Save) + pow2(0.5 * mWidthNow));  
326     } while (runBW < particleDataPtr->rndmPtr->flat() 
327       * particleDataPtr->maxEnhanceBW * fixBW);
328        
329   // Mass according to a Breit-Wigner quadratic in m.
330   } else if (modeBWnow == 3) {
331     m2Now = m0Save*m0Save + m0Save * mWidthSave 
332       * tan( atanLow + atanDif * particleDataPtr->rndmPtr->flat() );
333     mNow = sqrtpos( m2Now);
334        
335   // Ditto, but m_0 Gamma_0 -> m Gamma(m) with threshold factor as above.
336   } else {
337     double mwNow, fixBW, runBW;
338     double m2Ref = m0Save * m0Save; 
339     double mwRef = m0Save * mWidthSave; 
340     double m2Thr = mThr * mThr;
341     do {
342       m2Now = m2Ref + mwRef * tan( atanLow + atanDif 
343         * particleDataPtr->rndmPtr->flat() );
344       mNow = sqrtpos( m2Now);
345       mwNow = mNow * mWidthSave 
346         * sqrtpos( (m2Now - m2Thr) / (m2Ref - m2Thr) );
347       fixBW = mwRef / (pow2(m2Now - m2Ref) + pow2(mwRef));
348       runBW = mwNow / (pow2(m2Now - m2Ref) + pow2(mwNow));
349     } while (runBW < particleDataPtr->rndmPtr->flat() 
350       * particleDataPtr->maxEnhanceBW * fixBW);
351   }
352
353   // Done.
354   return mNow;
355 }
356
357 //--------------------------------------------------------------------------
358
359 // Function to calculate running mass at given mass scale.
360
361 double ParticleDataEntry::mRun(double mHat) {
362
363   // Except for six quarks return nominal mass.
364   if (idSave > 6) return m0Save;
365   double mQRun = particleDataPtr->mQRun[idSave];
366   double Lam5  = particleDataPtr->Lambda5Run; 
367
368   // For d, u, s quarks start running at 2 GeV (RPP 2006 p. 505).
369   if (idSave < 4) return mQRun * pow ( log(2. / Lam5) 
370     / log(max(2., mHat) / Lam5), 12./23.);
371
372   // For c, b and t quarks start running at respective mass.
373   return mQRun * pow ( log(mQRun / Lam5) 
374     / log(max(mQRun, mHat) / Lam5), 12./23.);
375
376 }
377
378 //--------------------------------------------------------------------------
379
380 // Rescale all branching ratios to assure normalization to unity.
381
382 void ParticleDataEntry::rescaleBR(double newSumBR) {
383
384   // Sum up branching ratios. Find rescaling factor. Rescale.
385   double oldSumBR = 0.;
386   for ( int i = 0; i < int(channels.size()); ++ i) 
387     oldSumBR += channels[i].bRatio(); 
388   double rescaleFactor = newSumBR / oldSumBR;
389   for ( int i = 0; i < int(channels.size()); ++ i) 
390     channels[i].rescaleBR(rescaleFactor); 
391
392 }
393
394 //--------------------------------------------------------------------------
395
396 // Prepare to pick a decay channel.
397
398 bool ParticleDataEntry::preparePick(int idSgn, double mHat, int idInFlav) {
399
400   // Reset sum of allowed widths/branching ratios. 
401   currentBRSum = 0.;
402
403   // For resonances the widths are calculated dynamically.
404   if (isResonanceSave && resonancePtr != 0) {
405     resonancePtr->widthStore(idSgn, mHat, idInFlav);
406     for (int i = 0; i < int(channels.size()); ++i) 
407       currentBRSum += channels[i].currentBR();
408     
409   // Else use normal fixed branching ratios.
410   } else {
411     int onMode;
412     double currentBRNow;
413     for (int i = 0; i < int(channels.size()); ++i) {
414       onMode = channels[i].onMode();
415       currentBRNow = 0.;
416       if ( idSgn > 0 && (onMode == 1 || onMode == 2) ) 
417         currentBRNow = channels[i].bRatio();
418       else if ( idSgn < 0 && (onMode == 1 || onMode == 3) ) 
419         currentBRNow = channels[i].bRatio();
420       channels[i].currentBR(currentBRNow);
421       currentBRSum += currentBRNow;
422     }
423   }
424
425   // Failure if no channels found with positive branching ratios.
426   return (currentBRSum > 0.);
427
428 }
429
430 //--------------------------------------------------------------------------
431
432 // Pick a decay channel according to branching ratios from preparePick.
433
434 DecayChannel& ParticleDataEntry::pickChannel() {
435
436   // Find channel in table.
437   int size = channels.size();
438   double rndmBR = currentBRSum * particleDataPtr->rndmPtr->flat();
439   int i = -1;
440   do rndmBR -= channels[++i].currentBR();
441   while (rndmBR > 0. && i < size);
442
443   // Emergency if no channel found. Done.
444   if (i == size) i = 0;
445   return channels[i];
446
447 }
448
449 //--------------------------------------------------------------------------
450
451 // Access methods stored in ResonanceWidths. Could have been 
452 // inline in .h, except for problems with forward declarations.
453
454 void ParticleDataEntry::setResonancePtr(
455   ResonanceWidths* resonancePtrIn) {
456   if (resonancePtr == resonancePtrIn) return;
457   if (resonancePtr != 0) delete resonancePtr; 
458   resonancePtr = resonancePtrIn;
459 }
460
461 void ParticleDataEntry::resInit(Info* infoPtrIn, Settings* settingsPtrIn, 
462   ParticleData* particleDataPtrIn, Couplings* couplingsPtrIn) {
463   if (resonancePtr != 0) resonancePtr->init(infoPtrIn, settingsPtrIn, 
464   particleDataPtrIn, couplingsPtrIn);
465 }  
466
467 double ParticleDataEntry::resWidth(int idSgn, double mHat, int idIn, 
468   bool openOnly, bool setBR) {
469   return (resonancePtr != 0) ? resonancePtr->width( idSgn, mHat, 
470     idIn, openOnly, setBR) : 0.;
471 }
472
473 double ParticleDataEntry::resWidthOpen(int idSgn, double mHat, int idIn) {
474   return (resonancePtr != 0) ? resonancePtr->widthOpen( idSgn, mHat, idIn) 
475   : 0.;
476 }
477
478 double ParticleDataEntry::resWidthStore(int idSgn, double mHat, int idIn) {
479   return (resonancePtr != 0) ? resonancePtr->widthStore( idSgn, mHat, idIn) 
480   : 0.;
481 }
482
483 double ParticleDataEntry::resOpenFrac(int idSgn) {
484   return (resonancePtr != 0) ? resonancePtr->openFrac(idSgn) : 1.;
485 }  
486
487 double ParticleDataEntry::resWidthRescaleFactor() {
488   return (resonancePtr != 0) ? resonancePtr->widthRescaleFactor() : 1.;
489 }  
490
491 double ParticleDataEntry::resWidthChan(double mHat, int idAbs1, 
492   int idAbs2) {    
493   return (resonancePtr != 0) ? resonancePtr->widthChan( mHat, idAbs1, 
494     idAbs2) : 0.;
495 }
496
497 //--------------------------------------------------------------------------
498
499 // Constituent masses for (d, u, s, c, b) quarks and diquarks.
500 // Hardcoded in CONSTITUENTMASSTABLE so that they are not overwritten
501 // by mistake, and separated from the "normal" masses. 
502 // Called both by setDefaults and setM0 so kept as separate method.
503   
504 void ParticleDataEntry::setConstituentMass() {
505
506   // Equate with the normal masses as default guess.
507   constituentMassSave = m0Save;
508
509   // Quark masses trivial. Also gluon mass.
510   if (idSave < 6) constituentMassSave = CONSTITUENTMASSTABLE[idSave];
511   if (idSave == 21) constituentMassSave = CONSTITUENTMASSTABLE[9];
512  
513   // Diquarks as simple sum of constituent quarks.  
514   if (idSave > 1000 && idSave < 10000 && (idSave/10)%10 == 0) {
515     int id1 = idSave/1000;
516     int id2 = (idSave/100)%10;
517     if (id1 <6 && id2 < 6) constituentMassSave 
518       = CONSTITUENTMASSTABLE[id1] + CONSTITUENTMASSTABLE[id2];
519   }
520
521 }
522
523 //--------------------------------------------------------------------------
524
525 // Convert string to lowercase for case-insensitive comparisons.
526
527 string ParticleDataEntry::toLower(const string& nameConv) { 
528
529   string temp(nameConv);
530   for (int i = 0; i < int(temp.length()); ++i) 
531     temp[i] = std::tolower(temp[i]); 
532   return temp; 
533
534 }
535
536 //==========================================================================
537
538 // ParticleData class.
539 // This class holds a map of all ParticleDataEntries,
540 // each entry containing info on a particle species.
541
542 //--------------------------------------------------------------------------
543
544 // Get data to be distributed among particles during setup.
545 // Note: this routine is called twice. Firstly from init(...), but
546 // the data should not be used at that point, so is likely overkill.
547 // Secondly, from initWidths, after user has had time to change.
548
549 void ParticleData::initCommon() {
550
551   // Mass generation: fixed mass or linear/quadratic Breit-Wigner.
552   modeBreitWigner = settingsPtr->mode("ParticleData:modeBreitWigner");
553
554   // Maximum tail enhancement when adding threshold factor to Breit-Wigner.
555   maxEnhanceBW    = settingsPtr->parm("ParticleData:maxEnhanceBW");
556  
557   // Find initial MSbar masses for five light flavours.
558   mQRun[1]        = settingsPtr->parm("ParticleData:mdRun");  
559   mQRun[2]        = settingsPtr->parm("ParticleData:muRun");  
560   mQRun[3]        = settingsPtr->parm("ParticleData:msRun");  
561   mQRun[4]        = settingsPtr->parm("ParticleData:mcRun");  
562   mQRun[5]        = settingsPtr->parm("ParticleData:mbRun");
563   mQRun[6]        = settingsPtr->parm("ParticleData:mtRun");
564
565   // Find Lambda5 value to use in running of MSbar masses.
566   double alphaSvalue = settingsPtr->parm("ParticleData:alphaSvalueMRun");
567   AlphaStrong alphaS;
568   alphaS.init( alphaSvalue, 1); 
569   Lambda5Run = alphaS.Lambda5();  
570
571 }
572
573 //--------------------------------------------------------------------------
574
575 // Initialize pointer for particles to the full database, the Breit-Wigners 
576 // of normal hadrons and the ResonanceWidths of resonances. For the latter 
577 // the order of initialization is essential to get secondary widths right.
578
579 void ParticleData::initWidths( vector<ResonanceWidths*> resonancePtrs) {
580
581   // Initialize some common data.
582   initCommon();
583
584   // Pointer to database and Breit-Wigner mass initialization for each 
585   // particle.
586   ResonanceWidths* resonancePtr = 0;
587   for (map<int, ParticleDataEntry>::iterator pdtEntry = pdt.begin(); 
588     pdtEntry != pdt.end(); ++pdtEntry) {
589     ParticleDataEntry& pdtNow = pdtEntry->second;
590     pdtNow.initPtr( this);
591     pdtNow.initBWmass(); 
592
593     // Remove any existing resonances. 
594     resonancePtr = pdtNow.getResonancePtr();
595     if (resonancePtr != 0) pdtNow.setResonancePtr(0);
596   }
597
598   // Begin set up new resonance objects. 
599   // Z0, W+- and top are almost always needed.
600   resonancePtr = new ResonanceGmZ(23);
601   setResonancePtr( 23, resonancePtr);
602   resonancePtr = new ResonanceW(24);
603   setResonancePtr( 24, resonancePtr);
604   resonancePtr = new ResonanceTop(6);
605   setResonancePtr(  6, resonancePtr);
606
607   // Higgs in SM.
608   if (!settingsPtr->flag("Higgs:useBSM")) { 
609     resonancePtr = new ResonanceH(0, 25);
610     setResonancePtr( 25, resonancePtr);
611
612   // Higgses in BSM.
613   } else {
614     resonancePtr = new ResonanceH(1, 25);
615     setResonancePtr( 25, resonancePtr);
616     resonancePtr = new ResonanceH(2, 35);
617     setResonancePtr( 35, resonancePtr);
618     resonancePtr = new ResonanceH(3, 36);
619     setResonancePtr( 36, resonancePtr);
620     resonancePtr = new ResonanceHchg(37);
621     setResonancePtr( 37, resonancePtr);
622   }
623
624   // A fourth generation: b', t', tau', nu'_tau.
625   resonancePtr = new ResonanceFour(7);
626   setResonancePtr( 7, resonancePtr);
627   resonancePtr = new ResonanceFour(8);
628   setResonancePtr( 8, resonancePtr);
629   resonancePtr = new ResonanceFour(17);
630   setResonancePtr( 17, resonancePtr);
631   resonancePtr = new ResonanceFour(18);
632   setResonancePtr( 18, resonancePtr);
633
634   // New gauge bosons: Z', W', R.
635   resonancePtr = new ResonanceZprime(32);
636   setResonancePtr( 32, resonancePtr);
637   resonancePtr = new ResonanceWprime(34);
638   setResonancePtr( 34, resonancePtr);
639   resonancePtr = new ResonanceRhorizontal(41);
640   setResonancePtr( 41, resonancePtr);
641
642   // A leptoquark.
643   resonancePtr = new ResonanceLeptoquark(42);
644   setResonancePtr( 42, resonancePtr);
645
646   // Supersymmetry
647   //  - Squarks
648   for(int i = 1; i < 7; i++){
649     resonancePtr = new ResonanceSquark(1000000 + i);
650     setResonancePtr( 1000000 + i, resonancePtr);
651     resonancePtr = new ResonanceSquark(2000000 + i);
652     setResonancePtr( 2000000 + i, resonancePtr);
653   }
654
655   //  - Sleptons and sneutrinos
656   for(int i = 1; i < 7; i++){
657     resonancePtr = new ResonanceSlepton(1000010 + i);
658     setResonancePtr( 1000010 + i, resonancePtr);
659     resonancePtr = new ResonanceSlepton(2000010 + i);
660     setResonancePtr( 2000010 + i, resonancePtr);
661   }
662
663   // - Gluino
664   resonancePtr = new ResonanceGluino(1000021);
665   setResonancePtr( 1000021, resonancePtr);
666
667   // - Charginos
668   resonancePtr = new ResonanceChar(1000024);
669   setResonancePtr( 1000024, resonancePtr);
670   resonancePtr = new ResonanceChar(1000037);
671   setResonancePtr( 1000037, resonancePtr);
672
673   // - Neutralinos
674   resonancePtr = new ResonanceNeut(1000022);
675   setResonancePtr( 1000022, resonancePtr);
676   resonancePtr = new ResonanceNeut(1000023);
677   setResonancePtr( 1000023, resonancePtr);
678   resonancePtr = new ResonanceNeut(1000025);
679   setResonancePtr( 1000025, resonancePtr);
680   resonancePtr = new ResonanceNeut(1000035);
681   setResonancePtr( 1000035, resonancePtr);
682   resonancePtr = new ResonanceNeut(1000045);
683   setResonancePtr( 1000045, resonancePtr);
684
685   // Excited quarks and leptons.
686   for (int i = 1; i < 7; ++i) {
687     resonancePtr = new ResonanceExcited(4000000 + i);
688     setResonancePtr( 4000000 + i, resonancePtr);
689   }
690   for (int i = 11; i < 17; ++i) {
691     resonancePtr = new ResonanceExcited(4000000 + i);
692     setResonancePtr( 4000000 + i, resonancePtr);
693   }
694
695   // An excited graviton/gluon in extra-dimensional scenarios.
696   resonancePtr = new ResonanceGraviton(5100039);
697   setResonancePtr( 5100039, resonancePtr);
698   resonancePtr = new ResonanceKKgluon(5100021);
699   setResonancePtr( 5100021, resonancePtr);
700
701   // A left-right-symmetric scenario with new righthanded neutrinos,
702   // righthanded gauge bosons and doubly charged Higgses.
703   resonancePtr = new ResonanceNuRight(9900012);
704   setResonancePtr( 9900012, resonancePtr);
705   resonancePtr = new ResonanceNuRight(9900014);
706   setResonancePtr( 9900014, resonancePtr);
707   resonancePtr = new ResonanceNuRight(9900016);
708   setResonancePtr( 9900016, resonancePtr);
709   resonancePtr = new ResonanceZRight(9900023);
710   setResonancePtr( 9900023, resonancePtr);
711   resonancePtr = new ResonanceWRight(9900024);
712   setResonancePtr( 9900024, resonancePtr);
713   resonancePtr = new ResonanceHchgchgLeft(9900041);
714   setResonancePtr( 9900041, resonancePtr);
715   resonancePtr = new ResonanceHchgchgRight(9900042);
716   setResonancePtr( 9900042, resonancePtr);
717
718   // Attach user-defined external resonances and do basic initialization.
719   for (int i = 0; i < int(resonancePtrs.size()); ++i) {
720     int idNow = resonancePtrs[i]->id(); 
721     resonancePtrs[i]->initBasic(idNow);
722     setResonancePtr( idNow, resonancePtrs[i]);
723   }
724
725   // Set up lists to order resonances in ascending mass.
726   vector<int>    idOrdered;
727   vector<double> m0Ordered;
728
729   // Put Z0 and W+- first, since known to be SM and often off-shell.
730   idOrdered.push_back(23);
731   m0Ordered.push_back(m0(23));
732   idOrdered.push_back(24);
733   m0Ordered.push_back(m0(24));
734   
735   // Loop through particle table to find resonances.
736   for (map<int, ParticleDataEntry>::iterator pdtEntry = pdt.begin(); 
737     pdtEntry != pdt.end(); ++pdtEntry) {
738     ParticleDataEntry& pdtNow = pdtEntry->second;
739     int idNow = pdtNow.id();
740
741     // Set up a simple default object for uninitialized resonances.
742     if (pdtNow.isResonance() && pdtNow.getResonancePtr() == 0) { 
743       resonancePtr = new ResonanceGeneric(idNow);
744       setResonancePtr( idNow, resonancePtr);
745     }
746
747     // Insert resonances in ascending mass, to respect decay hierarchies.
748     if (pdtNow.getResonancePtr() != 0 && idNow != 23 && idNow != 24) {
749       double m0Now = pdtNow.m0();
750       idOrdered.push_back(idNow);
751       m0Ordered.push_back(m0Now);
752       for (int i = int(idOrdered.size()) - 2; i > 1; --i) {
753         if (m0Ordered[i] < m0Now) break;
754         swap( idOrdered[i], idOrdered[i + 1]);
755         swap( m0Ordered[i], m0Ordered[i + 1]);
756       }
757     }
758   }
759
760   // Initialize the resonances in ascending mass order.
761   for (int i = 0; i < int(idOrdered.size()); ++i) resInit( idOrdered[i]);
762   
763 }
764
765 //--------------------------------------------------------------------------
766
767 // Read in database from specific XML file (which may refer to others).
768
769 bool ParticleData::readXML(string inFile, bool reset) {
770
771   // Normally reset whole database before beginning.
772   if (reset) {pdt.clear(); isInit = false;}
773  
774   // List of files to be checked.
775   vector<string> files;
776   files.push_back(inFile);
777
778   // Loop over files. Open them for read.
779   for (int i = 0; i < int(files.size()); ++i) {
780     const char* cstring = files[i].c_str();
781     ifstream is(cstring);  
782
783     // Check that instream is OK.
784     if (!is.good()) {
785       infoPtr->errorMsg("Error in ParticleData::readXML:"
786         " did not find file", files[i]);
787       return false;
788     }
789
790     // Read in one line at a time.
791     particlePtr = 0;
792     string line;
793     while ( getline(is, line) ) {
794
795       // Get first word of a line.
796       istringstream getfirst(line);
797       string word1;
798       getfirst >> word1;
799     
800       // Check for occurence of a particle. Add any continuation lines.
801       if (word1 == "<particle") {
802         while (line.find(">") == string::npos) {   
803           string addLine;
804           getline(is, addLine);
805           line += addLine;
806         } 
807
808         // Read in particle properties.
809         int idTmp          = intAttributeValue( line, "id");
810         string nameTmp     = attributeValue( line, "name");
811         string antiNameTmp = attributeValue( line, "antiName");
812         if (antiNameTmp == "") antiNameTmp = "void";
813         int spinTypeTmp    = intAttributeValue( line, "spinType");
814         int chargeTypeTmp  = intAttributeValue( line, "chargeType");
815         int colTypeTmp     = intAttributeValue( line, "colType");
816         double m0Tmp       = doubleAttributeValue( line, "m0");
817         double mWidthTmp   = doubleAttributeValue( line, "mWidth");
818         double mMinTmp     = doubleAttributeValue( line, "mMin");
819         double mMaxTmp     = doubleAttributeValue( line, "mMax");
820         double tau0Tmp     = doubleAttributeValue( line, "tau0");
821
822         // Erase if particle already exists.
823         if (isParticle(idTmp)) pdt.erase(idTmp);
824
825         // Store new particle. Save pointer, to be used for decay channels.
826         addParticle( idTmp, nameTmp, antiNameTmp, spinTypeTmp, chargeTypeTmp, 
827           colTypeTmp, m0Tmp, mWidthTmp, mMinTmp, mMaxTmp, tau0Tmp);
828         particlePtr = particleDataEntryPtr(idTmp);
829  
830       // Check for occurence of a decay channel. Add any continuation lines. 
831       } else if (word1 == "<channel") {
832         while (line.find(">") == string::npos) {   
833           string addLine;
834           getline(is, addLine);
835           line += addLine;
836         } 
837
838         // Read in channel properties - products so far only as a string.
839         int onMode      = intAttributeValue( line, "onMode");
840         double bRatio   = doubleAttributeValue( line, "bRatio");
841         int meMode      = intAttributeValue( line, "meMode");
842         string products = attributeValue( line, "products");
843  
844         // Read in decay products from stream. Must have at least one.
845         istringstream prodStream(products);
846         int prod0 = 0; int prod1 = 0; int prod2 = 0; int prod3 = 0;
847         int prod4 = 0; int prod5 = 0; int prod6 = 0; int prod7 = 0;
848         prodStream >> prod0 >> prod1 >> prod2 >> prod3 >> prod4 >> prod5 
849                    >> prod6 >> prod7;   
850         if (prod0 == 0) {
851           infoPtr->errorMsg("Error in ParticleData::readXML:"
852             " incomplete decay channel", line);
853           return false;
854         }
855
856         // Store new channel (if particle already known).
857         if (particlePtr == 0) {
858           infoPtr->errorMsg("Error in ParticleData::readXML:"
859             " orphan decay channel", line);
860           return false;
861         }
862         particlePtr->addChannel(onMode, bRatio, meMode, prod0, prod1, 
863           prod2, prod3, prod4, prod5, prod6, prod7);  
864     
865       // Check for occurence of a file also to be read.
866       } else if (word1 == "<file") {
867         string file = attributeValue(line, "name");
868         if (file == "") {
869           infoPtr->errorMsg("Warning in ParticleData::readXML:"
870             " skip unrecognized file name", line);
871         } else files.push_back(file);
872       }
873
874     // End of loop over lines in input file and loop over files.
875     };
876   };
877
878   // All particle data at this stage defines baseline original.
879   if (reset) for (map<int, ParticleDataEntry>::iterator pdtEntry 
880     = pdt.begin(); pdtEntry != pdt.end(); ++pdtEntry) {
881     particlePtr = &pdtEntry->second;
882     particlePtr->setHasChanged(false);
883   }
884
885   // Done.
886   isInit = true;
887   return true;
888
889 }
890
891 //--------------------------------------------------------------------------
892  
893 // Print out complete database in numerical order as an XML file.
894
895 void ParticleData::listXML(string outFile) {
896
897   // Convert file name to ofstream.
898     const char* cstring = outFile.c_str();
899     ofstream os(cstring);  
900
901   // Iterate through the particle data table.
902   for (map<int, ParticleDataEntry>::iterator pdtEntry 
903     = pdt.begin(); pdtEntry != pdt.end(); ++pdtEntry) {
904     particlePtr = &pdtEntry->second;
905
906     // Print particle properties.
907     os << "<particle id=\"" << particlePtr->id() << "\""
908        << " name=\"" << particlePtr->name() << "\"";
909     if (particlePtr->hasAnti()) 
910       os << " antiName=\"" << particlePtr->name(-1) << "\"";
911     os << " spinType=\"" << particlePtr->spinType() << "\"" 
912        << " chargeType=\"" << particlePtr->chargeType() << "\""
913        << " colType=\"" << particlePtr->colType() << "\"\n";
914     // Pick format for mass and width based on mass value.
915     double m0Now = particlePtr->m0();
916     if (m0Now == 0 || (m0Now > 0.1 && m0Now < 1000.)) 
917       os << fixed << setprecision(5);
918     else  os << scientific << setprecision(3); 
919     os << "          m0=\"" << m0Now << "\"";
920     if (particlePtr->mWidth() > 0.) 
921       os << " mWidth=\"" << particlePtr->mWidth() << "\""
922          << " mMin=\"" << particlePtr->mMin() << "\""
923          << " mMax=\"" << particlePtr->mMax() << "\"";
924     if (particlePtr->tau0() > 0.) os << scientific << setprecision(5) 
925          << " tau0=\"" << particlePtr->tau0() << "\"";
926     os << ">\n";
927
928     // Loop through the decay channel table for each particle.
929     if (particlePtr->sizeChannels() > 0) {
930       for (int i = 0; i < particlePtr->sizeChannels(); ++i) {
931         const DecayChannel& channel = particlePtr->channel(i);
932         int mult = channel.multiplicity();
933
934         // Print decay channel properties.
935         os << " <channel onMode=\"" << channel.onMode() << "\"" 
936            << fixed << setprecision(7)
937            << " bRatio=\"" << channel.bRatio() << "\"";
938         if (channel.meMode() > 0) 
939           os << " meMode=\"" << channel.meMode() << "\"";  
940         os << " products=\"";
941         for (int j = 0; j < mult; ++j) {
942           os << channel.product(j);
943           if (j < mult - 1) os << " ";
944         }
945
946         // Finish off line and loop over allowed decay channels.
947         os  << "\"/>\n";
948       }
949     }
950         
951     // Finish off existing particle.
952     os << "</particle>\n\n";   
953
954   } 
955
956 }
957
958 //--------------------------------------------------------------------------
959
960 // Read in database from specific free format file.
961
962 bool ParticleData::readFF(string inFile, bool reset) {
963
964   // Normally reset whole database before beginning.
965   if (reset) {pdt.clear(); isInit = false;}
966
967   // Open file for read and check that instream is OK. 
968   const char* cstring = inFile.c_str();
969   ifstream is(cstring);  
970   if (!is.good()) {
971     infoPtr->errorMsg("Error in ParticleData::readFF:"
972       " did not find file", inFile);
973     return false;
974   }
975
976   // Read in one line at a time.
977   particlePtr = 0;
978   string line;
979   bool readParticle = false;
980   while ( getline(is, line) ) {
981
982     // Empty lines begins new particle. 
983     if (line.find_first_not_of(" \n\t\v\b\r\f\a") == string::npos) {
984       readParticle = true;
985       continue;
986     } 
987  
988     // Prepare to use standard read from line.
989     istringstream readLine(line);
990
991     // Read in a line with particle information.
992     if (readParticle) {
993
994       // Properties to be read. 
995       int    idTmp;
996       string nameTmp, antiNameTmp;
997       int    spinTypeTmp, chargeTypeTmp, colTypeTmp;
998       double m0Tmp, mWidthTmp, mMinTmp, mMaxTmp, tau0Tmp;
999       string mayTmp;
1000
1001       // Do the reading.
1002       readLine >> idTmp >> nameTmp >> antiNameTmp >> spinTypeTmp 
1003                >> chargeTypeTmp >> colTypeTmp >> m0Tmp >> mWidthTmp
1004                >> mMinTmp >> mMaxTmp >> tau0Tmp;          
1005
1006       // Error printout if something went wrong.
1007       if (!readLine) {
1008         infoPtr->errorMsg("Error in ParticleData::readFF:"
1009           " incomplete particle", line);
1010         return false;
1011       }
1012
1013       // Erase if particle already exists.
1014       if (isParticle(idTmp)) pdt.erase(idTmp);
1015
1016       // Store new particle. Save pointer, to be used for decay channels.
1017       addParticle( idTmp, nameTmp, antiNameTmp, spinTypeTmp, chargeTypeTmp, 
1018         colTypeTmp, m0Tmp, mWidthTmp, mMinTmp, mMaxTmp, tau0Tmp);
1019       particlePtr = particleDataEntryPtr(idTmp);
1020       readParticle = false;
1021
1022     // Read in a line with decay channel information.
1023     } else {
1024        
1025       // Properties to be read. 
1026       int    onMode = 0;
1027       double bRatio = 0.;
1028       int    meMode = 0;
1029       int prod0 = 0; int prod1 = 0; int prod2 = 0; int prod3 = 0;
1030       int prod4 = 0; int prod5 = 0; int prod6 = 0; int prod7 = 0;
1031   
1032       // Read in data from stream. Need at least one decay product.
1033       readLine >> onMode >> bRatio >> meMode >> prod0;
1034       if (!readLine) {
1035         infoPtr->errorMsg("Error in ParticleData::readFF:"
1036           " incomplete decay channel", line);
1037         return false;
1038       }
1039       readLine >> prod1 >> prod2 >> prod3 >> prod4 >> prod5 
1040         >> prod6  >> prod7;   
1041
1042       // Store new channel.
1043       if (particlePtr == 0) {
1044         infoPtr->errorMsg("Error in ParticleData::readFF:"
1045           " orphan decay channel", line);
1046         return false;
1047       }
1048       particlePtr->addChannel(onMode, bRatio, meMode, prod0, prod1, 
1049         prod2, prod3, prod4, prod5, prod6, prod7); 
1050
1051     }
1052
1053   // End of while loop over lines in the file.
1054   }
1055
1056
1057   // Done.
1058   isInit = true;
1059   return true;
1060    
1061 }  
1062
1063 //--------------------------------------------------------------------------
1064   
1065 // Print out complete database in numerical order as a free format file.
1066
1067 void ParticleData::listFF(string outFile) {
1068
1069   // Convert file name to ofstream.
1070     const char* cstring = outFile.c_str();
1071     ofstream os(cstring);  
1072
1073   // Iterate through the particle data table. 
1074   for (map<int, ParticleDataEntry>::iterator pdtEntry 
1075     = pdt.begin(); pdtEntry != pdt.end(); ++pdtEntry) {
1076     particlePtr = &pdtEntry->second;
1077
1078     // Pick format for mass and width based on mass value.
1079     double m0Now = particlePtr->m0();
1080     if (m0Now == 0 || (m0Now > 0.1 && m0Now < 1000.)) 
1081       os << fixed << setprecision(5);
1082     else os << scientific << setprecision(3); 
1083
1084     // Print particle properties.
1085     os << "\n" << setw(8) << particlePtr->id() << "  " 
1086        << left << setw(16) << particlePtr->name() << " " 
1087        << setw(16) << particlePtr->name(-1) << "  " 
1088        << right << setw(2) << particlePtr->spinType() << "  " 
1089        << setw(2) << particlePtr->chargeType() << "  " 
1090        << setw(2) << particlePtr->colType() << " " 
1091        << setw(10) << particlePtr->m0() << " " 
1092        << setw(10) << particlePtr->mWidth() << " " 
1093        << setw(10) << particlePtr->mMin() << " "
1094        << setw(10) << particlePtr->mMax() << " " 
1095        << scientific << setprecision(5) 
1096        << setw(12) << particlePtr->tau0() << "\n";
1097
1098     // Loop through the decay channel table for each particle.
1099     if (particlePtr->sizeChannels() > 0) {
1100       for (int i = 0; i < particlePtr->sizeChannels(); ++i) {
1101         const DecayChannel& channel = particlePtr->channel(i);
1102         os << "               " << setw(6) << channel.onMode()
1103            << "  " << fixed << setprecision(7) << setw(10) 
1104            << channel.bRatio() << "  " 
1105            << setw(3) << channel.meMode() << " ";
1106         for (int j = 0; j < channel.multiplicity(); ++j) 
1107           os << setw(8) << channel.product(j) << " ";
1108         os << "\n";  
1109       }
1110     }  
1111
1112   } 
1113
1114 }
1115
1116 //--------------------------------------------------------------------------
1117
1118 // Read in updates from a character string, like a line of a file. 
1119 // Is used by readString (and readFile) in Pythia.
1120
1121   bool ParticleData::readString(string lineIn, bool warn, ostream& os) {
1122
1123   // If empty line then done.
1124   if (lineIn.find_first_not_of(" \n\t\v\b\r\f\a") == string::npos) return true;
1125
1126   // Take copy that will be modified.
1127   string line = lineIn;
1128
1129   // If first character is not a digit then taken to be a comment.
1130   int firstChar = line.find_first_not_of(" \n\t\v\b\r\f\a");
1131   if (!isdigit(line[firstChar])) return true; 
1132
1133   // Replace colons and equal signs by blanks to make parsing simpler.
1134   for ( int j = 0; j < int(line.size()); ++ j) 
1135      if (line[j] == ':' || line[j] == '=') line[j] = ' ';
1136
1137   // Get particle id and property name.
1138   int    idTmp;
1139   string property;
1140   istringstream getWord(line);
1141   getWord >> idTmp >> property;
1142   property = toLower(property);
1143   
1144   // Check that valid particle.
1145   if ( (!isParticle(idTmp) && property  != "all" && property  != "new") 
1146   || idTmp <= 0) {
1147     if (warn) os << "\n Warning: input particle not found in Particle"
1148       << " Data Table; skip:\n   " << lineIn << "\n";
1149     return false;
1150   }
1151
1152   // Identify particle property and read + set its value, case by case.
1153   if (property == "name") {
1154     string nameTmp;
1155     getWord >> nameTmp;    
1156     pdt[idTmp].setName(nameTmp);
1157     return true; 
1158   }
1159   if (property == "antiname") {
1160     string antiNameTmp;
1161     getWord >> antiNameTmp;    
1162     pdt[idTmp].setAntiName(antiNameTmp);
1163     return true; 
1164   }
1165   if (property == "names") {
1166     string nameTmp, antiNameTmp; 
1167     getWord >> nameTmp >> antiNameTmp;
1168     pdt[idTmp].setNames(nameTmp, antiNameTmp); 
1169     return true; 
1170   }
1171   if (property == "spintype") {
1172     int spinTypeTmp;
1173     getWord >> spinTypeTmp;
1174     pdt[idTmp].setSpinType(spinTypeTmp); 
1175     return true; 
1176   }
1177   if (property == "chargetype") {
1178     int chargeTypeTmp;
1179     getWord >> chargeTypeTmp;
1180     pdt[idTmp].setChargeType(chargeTypeTmp); 
1181     return true; 
1182   }
1183   if (property == "coltype") {
1184     int colTypeTmp;
1185     getWord >> colTypeTmp;
1186     pdt[idTmp].setColType(colTypeTmp); 
1187     return true; 
1188   }
1189   if (property == "m0") {
1190     double m0Tmp;
1191     getWord >> m0Tmp;
1192     pdt[idTmp].setM0(m0Tmp); 
1193     return true; 
1194   }
1195   if (property == "mwidth") {
1196     double mWidthTmp;
1197     getWord >> mWidthTmp;
1198     pdt[idTmp].setMWidth(mWidthTmp); 
1199     return true; 
1200   }
1201   if (property == "mmin") {
1202     double mMinTmp;
1203     getWord >> mMinTmp;
1204     pdt[idTmp].setMMin(mMinTmp); 
1205     return true; 
1206   }
1207   if (property == "mmax") {
1208     double mMaxTmp;
1209     getWord >> mMaxTmp;
1210     pdt[idTmp].setMMax(mMaxTmp); 
1211     return true; 
1212   }
1213   if (property == "tau0") {
1214     double tau0Tmp;
1215     getWord >> tau0Tmp;
1216     pdt[idTmp].setTau0(tau0Tmp); 
1217     return true; 
1218   }
1219   if (property == "isresonance") {
1220     string isresTmp;
1221     getWord >> isresTmp;
1222     bool isResonanceTmp = boolString(isresTmp);
1223     pdt[idTmp].setIsResonance(isResonanceTmp);
1224     return true; 
1225   }
1226   if (property == "maydecay") {
1227     string mayTmp;
1228     getWord >> mayTmp;
1229     bool mayDecayTmp = boolString(mayTmp);
1230     pdt[idTmp].setMayDecay(mayDecayTmp);
1231     return true; 
1232   }  
1233   if (property == "doexternaldecay") {
1234     string extdecTmp;
1235     getWord >> extdecTmp;
1236     bool doExternalDecayTmp = boolString(extdecTmp);
1237     pdt[idTmp].setDoExternalDecay(doExternalDecayTmp);
1238     return true; 
1239   }
1240   if (property == "isvisible") {
1241     string isvisTmp;
1242     getWord >> isvisTmp;
1243     bool isVisibleTmp = boolString(isvisTmp);
1244     pdt[idTmp].setIsVisible(isVisibleTmp);
1245     return true; 
1246   }       
1247   if (property == "doforcewidth") {
1248     string doforceTmp;
1249     getWord >> doforceTmp;
1250     bool doForceWidthTmp = boolString(doforceTmp);
1251     pdt[idTmp].setDoForceWidth(doForceWidthTmp);
1252     return true; 
1253   }       
1254    
1255   // Addition or complete replacement of a particle.
1256   if (property == "all" || property == "new") {
1257
1258     // Default values for properties to be read. 
1259     string nameTmp       = "void";
1260     string antiNameTmp   = "void";
1261     int    spinTypeTmp   = 0;
1262     int    chargeTypeTmp = 0;
1263     int    colTypeTmp    = 0;
1264     double m0Tmp         = 0.;
1265     double mWidthTmp     = 0.;
1266     double mMinTmp       = 0.;
1267     double mMaxTmp       = 0.;
1268     double tau0Tmp       = 0.;
1269
1270     // Read in data from stream.
1271     getWord >> nameTmp >> antiNameTmp >> spinTypeTmp >> chargeTypeTmp 
1272             >> colTypeTmp >> m0Tmp >> mWidthTmp >> mMinTmp >> mMaxTmp 
1273             >> tau0Tmp;   
1274
1275     // To keep existing decay channels, only overwrite particle data.
1276     if (property == "all" && isParticle(idTmp)) {
1277       setAll( idTmp, nameTmp, antiNameTmp, spinTypeTmp, chargeTypeTmp, 
1278         colTypeTmp, m0Tmp, mWidthTmp, mMinTmp, mMaxTmp, tau0Tmp);   
1279
1280     // Else start over completely from scratch.
1281     } else {
1282       if (isParticle(idTmp)) pdt.erase(idTmp);
1283       addParticle( idTmp, nameTmp, antiNameTmp, spinTypeTmp, chargeTypeTmp, 
1284         colTypeTmp, m0Tmp, mWidthTmp, mMinTmp, mMaxTmp, tau0Tmp);   
1285     }
1286     return true;
1287   }
1288
1289   // Set onMode of all decay channels in one go.
1290   if (property == "onmode") {
1291       int    onMode = 0;
1292       string onModeIn;
1293       getWord >> onModeIn;
1294       // For onMode allow the optional possibility of Bool input.
1295       if (isdigit(onModeIn[0])) {
1296         istringstream getOnMode(onModeIn);
1297         getOnMode >> onMode;
1298       } else onMode = (boolString(onModeIn)) ? 1 : 0;
1299     for (int i = 0; i < pdt[idTmp].sizeChannels(); ++i) 
1300       pdt[idTmp].channel(i).onMode(onMode);
1301     return true; 
1302   } 
1303
1304   // Selective search for matching decay channels.
1305   int matchKind = 0;
1306   if (property == "offifany" || property == "onifany" || 
1307     property == "onposifany" || property == "onnegifany") matchKind = 1;
1308   if (property == "offifall" || property == "onifall" || 
1309     property == "onposifall" || property == "onnegifall") matchKind = 2;
1310   if (property == "offifmatch" || property == "onifmatch" || 
1311     property == "onposifmatch" || property == "onnegifmatch") matchKind = 3;
1312   if (matchKind > 0) {
1313     int onMode = 0;
1314     if (property == "onifany" || property == "onifall"
1315       || property == "onifmatch") onMode = 1;
1316     if (property == "onposifany" || property == "onposifall"
1317       || property == "onposifmatch") onMode = 2;
1318     if (property == "onnegifany" || property == "onnegifall"
1319       || property == "onnegifmatch") onMode = 3;
1320
1321     // Read in particles to match.
1322     vector<int> idToMatch;
1323     int idRead;
1324     for ( ; ; ) {
1325       getWord >> idRead;
1326       if (!getWord) break;
1327       idToMatch.push_back(abs(idRead));
1328     }   
1329     int nToMatch = idToMatch.size();
1330   
1331     // Loop over all decay channels.
1332     for (int i = 0; i < pdt[idTmp].sizeChannels(); ++i) {
1333       int multi = pdt[idTmp].channel(i).multiplicity();
1334
1335       // Look for any match at all.
1336       if (matchKind == 1) {      
1337         bool foundMatch = false;
1338         for (int j = 0; j < multi; ++j) {        
1339           int idNow =  abs(pdt[idTmp].channel(i).product(j));
1340           for (int k = 0; k < nToMatch; ++k) 
1341           if (idNow == idToMatch[k]) {foundMatch = true; break;}
1342           if (foundMatch) break;
1343         }
1344         if (foundMatch) pdt[idTmp].channel(i).onMode(onMode); 
1345
1346       // Look for match of all products provided.
1347       } else {
1348         int nUnmatched = nToMatch;
1349         if (multi < nToMatch);
1350         else if (multi > nToMatch && matchKind == 3);    
1351         else {
1352           vector<int> idUnmatched;
1353           for (int k = 0; k < nToMatch; ++k) 
1354             idUnmatched.push_back(idToMatch[k]);
1355           for (int j = 0; j < multi; ++j) {        
1356             int idNow =  abs(pdt[idTmp].channel(i).product(j));
1357             for (int k = 0; k < nUnmatched; ++k) 
1358             if (idNow == idUnmatched[k]) {
1359               idUnmatched[k] = idUnmatched[--nUnmatched];
1360               break;
1361             }
1362             if (nUnmatched == 0) break;
1363           }
1364         }
1365         if (nUnmatched == 0) pdt[idTmp].channel(i).onMode(onMode); 
1366       }
1367     }
1368     return true;
1369   }
1370
1371   // Rescale all branching ratios by common factor.
1372   if (property == "rescalebr") {
1373     double factor;
1374     getWord >> factor;
1375     pdt[idTmp].rescaleBR(factor); 
1376     return true; 
1377   }   
1378
1379   // Reset decay table in preparation for new input.
1380   if (property == "onechannel") pdt[idTmp].clearChannels();
1381
1382   // Add or change a decay channel: get channel number and new property.
1383   if (property == "addchannel" || property == "onechannel" 
1384     || isdigit(property[0])) {
1385     int channel;
1386     if (property == "addchannel" || property == "onechannel") {
1387       pdt[idTmp].addChannel(); 
1388       channel = pdt[idTmp].sizeChannels() - 1; 
1389       property = "all"; 
1390     } else{ 
1391       istringstream getChannel(property);
1392       getChannel >> channel;
1393       getWord >> property;
1394       property = toLower(property);
1395     }
1396
1397     // Check that channel exists.
1398     if (channel < 0 || channel >= pdt[idTmp].sizeChannels()) return false;   
1399   
1400     // Find decay channel property and value, case by case.
1401     // At same time also do case where all should be replaced.
1402     if (property == "onmode" || property == "all") {
1403       int    onMode = 0;
1404       string onModeIn;
1405       getWord >> onModeIn;
1406       // For onMode allow the optional possibility of Bool input.
1407       if (isdigit(onModeIn[0])) {
1408         istringstream getOnMode(onModeIn);
1409         getOnMode >> onMode;
1410       } else onMode = (boolString(onModeIn)) ? 1 : 0;
1411       pdt[idTmp].channel(channel).onMode(onMode); 
1412       if (property == "onmode") return true; 
1413     }
1414     if (property == "bratio" || property == "all") {
1415       double bRatio;
1416       getWord >> bRatio;
1417       pdt[idTmp].channel(channel).bRatio(bRatio); 
1418       if (property == "bratio") return true; 
1419     }
1420     if (property == "memode" || property == "all") {
1421       int meMode;
1422       getWord >> meMode;
1423       pdt[idTmp].channel(channel).meMode(meMode); 
1424       if (property == "memode") return true; 
1425     }    
1426
1427     // Scan for products until end of line.  
1428     if (property == "products" || property == "all") {
1429       int nProd = 0;
1430       for (int iProd = 0; iProd < 8; ++iProd) {
1431         int idProd;
1432         getWord >> idProd;
1433         if (!getWord) break;
1434         pdt[idTmp].channel(channel).product(iProd, idProd);
1435         ++nProd;
1436       }   
1437       for (int iProd = nProd; iProd < 8; ++iProd) 
1438         pdt[idTmp].channel(channel).product(iProd, 0);
1439       pdt[idTmp].channel(channel).multiplicity(nProd);
1440       return true; 
1441     }
1442
1443     // Rescale an existing branching ratio.
1444     if (property == "rescalebr") {
1445       double factor;
1446       getWord >> factor;
1447       pdt[idTmp].channel(channel).rescaleBR(factor); 
1448       return true; 
1449     }        
1450   }
1451
1452   // Return false if failed to recognize property.
1453   if (warn) os << "\n Warning: input property not found in Particle"
1454     << " Data Table; skip:\n   " << lineIn << "\n";
1455   return false;
1456
1457 }
1458
1459 //--------------------------------------------------------------------------
1460  
1461 // Print out complete or changed table of database in numerical order.
1462
1463 void ParticleData::list(bool changedOnly, bool changedRes, ostream& os) {
1464
1465   // Table header; output for bool as off/on.
1466   if (!changedOnly) {
1467     os << "\n --------  PYTHIA Particle Data Table (complete)  --------"
1468        << "------------------------------------------------------------"
1469        << "--------------\n \n";
1470
1471   } else { 
1472     os << "\n --------  PYTHIA Particle Data Table (changed only)  ----"
1473        << "------------------------------------------------------------" 
1474        << "--------------\n \n";
1475   }
1476   os << "      id   name            antiName         spn chg col      m0"
1477      << "        mWidth      mMin       mMax       tau0    res dec ext "
1478      << "vis wid\n             no onMode   bRatio   meMode     products \n";
1479
1480   // Iterate through the particle data table. Option to skip unchanged.
1481   int nList = 0;
1482   for (map<int, ParticleDataEntry>::iterator pdtEntry 
1483     = pdt.begin(); pdtEntry != pdt.end(); ++pdtEntry) {
1484     particlePtr = &pdtEntry->second;
1485     if ( !changedOnly || particlePtr->hasChanged() ||
1486       ( changedRes && particlePtr->getResonancePtr() != 0 ) ) {
1487
1488       // Pick format for mass and width based on mass value.
1489       double m0Now = particlePtr->m0();
1490       if (m0Now == 0 || (m0Now > 0.1 && m0Now < 1000.)) 
1491         os << fixed << setprecision(5);
1492       else os << scientific << setprecision(3); 
1493
1494       // Print particle properties.
1495       ++nList;
1496       string antiNameTmp = particlePtr->name(-1);
1497       if (antiNameTmp == "void") antiNameTmp = " ";
1498       os << "\n" << setw(8) << particlePtr->id() << "  " 
1499          << left << setw(16) << particlePtr->name() << " " 
1500          << setw(16) << antiNameTmp << "  " 
1501          << right << setw(2) << particlePtr->spinType() << "  " 
1502          << setw(2) << particlePtr->chargeType() << "  " 
1503          << setw(2) << particlePtr->colType() << " " 
1504          << setw(10) << particlePtr->m0() << " " 
1505          << setw(10) << particlePtr->mWidth() << " " 
1506          << setw(10) << particlePtr->mMin() << " " 
1507          << setw(10) << particlePtr->mMax() << " "
1508          << scientific << setprecision(5) 
1509          << setw(12) << particlePtr->tau0() << "  " << setw(2)
1510          << particlePtr->isResonance() << "  " << setw(2) 
1511          << (particlePtr->mayDecay() && particlePtr->canDecay()) 
1512          << "  " << setw(2) << particlePtr->doExternalDecay() << "  "
1513          << setw(2) << particlePtr->isVisible()<< "  "
1514          << setw(2) << particlePtr->doForceWidth() << "\n";
1515
1516       // Loop through the decay channel table for each particle.
1517       if (particlePtr->sizeChannels() > 0) {
1518         for (int i = 0; i < int(particlePtr->sizeChannels()); ++i) {
1519           const DecayChannel& channel = particlePtr->channel(i);
1520           os << "          "  << setprecision(7) 
1521              << setw(5) << i 
1522              << setw(6) << channel.onMode() 
1523              << fixed<< setw(12) << channel.bRatio() 
1524              << setw(5) << channel.meMode() << " ";
1525           for (int j = 0; j < channel.multiplicity(); ++j) 
1526             os << setw(8) << channel.product(j) << " ";
1527           os << "\n"; 
1528         } 
1529       }
1530     }  
1531
1532   } 
1533
1534   // End of loop over database contents.
1535   if (changedOnly && nList == 0) os << "\n no particle data has been "
1536     << "changed from its default value \n";
1537   os << "\n --------  End PYTHIA Particle Data Table  -----------------"
1538      << "--------------------------------------------------------------"
1539      << "----------\n" << endl;
1540
1541 }
1542
1543 //--------------------------------------------------------------------------
1544  
1545 // Print out partial table of database in input order.
1546
1547 void ParticleData::list(vector<int> idList, ostream& os) {
1548
1549   // Table header; output for bool as off/on.
1550   os << "\n --------  PYTHIA Particle Data Table (partial)  ---------"
1551      << "------------------------------------------------------------"
1552      << "--------------\n \n";
1553   os << "      id   name            antiName         spn chg col      m0"
1554      << "        mWidth      mMin       mMax       tau0    res dec ext "
1555      << "vis wid\n             no onMode   bRatio   meMode     products \n";
1556
1557   // Iterate through the given list of input particles.
1558   for (int i = 0; i < int(idList.size()); ++i) {
1559     particlePtr = particleDataEntryPtr(idList[i]);
1560
1561     // Pick format for mass and width based on mass value.
1562     double m0Now = particlePtr->m0();
1563     if (m0Now == 0 || (m0Now > 0.1 && m0Now < 1000.)) 
1564       os << fixed << setprecision(5);
1565     else os << scientific << setprecision(3); 
1566
1567     // Print particle properties.
1568     string antiNameTmp = particlePtr->name(-1);
1569     if (antiNameTmp == "void") antiNameTmp = " ";
1570     os << "\n" << setw(8) << particlePtr->id() << "  " 
1571        << left << setw(16) << particlePtr->name() << " " 
1572        << setw(16) << antiNameTmp << "  " 
1573        << right << setw(2) << particlePtr->spinType() << "  " 
1574        << setw(2) << particlePtr->chargeType() << "  " 
1575        << setw(2) << particlePtr->colType() << " " 
1576        << setw(10) << particlePtr->m0() << " " 
1577        << setw(10) << particlePtr->mWidth() << " " 
1578        << setw(10) << particlePtr->mMin() << " " 
1579        << setw(10) << particlePtr->mMax() << " "
1580        << scientific << setprecision(5) 
1581        << setw(12) << particlePtr->tau0() << "  " << setw(2)
1582        << particlePtr->isResonance() << "  " << setw(2) 
1583        << (particlePtr->mayDecay() && particlePtr->canDecay()) 
1584        << "  " << setw(2) << particlePtr->doExternalDecay() << "  "
1585        << setw(2) << particlePtr->isVisible() << "  "
1586        << setw(2) << particlePtr->doForceWidth() << "\n";
1587
1588     // Loop through the decay channel table for each particle.
1589     if (particlePtr->sizeChannels() > 0) {
1590       for (int j = 0; j < int(particlePtr->sizeChannels()); ++j) {
1591         const DecayChannel& channel = particlePtr->channel(j);
1592         os << "          "  << setprecision(7) 
1593            << setw(5) << j 
1594            << setw(6) << channel.onMode() 
1595            << fixed<< setw(12) << channel.bRatio() 
1596            << setw(5) << channel.meMode() << " ";
1597         for (int k = 0; k < channel.multiplicity(); ++k) 
1598           os << setw(8) << channel.product(k) << " ";
1599         os << "\n";  
1600       }
1601     }  
1602
1603   } 
1604
1605   // End of loop over database contents.
1606   os << "\n --------  End PYTHIA Particle Data Table  -----------------"
1607      << "--------------------------------------------------------------"
1608      << "----------\n" << endl;
1609
1610 }
1611
1612 //--------------------------------------------------------------------------
1613  
1614 // Check that table makes sense: e.g. consistent names and mass ranges, 
1615 // that branching ratios sum to unity, that charge is conserved and 
1616 // that phase space is open in each channel.
1617 // verbosity = 0: mimimal amount of checks, e.g. that no channels open.
1618 //           = 1: further warning if individual channels closed
1619 //                (except for resonances). 
1620 //           = 2:  also print branching-ratio-averaged threshold mass.
1621 //      = 11, 12: as 1, 2, but include resonances in detailed checks.
1622
1623 void ParticleData::checkTable(int verbosity, ostream& os) {
1624
1625   // Header.
1626   os << "\n --------  PYTHIA Check of Particle Data Table  ------------"
1627      <<"------\n\n";
1628   int nErr = 0;
1629
1630   // Loop through all particles.
1631   for (map<int, ParticleDataEntry>::iterator pdtEntry 
1632   = pdt.begin(); pdtEntry != pdt.end(); ++pdtEntry) {
1633     particlePtr = &pdtEntry->second;
1634   
1635     // Extract some particle properties. Set some flags.
1636     int    idNow          = particlePtr->id();
1637     bool   hasAntiNow     = particlePtr->hasAnti();
1638     int    spinTypeNow    = particlePtr->spinType();
1639     int    chargeTypeNow  = particlePtr->chargeType();
1640     int    baryonTypeNow  = particlePtr->baryonNumberType();
1641     double m0Now          = particlePtr->m0();
1642     double mMinNow        = particlePtr->mMin();
1643     double mMaxNow        = particlePtr->mMax();
1644     double mWidthNow      = particlePtr->mWidth();
1645     double tau0Now        = particlePtr->tau0();
1646     bool   isResonanceNow = particlePtr->isResonance();
1647     bool   hasPrinted     = false;
1648     bool   studyCloser    = verbosity > 10 || !isResonanceNow;
1649
1650     // Check that particle name consistent with charge information.
1651     string particleName = particlePtr->name(1);
1652     if (particleName.size() > 16) {
1653       os << " Warning: particle " << idNow << " has name " << particleName 
1654          << " of length " << particleName.size() << "\n"; 
1655       hasPrinted = true;
1656       ++nErr;
1657     }   
1658     int nPos = 0;
1659     int nNeg = 0;
1660     for (int i = 0; i < int(particleName.size()); ++i) {
1661       if (particleName[i] == '+') ++nPos;
1662       if (particleName[i] == '-') ++nNeg;
1663     }
1664     if ( (nPos > 0 && nNeg > 0) || ( nPos + nNeg > 0 
1665       && 3 * (nPos - nNeg) != chargeTypeNow )) {
1666       os << " Warning: particle " << idNow << " has name " << particleName 
1667          << " inconsistent with charge type " << chargeTypeNow << "\n"; 
1668       hasPrinted = true;
1669       ++nErr;
1670     }  
1671
1672     // Check that antiparticle name consistent with charge information.
1673     if (hasAntiNow) {
1674       particleName = particlePtr->name(-1);
1675       if (particleName.size() > 16) {
1676         os << " Warning: particle " << idNow << " has name " << particleName 
1677            << " of length " << particleName.size() << "\n"; 
1678         hasPrinted = true;
1679         ++nErr;
1680       }   
1681       nPos = 0;
1682       nNeg = 0;
1683       for (int i = 0; i < int(particleName.size()); ++i) {
1684         if (particleName[i] == '+') ++nPos;
1685         if (particleName[i] == '-') ++nNeg;
1686       }
1687       if ( (nPos > 0 && nNeg > 0) || ( nPos + nNeg > 0 
1688         && 3 * (nPos - nNeg) != -chargeTypeNow )) {
1689         os << " Warning: particle " << -idNow << " has name " 
1690            << particleName << " inconsistent with charge type " 
1691            << -chargeTypeNow << "\n"; 
1692         hasPrinted = true;
1693         ++nErr;
1694       }  
1695     }
1696
1697     // Check that mass, mass range and width are consistent.
1698     if (particlePtr->useBreitWigner()) {
1699       if (mMinNow > m0Now) {
1700         os << " Error: particle " << idNow << " has mMin " 
1701            << fixed << setprecision(5) << mMinNow 
1702            << " larger than m0 " << m0Now << "\n"; 
1703         hasPrinted = true;
1704         ++nErr;
1705       }  
1706       if (mMaxNow > mMinNow && mMaxNow < m0Now) {
1707         os << " Error: particle " << idNow << " has mMax " 
1708            << fixed << setprecision(5) << mMaxNow 
1709            << " smaller than m0 " << m0Now << "\n"; 
1710         hasPrinted = true;
1711         ++nErr;
1712       }  
1713       if (mMaxNow > mMinNow && mMaxNow - mMinNow < mWidthNow) {
1714         os << " Warning: particle " << idNow << " has mMax - mMin " 
1715            << fixed << setprecision(5) << mMaxNow - mMinNow
1716            << " smaller than mWidth " << mWidthNow << "\n"; 
1717         hasPrinted = true;
1718         ++nErr;
1719       }  
1720     }  
1721
1722     // Check that particle does not both have width and lifetime.
1723     if (mWidthNow > 0. && tau0Now > 0.) {
1724       os << " Warning: particle " << idNow << " has both nonvanishing width " 
1725          << scientific << setprecision(5) << mWidthNow << " and lifetime " 
1726          << tau0Now << "\n"; 
1727       hasPrinted = true;
1728       ++nErr;  
1729     }
1730
1731     // Begin study decay channels.
1732     if (particlePtr->sizeChannels() > 0) {  
1733  
1734       // Loop through all decay channels.
1735       double bRatioSum = 0.;
1736       double bRatioPos = 0.;
1737       double bRatioNeg = 0.;
1738       bool hasPosBR = false;
1739       bool hasNegBR = false;
1740       double threshMass = 0.;
1741       bool openChannel = false;
1742       for (int i = 0; i < particlePtr->sizeChannels(); ++i) {
1743
1744         // Extract channel properties.
1745         int onMode = particlePtr->channel(i).onMode();
1746         double bRatio = particlePtr->channel(i).bRatio();
1747         int meMode = particlePtr->channel(i).meMode();
1748         int mult = particlePtr->channel(i).multiplicity();
1749         int prod[8];
1750         for (int j = 0; j < 8; ++j) 
1751           prod[j] = particlePtr->channel(i).product(j);
1752
1753         // Sum branching ratios. Include off-channels.
1754         if (onMode == 0 || onMode == 1) bRatioSum += bRatio;
1755         else if (onMode == 2) {bRatioPos += bRatio; hasPosBR = true;}
1756         else if (onMode == 3) {bRatioNeg += bRatio; hasNegBR = true;}
1757
1758         // Error printout when unknown decay product code.
1759         for (int j = 0; j < 8; ++j) {
1760           if ( prod[j] != 0 && !isParticle(prod[j]) ) {
1761             os << " Error: unknown decay product for " << idNow 
1762                << " -> " << prod[j] << "\n";
1763             hasPrinted = true;
1764             ++nErr;
1765             continue;
1766           }
1767         }
1768
1769         // Error printout when no decay products or 0 interspersed.
1770         int nLast = 0;
1771         for (int j = 0; j < 8; ++j)
1772           if (prod[j] != 0) nLast = j + 1;
1773         if (mult == 0 || mult != nLast) {
1774           os << " Error: corrupted decay product list for "
1775              <<  particlePtr->id() << " -> ";
1776           for (int j = 0; j < 8; ++j) os << prod[j] << " ";
1777           os << "\n";  
1778           hasPrinted = true;
1779           ++nErr;
1780           continue;
1781         }
1782
1783         // Check charge conservation and open phase space in decay channel.
1784         int chargeTypeSum = -chargeTypeNow;
1785         int baryonTypeSum = -baryonTypeNow;
1786         double avgFinalMass = 0.;
1787         double minFinalMass = 0.;
1788         bool canHandle = true;
1789         for (int j = 0; j < mult; ++j) {
1790           chargeTypeSum += chargeType( prod[j] );
1791           baryonTypeSum += baryonNumberType( prod[j] );
1792           avgFinalMass += m0( prod[j] );
1793           minFinalMass += m0Min( prod[j] );
1794           if (prod[j] == 81 || prod[j] == 82 || prod[j] == 83) 
1795             canHandle = false;
1796         }
1797         threshMass += bRatio * avgFinalMass;
1798
1799         // Error printout when charge or baryon number not conserved.
1800         if (chargeTypeSum != 0 && canHandle) {
1801           os << " Error: 3*charge changed by " << chargeTypeSum
1802              << " in " << idNow << " -> ";
1803           for (int j = 0; j < mult; ++j) os << prod[j] << " ";
1804           os << "\n";  
1805           hasPrinted = true;
1806           ++nErr;
1807           continue;
1808         }
1809         if ( baryonTypeSum != 0 && canHandle && particlePtr->isHadron() ) {
1810           os << " Error: 3*baryon number changed by " << baryonTypeSum
1811              << " in " << idNow << " -> ";
1812           for (int j = 0; j < mult; ++j) os << prod[j] << " ";
1813           os << "\n";  
1814           hasPrinted = true;
1815           ++nErr;
1816           continue;
1817         }
1818
1819         // Begin check that some matrix elements are used correctly.
1820         bool correctME = true;
1821
1822         // Check matrix element mode 0: recommended not into partons.
1823         if (meMode == 0 && !isResonanceNow) {
1824           bool hasPartons = false;
1825           for (int j = 0; j < mult; ++j) {
1826             int idAbs = abs(prod[j]);
1827             if ( idAbs < 10 || idAbs == 21 || idAbs == 81 || idAbs == 82
1828             || idAbs == 83 || (idAbs > 1000 && idAbs < 10000 
1829             && (idAbs/10)%10 == 0) ) hasPartons = true;
1830           }
1831           if (hasPartons) correctME = false;
1832         }
1833
1834         // Check matrix element mode 1: rho/omega -> pi+ pi- pi0.
1835         bool useME1 = ( mult == 3 && spinTypeNow == 3 && idNow > 100 
1836           && idNow < 1000 
1837           && particlePtr->channel(i).contains(211, -211, 111) );
1838         if ( meMode == 1 && !useME1 ) correctME = false;
1839         if ( meMode != 1 &&  useME1 ) correctME = false;
1840
1841         // Check matrix element mode 2: polarization in V -> PS + PS.
1842         bool useME2 = ( mult == 2 && spinTypeNow == 3  && idNow > 100 
1843           && idNow < 1000 && spinType(prod[0]) == 1 
1844           && spinType(prod[1]) == 1 );   
1845         if ( meMode == 2 && !useME2 ) correctME = false;
1846         if ( meMode != 2 &&  useME2 ) correctME = false;
1847
1848         // Check matrix element mode 11, 12 and 13: Dalitz decay with
1849         // one or more particles in addition to the lepton pair,
1850         // or double Dalitz decay.
1851         bool useME11 = ( mult == 3 && !isResonanceNow
1852           && (prod[1] == 11 || prod[1] == 13 || prod[1] == 15) 
1853           && prod[2] == -prod[1] );   
1854         bool useME12 = ( mult > 3 && !isResonanceNow
1855           && (prod[mult - 2] == 11 || prod[mult - 2] == 13 
1856           || prod[mult - 2] == 15) && prod[mult - 1] == -prod[mult - 2] );   
1857         bool useME13 = ( mult == 4 && !isResonanceNow
1858           && (prod[0] == 11 || prod[0] == 13) && prod[1] == -prod[0]
1859           && (prod[2] == 11 || prod[2] == 13) && prod[3] == -prod[2] );
1860         if (useME13) useME12 = false;
1861         if ( meMode == 11 && !useME11 ) correctME = false;
1862         if ( meMode != 11 &&  useME11 ) correctME = false;
1863         if ( meMode == 12 && !useME12 ) correctME = false;
1864         if ( meMode != 12 &&  useME12 ) correctME = false;
1865         if ( meMode == 13 && !useME13 ) correctME = false;
1866         if ( meMode != 13 &&  useME13 ) correctME = false;
1867
1868         // Check matrix element mode 21: tau -> nu_tau hadrons.
1869         bool useME21 = (idNow == 15 && mult > 2 && prod[0] == 16 
1870           && abs(prod[1]) > 100);
1871         if ( meMode == 21 && !useME21 ) correctME = false;
1872         if ( meMode != 21 &&  useME21 ) correctME = false;  
1873
1874         // Check matrix element mode 22, but only for semileptonic decay.
1875         // For a -> b c d require types u = 2, ubar = -2, d = 1, dbar = -1.
1876         if ( isLepton(prod[0]) && isLepton(prod[1]) ) {
1877           bool useME22 = false;
1878           int typeA = 0;
1879           int typeB = 0;
1880           int typeC = 0;
1881           if (particlePtr->isLepton()) {
1882             typeA = (idNow > 0) ? 1 + (idNow-1)%2 : -1 - (1-idNow)%2;
1883           } else if (particlePtr->isHadron()) {
1884             int hQ = particlePtr->heaviestQuark();
1885             // Special case: for B_c either bbar or c decays.
1886             if (idNow == 541 && heaviestQuark(prod[2]) == -5) hQ = 4;
1887             typeA = (hQ > 0) ? 1 + (hQ-1)%2 : -1 - (1-hQ)%2;
1888           }
1889           typeB = (prod[0] > 0) ? 1 + (prod[0]-1)%2 : -1 - (1-prod[0])%2;
1890           typeC = (prod[1] > 0) ? 1 + (prod[1]-1)%2 : -1 - (1-prod[1])%2;
1891           // Special cases.
1892           if ( (idNow == 130 || idNow == 310) && typeC * typeA < 0) 
1893             typeA = -typeA;
1894           if (mult == 3 && idNow == 2112 && prod[2] == 2212) 
1895             typeA = 3 - typeA;
1896           if (mult == 3 && idNow == 3222 && prod[2] == 3122) 
1897             typeA = 3 - typeA;
1898           if (mult > 2 && typeC == typeA && typeB * typeC < 0 
1899             && (typeB + typeC)%2 != 0) useME22 = true;
1900           if ( meMode == 22 && !useME22 ) correctME = false;
1901           if ( meMode != 22 &&  useME22 ) correctME = false;  
1902         }
1903
1904         // Check for matrix element mode 31.
1905         if (meMode == 31) {
1906           int nGamma = 0;
1907           for (int j = 0; j < mult; ++j) if (prod[j] == 22) ++nGamma;
1908           if (nGamma != 1) correctME = false; 
1909         }   
1910
1911         // Check for unknown mode, or resonance-only mode.
1912         if ( !isResonanceNow && (meMode < 0 || (meMode > 2 && meMode <= 10) 
1913           || (meMode > 13 && meMode <= 20) || (meMode > 23 && meMode <= 30)
1914           || (meMode > 31 && meMode <= 41) || meMode == 51 || meMode == 61
1915           || meMode == 71 || (meMode > 80 && meMode <= 90) 
1916           || (!particlePtr->isOctetHadron() && meMode > 92) ) )
1917           correctME = false;
1918
1919         // Print if incorrect matrix element mode.
1920         if ( !correctME ) {
1921           os << " Warning: meMode " << meMode << " used for "
1922              << idNow << " -> ";
1923           for (int j = 0; j < mult; ++j) os << prod[j] << " ";
1924           os << "\n";  
1925           hasPrinted = true;
1926           ++nErr;
1927         }
1928
1929         // Warning printout when no phase space for decay.
1930         if ( studyCloser && verbosity > 0  && canHandle && onMode > 0
1931           && particlePtr->m0Min() - minFinalMass < 0. ) {
1932           if (particlePtr->m0Max() - minFinalMass < 0.)
1933             os << " Error: decay never possible for ";
1934           else  os << " Warning: decay sometimes not possible for ";
1935           os << idNow << " -> ";
1936           for (int j = 0; j < mult; ++j) os << prod[j] << " ";
1937           os << "\n";  
1938           hasPrinted = true;
1939           ++nErr;
1940         }
1941
1942         // End loop over decay channels. 
1943         if (onMode > 0 && bRatio > 0.) openChannel = true;
1944       }
1945
1946       // Optional printout of threshold.
1947       if (verbosity%10 > 1 && particlePtr->useBreitWigner()) {
1948         threshMass /= bRatioSum;
1949         os << " Info: particle " << idNow << fixed << setprecision(5)  
1950            << " has average mass threshold " << threshMass 
1951            << " while mMin is " << mMinNow << "\n"; 
1952         hasPrinted = true;
1953       }
1954  
1955       // Error printout when no acceptable decay channels found.
1956       if (studyCloser && !openChannel) { 
1957         os << " Error: no acceptable decay channel found for particle " 
1958            << idNow << "\n"; 
1959         hasPrinted = true;
1960         ++nErr;
1961       }      
1962
1963       // Warning printout when branching ratios do not sum to unity.
1964       if (studyCloser && (!hasAntiNow || (!hasPosBR && !hasNegBR))
1965         && abs(bRatioSum + bRatioPos - 1.) > 1e-8) {
1966         os << " Warning: particle " << idNow  << fixed << setprecision(8)
1967            << " has branching ratio sum " << bRatioSum << "\n"; 
1968         hasPrinted = true;
1969         ++nErr;
1970       } else if (studyCloser && hasAntiNow 
1971         && (abs(bRatioSum + bRatioPos - 1.) > 1e-8 
1972         || abs(bRatioSum + bRatioNeg - 1.) > 1e-8)) {
1973         os << " Warning: particle " << idNow  << fixed << setprecision(8)
1974            << " has branching ratio sum " << bRatioSum + bRatioPos
1975            << " while its antiparticle has " << bRatioSum + bRatioNeg  
1976            << "\n"; 
1977         hasPrinted = true;
1978         ++nErr;  
1979       }  
1980
1981     // End study of decay channels and loop over particles.
1982     }
1983     if (hasPrinted) os << "\n";
1984   }
1985
1986   // Final output. Done.
1987   os << " Total number of errors and warnings is " << nErr << "\n";
1988   os << "\n --------  End PYTHIA Check of Particle Data Table  --------"
1989      << "------\n" << endl;
1990
1991 }
1992
1993 //--------------------------------------------------------------------------
1994
1995 // Return the id of the sequentially next particle stored in table.
1996   
1997 int ParticleData::nextId(int idIn) {
1998
1999   // Return 0 for negative or unknown codes. Return first for 0.
2000   if (idIn < 0 || (idIn > 0 && !isParticle(idIn))) return 0;
2001   if (idIn == 0) return pdt.begin()->first;
2002   
2003   // Find pointer to current particle and step up. Return 0 if impossible. 
2004   map<int, ParticleDataEntry>::const_iterator pdtIn = pdt.find(idIn);
2005   if (pdtIn == pdt.end()) return 0;
2006   return (++pdtIn)->first;
2007
2008 }
2009
2010 //--------------------------------------------------------------------------
2011
2012 // Fractional width associated with open channels of one or two resonances.
2013    
2014 double ParticleData::resOpenFrac(int id1In, int id2In, int id3In) {
2015
2016   // Default value.
2017   double answer = 1.; 
2018  
2019   // First resonance.
2020   if (isParticle(id1In)) answer  = pdt[abs(id1In)].resOpenFrac(id1In);
2021  
2022   // Possibly second resonance.
2023   if (isParticle(id2In)) answer *= pdt[abs(id2In)].resOpenFrac(id2In);
2024  
2025   // Possibly third resonance.
2026   if (isParticle(id3In)) answer *= pdt[abs(id2In)].resOpenFrac(id3In);
2027
2028   // Done.
2029   return answer;
2030
2031 }
2032
2033 //--------------------------------------------------------------------------
2034
2035 // Convert string to lowercase for case-insensitive comparisons.
2036
2037 string ParticleData::toLower(const string& nameConv) { 
2038
2039   string temp(nameConv);
2040   for (int i = 0; i < int(temp.length()); ++i) 
2041     temp[i] = std::tolower(temp[i]); 
2042   return temp; 
2043
2044 }
2045
2046 //--------------------------------------------------------------------------
2047
2048 // Allow several alternative inputs for true/false.
2049
2050 bool ParticleData::boolString(string tag) {
2051
2052   string tagLow = toLower(tag);
2053   return ( tagLow == "true" || tagLow == "1" || tagLow == "on" 
2054   || tagLow == "yes" || tagLow == "ok" ); 
2055
2056 }  
2057
2058 //--------------------------------------------------------------------------
2059
2060 // Extract XML value string following XML attribute.
2061
2062 string ParticleData::attributeValue(string line, string attribute) {
2063
2064   if (line.find(attribute) == string::npos) return "";
2065   int iBegAttri = line.find(attribute); 
2066   int iBegQuote = line.find("\"", iBegAttri + 1);
2067   int iEndQuote = line.find("\"", iBegQuote + 1);
2068   return line.substr(iBegQuote + 1, iEndQuote - iBegQuote - 1);
2069
2070 }
2071
2072 //--------------------------------------------------------------------------
2073
2074 // Extract XML bool value following XML attribute.
2075
2076 bool ParticleData::boolAttributeValue(string line, string attribute) {
2077
2078   string valString = attributeValue(line, attribute);
2079   if (valString == "") return false;
2080   return boolString(valString);   
2081
2082 }
2083
2084 //--------------------------------------------------------------------------
2085
2086 // Extract XML int value following XML attribute.
2087
2088 int ParticleData::intAttributeValue(string line, string attribute) {
2089   string valString = attributeValue(line, attribute);
2090   if (valString == "") return 0; 
2091   istringstream valStream(valString);
2092   int intVal; 
2093   valStream >> intVal; 
2094   return intVal;     
2095
2096 }
2097
2098 //--------------------------------------------------------------------------
2099
2100 // Extract XML double value following XML attribute.
2101
2102 double ParticleData::doubleAttributeValue(string line, string attribute) {
2103   string valString = attributeValue(line, attribute);
2104   if (valString == "") return 0.; 
2105   istringstream valStream(valString);
2106   double doubleVal; 
2107   valStream >> doubleVal; 
2108   return doubleVal;     
2109
2110 }
2111
2112 //==========================================================================
2113
2114 } // end namespace Pythia8