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);
165 if (!useWidth || m_Width == 0.0 || m_Width / m_Mass < 1.e-2 || m_ResonanceWidthIntegrationType !=
eBW) {
166 for (
size_t j = 0; j < m_Decays.size(); ++j) {
167 m_Decays[j].mBratioAverage = m_Decays[j].mBratio;
172 if (!(
params.gammaS == 1. || m_AbsS == 0.)) mu += log(
params.gammaS) * m_AbsS *
params.T;
173 if (!(
params.gammaC == 1. || m_AbsC == 0.)) mu += log(
params.gammaC) * m_AbsC *
params.T;
175 for (
size_t j = 0; j < m_Decays.size(); ++j) {
176 m_Decays[j].mBratioAverage = 0.;
179 double ret1 = 0., ret2 = 0., tmp = 0.;
180 for (
size_t i = 0; i < m_xalldyn.size(); i++) {
186 for (
size_t j = 0; j < m_Decays.size(); ++j) {
187 const_cast<double&
>(m_Decays[j].mBratioAverage) += tmp * dens * m_Decays[j].mBratioVsM[i];
191 for (
size_t j = 0; j < m_Decays.size(); ++j) {
193 m_Decays[j].mBratioAverage /= ret1;
195 m_Decays[j].mBratioAverage = m_Decays[j].mBratio;
202 std::vector<double> ret = ms;
204 std::vector<double> mthr, br;
206 for (
size_t i = 0; i < m_Decays.size(); ++i) {
207 mthr.push_back(m_Decays[i].mM0);
208 br.push_back(m_Decays[i].mBratio);
209 tsum += m_Decays[i].mBratio;
213 br.push_back(1. - tsum);
215 else if (tsum > 1.) {
216 for (
size_t i = 0; i < br.size(); ++i)
220 for (
size_t i = 0; i < ms.size(); ++i) {
222 for (
size_t j = 0; j < br.size(); ++j) {
223 if (mthr[j] <= ms[i])
233 string name =
Name();
234 if (
BaryonCharge() == 0 && name[name.size() - 1] ==
'+')
235 name[name.size() - 1] =
'-';
236 else if (
BaryonCharge() == 0 && name[name.size() - 1] ==
'-')
237 name[name.size() - 1] =
'+';
239 name =
"anti-" + name;
270 ret &= m_Stable == rhs.m_Stable;
271 ret &= m_AntiParticle == rhs.m_AntiParticle;
272 ret &= m_Name == rhs.m_Name;
273 ret &= m_PDGID == rhs.m_PDGID;
274 ret &= m_Degeneracy == rhs.m_Degeneracy;
275 ret &= m_Statistics == rhs.m_Statistics;
276 ret &= m_StatisticsOrig == rhs.m_StatisticsOrig;
277 ret &= m_Mass == rhs.m_Mass;
278 ret &= m_QuantumStatisticsCalculationType == rhs.m_QuantumStatisticsCalculationType;
279 ret &= m_ClusterExpansionOrder == rhs.m_ClusterExpansionOrder;
280 ret &= m_Baryon == rhs.m_Baryon;
281 ret &= m_ElectricCharge == rhs.m_ElectricCharge;
282 ret &= m_Strangeness == rhs.m_Strangeness;
283 ret &= m_Charm == rhs.m_Charm;
284 ret &= m_Quark == rhs.m_Quark;
285 ret &= m_ArbitraryCharge == rhs.m_ArbitraryCharge;
286 ret &= m_AbsQuark == rhs.m_AbsQuark;
287 ret &= m_AbsS == rhs.m_AbsS;
288 ret &= m_AbsC == rhs.m_AbsC;
289 ret &= m_Width == rhs.m_Width;
290 ret &= m_Threshold == rhs.m_Threshold;
291 ret &= m_ThresholdDynamical == rhs.m_ThresholdDynamical;
292 ret &= m_ResonanceWidthShape == rhs.m_ResonanceWidthShape;
293 ret &= m_ResonanceWidthIntegrationType == rhs.m_ResonanceWidthIntegrationType;
294 ret &= m_Weight == rhs.m_Weight;
295 ret &= m_DecayType == rhs.m_DecayType;
296 ret &= m_Decays == rhs.m_Decays;
297 ret &= m_DecaysOrig == rhs.m_DecaysOrig;
304 for (
size_t i = 0; i < m_Decays.size(); ++i) {
305 sum += m_Decays[i].mBratio;
307 for (
size_t i = 0; i < m_Decays.size(); ++i) {
308 m_Decays[i].mBratio *= 1. / sum;
316 for (
size_t i = 0; i < m_Decays.size(); ++i) {
317 m_Decays[i].mBratio = m_DecaysOrig[i].mBratio;
324 if (m_ResonanceWidthIntegrationType !=
BWTwoGamma && m_Threshold >= 0.) {
326 b = m_Mass + 2.*m_Width;
331 a = max(m_Threshold, m_Mass - 2.*m_Width);
332 b = m_Mass + 2.*m_Width;
348 if (m_Width == 0.0)
return;
352 if (m_Decays.size() == 0)
353 m_Threshold = m_ThresholdDynamical = m_Mass - 2.*m_Width + 1.e-6;
356 a = m_ThresholdDynamical;
358 b = m_Mass + 2.*m_Width;
359 if (a >= m_Mass - 2.*m_Width) {
360 m_xlegpdyn.resize(0);
361 if (a >= m_Mass + 2.*m_Width)
372 m_vallegpdyn = m_xlegpdyn;
373 m_vallegdyn = m_xlegdyn;
374 m_vallagdyn = m_xlagdyn;
379 vector<double> tCP(m_Decays.size(), 0.);
381 for (
size_t i = 0; i < m_Decays.size(); ++i) {
382 tsumb += m_Decays[i].mBratio;
383 m_Decays[i].mBratioVsM.resize(0);
386 for (
size_t j = 0; j < m_xlegpdyn.size(); ++j) {
389 for (
size_t i = 0; i < m_Decays.size(); ++i) {
390 twid += m_Decays[i].ModifiedWidth(m_xlegpdyn[j]) * m_Width;
394 twid += (1. - tsumb) * m_Width;
397 m_vallegpdyn[j] = 0.;
398 for (
size_t i = 0; i < m_Decays.size(); ++i)
399 m_Decays[i].mBratioVsM.push_back(m_Decays[i].mBratio);
403 for (
size_t i = 0; i < m_Decays.size(); ++i) {
404 double ttwid = m_Decays[i].ModifiedWidth(m_xlegpdyn[j]) * m_Width;
405 m_Decays[i].mBratioVsM.push_back(ttwid / twid);
406 tCP[i] += m_wlegpdyn[j] * ttwid / twid *
MassDistribution(m_xlegpdyn[j], twid);
413 for (
size_t j = 0; j < m_xlegdyn.size(); ++j) {
416 for (
size_t i = 0; i < m_Decays.size(); ++i) {
417 twid += m_Decays[i].ModifiedWidth(m_xlegdyn[j]) * m_Width;
421 twid += (1. - tsumb) * m_Width;
425 for (
size_t i = 0; i < m_Decays.size(); ++i)
426 m_Decays[i].mBratioVsM.push_back(m_Decays[i].mBratio);
430 for (
size_t i = 0; i < m_Decays.size(); ++i) {
431 double ttwid = m_Decays[i].ModifiedWidth(m_xlegdyn[j]) * m_Width;
432 m_Decays[i].mBratioVsM.push_back(ttwid / twid);
433 tCP[i] += m_wlegdyn[j] * ttwid / twid *
MassDistribution(m_xlegdyn[j], twid);
440 for (
size_t j = 0; j < m_xlagdyn.size(); ++j) {
442 double tx = m_Mass + 2.*m_Width + m_xlagdyn[j] * m_Width;
444 for (
size_t i = 0; i < m_Decays.size(); ++i) {
445 twid += m_Decays[i].ModifiedWidth(tx) * m_Width;
449 twid += (1. - tsumb) * m_Width;
453 for (
size_t i = 0; i < m_Decays.size(); ++i)
454 m_Decays[i].mBratioVsM.push_back(m_Decays[i].mBratio);
458 for (
size_t i = 0; i < m_Decays.size(); ++i) {
459 double ttwid = m_Decays[i].ModifiedWidth(tx) * m_Width;
460 m_Decays[i].mBratioVsM.push_back(ttwid / twid);
461 tCP[i] += m_wlagdyn[j] * m_Width * ttwid / twid *
MassDistribution(tx, twid);
471 for (
size_t j = 0; j < m_xlegpdyn.size(); ++j) {
472 m_xalldyn.push_back(m_xlegpdyn[j]);
473 m_walldyn.push_back(m_wlegpdyn[j] * m_vallegpdyn[j] / tC);
476 for (
size_t j = 0; j < m_xlegdyn.size(); ++j) {
477 m_xalldyn.push_back(m_xlegdyn[j]);
478 m_walldyn.push_back(m_wlegdyn[j] * m_vallegdyn[j] / tC);
481 for (
size_t j = 0; j < m_xlagdyn.size(); ++j) {
482 m_xalldyn.push_back(m_Mass + 2.*m_Width + m_xlagdyn[j] * m_Width);
483 m_walldyn.push_back(m_wlagdyn[j] * m_vallagdyn[j] / tC);
486 m_densalldyn.resize(m_xalldyn.size());
489 for (
size_t j = 0; j < m_walldyn.size(); ++j) {
490 tsum += m_walldyn[j];
501 if (m_Width / m_Mass < 0.01) {
506 for (
size_t i = 0; i < m_Decays.size(); ++i) {
507 tsumb += m_Decays[i].mBratio;
511 for (
size_t i = 0; i < m_Decays.size(); ++i) {
512 twid += m_Decays[i].ModifiedWidth(M) * m_Width;
516 twid += (1. - tsumb) * m_Width;
523 std::vector<double> ret(m_Decays.size(), 0.);
525 if (!
eBW || m_Width / m_Mass < 0.01) {
526 for (
size_t i = 0; i < m_Decays.size(); ++i)
527 ret[i] = m_Decays[i].mBratio;
534 for (
size_t i = 0; i < m_Decays.size(); ++i) {
535 double partialwid = m_Decays[i].ModifiedWidth(M) * m_Width;
536 ret[i] = partialwid / totwid;
553 if (!enable) m_Statistics = 0;
554 else m_Statistics = m_StatisticsOrig;
560 if (m_Width != 0.0) {
580 return (m_Baryon == 0 && m_ElectricCharge == 0 && m_Strangeness == 0 && m_Charm == 0);
585 if (m_GeneralizedDensity != NULL)
586 return m_GeneralizedDensity->Quantity(type,
params.T, mu);
588 if (m_Degeneracy == 0.0)
592 if (!(
params.gammaS == 1. || m_AbsS == 0.)) mu += log(
params.gammaS) * m_AbsS *
params.T;
593 if (!(
params.gammaC == 1. || m_AbsC == 0.)) mu += log(
params.gammaC) * m_AbsC *
params.T;
599 int ind = m_xleg.size();
600 const vector<double> &x = m_xleg, &w = m_wleg;
601 double ret1 = 0., ret2 = 0., tmp = 0.;
604 if (m_ResonanceWidthIntegrationType !=
eBW && m_ResonanceWidthIntegrationType !=
eBWconstBR) {
605 for (
int i = 0; i < ind; i++) {
610 tmp *= m_brweight[i];
620 int ind2 = m_xlag32.size();
621 for (
int i = 0; i < ind2; ++i) {
622 double tmass = m_Mass + 2.*m_Width + m_xlag32[i] * m_Width;
631 if (m_ResonanceWidthIntegrationType ==
eBW || m_ResonanceWidthIntegrationType ==
eBWconstBR) {
632 for (
size_t i = 0; i < m_xalldyn.size(); i++) {
650 if (!(
params.gammaS == 1. || m_AbsS == 0.)) mu += log(
params.gammaS) * m_AbsS *
params.T;
651 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.