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;
384 for (
size_t i = 0; i < tpart.Decays().size(); ++i) {
385 double tbr = tpart.Decays()[i].mBratio;
387 tbr = m_Particles[ind].Decays()[i].mBratioAverage;
389 std::vector< std::pair<double, std::vector<int> > > tret = retorig;
391 for (
size_t j = 0; j < tpart.Decays()[i].mDaughters.size(); ++j) {
392 if (m_PDGtoID.count(tpart.Decays()[i].mDaughters[j]) != 0) {
394 std::vector< std::pair<double, std::vector<int> > > tmp = GoResonanceDecayDistributions(m_PDGtoID[tpart.Decays()[i].mDaughters[j]]);
395 std::vector< std::pair<double, std::vector<int> > > tmp2(tret.size() * tmp.size());
396 for (
int i1 = 0; i1 < static_cast<int>(tret.size()); ++i1) {
397 for (
int i2 = 0; i2 < static_cast<int>(tmp.size()); ++i2) {
398 tmp2[i1*tmp.size() + i2].first = tret[i1].first * tmp[i2].first;
399 tmp2[i1*tmp.size() + i2].second.resize(m_Particles.size());
400 for (
size_t jj = 0; jj < tmp2[i1*tmp.size() + i2].second.size(); ++jj)
401 tmp2[i1*tmp.size() + i2].second[jj] = tret[i1].second[jj] + tmp[i2].second[jj];
407 if (
static_cast<int>(tret.size()) > m_MaxDecayDistributionsSize) {
414 for (
size_t j = 0; j < tret.size(); ++j) {
415 tret[j].first *= tbr;
416 ret.push_back(tret[j]);
421 if (
static_cast<int>(ret.size()) > m_MaxDecayDistributionsSize) {
426 if (wasCut && firstdecay) {
427 printf(
"**WARNING** %s (%lld) Decay Distributions: Too large array, cutting the number of channels to %d\n",
428 m_Particles[ind].Name().c_str(),
429 m_Particles[ind].PdgId(),
430 m_MaxDecayDistributionsSize);
434 for (
size_t i = 0; i < ret.size(); ++i)
435 totprob += ret[i].first;
437 for (
size_t i = 0; i < ret.size(); ++i)
438 ret[i].first *= 1. / totprob;
440 else if (totprob < 1.) {
441 double emptyprob = 1. - totprob;
442 ret.push_back(std::make_pair(emptyprob, retorig[0].second));
446 m_DecayDistributionsMap[ind] = ret;
472 bool ThermalParticleSystem::AcceptParticle(
const ThermalParticle& part,
const std::set<std::string>& flags,
double mcut)
const
474 if (mcut >= 0. && part.Mass() > mcut)
487 void ThermalParticleSystem::LoadList(
const std::vector<std::string>& ListFiles,
const std::vector<std::string>& DecayFiles,
const std::set<std::string>& flags,
double mcut)
489 m_NumberOfParticles = 0;
490 m_Particles.resize(0);
493 m_NumBaryons = m_NumCharged = m_NumStrange = m_NumCharmed = 0;
494 m_MaxAbsBaryonNumber = 0;
496 if (ListFiles.size() == 1 && CheckListIsiSS(ListFiles[0])) {
497 LoadListiSS(ListFiles[0], flags, mcut);
501 for(
int i = 0; i < ListFiles.size(); ++i)
506 std::vector<std::string> tDecayFiles = DecayFiles;
507 if (tDecayFiles.size() == 1 && tDecayFiles[0] ==
"")
510 if (tDecayFiles.size() == 0 && ListFiles.size() > 0) {
511 for (
size_t ilist = 0; ilist < ListFiles.size(); ++ilist) {
512 string decayprefix =
"";
513 string decayprefixfile =
"";
515 for (
int i = ListFiles[ilist].size() - 1; i >= 0; --i) {
516 if (ListFiles[ilist][i] ==
'\\' || ListFiles[ilist][i] ==
'/')
518 decayprefix = ListFiles[ilist].substr(0, i + 1);
521 decayprefixfile += ListFiles[ilist][i];
524 reverse(decayprefixfile.begin(), decayprefixfile.end());
527 string DecayFile =
"";
528 if (decayprefixfile.substr(0, 4) ==
"list") {
529 DecayFile = decayprefix +
"decays" + decayprefixfile.substr(4);
532 DecayFile = decayprefix +
"decays.dat";
536 tDecayFiles.push_back(decayprefix +
"decays.dat");
538 tDecayFiles.push_back(DecayFile);
549 std::set<std::string> flags;
553 std::vector<std::string> DecayFiles(0);
555 DecayFiles.push_back(DecayFile);
557 LoadList(std::vector<std::string>(1, InputFile), DecayFiles, flags, mcut);
563 fin.open(InputFile.c_str());
567 fin.getline(tmpc, 2000);
568 string tmp = string(tmpc);
578 fin.seekg(0, ios::beg);
581 LoadTable_NewFormat(fin, flags, mcut);
583 LoadTable_OldFormat(fin, flags, mcut);
590 void ThermalParticleSystem::LoadTable_OldFormat(std::ifstream & fin,
const std::set<std::string>& flags,
double mcut)
596 fin.getline(tmpc, 500);
600 if (fields.size() < 14)
break;
601 int stable, spin, stat, str, bary, chg, charm;
603 double mass, width, threshold, abss, absc, radius = 0.5;
604 string name, decayname =
"";
605 stable = atoi(fields[0].c_str());
609 spin = atoi(fields[3].c_str());
610 stat = atoi(fields[4].c_str());
611 mass = atof(fields[5].c_str());
612 str = atoi(fields[6].c_str());
613 bary = atoi(fields[7].c_str());
614 chg = atoi(fields[8].c_str());
615 charm = atoi(fields[9].c_str());
616 abss = atof(fields[10].c_str());
617 absc = atof(fields[11].c_str());
618 width = atof(fields[12].c_str());
619 threshold = atof(fields[13].c_str());
620 if (fields.size() >= 15) radius = atof(fields[14].c_str());
621 if (fields.size() == 16) decayname = fields[15];
623 ThermalParticle part_candidate =
ThermalParticle(
static_cast<bool>(stable), name, pdgid,
static_cast<double>(spin), stat, mass, str, bary, chg, abss, width, threshold, charm, absc);
626 if (m_PDGtoID.count(pdgid) != 0) {
627 throw std::invalid_argument(
"ThermalParticleSystem::LoadTable_NewFormat: Duplicate pdg code " + std::to_string(pdgid));
629 if (!AcceptParticle(part_candidate, flags, mcut) || m_PDGtoID.count(pdgid) != 0) {
630 fin.getline(tmpc, 500);
635 if (bary != 0) m_NumBaryons++;
636 if (chg != 0) m_NumCharged++;
637 if (str != 0) m_NumStrange++;
638 if (charm != 0) m_NumCharmed++;
639 m_MaxAbsBaryonNumber = max(m_MaxAbsBaryonNumber, abs(bary));
641 m_Particles.push_back(part_candidate);
642 m_PDGtoID[pdgid] = m_Particles.size() - 1;
643 m_NumberOfParticles++;
645 if (GenerateAntiParticles && !(bary == 0 && chg == 0 && str == 0 && charm == 0) && (m_PDGtoID.count(-pdgid) == 0)) {
647 if (bary != 0) m_NumBaryons++;
648 if (chg != 0) m_NumCharged++;
649 if (str != 0) m_NumStrange++;
650 if (charm != 0) m_NumCharmed++;
652 if (bary == 0 && name[name.size() - 1] ==
'+')
653 name[name.size() - 1] =
'-';
654 else if (bary == 0 && name[name.size() - 1] ==
'-')
655 name[name.size() - 1] =
'+';
657 name =
"anti-" + name;
658 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));
659 m_Particles[m_Particles.size() - 1].SetAntiParticle(
true);
660 m_PDGtoID[-pdgid] = m_Particles.size() - 1;
663 fin.getline(tmpc, 500);
669 void ThermalParticleSystem::LoadTable_NewFormat(std::ifstream & fin,
const std::set<std::string>& flags,
double mcut)
675 fin.getline(cc, 2000);
676 string tmp = string(cc);
678 if (elems.size() < 1 || elems[0].size() == 0)
681 istringstream iss(elems[0]);
683 int stable, stat, str, bary, chg, charm;
685 double mass, degeneracy, width, threshold, abss, absc;
703 ThermalParticle part_candidate = ThermalParticle((
bool)stable, name, pdgid, degeneracy, stat, mass, str, bary, chg, abss, width, threshold, charm, absc);
706 if (m_PDGtoID.count(pdgid) != 0) {
707 throw std::invalid_argument(
"ThermalParticleSystem::LoadTable_NewFormat: Duplicate pdg code " + std::to_string(pdgid));
710 if (!AcceptParticle(part_candidate, flags, mcut) || m_PDGtoID.count(pdgid) != 0)
713 if (bary != 0) m_NumBaryons++;
714 if (chg != 0) m_NumCharged++;
715 if (str != 0) m_NumStrange++;
716 if (charm != 0) m_NumCharmed++;
717 m_MaxAbsBaryonNumber = max(m_MaxAbsBaryonNumber, abs(bary));
719 m_Particles.push_back(part_candidate);
720 m_PDGtoID[pdgid] = m_Particles.size() - 1;
721 m_NumberOfParticles++;
723 if (GenerateAntiParticles && !(bary == 0 && chg == 0 && str == 0 && charm == 0) && (m_PDGtoID.count(-pdgid) == 0)) {
725 if (bary != 0) m_NumBaryons++;
726 if (chg != 0) m_NumCharged++;
727 if (str != 0) m_NumStrange++;
728 if (charm != 0) m_NumCharmed++;
730 if (bary == 0 && name[name.size() - 1] ==
'+')
731 name[name.size() - 1] =
'-';
732 else if (bary == 0 && name[name.size() - 1] ==
'-')
733 name[name.size() - 1] =
'+';
735 name =
"anti-" + name;
736 m_Particles.push_back(ThermalParticle((
bool)stable, name, -pdgid, degeneracy, stat, mass, -str, -bary, -chg, abss, width, threshold, -charm, absc));
737 m_Particles[m_Particles.size() - 1].SetAntiParticle(
true);
738 m_PDGtoID[pdgid] = m_Particles.size() - 1;
747 m_Particles.resize(0);
749 for (
size_t i = 0; i < part_in.size(); ++i) {
751 if (!GenerateAntiParticles) {
752 m_Particles.push_back(part);
754 else if (part.
PdgId() > 0) {
755 m_Particles.push_back(part);
765 if (GenerateAntiParticles) {
766 for (
size_t i = 0; i < m_Particles.size(); ++i) {
767 if (m_Particles[i].IsAntiParticle() &&
PdgToId(-m_Particles[i].PdgId()) != -1) {
773 FinalizeDecaysLoad();
782 std::ofstream fout(OutputFile.c_str());
783 if (fout.is_open()) {
785 << std::setw(14) <<
"pdgid"
786 << std::setw(20) <<
"name"
787 << std::setw(15) <<
"stable"
788 << std::setw(15) <<
"mass[GeV]"
789 << std::setw(15) <<
"degeneracy"
790 << std::setw(15) <<
"statistics"
791 << std::setw(15) <<
"B"
792 << std::setw(15) <<
"Q"
793 << std::setw(15) <<
"S"
794 << std::setw(15) <<
"C"
795 << std::setw(15) <<
"|S|"
796 << std::setw(15) <<
"|C|"
797 << std::setw(15) <<
"width[GeV]"
798 << std::setw(15) <<
"threshold[GeV]"
801 for (
size_t i = 0; i < m_Particles.size(); ++i) {
803 if (part.
PdgId() < 0 && !WriteAntiParticles)
806 fout << std::setw(15) << part.
PdgId()
807 << std::setw(20) << part.
Name()
808 << std::setw(15) <<
static_cast<int>(part.
IsStable())
809 << std::setw(15) << part.
Mass()
815 << std::setw(15) << part.
Charm()
828 for (
size_t i = 0; i < m_Particles.size(); ++i)
829 m_Particles[i].ClearDecays();
831 for (
size_t i = 0; i < DecayFiles.size(); ++i) {
832 ifstream fin(DecayFiles[i].c_str());
837 fin.getline(tmpc, 2000);
838 string tmp = string(tmpc);
842 if (tmp.size() == 0 || elems.size() >= 2)
848 fin.seekg(0, ios::beg);
851 ReadDecays_NewFormat(fin);
853 ReadDecays_OldFormat(fin);
862 for (
size_t i = 0; i < m_Particles.size(); ++i) {
863 if (m_Particles[i].PdgId() < 0)
868 FinalizeDecaysLoad();
873 std::set<std::string> flags;
874 if (!GenerateAntiParticles)
877 LoadDecays(vector<string>(1, DecaysFile), flags);
880 void ThermalParticleSystem::ReadDecays_NewFormat(std::ifstream & fin)
882 vector< ThermalParticle::ParticleDecaysVector > decays(0);
883 map<long long, int> decaymap;
891 fin.getline(cc, 2000);
892 string tmp = string(cc);
894 if (elems.size() < 1 || elems[0].size() == 0)
897 int tdecaysnumber = 0;
898 long long tpdgid = 0;
901 istringstream iss(elems[0]);
902 if (!(iss >> tpdgid))
continue;
907 if (fin.eof())
break;
908 fin.getline(cc, 500);
911 if (elems.size() < 1 || elems[0].size() == 0)
914 istringstream isstnum(elems[0]);
915 if (!(isstnum >> tdecaysnumber)) {
923 for (
int i = 0; i < tdecaysnumber; ++i) {
926 if (fin.eof())
break;
927 fin.getline(cc, 500);
930 if (elems.size() < 1 || elems[0].size() == 0)
933 ParticleDecayChannel tdecay;
934 istringstream issdec(elems[0]);
935 if (!(issdec >> tdecay.mBratio))
continue;
937 while (issdec >> tmpid) {
938 tdecay.mDaughters.push_back(tmpid);
940 tdecays.push_back(tdecay);
945 if (
static_cast<int>(tdecays.size()) == tdecaysnumber &&
static_cast<int>(tdecays.size()) != 0) {
946 decays.push_back(tdecays);
947 decaymap[tpdgid] = index;
952 for (
size_t i = 0; i < m_Particles.size(); ++i) {
953 if (decaymap.count(m_Particles[i].PdgId()) != 0)
954 m_Particles[i].SetDecays(decays[decaymap[m_Particles[i].PdgId()]]);
959 void ThermalParticleSystem::Initialize(
const std::vector<std::string>& ListFiles,
const std::vector<std::string>& DecayFiles,
const std::set<std::string>& flags,
double mcut)
964 m_NumberOfParticles = 0;
965 m_Particles.resize(0);
972 m_MaxDecayDistributionsSize = 8000;
980 LoadList(ListFiles, DecayFiles, flags, mcut);
983 void ThermalParticleSystem::Initialize(
const std::string& InputFile,
const std::string& DecayFile,
bool GenAntiP,
double mcut)
985 std::set<std::string> flags;
988 Initialize(vector<string>(1, InputFile), vector<string>(1, DecayFile), flags, mcut);
991 void ThermalParticleSystem::FinalizeListLoad()
1001 void ThermalParticleSystem::FinalizeDecaysLoad()
1003 for (
size_t i = 0; i < m_Particles.size(); ++i)
1004 m_Particles[i].SetDecaysOriginal(m_Particles[i].Decays());
1011 bool ThermalParticleSystem::CheckListIsiSS(
const std::string& filename)
1013 ifstream fin(filename.c_str());
1014 if (fin.is_open()) {
1017 return (tmp ==
"iSS");
1022 void ThermalParticleSystem::LoadListiSS(
const std::string& filename,
const std::set<std::string>& flags,
double mcut)
1024 m_NumberOfParticles = 0;
1025 m_Particles.resize(0);
1028 m_NumBaryons = m_NumCharged = m_NumStrange = m_NumCharmed = 0;
1029 m_MaxAbsBaryonNumber = 0;
1031 ifstream fin(filename.c_str());
1033 if (fin.is_open()) {
1036 fin.getline(cc, 2000);
1038 while (!fin.eof()) {
1039 fin.getline(cc, 2000);
1040 string tmp = string(cc);
1042 if (elems.size() < 1 || elems[0].size() == 0)
1045 istringstream iss(elems[0]);
1047 int stable, stat, str, bary, chg, charm, itmp, tdecaynumber;
1048 long long pdgid, ltmp;
1049 double mass, degeneracy, width, threshold, abss, absc;
1067 abss = std::abs(str);
1070 absc = std::abs(charm);
1072 stat = (std::abs(bary) % 2 == 0 ? -1 : 1);
1074 ThermalParticle part_candidate = ThermalParticle(
1075 (
bool)stable, name, pdgid, degeneracy, stat, mass, str, bary, chg, abss, width, threshold, charm, absc);
1078 part_candidate.SetAntiParticle(
true);
1080 if (!AcceptParticle(part_candidate, flags, mcut) || m_PDGtoID.count(pdgid) != 0)
1083 if (bary != 0) m_NumBaryons++;
1084 if (chg != 0) m_NumCharged++;
1085 if (str != 0) m_NumStrange++;
1086 if (charm != 0) m_NumCharmed++;
1087 m_MaxAbsBaryonNumber = max(m_MaxAbsBaryonNumber, abs(bary));
1089 m_Particles.push_back(part_candidate);
1090 m_PDGtoID[pdgid] = m_Particles.size() - 1;
1091 m_NumberOfParticles++;
1095 for (
size_t idec = 0; idec < tdecaynumber; ++idec) {
1096 fin.getline(cc, 2000);
1097 string tmp = string(cc);
1099 istringstream issdec(elems[0]);
1101 ParticleDecayChannel tdecay;
1103 int ndecayparticles;
1105 issdec >> ndecayparticles >> tdecay.mBratio;
1106 for (
size_t idaughter = 0; idaughter < 5; ++idaughter) {
1108 if (idaughter < ndecayparticles)
1109 tdecay.mDaughters.push_back(ltmp);
1111 tdecays.push_back(tdecay);
1114 if (
static_cast<int>(tdecays.size()) == tdecaynumber
1115 &&
static_cast<int>(tdecays.size()) != 0
1116 && tdecays[0].mDaughters.size() != 1) {
1117 m_Particles.back().SetDecays(tdecays);
1121 m_Particles.back().SetStable(
true);
1125 if (bary > 0 && (m_PDGtoID.count(-pdgid) == 0)) {
1127 if (bary != 0) m_NumBaryons++;
1128 if (chg != 0) m_NumCharged++;
1129 if (str != 0) m_NumStrange++;
1130 if (charm != 0) m_NumCharmed++;
1132 if (bary == 0 && name[name.size() - 1] ==
'+')
1133 name[name.size() - 1] =
'-';
1134 else if (bary == 0 && name[name.size() - 1] ==
'-')
1135 name[name.size() - 1] =
'+';
1137 name =
"anti-" + name;
1138 m_Particles.push_back(ThermalParticle((
bool)stable, name, -pdgid, degeneracy, stat, mass, -str, -bary, -chg, abss, width, threshold, -charm, absc));
1139 m_Particles.back().SetAntiParticle(
true);
1140 m_PDGtoID[pdgid] = m_Particles.size() - 1;
1148 for (
size_t i = 0; i < m_Particles.size(); ++i) {
1149 if (m_Particles[i].BaryonCharge() < 0)
1153 FinalizeDecaysLoad();
1161 std::ofstream fout(OutputFile.c_str());
1162 if (fout.is_open()) {
1163 fout <<
"# the list of decays" << std::endl;
1164 fout <<
"# each entry consists of the following:" << std::endl;
1165 fout <<
"# a line with the pdgid of decaying particle" << std::endl;
1166 fout <<
"# a line with the number of decay channels" << std::endl;
1167 fout <<
"# for each channel a line containing whitespace-separated values of the channel branching ratio and pdg ids of the daughter products" << std::endl;
1168 fout <<
"# everything after the # symbol is treated as a comment and ignored" << std::endl;
1169 fout <<
"# decays of antiparticles are not listed but generated from the listed decays of particles" << std::endl;
1172 for (
unsigned int i = 0; i < m_Particles.size(); ++i) {
1173 if ((m_Particles[i].PdgId()>0 || WriteAntiParticles) && m_Particles[i].Decays().size()>0) {
1174 fout << std::left << std::setw(36) << m_Particles[i].PdgId();
1175 fout <<
" # " << m_Particles[i].Name() << std::endl;
1177 fout << std::left << std::setw(36) << m_Particles[i].Decays().size();
1178 fout <<
" # " << m_Particles[i].Decays().size() <<
" decay channel";
1179 if (m_Particles[i].Decays().size() % 10 != 1 || m_Particles[i].Decays().size() % 100 == 11) fout <<
"s";
1182 for (
unsigned int j = 0; j < m_Particles[i].Decays().size(); ++j) {
1183 fout << std::left << std::setw(15) << m_Particles[i].Decays()[j].mBratio <<
" ";
1184 std::ostringstream oss;
1185 for (
unsigned int k = 0; k < m_Particles[i].Decays()[j].mDaughters.size(); ++k) {
1186 oss << m_Particles[i].Decays()[j].mDaughters[k];
1187 if (k != m_Particles[i].Decays()[j].mDaughters.size() - 1)
1190 fout << std::left << std::setw(20) << oss.str();
1191 fout <<
" # " << m_Particles[i].Name() <<
" -> ";
1192 for (
unsigned int k = 0; k < m_Particles[i].Decays()[j].mDaughters.size(); ++k) {
1193 if (m_PDGtoID.count(m_Particles[i].Decays()[j].mDaughters[k]) == 0) {
1195 long long tpdg = m_Particles[i].Decays()[j].mDaughters[k];
1201 fout << m_Particles[m_PDGtoID[m_Particles[i].Decays()[j].mDaughters[k]]].Name();
1202 if (k != m_Particles[i].Decays()[j].mDaughters.size() - 1)
1215 void ThermalParticleSystem::ReadDecays_OldFormat(std::ifstream & fin)
1217 vector< ThermalParticle::ParticleDecaysVector > decays(0);
1218 vector<long long> pdgids(0);
1219 map<long long, int> decaymap;
1222 if (fin.is_open()) {
1223 int decaypartnumber = 0;
1224 fin >> decaypartnumber;
1225 decays.reserve(decaypartnumber);
1227 for (
int i = 0; i < decaypartnumber; ++i) {
1228 int decaysnumber, daughters;
1229 long long pdgid, tmpid;
1231 fin >> pdgid >> decaysnumber;
1232 decaymap[pdgid] = i;
1234 pdgids.push_back(pdgid);
1235 for (
int j = 0; j < decaysnumber; ++j) {
1238 decay.
mBratio = bratio / 100.;
1241 for (
int k = 0; k < daughters; ++k) {
1245 decays[i].push_back(decay);
1250 for (
size_t i = 0; i < m_Particles.size(); ++i) {
1251 if (decaymap.count(m_Particles[i].PdgId()) != 0)
1252 m_Particles[i].SetDecays(decays[decaymap[m_Particles[i].PdgId()]]);
1258 if (m_PDGtoID.count(pdgid) != 0)
1259 return m_Particles[m_PDGtoID[pdgid]].Name();
1260 if (pdgid == 1)
return string(
"Npart");
1261 if (pdgid == 310)
return string(
"K0S");
1262 if (pdgid == 130)
return string(
"K0L");
1263 if (pdgid % 10 == 0) {
1264 long long tpdgid = pdgid / 10;
1266 return m_Particles[
PdgToId(tpdgid)].Name() +
"+" + m_Particles[
PdgToId(-tpdgid)].Name();
1268 if (pdgid == 22122112)
return string(
"p+n");
1288 m_QStatsCalculationType = type;
1289 for (
size_t i = 0; i < m_Particles.size(); ++i)
1295 for (
size_t i = 0; i < m_Particles.size(); ++i)
1301 m_ResonanceWidthShape = shape;
1302 for (
size_t i = 0; i < m_Particles.size(); ++i)
1308 bool dodecays = (type != m_ResonanceWidthIntegrationType);
1310 m_ResonanceWidthIntegrationType = type;
1312 for (
size_t i = 0; i < m_Particles.size(); ++i) {
1313 if (!m_Particles[i].ZeroWidthEnforced())
1314 m_Particles[i].SetResonanceWidthIntegrationType(type);
1323 if (id < 0 || id >=
static_cast<int>(m_Particles.size())) {
1324 throw std::out_of_range(
"ThermalParticleSystem::Particle(int id): id is out of bounds!");
1326 return m_Particles[id];
1331 if (id < 0 || id >=
static_cast<int>(m_Particles.size())) {
1332 throw std::out_of_range(
"ThermalParticleSystem::Particle(int id): id is out of bounds!");
1334 return m_Particles[id];
1341 throw std::invalid_argument(
"ThermalParticleSystem::ParticleByPDG(long long pdgid): pdgid " + std::to_string(pdgid) +
" is unknown");
1343 return m_Particles[id];
1350 throw std::invalid_argument(
"ThermalParticleSystem::ParticleByPDG(long long pdgid): pdgid " + std::to_string(pdgid) +
" is unknown");
1352 return m_Particles[id];
1357 map<long long, int>::const_iterator it = m_PDGtoID.find(pdgid);
1359 if (it != m_PDGtoID.end()) {
1369 m_NumBaryons = m_NumCharged = m_NumStrange = m_NumCharmed = 0;
1370 m_MaxAbsBaryonNumber = 0;
1371 m_NumberOfParticles = 0;
1373 for (
size_t i = 0; i < m_Particles.size(); ++i) {
1374 m_PDGtoID[m_Particles[i].PdgId()] = i;
1375 if (m_Particles[i].BaryonCharge() != 0) m_NumBaryons++;
1376 if (m_Particles[i].ElectricCharge() != 0) m_NumCharged++;
1377 if (m_Particles[i].Strangeness() != 0) m_NumStrange++;
1378 if (m_Particles[i].Charm() != 0) m_NumCharmed++;
1379 if (m_Particles[i].PdgId() > 0) m_NumberOfParticles++;
1380 m_MaxAbsBaryonNumber = max(m_MaxAbsBaryonNumber, abs(m_Particles[i].BaryonCharge()));
1383 for (
size_t i = 0; i < m_DecayContributionsByFeeddown.size(); ++i)
1384 m_DecayContributionsByFeeddown[i].resize(m_Particles.size());
1390 sort(m_Particles.begin(), m_Particles.end(), cmpParticleMass);
1392 sort(m_Particles.begin(), m_Particles.end(), cmpParticleMassAndPdg);
1394 sort(m_Particles.begin(), m_Particles.end(), cmpParticlePDG);
1396 for (
size_t i = 0; i < m_Particles.size(); ++i) {
1404 m_Particles.push_back(part);
1410 if (ind >= 0 && ind <
static_cast<int>(m_Particles.size())) {
1411 m_Particles.erase(m_Particles.begin() + ind);
1419 for (
int i = 0; i < check.size(); ++i)
1429 for (
int i = 0; i <
Particles().size(); ++i) {
1432 printf(
"**WARNING** %s (%lld): Particle marked unstable but no decay channels found!\n",
1433 part.
Name().c_str(),
1439 printf(
"**WARNING** Further warnings are discarded...\n");
1449 for (
int i = 0; i <
Particles().size(); ++i) {
1452 std::cerr <<
"**WARNING** " << part.
Name() <<
" (" << part.
PdgId() <<
"): Particle with non-zero strangeness has zero strange quark content |s|!" << std::endl;
1457 std::cerr <<
"**WARNING** " << part.
Name() <<
" (" << part.
PdgId() <<
"): Particle with non-zero charm has zero charm quark content |s|!" << std::endl;
1470 int goalC = part.
Charm();
1472 std::map<long long, int> tPDGtoID = m_PDGtoID;
1474 std::vector<int> ret(4, 1);
1476 for (
size_t i = 0; i < part.
Decays().size(); ++i) {
1477 int decB = 0, decQ = 0, decS = 0, decC = 0;
1478 for (
size_t j = 0; j < part.
Decays()[i].mDaughters.size(); ++j) {
1479 long long tpdg = part.
Decays()[i].mDaughters[j];
1480 if (tPDGtoID.count(tpdg) != 0) {
1481 int tid = tPDGtoID[tpdg];
1482 decB +=
Particles()[tid].BaryonCharge();
1483 decQ +=
Particles()[tid].ElectricCharge();
1512 ret &= m_PDGtoID == rhs.m_PDGtoID;
1513 ret &= m_NumBaryons == rhs.m_NumBaryons;
1514 ret &= m_NumCharged == rhs.m_NumCharged;
1515 ret &= m_NumStrange == rhs.m_NumStrange;
1516 ret &= m_NumCharmed == rhs.m_NumCharmed;
1517 ret &= m_MaxAbsBaryonNumber == rhs.m_MaxAbsBaryonNumber;
1518 ret &= m_NumberOfParticles == rhs.m_NumberOfParticles;
1519 ret &= m_ResonanceWidthIntegrationType == rhs.m_ResonanceWidthIntegrationType;
1520 ret &= m_DecayDistributionsMap == rhs.m_DecayDistributionsMap;
1522 ret &= m_Particles == rhs.m_Particles;
1530 set<long long> stablePDG;
1531 stablePDG.insert(2212); stablePDG.insert(-2212);
1532 stablePDG.insert(2112); stablePDG.insert(-2112);
1533 stablePDG.insert(1000010020); stablePDG.insert(-1000010020);
1534 stablePDG.insert(1000020030); stablePDG.insert(-1000020030);
1535 stablePDG.insert(1000010030); stablePDG.insert(-1000010030);
1536 stablePDG.insert(1000020040); stablePDG.insert(-1000020040);
1538 if (stablePDG.count(part.
PdgId()) > 0) {
1543 set<long long> weakPDG;
1544 weakPDG.insert(310);
1545 weakPDG.insert(130);
1546 weakPDG.insert(211); weakPDG.insert(-211);
1547 weakPDG.insert(321); weakPDG.insert(-321);
1548 weakPDG.insert(3122); weakPDG.insert(-3122);
1549 weakPDG.insert(3222); weakPDG.insert(-3222);
1550 weakPDG.insert(3112); weakPDG.insert(-3112);
1551 weakPDG.insert(3322); weakPDG.insert(-3322);
1552 weakPDG.insert(3312); weakPDG.insert(-3312);
1553 weakPDG.insert(3334); weakPDG.insert(-3334);
1554 weakPDG.insert(411); weakPDG.insert(-411);
1555 weakPDG.insert(421); weakPDG.insert(-421);
1556 weakPDG.insert(431); weakPDG.insert(-431);
1557 weakPDG.insert(4232); weakPDG.insert(-4232);
1558 weakPDG.insert(4132); weakPDG.insert(-4132);
1559 weakPDG.insert(4422); weakPDG.insert(-4422);
1560 weakPDG.insert(4412); weakPDG.insert(-4412);
1561 weakPDG.insert(4332); weakPDG.insert(-4332);
1563 if (weakPDG.count(part.
PdgId()) > 0) {
1569 set<long long> emPDG;
1573 emPDG.insert(3212); emPDG.insert(-3212);
1575 if (emPDG.count(part.
PdgId()) > 0) {
1596 m_DecayContributionsByFeeddown[
Feeddown::Weak].resize(m_Particles.size());
1598 m_DecayContributionsByFeeddown[
Feeddown::Strong].resize(m_Particles.size());
1599 for (
size_t i = 0; i < m_Particles.size(); ++i) {
1604 for (
int i =
static_cast<int>(m_Particles.size()) - 1; i >= 0; i--)
1606 GoResonanceByFeeddown(i, i, 1.,
Feeddown::Type(
static_cast<int>(m_Particles[i].DecayType())));
1610 void ThermalParticleSystem::GoResonanceByFeeddown(
int ind,
int startind,
double BR,
Feeddown::Type feeddown) {
1612 if (
static_cast<int>(feeddown) < feed_index)
continue;
1615 if (ind != startind && decayContributions.size() > 0 && decayContributions[decayContributions.size() - 1].second == startind)
1617 decayContributions[decayContributions.size() - 1].first += BR;
1619 else if (ind != startind) {
1620 decayContributions.push_back(make_pair(BR, startind));
1626 for (
size_t i = 0; i < m_Particles[ind].Decays().size(); ++i) {
1627 const ParticleDecayChannel& decaychannel = m_Particles[ind].Decays()[i];
1628 double tbr = decaychannel.mBratio;
1631 tbr = decaychannel.mBratioAverage;
1633 for (
size_t j = 0; j < decaychannel.mDaughters.size(); ++j) {
1634 if (m_PDGtoID.count(decaychannel.mDaughters[j]) != 0)
1635 GoResonanceByFeeddown(m_PDGtoID[decaychannel.mDaughters[j]], startind, BR*tbr,
Feeddown::Type(
static_cast<int>(m_Particles[ind].DecayType())));
1643 for (
size_t i = 0; i < m_Particles.size(); ++i) {
1644 ret[i] =
static_cast<double>(m_Particles[i].ConservedCharge(charge));
1651 std::vector<std::string>&
split(
const std::string& s,
char delim, std::vector<std::string>& elems) {
1652 std::stringstream ss(s);
1654 while (std::getline(ss, item, delim)) {
1655 elems.push_back(item);
1660 std::vector<std::string>
split(
const std::string& s,
char delim) {
1661 std::vector<std::string> elems;
1662 split(s, delim, elems);
1668 if (
static_cast<int>(vect.size()) > maxsize) {
1669 std::sort(vect.begin(), vect.end());
1670 std::reverse(vect.begin(), vect.end());
1671 vect.resize(maxsize);
1676 namespace DecayLifetimes {
1707 if (
widths.count(abs(pdg))) {
1708 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=2000)
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.