30 return (a.Mass() < b.Mass());
36 if (a.Mass() == b.Mass()) {
37 if (abs(a.PdgId()) != abs(b.PdgId()))
38 return abs(a.PdgId()) < abs(b.PdgId());
39 return (a.PdgId() > b.PdgId());
41 return (a.Mass() < b.Mass());
46 if (abs(a.Charm()) != abs(b.Charm()))
return (abs(a.Charm()) < abs(b.Charm()));
47 if (abs(a.AbsoluteCharm()) != abs(b.AbsoluteCharm()))
return (abs(a.AbsoluteCharm()) < abs(b.AbsoluteCharm()));
48 if (abs(a.BaryonCharge()) != abs(b.BaryonCharge()))
return (abs(a.BaryonCharge()) < abs(b.BaryonCharge()));
49 if (abs(a.Strangeness()) != abs(b.Strangeness()))
return (abs(a.Strangeness()) < abs(b.Strangeness()));
50 if (a.Mass() == b.Mass()) {
51 if (abs(a.PdgId()) != abs(b.PdgId()))
52 return abs(a.PdgId()) < abs(b.PdgId());
53 return (a.PdgId() > b.PdgId());
55 return (a.Mass() < b.Mass());
68 Initialize(ListFiles, DecayFiles, flags, mcut);
77 for (
unsigned int i = 0; i < ret.size(); ++i) {
78 for (
unsigned int j = 0; j < ret[i].mDaughters.size(); ++j) {
79 if (m_PDGtoID.count(-ret[i].mDaughters[j]) > 0) ret[i].mDaughters[j] = -ret[i].mDaughters[j];
93 for (
size_t i = 0; i < m_Particles.size(); ++i) {
94 if (m_Particles[i].Decays().size() != 0) {
97 for (
size_t j = 0; j < m_Particles[i].Decays().size(); ++j) {
99 m_Particles[i].Decays()[j].mPole = m_Particles[i].Mass();
101 std::string tname =
"";
105 for (
size_t k = 0; k < m_Particles[i].Decays()[j].mDaughters.size(); ++k) {
106 int tid =
PdgToId(m_Particles[i].Decays()[j].mDaughters[k]);
108 M0 += m_Particles[tid].Mass();
109 tS += max(0., (m_Particles[tid].Degeneracy() - 1.) / 2.);
112 tname += m_Particles[tid].Name();
115 m_Particles[i].Decays()[j].mM0 = M0;
116 m_Particles[i].Decays()[j].mL = abs(max(0., (m_Particles[i].Degeneracy() - 1.) / 2.) - tS);
118 tsumb += m_Particles[i].Decays()[j].mBratio;
119 m_Particles[i].Decays()[j].mBratioAverage = m_Particles[i].Decays()[j].mBratio;
121 if (tname.size() > 0)
122 m_Particles[i].Decays()[j].mChannelName = tname;
125 m_Particles[i].CalculateAndSetDynamicalThreshold();
126 m_Particles[i].FillCoefficientsDynamical();
132 for (
size_t i = 0; i < m_Particles.size(); ++i) {
133 if (m_Particles[i].Decays().size() != 0) {
134 for (
size_t j = 0; j < m_Particles[i].Decays().size(); ++j) {
136 for (
size_t k = 0; k < m_Particles[i].Decays()[j].mDaughters.size(); ++k) {
137 if (
PdgToId(m_Particles[i].Decays()[j].mDaughters[k]) != -1)
138 M0 += m_Particles[
PdgToId(m_Particles[i].Decays()[j].mDaughters[k])].Mass();
140 m_Particles[i].Decays()[j].mM0 = M0;
142 m_Particles[i].FillCoefficients();
149 m_DecayCumulants.resize(m_Particles.size());
150 m_DecayProbabilities.resize(m_Particles.size());
151 for (
size_t i = 0; i < m_Particles.size(); ++i) {
153 m_DecayProbabilities[i].resize(0);
154 m_DecayCumulants[i].resize(0);
156 for (
int i =
static_cast<int>(m_Particles.size()) - 1; i >= 0; i--)
157 if (!m_Particles[i].IsStable()) {
158 GoResonance(i, i, 1.);
161 for (
size_t i = 0; i < m_Particles.size(); ++i) {
164 vector<double> tmp = GoResonanceDecayProbs(DecayContrib.second, i,
true);
165 if (tmp.size() > 1) m_DecayProbabilities[i].push_back(make_pair(tmp, DecayContrib.second));
167 for (
size_t j = 0; j < m_DecayProbabilities[i].size(); ++j) {
168 double tmp = 0., tmp2 = 0., tmp3 = 0., tmp4 = 0.;
169 for (
int jj = 0; jj < static_cast<int>(m_DecayProbabilities[i][j].first.size()); ++jj) {
170 tmp += m_DecayProbabilities[i][j].first[jj] * jj;
171 tmp2 += m_DecayProbabilities[i][j].first[jj] * jj * jj;
172 tmp3 += m_DecayProbabilities[i][j].first[jj] * jj * jj * jj;
173 tmp4 += m_DecayProbabilities[i][j].first[jj] * jj * jj * jj * jj;
175 double n2 = 0., n3 = 0., n4 = 0.;
176 n2 = tmp2 - tmp * tmp;
177 n3 = tmp3 - 3. * tmp2 * tmp + 2. * tmp * tmp * tmp;
178 n4 = tmp4 - 4. * tmp3 * tmp + 6. * tmp2 * tmp * tmp - 3. * tmp * tmp * tmp * tmp - 3. * n2 * n2;
179 vector<double> moments(0);
180 moments.push_back(tmp);
181 moments.push_back(n2);
182 moments.push_back(n3);
183 moments.push_back(n4);
184 m_DecayCumulants[i].push_back(make_pair(moments, m_DecayProbabilities[i][j].second));
188 m_DecayDistributionsMap.resize(m_Particles.size());
189 m_ResonanceFinalStatesDistributions.resize(m_Particles.size());
190 for (
size_t i = 0; i < m_Particles.size(); ++i) {
191 m_ResonanceFinalStatesDistributions[i].resize(0);
192 m_DecayDistributionsMap[i].resize(0);
194 for (
size_t i = 0; i < m_Particles.size(); ++i) {
195 m_ResonanceFinalStatesDistributions[i] = GoResonanceDecayDistributions(i,
true);
198 std::vector< std::vector< std::pair<double, std::vector<int> > > >().swap(m_DecayDistributionsMap);
200 for (
size_t i = 0; i < m_Particles.size(); ++i) {
201 vector<int> nchtyp(0);
204 nchtyp.push_back(-1);
206 m_Particles[i].Nch().resize(0);
207 m_Particles[i].DeltaNch().resize(0);
209 for (
int nti = 0; nti < 3; nti++) {
210 vector<double> prob = GoResonanceDecayProbsCharge(i, nchtyp[nti],
true);
211 double tmp = 0., tmp2 = 0., tmp3 = 0., tmp4 = 0.;
212 for (
int jj = 0; jj < static_cast<int>(prob.size()); ++jj) {
213 tmp += prob[jj] * jj;
214 tmp2 += prob[jj] * jj * jj;
215 tmp3 += prob[jj] * jj * jj * jj;
216 tmp4 += prob[jj] * jj * jj * jj * jj;
218 double n2 = 0., n3 = 0., n4 = 0.;
219 n2 = tmp2 - tmp * tmp;
220 n3 = tmp3 - 3. * tmp2 * tmp + 2. * tmp * tmp * tmp;
221 n4 = tmp4 - 4. * tmp3 * tmp + 6. * tmp2 * tmp * tmp - 3. * tmp * tmp * tmp * tmp - 3. * n2 * n2;
222 m_Particles[i].Nch().push_back(tmp);
223 m_Particles[i].DeltaNch().push_back(n2);
230 void ThermalParticleSystem::GoResonance(
int ind,
int startind,
double BR) {
232 if (ind != startind && DecayContrib.size() > 0 && DecayContrib[DecayContrib.size() - 1].second == startind)
234 DecayContrib[DecayContrib.size() - 1].first += BR;
236 else if (ind != startind)
237 DecayContrib.push_back(make_pair(BR, startind));
239 if (!m_Particles[ind].IsStable()) {
240 for (
size_t i = 0; i < m_Particles[ind].Decays().size(); ++i) {
241 const ParticleDecayChannel& decaychannel = m_Particles[ind].Decays()[i];
242 double tbr = decaychannel.mBratio;
245 tbr = decaychannel.mBratioAverage;
247 for (
size_t j = 0; j < decaychannel.mDaughters.size(); ++j) {
248 if (m_PDGtoID.count(decaychannel.mDaughters[j]) != 0)
249 GoResonance(m_PDGtoID[decaychannel.mDaughters[j]], startind, BR*tbr);
255 std::vector<double> ThermalParticleSystem::GoResonanceDecayProbs(
int ind,
int goalind,
bool firstdecay) {
256 std::vector<double> ret(1, 0.);
257 if (m_Particles[ind].IsStable()) {
258 if (ind == goalind) ret.push_back(1.);
262 else if (ind == goalind) {
269 for (
size_t i = 0; i < m_Particles[ind].Decays().size(); ++i) {
270 double tbr = m_Particles[ind].Decays()[i].mBratio;
272 tbr = m_Particles[ind].Decays()[i].mBratioAverage;
276 for (
size_t j = 0; j < m_Particles[ind].Decays()[i].mDaughters.size(); ++j) {
277 if (m_PDGtoID.count(m_Particles[ind].Decays()[i].mDaughters[j]) != 0) {
278 vector<double> tmp = GoResonanceDecayProbs(m_PDGtoID[m_Particles[ind].Decays()[i].mDaughters[j]], goalind);
279 vector<double> tmp2(tret.size() + tmp.size() - 1, 0.);
280 for (
size_t i1 = 0; i1 < tret.size(); ++i1)
281 for (
size_t i2 = 0; i2 < tmp.size(); ++i2)
282 tmp2[i1 + i2] += tret[i1] * tmp[i2];
286 if (ret.size() < tret.size()) ret.resize(tret.size(), 0.);
287 for (
size_t j = 0; j < tret.size(); ++j)
288 ret[j] += tbr * tret[j];
291 for (
size_t i = 0; i < ret.size(); ++i)
294 for (
size_t i = 0; i < ret.size(); ++i)
295 ret[i] *= 1. / totprob;
298 ret[0] += 1. - totprob;
305 std::vector<double> ThermalParticleSystem::GoResonanceDecayProbsCharge(
int ind,
int nch,
bool firstdecay)
308 int tQ = m_Particles[ind].ElectricCharge();
309 if (nch == 0 && tQ != 0)
311 if (nch == 1 && tQ > 0)
313 if (nch == -1 && tQ < 0)
316 std::vector<double> ret(1, 0.);
317 if (m_Particles[ind].IsStable()) {
318 if (fl) ret.push_back(1.);
325 for (
size_t i = 0; i < m_Particles[ind].Decays().size(); ++i) {
326 double tbr = m_Particles[ind].Decays()[i].mBratio;
328 tbr = m_Particles[ind].Decays()[i].mBratioAverage;
332 for (
size_t j = 0; j < m_Particles[ind].Decays()[i].mDaughters.size(); ++j) {
333 if (m_PDGtoID.count(m_Particles[ind].Decays()[i].mDaughters[j]) != 0) {
334 vector<double> tmp = GoResonanceDecayProbsCharge(m_PDGtoID[m_Particles[ind].Decays()[i].mDaughters[j]], nch);
335 vector<double> tmp2(tret.size() + tmp.size() - 1, 0.);
336 for (
size_t i1 = 0; i1 < tret.size(); ++i1)
337 for (
size_t i2 = 0; i2 < tmp.size(); ++i2)
338 tmp2[i1 + i2] += tret[i1] * tmp[i2];
342 if (ret.size() < tret.size())
343 ret.resize(tret.size(), 0.);
344 for (
size_t j = 0; j < tret.size(); ++j)
345 ret[j] += tbr * tret[j];
348 for (
size_t i = 0; i < ret.size(); ++i)
351 for (
size_t i = 0; i < ret.size(); ++i)
352 ret[i] *= 1. / totprob;
355 ret[0] += 1. - totprob;
364 if (!firstdecay && m_DecayDistributionsMap[ind].size() != 0)
365 return m_DecayDistributionsMap[ind];
368 std::vector< std::pair<double, std::vector<int> > > retorig(1);
369 retorig[0].first = 1.;
370 retorig[0].second = std::vector<int>(m_Particles.size(), 0);
371 retorig[0].second[ind] = 1;
373 std::vector< std::pair<double, std::vector<int> > > ret(0);
375 ThermalParticle &tpart = m_Particles[ind];
377 if (tpart.IsStable()) {
378 m_ResonanceFinalStatesDistributions[ind] = retorig;
382 for (
size_t i = 0; i < tpart.Decays().size(); ++i) {
383 double tbr = tpart.Decays()[i].mBratio;
385 tbr = m_Particles[ind].Decays()[i].mBratioAverage;
387 std::vector< std::pair<double, std::vector<int> > > tret = retorig;
389 for (
size_t j = 0; j < tpart.Decays()[i].mDaughters.size(); ++j) {
390 if (m_PDGtoID.count(tpart.Decays()[i].mDaughters[j]) != 0) {
392 std::vector< std::pair<double, std::vector<int> > > tmp = GoResonanceDecayDistributions(m_PDGtoID[tpart.Decays()[i].mDaughters[j]]);
393 std::vector< std::pair<double, std::vector<int> > > tmp2(tret.size() * tmp.size());
394 for (
int i1 = 0; i1 < static_cast<int>(tret.size()); ++i1) {
395 for (
int i2 = 0; i2 < static_cast<int>(tmp.size()); ++i2) {
396 tmp2[i1*tmp.size() + i2].first = tret[i1].first * tmp[i2].first;
397 tmp2[i1*tmp.size() + i2].second.resize(m_Particles.size());
398 for (
size_t jj = 0; jj < tmp2[i1*tmp.size() + i2].second.size(); ++jj)
399 tmp2[i1*tmp.size() + i2].second[jj] = tret[i1].second[jj] + tmp[i2].second[jj];
405 if (tret.size() > 1500) {
406 printf(
"**WARNING** %s (%lld) Decay Distributions: Too large array, cutting the number of channels to 1500!\n",
407 m_Particles[ind].Name().c_str(),
408 m_Particles[ind].PdgId());
414 for (
size_t j = 0; j < tret.size(); ++j) {
415 tret[j].first *= tbr;
416 ret.push_back(tret[j]);
421 if (ret.size() > 1500) {
422 printf(
"**WARNING** %s (%lld) Decay Distributions: Too large array, cutting the number of channels to 1500!\n",
423 m_Particles[ind].Name().c_str(),
424 m_Particles[ind].PdgId());
429 for (
size_t i = 0; i < ret.size(); ++i)
430 totprob += ret[i].first;
432 for (
size_t i = 0; i < ret.size(); ++i)
433 ret[i].first *= 1. / totprob;
435 else if (totprob < 1.) {
436 double emptyprob = 1. - totprob;
437 ret.push_back(std::make_pair(emptyprob, retorig[0].second));
441 m_DecayDistributionsMap[ind] = ret;
467 bool ThermalParticleSystem::AcceptParticle(
const ThermalParticle& part,
const std::set<std::string>& flags,
double mcut)
const
469 if (mcut >= 0. && part.Mass() > mcut)
482 void ThermalParticleSystem::LoadList(
const std::vector<std::string>& ListFiles,
const std::vector<std::string>& DecayFiles,
const std::set<std::string>& flags,
double mcut)
484 m_NumberOfParticles = 0;
485 m_Particles.resize(0);
488 m_NumBaryons = m_NumCharged = m_NumStrange = m_NumCharmed = 0;
489 m_MaxAbsBaryonNumber = 0;
491 if (ListFiles.size() == 1 && CheckListIsiSS(ListFiles[0])) {
492 LoadListiSS(ListFiles[0], flags, mcut);
496 for(
int i = 0; i < ListFiles.size(); ++i)
501 std::vector<std::string> tDecayFiles = DecayFiles;
502 if (tDecayFiles.size() == 1 && tDecayFiles[0] ==
"")
505 if (tDecayFiles.size() == 0 && ListFiles.size() > 0) {
506 for (
size_t ilist = 0; ilist < ListFiles.size(); ++ilist) {
507 string decayprefix =
"";
508 string decayprefixfile =
"";
510 for (
int i = ListFiles[ilist].size() - 1; i >= 0; --i) {
511 if (ListFiles[ilist][i] ==
'\\' || ListFiles[ilist][i] ==
'/')
513 decayprefix = ListFiles[ilist].substr(0, i + 1);
516 decayprefixfile += ListFiles[ilist][i];
519 reverse(decayprefixfile.begin(), decayprefixfile.end());
522 string DecayFile =
"";
523 if (decayprefixfile.substr(0, 4) ==
"list") {
524 DecayFile = decayprefix +
"decays" + decayprefixfile.substr(4);
527 DecayFile = decayprefix +
"decays.dat";
531 tDecayFiles.push_back(decayprefix +
"decays.dat");
533 tDecayFiles.push_back(DecayFile);
544 std::set<std::string> flags;
548 std::vector<std::string> DecayFiles(0);
550 DecayFiles.push_back(DecayFile);
552 LoadList(std::vector<std::string>(1, InputFile), DecayFiles, flags, mcut);
558 fin.open(InputFile.c_str());
562 fin.getline(tmpc, 2000);
563 string tmp = string(tmpc);
573 fin.seekg(0, ios::beg);
576 LoadTable_NewFormat(fin, flags, mcut);
578 LoadTable_OldFormat(fin, flags, mcut);
585 void ThermalParticleSystem::LoadTable_OldFormat(std::ifstream & fin,
const std::set<std::string>& flags,
double mcut)
591 fin.getline(tmpc, 500);
595 if (fields.size() < 14)
break;
596 int stable, spin, stat, str, bary, chg, charm;
598 double mass, width, threshold, abss, absc, radius = 0.5;
599 string name, decayname =
"";
600 stable = atoi(fields[0].c_str());
604 spin = atoi(fields[3].c_str());
605 stat = atoi(fields[4].c_str());
606 mass = atof(fields[5].c_str());
607 str = atoi(fields[6].c_str());
608 bary = atoi(fields[7].c_str());
609 chg = atoi(fields[8].c_str());
610 charm = atoi(fields[9].c_str());
611 abss = atof(fields[10].c_str());
612 absc = atof(fields[11].c_str());
613 width = atof(fields[12].c_str());
614 threshold = atof(fields[13].c_str());
615 if (fields.size() >= 15) radius = atof(fields[14].c_str());
616 if (fields.size() == 16) decayname = fields[15];
618 ThermalParticle part_candidate =
ThermalParticle(
static_cast<bool>(stable), name, pdgid,
static_cast<double>(spin), stat, mass, str, bary, chg, abss, width, threshold, charm, absc);
621 if (m_PDGtoID.count(pdgid) != 0) {
622 throw std::invalid_argument(
"ThermalParticleSystem::LoadTable_NewFormat: Duplicate pdg code " + std::to_string(pdgid));
624 if (!AcceptParticle(part_candidate, flags, mcut) || m_PDGtoID.count(pdgid) != 0) {
625 fin.getline(tmpc, 500);
630 if (bary != 0) m_NumBaryons++;
631 if (chg != 0) m_NumCharged++;
632 if (str != 0) m_NumStrange++;
633 if (charm != 0) m_NumCharmed++;
634 m_MaxAbsBaryonNumber = max(m_MaxAbsBaryonNumber, abs(bary));
636 m_Particles.push_back(part_candidate);
637 m_PDGtoID[pdgid] = m_Particles.size() - 1;
638 m_NumberOfParticles++;
640 if (GenerateAntiParticles && !(bary == 0 && chg == 0 && str == 0 && charm == 0) && (m_PDGtoID.count(-pdgid) == 0)) {
642 if (bary != 0) m_NumBaryons++;
643 if (chg != 0) m_NumCharged++;
644 if (str != 0) m_NumStrange++;
645 if (charm != 0) m_NumCharmed++;
647 if (bary == 0 && name[name.size() - 1] ==
'+')
648 name[name.size() - 1] =
'-';
649 else if (bary == 0 && name[name.size() - 1] ==
'-')
650 name[name.size() - 1] =
'+';
652 name =
"anti-" + name;
653 m_Particles.push_back(ThermalParticle(
static_cast<bool>(stable), name, -pdgid,
static_cast<double>(spin), stat, mass, -str, -bary, -chg, abss, width, threshold, -charm, absc));
654 m_Particles[m_Particles.size() - 1].SetAntiParticle(
true);
655 m_PDGtoID[-pdgid] = m_Particles.size() - 1;
658 fin.getline(tmpc, 500);
664 void ThermalParticleSystem::LoadTable_NewFormat(std::ifstream & fin,
const std::set<std::string>& flags,
double mcut)
670 fin.getline(cc, 2000);
671 string tmp = string(cc);
673 if (elems.size() < 1 || elems[0].size() == 0)
676 istringstream iss(elems[0]);
678 int stable, stat, str, bary, chg, charm;
680 double mass, degeneracy, width, threshold, abss, absc;
698 ThermalParticle part_candidate = ThermalParticle((
bool)stable, name, pdgid, degeneracy, stat, mass, str, bary, chg, abss, width, threshold, charm, absc);
701 if (m_PDGtoID.count(pdgid) != 0) {
702 throw std::invalid_argument(
"ThermalParticleSystem::LoadTable_NewFormat: Duplicate pdg code " + std::to_string(pdgid));
705 if (!AcceptParticle(part_candidate, flags, mcut) || m_PDGtoID.count(pdgid) != 0)
708 if (bary != 0) m_NumBaryons++;
709 if (chg != 0) m_NumCharged++;
710 if (str != 0) m_NumStrange++;
711 if (charm != 0) m_NumCharmed++;
712 m_MaxAbsBaryonNumber = max(m_MaxAbsBaryonNumber, abs(bary));
714 m_Particles.push_back(part_candidate);
715 m_PDGtoID[pdgid] = m_Particles.size() - 1;
716 m_NumberOfParticles++;
718 if (GenerateAntiParticles && !(bary == 0 && chg == 0 && str == 0 && charm == 0) && (m_PDGtoID.count(-pdgid) == 0)) {
720 if (bary != 0) m_NumBaryons++;
721 if (chg != 0) m_NumCharged++;
722 if (str != 0) m_NumStrange++;
723 if (charm != 0) m_NumCharmed++;
725 if (bary == 0 && name[name.size() - 1] ==
'+')
726 name[name.size() - 1] =
'-';
727 else if (bary == 0 && name[name.size() - 1] ==
'-')
728 name[name.size() - 1] =
'+';
730 name =
"anti-" + name;
731 m_Particles.push_back(ThermalParticle((
bool)stable, name, -pdgid, degeneracy, stat, mass, -str, -bary, -chg, abss, width, threshold, -charm, absc));
732 m_Particles[m_Particles.size() - 1].SetAntiParticle(
true);
733 m_PDGtoID[pdgid] = m_Particles.size() - 1;
742 m_Particles.resize(0);
744 for (
size_t i = 0; i < part_in.size(); ++i) {
746 if (!GenerateAntiParticles) {
747 m_Particles.push_back(part);
749 else if (part.
PdgId() > 0) {
750 m_Particles.push_back(part);
760 if (GenerateAntiParticles) {
761 for (
size_t i = 0; i < m_Particles.size(); ++i) {
762 if (m_Particles[i].IsAntiParticle() &&
PdgToId(-m_Particles[i].PdgId()) != -1) {
768 FinalizeDecaysLoad();
777 std::ofstream fout(OutputFile.c_str());
778 if (fout.is_open()) {
780 << std::setw(14) <<
"pdgid"
781 << std::setw(20) <<
"name"
782 << std::setw(15) <<
"stable"
783 << std::setw(15) <<
"mass[GeV]"
784 << std::setw(15) <<
"degeneracy"
785 << std::setw(15) <<
"statistics"
786 << std::setw(15) <<
"B"
787 << std::setw(15) <<
"Q"
788 << std::setw(15) <<
"S"
789 << std::setw(15) <<
"C"
790 << std::setw(15) <<
"|S|"
791 << std::setw(15) <<
"|C|"
792 << std::setw(15) <<
"width[GeV]"
793 << std::setw(15) <<
"threshold[GeV]"
796 for (
size_t i = 0; i < m_Particles.size(); ++i) {
798 if (part.
PdgId() < 0 && !WriteAntiParticles)
801 fout << std::setw(15) << part.
PdgId()
802 << std::setw(20) << part.
Name()
803 << std::setw(15) <<
static_cast<int>(part.
IsStable())
804 << std::setw(15) << part.
Mass()
810 << std::setw(15) << part.
Charm()
823 for (
size_t i = 0; i < m_Particles.size(); ++i)
824 m_Particles[i].ClearDecays();
826 for (
size_t i = 0; i < DecayFiles.size(); ++i) {
827 ifstream fin(DecayFiles[i].c_str());
832 fin.getline(tmpc, 2000);
833 string tmp = string(tmpc);
837 if (tmp.size() == 0 || elems.size() >= 2)
843 fin.seekg(0, ios::beg);
846 ReadDecays_NewFormat(fin);
848 ReadDecays_OldFormat(fin);
857 for (
size_t i = 0; i < m_Particles.size(); ++i) {
858 if (m_Particles[i].PdgId() < 0)
863 FinalizeDecaysLoad();
868 std::set<std::string> flags;
869 if (!GenerateAntiParticles)
872 LoadDecays(vector<string>(1, DecaysFile), flags);
875 void ThermalParticleSystem::ReadDecays_NewFormat(std::ifstream & fin)
877 vector< ThermalParticle::ParticleDecaysVector > decays(0);
878 map<long long, int> decaymap;
886 fin.getline(cc, 2000);
887 string tmp = string(cc);
889 if (elems.size() < 1 || elems[0].size() == 0)
892 int tdecaysnumber = 0;
893 long long tpdgid = 0;
896 istringstream iss(elems[0]);
897 if (!(iss >> tpdgid))
continue;
902 if (fin.eof())
break;
903 fin.getline(cc, 500);
906 if (elems.size() < 1 || elems[0].size() == 0)
909 istringstream isstnum(elems[0]);
910 if (!(isstnum >> tdecaysnumber)) {
918 for (
int i = 0; i < tdecaysnumber; ++i) {
921 if (fin.eof())
break;
922 fin.getline(cc, 500);
925 if (elems.size() < 1 || elems[0].size() == 0)
928 ParticleDecayChannel tdecay;
929 istringstream issdec(elems[0]);
930 if (!(issdec >> tdecay.mBratio))
continue;
932 while (issdec >> tmpid) {
933 tdecay.mDaughters.push_back(tmpid);
935 tdecays.push_back(tdecay);
940 if (
static_cast<int>(tdecays.size()) == tdecaysnumber &&
static_cast<int>(tdecays.size()) != 0) {
941 decays.push_back(tdecays);
942 decaymap[tpdgid] = index;
947 for (
size_t i = 0; i < m_Particles.size(); ++i) {
948 if (decaymap.count(m_Particles[i].PdgId()) != 0)
949 m_Particles[i].SetDecays(decays[decaymap[m_Particles[i].PdgId()]]);
954 void ThermalParticleSystem::Initialize(
const std::vector<std::string>& ListFiles,
const std::vector<std::string>& DecayFiles,
const std::set<std::string>& flags,
double mcut)
959 m_NumberOfParticles = 0;
960 m_Particles.resize(0);
973 LoadList(ListFiles, DecayFiles, flags, mcut);
976 void ThermalParticleSystem::Initialize(
const std::string& InputFile,
const std::string& DecayFile,
bool GenAntiP,
double mcut)
978 std::set<std::string> flags;
981 Initialize(vector<string>(1, InputFile), vector<string>(1, DecayFile), flags, mcut);
984 void ThermalParticleSystem::FinalizeListLoad()
994 void ThermalParticleSystem::FinalizeDecaysLoad()
996 for (
size_t i = 0; i < m_Particles.size(); ++i)
997 m_Particles[i].SetDecaysOriginal(m_Particles[i].Decays());
1004 bool ThermalParticleSystem::CheckListIsiSS(
const std::string& filename)
1006 ifstream fin(filename.c_str());
1007 if (fin.is_open()) {
1010 return (tmp ==
"iSS");
1015 void ThermalParticleSystem::LoadListiSS(
const std::string& filename,
const std::set<std::string>& flags,
double mcut)
1017 m_NumberOfParticles = 0;
1018 m_Particles.resize(0);
1021 m_NumBaryons = m_NumCharged = m_NumStrange = m_NumCharmed = 0;
1022 m_MaxAbsBaryonNumber = 0;
1024 ifstream fin(filename.c_str());
1026 if (fin.is_open()) {
1029 fin.getline(cc, 2000);
1031 while (!fin.eof()) {
1032 fin.getline(cc, 2000);
1033 string tmp = string(cc);
1035 if (elems.size() < 1 || elems[0].size() == 0)
1038 istringstream iss(elems[0]);
1040 int stable, stat, str, bary, chg, charm, itmp, tdecaynumber;
1041 long long pdgid, ltmp;
1042 double mass, degeneracy, width, threshold, abss, absc;
1060 abss = std::abs(str);
1063 absc = std::abs(charm);
1065 stat = (std::abs(bary) % 2 == 0 ? -1 : 1);
1067 ThermalParticle part_candidate = ThermalParticle(
1068 (
bool)stable, name, pdgid, degeneracy, stat, mass, str, bary, chg, abss, width, threshold, charm, absc);
1071 part_candidate.SetAntiParticle(
true);
1073 if (!AcceptParticle(part_candidate, flags, mcut) || m_PDGtoID.count(pdgid) != 0)
1076 if (bary != 0) m_NumBaryons++;
1077 if (chg != 0) m_NumCharged++;
1078 if (str != 0) m_NumStrange++;
1079 if (charm != 0) m_NumCharmed++;
1080 m_MaxAbsBaryonNumber = max(m_MaxAbsBaryonNumber, abs(bary));
1082 m_Particles.push_back(part_candidate);
1083 m_PDGtoID[pdgid] = m_Particles.size() - 1;
1084 m_NumberOfParticles++;
1088 for (
size_t idec = 0; idec < tdecaynumber; ++idec) {
1089 fin.getline(cc, 2000);
1090 string tmp = string(cc);
1092 istringstream issdec(elems[0]);
1094 ParticleDecayChannel tdecay;
1096 int ndecayparticles;
1098 issdec >> ndecayparticles >> tdecay.mBratio;
1099 for (
size_t idaughter = 0; idaughter < 5; ++idaughter) {
1101 if (idaughter < ndecayparticles)
1102 tdecay.mDaughters.push_back(ltmp);
1104 tdecays.push_back(tdecay);
1107 if (
static_cast<int>(tdecays.size()) == tdecaynumber
1108 &&
static_cast<int>(tdecays.size()) != 0
1109 && tdecays[0].mDaughters.size() != 1) {
1110 m_Particles.back().SetDecays(tdecays);
1114 m_Particles.back().SetStable(
true);
1118 if (bary > 0 && (m_PDGtoID.count(-pdgid) == 0)) {
1120 if (bary != 0) m_NumBaryons++;
1121 if (chg != 0) m_NumCharged++;
1122 if (str != 0) m_NumStrange++;
1123 if (charm != 0) m_NumCharmed++;
1125 if (bary == 0 && name[name.size() - 1] ==
'+')
1126 name[name.size() - 1] =
'-';
1127 else if (bary == 0 && name[name.size() - 1] ==
'-')
1128 name[name.size() - 1] =
'+';
1130 name =
"anti-" + name;
1131 m_Particles.push_back(ThermalParticle((
bool)stable, name, -pdgid, degeneracy, stat, mass, -str, -bary, -chg, abss, width, threshold, -charm, absc));
1132 m_Particles.back().SetAntiParticle(
true);
1133 m_PDGtoID[pdgid] = m_Particles.size() - 1;
1141 for (
size_t i = 0; i < m_Particles.size(); ++i) {
1142 if (m_Particles[i].BaryonCharge() < 0)
1146 FinalizeDecaysLoad();
1154 std::ofstream fout(OutputFile.c_str());
1155 if (fout.is_open()) {
1156 fout <<
"# the list of decays" << std::endl;
1157 fout <<
"# each entry consists of the following:" << std::endl;
1158 fout <<
"# a line with the pdgid of decaying particle" << std::endl;
1159 fout <<
"# a line with the number of decay channels" << std::endl;
1160 fout <<
"# for each channel a line containing whitespace-separated values of the channel branching ratio and pdg ids of the daughter products" << std::endl;
1161 fout <<
"# everything after the # symbol is treated as a comment and ignored" << std::endl;
1162 fout <<
"# decays of antiparticles are not listed but generated from the listed decays of particles" << std::endl;
1165 for (
unsigned int i = 0; i < m_Particles.size(); ++i) {
1166 if ((m_Particles[i].PdgId()>0 || WriteAntiParticles) && m_Particles[i].Decays().size()>0) {
1167 fout << std::left << std::setw(36) << m_Particles[i].PdgId();
1168 fout <<
" # " << m_Particles[i].Name() << std::endl;
1170 fout << std::left << std::setw(36) << m_Particles[i].Decays().size();
1171 fout <<
" # " << m_Particles[i].Decays().size() <<
" decay channel";
1172 if (m_Particles[i].Decays().size() % 10 != 1 || m_Particles[i].Decays().size() % 100 == 11) fout <<
"s";
1175 for (
unsigned int j = 0; j < m_Particles[i].Decays().size(); ++j) {
1176 fout << std::left << std::setw(15) << m_Particles[i].Decays()[j].mBratio <<
" ";
1177 std::ostringstream oss;
1178 for (
unsigned int k = 0; k < m_Particles[i].Decays()[j].mDaughters.size(); ++k) {
1179 oss << m_Particles[i].Decays()[j].mDaughters[k];
1180 if (k != m_Particles[i].Decays()[j].mDaughters.size() - 1)
1183 fout << std::left << std::setw(20) << oss.str();
1184 fout <<
" # " << m_Particles[i].Name() <<
" -> ";
1185 for (
unsigned int k = 0; k < m_Particles[i].Decays()[j].mDaughters.size(); ++k) {
1186 if (m_PDGtoID.count(m_Particles[i].Decays()[j].mDaughters[k]) == 0) {
1188 long long tpdg = m_Particles[i].Decays()[j].mDaughters[k];
1194 fout << m_Particles[m_PDGtoID[m_Particles[i].Decays()[j].mDaughters[k]]].Name();
1195 if (k != m_Particles[i].Decays()[j].mDaughters.size() - 1)
1208 void ThermalParticleSystem::ReadDecays_OldFormat(std::ifstream & fin)
1210 vector< ThermalParticle::ParticleDecaysVector > decays(0);
1211 vector<long long> pdgids(0);
1212 map<long long, int> decaymap;
1215 if (fin.is_open()) {
1216 int decaypartnumber = 0;
1217 fin >> decaypartnumber;
1218 decays.reserve(decaypartnumber);
1220 for (
int i = 0; i < decaypartnumber; ++i) {
1221 int decaysnumber, daughters;
1222 long long pdgid, tmpid;
1224 fin >> pdgid >> decaysnumber;
1225 decaymap[pdgid] = i;
1227 pdgids.push_back(pdgid);
1228 for (
int j = 0; j < decaysnumber; ++j) {
1231 decay.
mBratio = bratio / 100.;
1234 for (
int k = 0; k < daughters; ++k) {
1238 decays[i].push_back(decay);
1243 for (
size_t i = 0; i < m_Particles.size(); ++i) {
1244 if (decaymap.count(m_Particles[i].PdgId()) != 0)
1245 m_Particles[i].SetDecays(decays[decaymap[m_Particles[i].PdgId()]]);
1251 if (m_PDGtoID.count(pdgid) != 0)
1252 return m_Particles[m_PDGtoID[pdgid]].Name();
1253 if (pdgid == 1)
return string(
"Npart");
1254 if (pdgid == 310)
return string(
"K0S");
1255 if (pdgid == 130)
return string(
"K0L");
1256 if (pdgid % 10 == 0) {
1257 long long tpdgid = pdgid / 10;
1259 return m_Particles[
PdgToId(tpdgid)].Name() +
"+" + m_Particles[
PdgToId(-tpdgid)].Name();
1261 if (pdgid == 22122112)
return string(
"p+n");
1281 m_QStatsCalculationType = type;
1282 for (
size_t i = 0; i < m_Particles.size(); ++i)
1288 for (
size_t i = 0; i < m_Particles.size(); ++i)
1294 m_ResonanceWidthShape = shape;
1295 for (
size_t i = 0; i < m_Particles.size(); ++i)
1301 bool dodecays = (type != m_ResonanceWidthIntegrationType);
1303 m_ResonanceWidthIntegrationType = type;
1305 for (
size_t i = 0; i < m_Particles.size(); ++i) {
1306 if (!m_Particles[i].ZeroWidthEnforced())
1307 m_Particles[i].SetResonanceWidthIntegrationType(type);
1316 if (id < 0 || id >=
static_cast<int>(m_Particles.size())) {
1317 throw std::out_of_range(
"ThermalParticleSystem::Particle(int id): id is out of bounds!");
1319 return m_Particles[id];
1324 if (id < 0 || id >=
static_cast<int>(m_Particles.size())) {
1325 throw std::out_of_range(
"ThermalParticleSystem::Particle(int id): id is out of bounds!");
1327 return m_Particles[id];
1334 throw std::invalid_argument(
"ThermalParticleSystem::ParticleByPDG(long long pdgid): pdgid " + std::to_string(pdgid) +
" is unknown");
1336 return m_Particles[id];
1343 throw std::invalid_argument(
"ThermalParticleSystem::ParticleByPDG(long long pdgid): pdgid " + std::to_string(pdgid) +
" is unknown");
1345 return m_Particles[id];
1350 map<long long, int>::const_iterator it = m_PDGtoID.find(pdgid);
1352 if (it != m_PDGtoID.end()) {
1362 m_NumBaryons = m_NumCharged = m_NumStrange = m_NumCharmed = 0;
1363 m_MaxAbsBaryonNumber = 0;
1364 m_NumberOfParticles = 0;
1366 for (
size_t i = 0; i < m_Particles.size(); ++i) {
1367 m_PDGtoID[m_Particles[i].PdgId()] = i;
1368 if (m_Particles[i].BaryonCharge() != 0) m_NumBaryons++;
1369 if (m_Particles[i].ElectricCharge() != 0) m_NumCharged++;
1370 if (m_Particles[i].Strangeness() != 0) m_NumStrange++;
1371 if (m_Particles[i].Charm() != 0) m_NumCharmed++;
1372 if (m_Particles[i].PdgId() > 0) m_NumberOfParticles++;
1373 m_MaxAbsBaryonNumber = max(m_MaxAbsBaryonNumber, abs(m_Particles[i].BaryonCharge()));
1376 for (
size_t i = 0; i < m_DecayContributionsByFeeddown.size(); ++i)
1377 m_DecayContributionsByFeeddown[i].resize(m_Particles.size());
1383 sort(m_Particles.begin(), m_Particles.end(), cmpParticleMass);
1385 sort(m_Particles.begin(), m_Particles.end(), cmpParticleMassAndPdg);
1387 sort(m_Particles.begin(), m_Particles.end(), cmpParticlePDG);
1389 for (
size_t i = 0; i < m_Particles.size(); ++i) {
1397 m_Particles.push_back(part);
1403 if (ind >= 0 && ind <
static_cast<int>(m_Particles.size())) {
1404 m_Particles.erase(m_Particles.begin() + ind);
1412 for (
int i = 0; i < check.size(); ++i)
1422 for (
int i = 0; i <
Particles().size(); ++i) {
1425 printf(
"**WARNING** %s (%lld): Particle marked unstable but no decay channels found!\n",
1426 part.
Name().c_str(),
1431 throw std::runtime_error(
"**WARNING** Further warnings are discarded...");
1441 for (
int i = 0; i <
Particles().size(); ++i) {
1444 std::cerr <<
"**WARNING** " << part.
Name() <<
" (" << part.
PdgId() <<
"): Particle with non-zero strangeness has zero strange quark content |s|!" << std::endl;
1449 std::cerr <<
"**WARNING** " << part.
Name() <<
" (" << part.
PdgId() <<
"): Particle with non-zero charm has zero charm quark content |s|!" << std::endl;
1462 int goalC = part.
Charm();
1464 std::map<long long, int> tPDGtoID = m_PDGtoID;
1466 std::vector<int> ret(4, 1);
1468 for (
size_t i = 0; i < part.
Decays().size(); ++i) {
1469 int decB = 0, decQ = 0, decS = 0, decC = 0;
1470 for (
size_t j = 0; j < part.
Decays()[i].mDaughters.size(); ++j) {
1471 long long tpdg = part.
Decays()[i].mDaughters[j];
1472 if (tPDGtoID.count(tpdg) != 0) {
1473 int tid = tPDGtoID[tpdg];
1474 decB +=
Particles()[tid].BaryonCharge();
1475 decQ +=
Particles()[tid].ElectricCharge();
1504 ret &= m_PDGtoID == rhs.m_PDGtoID;
1505 ret &= m_NumBaryons == rhs.m_NumBaryons;
1506 ret &= m_NumCharged == rhs.m_NumCharged;
1507 ret &= m_NumStrange == rhs.m_NumStrange;
1508 ret &= m_NumCharmed == rhs.m_NumCharmed;
1509 ret &= m_MaxAbsBaryonNumber == rhs.m_MaxAbsBaryonNumber;
1510 ret &= m_NumberOfParticles == rhs.m_NumberOfParticles;
1511 ret &= m_ResonanceWidthIntegrationType == rhs.m_ResonanceWidthIntegrationType;
1512 ret &= m_DecayDistributionsMap == rhs.m_DecayDistributionsMap;
1514 ret &= m_Particles == rhs.m_Particles;
1522 set<long long> stablePDG;
1523 stablePDG.insert(2212); stablePDG.insert(-2212);
1524 stablePDG.insert(2112); stablePDG.insert(-2112);
1525 stablePDG.insert(1000010020); stablePDG.insert(-1000010020);
1526 stablePDG.insert(1000020030); stablePDG.insert(-1000020030);
1527 stablePDG.insert(1000010030); stablePDG.insert(-1000010030);
1528 stablePDG.insert(1000020040); stablePDG.insert(-1000020040);
1530 if (stablePDG.count(part.
PdgId()) > 0) {
1535 set<long long> weakPDG;
1536 weakPDG.insert(310);
1537 weakPDG.insert(130);
1538 weakPDG.insert(211); weakPDG.insert(-211);
1539 weakPDG.insert(321); weakPDG.insert(-321);
1540 weakPDG.insert(3122); weakPDG.insert(-3122);
1541 weakPDG.insert(3222); weakPDG.insert(-3222);
1542 weakPDG.insert(3112); weakPDG.insert(-3112);
1543 weakPDG.insert(3322); weakPDG.insert(-3322);
1544 weakPDG.insert(3312); weakPDG.insert(-3312);
1545 weakPDG.insert(3334); weakPDG.insert(-3334);
1546 weakPDG.insert(411); weakPDG.insert(-411);
1547 weakPDG.insert(421); weakPDG.insert(-421);
1548 weakPDG.insert(431); weakPDG.insert(-431);
1549 weakPDG.insert(4232); weakPDG.insert(-4232);
1550 weakPDG.insert(4132); weakPDG.insert(-4132);
1551 weakPDG.insert(4422); weakPDG.insert(-4422);
1552 weakPDG.insert(4412); weakPDG.insert(-4412);
1553 weakPDG.insert(4332); weakPDG.insert(-4332);
1555 if (weakPDG.count(part.
PdgId()) > 0) {
1561 set<long long> emPDG;
1565 emPDG.insert(3212); emPDG.insert(-3212);
1567 if (emPDG.count(part.
PdgId()) > 0) {
1588 m_DecayContributionsByFeeddown[
Feeddown::Weak].resize(m_Particles.size());
1590 m_DecayContributionsByFeeddown[
Feeddown::Strong].resize(m_Particles.size());
1591 for (
size_t i = 0; i < m_Particles.size(); ++i) {
1596 for (
int i =
static_cast<int>(m_Particles.size()) - 1; i >= 0; i--)
1598 GoResonanceByFeeddown(i, i, 1.,
Feeddown::Type(
static_cast<int>(m_Particles[i].DecayType())));
1602 void ThermalParticleSystem::GoResonanceByFeeddown(
int ind,
int startind,
double BR,
Feeddown::Type feeddown) {
1604 if (
static_cast<int>(feeddown) < feed_index)
continue;
1607 if (ind != startind && decayContributions.size() > 0 && decayContributions[decayContributions.size() - 1].second == startind)
1609 decayContributions[decayContributions.size() - 1].first += BR;
1611 else if (ind != startind) {
1612 decayContributions.push_back(make_pair(BR, startind));
1618 for (
size_t i = 0; i < m_Particles[ind].Decays().size(); ++i) {
1619 const ParticleDecayChannel& decaychannel = m_Particles[ind].Decays()[i];
1620 double tbr = decaychannel.mBratio;
1623 tbr = decaychannel.mBratioAverage;
1625 for (
size_t j = 0; j < decaychannel.mDaughters.size(); ++j) {
1626 if (m_PDGtoID.count(decaychannel.mDaughters[j]) != 0)
1627 GoResonanceByFeeddown(m_PDGtoID[decaychannel.mDaughters[j]], startind, BR*tbr,
Feeddown::Type(
static_cast<int>(m_Particles[ind].DecayType())));
1635 for (
size_t i = 0; i < m_Particles.size(); ++i) {
1636 ret[i] =
static_cast<double>(m_Particles[i].ConservedCharge(charge));
1643 std::vector<std::string>&
split(
const std::string& s,
char delim, std::vector<std::string>& elems) {
1644 std::stringstream ss(s);
1646 while (std::getline(ss, item, delim)) {
1647 elems.push_back(item);
1652 std::vector<std::string>
split(
const std::string& s,
char delim) {
1653 std::vector<std::string> elems;
1654 split(s, delim, elems);
1660 if (
static_cast<int>(vect.size()) > maxsize) {
1661 std::sort(vect.begin(), vect.end());
1662 std::reverse(vect.begin(), vect.end());
1668 namespace DecayLifetimes {
1699 if (
widths.count(abs(pdg))) {
1700 double width =
widths[abs(pdg)];
Contains some helper functions.
static bool PrintDisclaimer()
static bool DisclaimerPrinted
Class containing all information about a particle specie.
long long PdgId() const
Particle's Particle Data Group (PDG) ID number.
double AbsoluteCharm() const
Absolute charm quark content |s|.
int BaryonCharge() const
Particle's baryon number.
int Statistics() const
Particle's statistics.
double Mass() const
Particle's mass [GeV].
std::vector< ParticleDecayChannel > ParticleDecaysVector
Vector of all decay channels of a particle.
int Strangeness() const
Particle's strangeness.
const ParticleDecaysVector & Decays() const
A vector of particle's decays.
ResonanceWidthIntegration
Treatment of finite resonance widths.
@ eBW
Energy-dependent Breit-Wigner scheme (eBW)
@ ZeroWidth
Zero-width approximation.
double AbsoluteStrangeness() const
Absolute strange quark content |s|.
double DecayThresholdMass() const
The decays threshold mass.
int ElectricCharge() const
Particle's electric charge.
ResonanceWidthShape
Relativistic vs non-relativistic Breit-Wigner shape.
@ RelativisticBreitWigner
bool IsNeutral() const
Whether particle is neutral one.
int Charm() const
Particle's charm.
const std::string & Name() const
Particle's name.
double ResonanceWidth() const
Particle's width at the pole mass (GeV)
bool IsStable() const
Return particle stability flag.
ThermalParticle GenerateAntiParticle() const
Generates the anti-particle to the current particle specie.
double Degeneracy() const
Particle's internal degeneracy factor.
void SetResonanceWidthIntegrationType(ThermalParticle::ResonanceWidthIntegration type)
Set (or get) the ThermalParticle::ResonanceWidthIntegration scheme for all particles.
void SetTableFromVector(const std::vector< ThermalParticle > &part_in, bool GenerateAntiParticles=true)
Sets the particle list from a provided vector of ThermalParticle objects.
bool CheckAbsoluteQuarkNumbers() const
std::vector< std::pair< double, std::vector< int > > > ResonanceFinalStatesDistribution
ThermalParticleSystem(const std::string &InputFile="", bool GenAntiP=true, double mcut=-1.)
Construct a new ThermalParticleSystem object.
static const std::string flag_noexcitednuclei
int PdgToId(long long pdgid) const
Transforms PDG ID to a 0-based particle id number.
static const std::string flag_nonuclei
SortModeType SortMode() const
Current mode to sort particle species.
void WriteTableToFile(const std::string &OutputFile="", bool WriteAntiParticles=false)
Writes the particle list to file.
void ProcessDecays()
Computes the decay contributions of decaying resonances to all particle yields.
std::string GetNameFromPDG(long long pdgid)
Get the name of particle species with the specified PDG ID.
bool CheckDecayChannelsAreSpecified() const
ThermalParticle::ParticleDecaysVector GetDecaysFromAntiParticle(const ThermalParticle::ParticleDecaysVector &Decays)
Generates the decay channels for an antiparticle based on the provided decay channels of a particle.
void SetCalculationType(IdealGasFunctions::QStatsCalculationType type)
Sets the CalculationType() method to evaluate quantum statistics.
static const std::string flag_nocharm
void NormalizeBranchingRatios()
Normalize branching ratios for all particles such that they add up to 100%.
bool operator==(const ThermalParticleSystem &rhs) const
void SetClusterExpansionOrder(int order)
Set the number of terms in the cluster expansion method.
const std::vector< ThermalParticle > & Particles() const
Returns the vector of all particle species.
std::vector< SingleDecayContribution > DecayContributionsToParticle
A vector of SingleDecayContribution where each element corresponds to a certain resonance species.
void RestoreBranchingRatios()
Restore the original values of all the branching ratios.
void FillDecayProperties()
Computes and fills decay channels of all particles with extra information.
void LoadList(const std::vector< std::string > &ListFiles, const std::vector< std::string > &DecayFiles=std::vector< std::string >(0), const std::set< std::string > &flags=std::set< std::string >(), double mcut=1.e9)
Loads the particle list from file.
static const std::string flag_no_antiparticles
std::pair< double, int > SingleDecayContribution
void FillResonanceDecaysByFeeddown()
Same as FillResonanceDecays() but separately for weak, electromagnetic, and strong decay feeddowns.
void FillDecayThresholds()
Computes mass thresholds of all decay channels of all particles. Obsolete.
void AddParticlesToListFromFile(const std::string &InputFile="", const std::set< std::string > &flags=std::set< std::string >(), double mcut=-1.)
static const std::string flag_nostrangeness
std::vector< int > CheckDecayChargesConservationVector(int ind) const
static ParticleDecayType::DecayType DecayTypeByParticleType(const ThermalParticle &part)
Determines the decay type of a given particle specie.
const ThermalParticle & Particle(int id) const
ThermalParticle object corresponding to particle species with a provided 0-based index.
void RemoveParticleAt(int ind)
Removes particle specie with specified 0-based particle id number from the list.
void AddParticle(const ThermalParticle &part)
Adds a new particle specie to the list.
bool CheckDecayChargesConservation(int ind) const
void SetResonanceWidthShape(ThermalParticle::ResonanceWidthShape shape)
Set (or get) the ThermalParticle::ResonanceWidthShape for all particles.
void LoadDecays(const std::vector< std::string > &DecayFiles, const std::set< std::string > &flags=std::set< std::string >())
Load the decay channels for all particles from a file.
const ThermalParticle & ParticleByPDG(long long pdgid) const
ThermalParticle object corresponding to particle species with a provided PDG ID.
void FillResonanceDecays()
Computes the decay contributions of decaying resonances to all particle yields.
std::vector< double > GetConservedChargesVector(ConservedCharge::Name charge)
Calculates vector of conserved charges for all particle species.
int ComponentsNumber() const
Number of different particle species in the list.
void WriteDecaysToFile(const std::string &OutputFile="", bool WriteAntiParticles=false)
Writes the decay channels to a file.
~ThermalParticleSystem(void)
Destroy the ThermalParticleSystem object.
Contains several helper routines.
void cutDecayDistributionsVector(std::vector< std::pair< double, std::vector< int > > > &vect, int maxsize=1000)
std::vector< std::string > split(const std::string &s, char delim)
map< long long, double > widths
map< long long, double > lifetimes
double GetLifetime(long long pdg)
const ThermalParticle & Particle(int id)
const ThermalParticle & ParticleByPdg(long long pdg)
std::string NameByPdg(long long pdg)
int PdgToId(long long pdg)
QStatsCalculationType
Identifies whether quantum statistics are to be computed using the cluster expansion or numerical int...
constexpr double GeVtoifm()
A constant to transform GeV into fm .
The main namespace where all classes and functions of the Thermal-FIST library reside.
long long stringToLongLong(const std::string &str)
Name
Set of all conserved charges considered.
static const int NumberOfTypes
@ Strong
Feeddown from strong decays.
@ Weak
Feeddown from strong, electromagnetic, and weak decays.
@ Electromagnetic
Feeddown from strong and electromagnetic decays.
@ StabilityFlag
Feeddown from all particles marked as unstable.
Structure containing information about a single decay channel of a particle.
std::vector< long long > mDaughters
DecayType
Type of particle's decay.
@ Strong
Strongly decaying.
@ Electromagnetic
Electromagnetically decaying.