27 int Strange,
int Baryon,
int Charge,
double AbsS,
double Width,
double Threshold,
int Charm,
double AbsC,
int Quark) :
28 m_Stable(Stable), m_AntiParticle(false), m_Name(
Name), m_PDGID(PDGID), m_Degeneracy(Deg), m_Statistics(Stat), m_StatisticsOrig(Stat), m_Mass(
Mass),
29 m_Strangeness(Strange), m_Baryon(Baryon), m_ElectricCharge(Charge), m_Charm(
Charm), m_ArbitraryCharge(Baryon), m_AbsS(AbsS), m_AbsC(AbsC), m_Width(Width), m_Threshold(Threshold), m_Quark(Quark), m_Weight(1.),
77 m_Threshold = threshold;
78 if (m_Threshold < 0.0) {
79 std::cerr <<
"**WARNING** Trying to set negative decay threshold for " << m_Name <<
", setting to zero instead" << std::endl;
86 m_ThresholdDynamical = threshold;
87 if (m_ThresholdDynamical < 0.0) {
88 std::cerr <<
"**WARNING** Trying to set negative dynamical decay threshold for " << m_Name <<
", setting to zero instead" << std::endl;
94 double Thr = m_Mass + m_Width;
95 for (
size_t i = 0; i < m_Decays.size(); ++i) {
96 Thr = min(Thr, m_Decays[i].mM0);
98 m_ThresholdDynamical = Thr;
103 if (shape != m_ResonanceWidthShape) {
104 m_ResonanceWidthShape = shape;
111 m_ResonanceWidthIntegrationType = type;
124 if (width < 0.) width = m_Width;
135 return m_Mass * width * m / ((m * m - m_Mass * m_Mass)*(m * m - m_Mass * m_Mass) + m_Mass * m_Mass*width*width);
137 return width / ((m - m_Mass)*(m - m_Mass) + width * width / 4.);
142 ifstream fin(filename.c_str());
143 if (!fin.is_open()) {
144 std::cerr <<
"Error: Could not open file " << filename << endl;
149 while (fin >> tmpbr) {
152 fin.getline(cc, 350);
156 while (ss >> tmpid) {
159 m_Decays.push_back(decay);
166 if (!useWidth || m_Width == 0.0 ||
ZeroWidthEnforced() || m_ResonanceWidthIntegrationType !=
eBW) {
167 for (
size_t j = 0; j < m_Decays.size(); ++j) {
168 m_Decays[j].mBratioAverage = m_Decays[j].mBratio;
173 if (!(
params.gammaS == 1. || m_AbsS == 0.)) mu += log(
params.gammaS) * m_AbsS *
params.T;
174 if (!(
params.gammaC == 1. || m_AbsC == 0.)) mu += log(
params.gammaC) * m_AbsC *
params.T;
176 for (
size_t j = 0; j < m_Decays.size(); ++j) {
177 m_Decays[j].mBratioAverage = 0.;
180 double ret1 = 0., ret2 = 0., tmp = 0.;
181 for (
size_t i = 0; i < m_xalldyn.size(); i++) {
187 for (
size_t j = 0; j < m_Decays.size(); ++j) {
188 const_cast<double&
>(m_Decays[j].mBratioAverage) += tmp * dens * m_Decays[j].mBratioVsM[i];
192 for (
size_t j = 0; j < m_Decays.size(); ++j) {
194 m_Decays[j].mBratioAverage /= ret1;
196 m_Decays[j].mBratioAverage = m_Decays[j].mBratio;
203 std::vector<double> ret = ms;
205 std::vector<double> mthr, br;
207 for (
size_t i = 0; i < m_Decays.size(); ++i) {
208 mthr.push_back(m_Decays[i].mM0);
209 br.push_back(m_Decays[i].mBratio);
210 tsum += m_Decays[i].mBratio;
214 br.push_back(1. - tsum);
216 else if (tsum > 1.) {
217 for (
size_t i = 0; i < br.size(); ++i)
221 for (
size_t i = 0; i < ms.size(); ++i) {
223 for (
size_t j = 0; j < br.size(); ++j) {
224 if (mthr[j] <= ms[i])
234 string name =
Name();
235 if (
BaryonCharge() == 0 && name[name.size() - 1] ==
'+')
236 name[name.size() - 1] =
'-';
237 else if (
BaryonCharge() == 0 && name[name.size() - 1] ==
'-')
238 name[name.size() - 1] =
'+';
240 name =
"anti-" + name;
271 ret &= m_Stable == rhs.m_Stable;
272 ret &= m_AntiParticle == rhs.m_AntiParticle;
273 ret &= m_Name == rhs.m_Name;
274 ret &= m_PDGID == rhs.m_PDGID;
275 ret &= m_Degeneracy == rhs.m_Degeneracy;
276 ret &= m_Statistics == rhs.m_Statistics;
277 ret &= m_StatisticsOrig == rhs.m_StatisticsOrig;
278 ret &= m_Mass == rhs.m_Mass;
279 ret &= m_QuantumStatisticsCalculationType == rhs.m_QuantumStatisticsCalculationType;
280 ret &= m_ClusterExpansionOrder == rhs.m_ClusterExpansionOrder;
281 ret &= m_Baryon == rhs.m_Baryon;
282 ret &= m_ElectricCharge == rhs.m_ElectricCharge;
283 ret &= m_Strangeness == rhs.m_Strangeness;
284 ret &= m_Charm == rhs.m_Charm;
285 ret &= m_Quark == rhs.m_Quark;
286 ret &= m_ArbitraryCharge == rhs.m_ArbitraryCharge;
287 ret &= m_AbsQuark == rhs.m_AbsQuark;
288 ret &= m_AbsS == rhs.m_AbsS;
289 ret &= m_AbsC == rhs.m_AbsC;
290 ret &= m_Width == rhs.m_Width;
291 ret &= m_Threshold == rhs.m_Threshold;
292 ret &= m_ThresholdDynamical == rhs.m_ThresholdDynamical;
293 ret &= m_ResonanceWidthShape == rhs.m_ResonanceWidthShape;
294 ret &= m_ResonanceWidthIntegrationType == rhs.m_ResonanceWidthIntegrationType;
295 ret &= m_Weight == rhs.m_Weight;
296 ret &= m_DecayType == rhs.m_DecayType;
297 ret &= m_Decays == rhs.m_Decays;
298 ret &= m_DecaysOrig == rhs.m_DecaysOrig;
305 for (
size_t i = 0; i < m_Decays.size(); ++i) {
306 sum += m_Decays[i].mBratio;
308 for (
size_t i = 0; i < m_Decays.size(); ++i) {
309 m_Decays[i].mBratio *= 1. / sum;
317 for (
size_t i = 0; i < m_Decays.size(); ++i) {
318 m_Decays[i].mBratio = m_DecaysOrig[i].mBratio;
325 if (m_ResonanceWidthIntegrationType !=
BWTwoGamma && m_Threshold >= 0.) {
327 b = m_Mass + 2.*m_Width;
332 a = max(m_Threshold, m_Mass - 2.*m_Width);
333 b = m_Mass + 2.*m_Width;
349 if (m_Width == 0.0)
return;
353 if (m_Decays.size() == 0)
354 m_Threshold = m_ThresholdDynamical = m_Mass - 2.*m_Width + 1.e-6;
357 a = m_ThresholdDynamical;
359 b = m_Mass + 2.*m_Width;
360 if (a >= m_Mass - 2.*m_Width) {
361 m_xlegpdyn.resize(0);
362 if (a >= m_Mass + 2.*m_Width)
373 m_vallegpdyn = m_xlegpdyn;
374 m_vallegdyn = m_xlegdyn;
375 m_vallagdyn = m_xlagdyn;
380 vector<double> tCP(m_Decays.size(), 0.);
382 for (
size_t i = 0; i < m_Decays.size(); ++i) {
383 tsumb += m_Decays[i].mBratio;
384 m_Decays[i].mBratioVsM.resize(0);
387 for (
size_t j = 0; j < m_xlegpdyn.size(); ++j) {
390 for (
size_t i = 0; i < m_Decays.size(); ++i) {
391 twid += m_Decays[i].ModifiedWidth(m_xlegpdyn[j]) * m_Width;
395 twid += (1. - tsumb) * m_Width;
398 m_vallegpdyn[j] = 0.;
399 for (
size_t i = 0; i < m_Decays.size(); ++i)
400 m_Decays[i].mBratioVsM.push_back(m_Decays[i].mBratio);
404 for (
size_t i = 0; i < m_Decays.size(); ++i) {
405 double ttwid = m_Decays[i].ModifiedWidth(m_xlegpdyn[j]) * m_Width;
406 m_Decays[i].mBratioVsM.push_back(ttwid / twid);
407 tCP[i] += m_wlegpdyn[j] * ttwid / twid *
MassDistribution(m_xlegpdyn[j], twid);
414 for (
size_t j = 0; j < m_xlegdyn.size(); ++j) {
417 for (
size_t i = 0; i < m_Decays.size(); ++i) {
418 twid += m_Decays[i].ModifiedWidth(m_xlegdyn[j]) * m_Width;
422 twid += (1. - tsumb) * m_Width;
426 for (
size_t i = 0; i < m_Decays.size(); ++i)
427 m_Decays[i].mBratioVsM.push_back(m_Decays[i].mBratio);
431 for (
size_t i = 0; i < m_Decays.size(); ++i) {
432 double ttwid = m_Decays[i].ModifiedWidth(m_xlegdyn[j]) * m_Width;
433 m_Decays[i].mBratioVsM.push_back(ttwid / twid);
434 tCP[i] += m_wlegdyn[j] * ttwid / twid *
MassDistribution(m_xlegdyn[j], twid);
441 for (
size_t j = 0; j < m_xlagdyn.size(); ++j) {
443 double tx = m_Mass + 2.*m_Width + m_xlagdyn[j] * m_Width;
445 for (
size_t i = 0; i < m_Decays.size(); ++i) {
446 twid += m_Decays[i].ModifiedWidth(tx) * m_Width;
450 twid += (1. - tsumb) * m_Width;
454 for (
size_t i = 0; i < m_Decays.size(); ++i)
455 m_Decays[i].mBratioVsM.push_back(m_Decays[i].mBratio);
459 for (
size_t i = 0; i < m_Decays.size(); ++i) {
460 double ttwid = m_Decays[i].ModifiedWidth(tx) * m_Width;
461 m_Decays[i].mBratioVsM.push_back(ttwid / twid);
462 tCP[i] += m_wlagdyn[j] * m_Width * ttwid / twid *
MassDistribution(tx, twid);
472 for (
size_t j = 0; j < m_xlegpdyn.size(); ++j) {
473 m_xalldyn.push_back(m_xlegpdyn[j]);
474 m_walldyn.push_back(m_wlegpdyn[j] * m_vallegpdyn[j] / tC);
477 for (
size_t j = 0; j < m_xlegdyn.size(); ++j) {
478 m_xalldyn.push_back(m_xlegdyn[j]);
479 m_walldyn.push_back(m_wlegdyn[j] * m_vallegdyn[j] / tC);
482 for (
size_t j = 0; j < m_xlagdyn.size(); ++j) {
483 m_xalldyn.push_back(m_Mass + 2.*m_Width + m_xlagdyn[j] * m_Width);
484 m_walldyn.push_back(m_wlagdyn[j] * m_vallagdyn[j] / tC);
487 m_densalldyn.resize(m_xalldyn.size());
490 for (
size_t j = 0; j < m_walldyn.size(); ++j) {
491 tsum += m_walldyn[j];
507 for (
size_t i = 0; i < m_Decays.size(); ++i) {
508 tsumb += m_Decays[i].mBratio;
512 for (
size_t i = 0; i < m_Decays.size(); ++i) {
513 twid += m_Decays[i].ModifiedWidth(M) * m_Width;
517 twid += (1. - tsumb) * m_Width;
524 std::vector<double> ret(m_Decays.size(), 0.);
527 for (
size_t i = 0; i < m_Decays.size(); ++i)
528 ret[i] = m_Decays[i].mBratio;
535 for (
size_t i = 0; i < m_Decays.size(); ++i) {
536 double partialwid = m_Decays[i].ModifiedWidth(M) * m_Width;
537 ret[i] = partialwid / totwid;
554 if (!enable) m_Statistics = 0;
555 else m_Statistics = m_StatisticsOrig;
561 if (m_Width != 0.0) {
581 return (m_Baryon == 0 && m_ElectricCharge == 0 && m_Strangeness == 0 && m_Charm == 0);
586 if (m_GeneralizedDensity != NULL)
587 return m_GeneralizedDensity->Quantity(type,
params.T, mu);
589 if (m_Degeneracy == 0.0)
593 if (!(
params.gammaS == 1. || m_AbsS == 0.)) mu += log(
params.gammaS) * m_AbsS *
params.T;
594 if (!(
params.gammaC == 1. || m_AbsC == 0.)) mu += log(
params.gammaC) * m_AbsC *
params.T;
600 int ind = m_xleg.size();
601 const vector<double> &x = m_xleg, &w = m_wleg;
602 double ret1 = 0., ret2 = 0., tmp = 0.;
605 if (m_ResonanceWidthIntegrationType !=
eBW && m_ResonanceWidthIntegrationType !=
eBWconstBR) {
606 for (
int i = 0; i < ind; i++) {
611 tmp *= m_brweight[i];
621 int ind2 = m_xlag32.size();
622 for (
int i = 0; i < ind2; ++i) {
623 double tmass = m_Mass + 2.*m_Width + m_xlag32[i] * m_Width;
632 if (m_ResonanceWidthIntegrationType ==
eBW || m_ResonanceWidthIntegrationType ==
eBWconstBR) {
633 for (
size_t i = 0; i < m_xalldyn.size(); i++) {
651 if (!(
params.gammaS == 1. || m_AbsS == 0.)) mu += log(
params.gammaS) * m_AbsS *
params.T;
652 if (!(
params.gammaC == 1. || m_AbsC == 0.)) mu += log(
params.gammaC) * m_AbsC *
params.T;
658 int ind = m_xleg.size();
659 const vector<double> &x = m_xleg, &w = m_wleg;
660 double ret1 = 0., ret2 = 0., tmp = 0.;
663 if (m_ResonanceWidthIntegrationType !=
eBW && m_ResonanceWidthIntegrationType !=
eBWconstBR) {
664 for (
int i = 0; i < ind; i++) {
668 tmp *= m_brweight[i];
679 int ind2 = m_xlag32.size();
680 for (
int i = 0; i < ind2; ++i) {
681 double tmass = m_Mass + 2.*m_Width + m_xlag32[i] * m_Width;
690 if (m_ResonanceWidthIntegrationType ==
eBW || m_ResonanceWidthIntegrationType ==
eBWconstBR) {
691 for (
size_t i = 0; i < m_xalldyn.size(); i++) {
699 return mn * ret1 / ret2;
714 if (m_Degeneracy == 0.0)
return 1.;
715 if (m_Statistics == 0)
return 1.;
717 if (dens == 0.)
return 1.;
719 if (ret != ret) ret = 1.;
725 if (m_Degeneracy == 0)
return 1.;
726 if (m_Statistics == 0)
return 1.;
728 if (dens == 0.)
return 1.;
730 if (ret != ret) ret = 1.;
736 if (m_Degeneracy == 0)
return 1.;
737 if (m_Statistics == 0)
return 1.;
739 if (dens == 0.)
return 1.;
741 if (ret != ret) ret = 1.;
746 double arg = (sqrt(k*k + m * m) - mu) / T;
747 return 1. / (exp(arg) + 1.);
751 if (m_Baryon == 0)
return 2. - m_AbsC - m_AbsS;
752 else return abs(m_Baryon) * 3. - m_AbsC - m_AbsS;
756 if (index == 0)
return (
double)m_Baryon;
757 if (index == 1)
return (
double)m_ElectricCharge;
758 if (index == 2)
return (
double)m_Strangeness;
759 if (index == 3)
return (
double)m_Charm;
764 if (index == 0)
return fabs((
double)m_Baryon);
765 if (index == 1)
return fabs((
double)m_ElectricCharge);
766 if (index == 2)
return m_AbsS;
767 if (index == 3)
return m_AbsC;
781 if (m_GeneralizedDensity != NULL) {
782 delete m_GeneralizedDensity;
783 m_GeneralizedDensity = NULL;
789 m_GeneralizedDensity = density_model;
793 m_IGFExtraConfig.MagneticField.B = B;
794 m_IGFExtraConfig.MagneticField.lmax = lmax;
795 m_IGFExtraConfig.MagneticField.Q =
static_cast<double>(m_ElectricCharge);
796 m_IGFExtraConfig.MagneticField.degSpin = m_Degeneracy;
map< string, double > params
Contains some helper functions.
static bool PrintDisclaimer()
static bool DisclaimerPrinted
Implements the possibility of a generalized calculation of the densities. For example,...
double MassDistribution(double m) const
long long PdgId() const
Particle's Particle Data Group (PDG) ID number.
void SetAntiParticle(bool antpar=true)
Set manually whether particle is an antiparticle.
void SetAbsoluteQuark(double abschg)
Set absolute light quark content |u,d|.
int BaryonCharge() const
Particle's baryon number.
double Kurtosis(const ThermalModelParameters ¶ms, bool useWidth=0, double mu=0.) const
Computes the normalized excess kurtosis of particle number fluctuations in the ideal gas.
void FillCoefficients()
Fills coefficients for mass integration in the energy independent BW scheme.
void RestoreBranchingRatios()
Restores all branching ratios to the original values.
double Mass() const
Particle's mass [GeV].
double ArbitraryCharge() const
Arbitrary (auxiliary) charge assigned to particle.
double chiDimensionfull(int index, const ThermalModelParameters ¶ms, bool useWidth=0, double mu=0.) const
Computes the ideal gas dimensionfull susceptibility .
int Strangeness() const
Particle's strangeness.
void SetCalculationType(IdealGasFunctions::QStatsCalculationType type)
Sets the CalculationType() method to evaluate quantum statistics.
double TotalWidtheBW(double M) const
Total width (eBW scheme) at a given mass.
void SetResonanceWidthShape(ResonanceWidthShape shape)
Set the resonance width profile to use.
void SetDecayThresholdMassDynamical(double threshold)
Set the threshold mass manually for use in the eBW scheme.
double Density(const ThermalModelParameters ¶ms, IdealGasFunctions::Quantity type=IdealGasFunctions::ParticleDensity, bool useWidth=0, double mu=0.) const
Computes a specified ideal gas thermodynamic function.
void SetResonanceWidthIntegrationType(ResonanceWidthIntegration type)
Set the ResonanceWidthIntegration scheme used to treat finite resonance widths.
ResonanceWidthIntegration
Treatment of finite resonance widths.
@ FullIntervalWeighted
Energy-independent Breit-Wigner in full energy interval with weighted branching ratios.
@ eBWconstBR
Energy-dependent Breit-Wigner scheme (eBW) with constant branching ratios when evaluating feeddown.
@ eBW
Energy-dependent Breit-Wigner scheme (eBW)
@ BWTwoGamma
Energy-independent Breit-Wigner in +-2\Gamma interval.
@ FullInterval
Energy-independent Breit-Wigner in full energy interval.
@ ZeroWidth
Zero-width approximation.
void ClearGeneralizedDensity()
Clear the generalized density.
void SetArbitraryCharge(double arbchg)
Assigns arbitrary (auxiliary) charge to particle.
double FD(double k, double T, double mu, double m) const
Fermi-Dirac distribution function.
void ReadDecays(std::string filename="")
Read decays from a file and assign them to the particle.
int ElectricCharge() const
Particle's electric charge.
void SetStrangenessCharge(int chg)
Set particle's strangeness.
ResonanceWidthShape
Relativistic vs non-relativistic Breit-Wigner shape.
@ RelativisticBreitWigner
bool IsNeutral() const
Whether particle is neutral one.
void SetPdgId(long long PdgId)
Set particle's particle's Particle Data Group (PDG) ID number.
void SetDecayThresholdMass(double threshold)
Set the decays threshold mass.
void SetCharm(int chg)
Set particle's charm.
int Charm() const
Particle's charm.
double chi(int index, const ThermalModelParameters ¶ms, bool useWidth=0, double mu=0.) const
Computes the ideal gas generalized susceptibility .
ThermalParticle(bool Stable=true, std::string Name="hadron", long long PDGID=0, double Deg=1., int Stat=0, double Mass=0., int Strange=0, int Baryon=0, int Charge=0, double AbsS=0., double Width=0., double Threshold=0., int Charm=0, double AbsC=0., int Quark=0)
Construct a new ThermalParticle object.
double ThermalMassDistribution(double M, double T, double Mu, double width)
Mass distribution of a resonance in a thermal environment.
void SetMass(double mass)
Set particle's mass [GeV].
double DensityCluster(int n, const ThermalModelParameters ¶ms, IdealGasFunctions::Quantity type=IdealGasFunctions::ParticleDensity, bool useWidth=0, double mu=0.) const
void SetBaryonCharge(int chg)
Set particle's baryon number.
void CalculateAndSetDynamicalThreshold()
void SetMagneticField(double B=0.0, int lmax=1)
Sets the value of magnetic field and the number of Landau levels to include.
double Skewness(const ThermalModelParameters ¶ms, bool useWidth=0, double mu=0.) const
Computes the normalized skewness of particle number fluctuations in the ideal gas.
double GetCharge(int index) const
Get the quantum number numbered by the index.
bool operator==(const ThermalParticle &rhs) const
const std::string & Name() const
Particle's name.
int ConservedCharge(ConservedCharge::Name chg) const
One of the four QCD conserved charges.
double ResonanceWidth() const
Particle's width at the pole mass (GeV)
std::vector< double > BranchingRatioWeights(const std::vector< double > &ms) const
void SetGeneralizedDensity(GeneralizedDensity *density_model)
void SetResonanceWidth(double width)
Sets the particle's width at the pole mass.
void SetName(const std::string &name)
Set particle's name.
ThermalParticle GenerateAntiParticle() const
Generates the anti-particle to the current particle specie.
void NormalizeBranchingRatios()
Normalizes all branching ratios such that they sum up to 100%.
void UseStatistics(bool enable)
Use quantum statistics.
std::vector< double > BranchingRatiosM(double M, bool eBW=true) const
(Energy-dependent) branching ratios
bool ZeroWidthEnforced() const
Whether zero-width approximation is enforced for this particle species.
void SetElectricCharge(int chg)
Set particle's electric charge.
void FillCoefficientsDynamical()
Fills coefficients for mass integration in the eBW scheme.
void CalculateThermalBranchingRatios(const ThermalModelParameters ¶ms, bool useWidth=0, double mu=0.)
Computes average decay branching ratios by integrating over the thermal mass distribution.
double GetAbsCharge(int index) const
Get the absolute value of a quantum number.
double ScaledVariance(const ThermalModelParameters ¶ms, bool useWidth=0, double mu=0.) const
Computes the scaled variance of particle number fluctuations in the ideal gas. Computes the scaled va...
void SetClusterExpansionOrder(int order)
Set ClusterExpansionOrder()
double IdealGasQuantity(Quantity quantity, QStatsCalculationType calctype, int statistics, double T, double mu, double m, double deg, int order=1, const IdealGasFunctionsExtraConfig &extraConfig=IdealGasFunctionsExtraConfig())
Calculation of a generic ideal gas function.
Quantity
Identifies the thermodynamic function.
void GetCoefsIntegrateLegendre10(double a, double b, std::vector< double > *x, std::vector< double > *w)
void GetCoefsIntegrateLegendre32(double a, double b, std::vector< double > *x, std::vector< double > *w)
void GetCoefsIntegrateLaguerre32(std::vector< double > *x, std::vector< double > *w)
constexpr double GeVtoifm()
A constant to transform GeV into fm .
The main namespace where all classes and functions of the Thermal-FIST library reside.
Name
Set of all conserved charges considered.
@ BaryonCharge
Baryon number.
@ StrangenessCharge
Strangeness.
@ ElectricCharge
Electric charge.
Structure containing information about a single decay channel of a particle.
std::vector< long long > mDaughters
Structure containing all thermal parameters of the model.
Contains some extra mathematical functions used in the code.