19#include "Minuit2/FCNBase.h"
20#include "Minuit2/FunctionMinimum.h"
21#include "Minuit2/MnMigrad.h"
22#include "Minuit2/MnMinos.h"
23#include "Minuit2/MnHesse.h"
24#include "Minuit2/MnUserParameterState.h"
37 using namespace ROOT::Minuit2;
41 class FitFCN :
public FCNBase {
45 FitFCN(ThermalModelFit *thmfit_,
bool verbose_ =
true) : m_THMFit(thmfit_), m_verbose(verbose_) {
50 double operator()(
const std::vector<double>& par)
const {
51 m_THMFit->Increment();
53 if (par[2]<0.)
return 1e12;
54 if (par[3]<0.)
return 1e12;
56 m_THMFit->SetParameterValue(
"T", par[0]);
57 m_THMFit->SetParameterValue(
"muB", par[1]);
58 m_THMFit->SetParameterValue(
"gammaS", par[2]);
59 m_THMFit->SetParameterValue(
"R", par[3]);
60 m_THMFit->SetParameterValue(
"Rc", par[4]);
61 m_THMFit->SetParameterValue(
"gammaq", par[5]);
62 m_THMFit->SetParameterValue(
"muQ", par[6]);
63 m_THMFit->SetParameterValue(
"muS", par[7]);
64 m_THMFit->SetParameterValue(
"muC", par[8]);
65 m_THMFit->SetParameterValue(
"gammac", par[9]);
66 m_THMFit->SetParameterValue(
"Tkin", par[10]);
68 m_THMFit->model()->SetTemperature(par[0]);
70 if (!m_THMFit->model()->ConstrainMuB())
71 m_THMFit->model()->SetBaryonChemicalPotential(par[1]);
73 m_THMFit->model()->SetGammaS(par[2]);
75 m_THMFit->model()->SetVolumeRadius(par[3]);
77 if (m_THMFit->FixVcOverV())
78 m_THMFit->model()->SetCanonicalVolume(m_THMFit->model()->Volume() * m_THMFit->VcOverV());
80 m_THMFit->model()->SetCanonicalVolumeRadius(par[4]);
83 m_THMFit->model()->SetGammaq(par[5]);
85 m_THMFit->model()->SetGammaC(par[9]);
87 if (m_THMFit->model()->ConstrainMuQ())
88 m_THMFit->model()->SetElectricChemicalPotential(-par[1] / 50.);
90 m_THMFit->model()->SetElectricChemicalPotential(par[6]);
92 if (m_THMFit->model()->ConstrainMuS())
93 m_THMFit->model()->SetStrangenessChemicalPotential(par[1] / 5.);
95 m_THMFit->model()->SetStrangenessChemicalPotential(par[7]);
97 if (m_THMFit->model()->ConstrainMuC())
98 m_THMFit->model()->SetCharmChemicalPotential(par[1] / 5.);
100 m_THMFit->model()->SetCharmChemicalPotential(par[8]);
102 m_THMFit->model()->SetParameters(m_THMFit->model()->Parameters());
106 IdealGasFunctions::calculationHadBECIssue =
false;
108 m_THMFit->model()->ConstrainChemicalPotentials();
110 if (m_THMFit->UseTkin()) {
111 m_THMFit->modelpce()->SetChemicalFreezeout(m_THMFit->model()->Parameters(), m_THMFit->model()->ChemicalPotentials());
112 m_THMFit->modelpce()->CalculatePCE(par[10]);
115 m_THMFit->model()->CalculateDensities();
121 if (IdealGasFunctions::calculationHadBECIssue) {
122 std::cerr << m_THMFit->Iters();
123 std::cerr <<
"**WARNING** Issue with Bose-Einstein condensation, discarding this iteration..." << std::endl;
124 return m_THMFit->Chi2() =
chi2 = 1.e12;
128 for (
size_t i = 0; i < m_THMFit->FittedQuantities().size(); ++i) {
129 if (m_THMFit->FittedQuantities()[i].type == FittedQuantity::Ratio) {
130 const ExperimentRatio &ratio = m_THMFit->FittedQuantities()[i].ratio;
131 double dens1 = m_THMFit->model()->GetDensity(ratio.fPDGID1, ratio.fFeedDown1);
132 double dens2 = m_THMFit->model()->GetDensity(ratio.fPDGID2, ratio.fFeedDown2);
133 double ModelRatio = dens1 / dens2;
134 m_THMFit->ModelData(i) = ModelRatio;
135 if (m_THMFit->FittedQuantities()[i].toFit)
136 chi2 += (ModelRatio - ratio.fValue) * (ModelRatio - ratio.fValue) / ratio.fError / ratio.fError;
141 for (
size_t i = 0; i < m_THMFit->FittedQuantities().size(); ++i) {
142 if (m_THMFit->FittedQuantities()[i].type == FittedQuantity::Multiplicity) {
143 const ExperimentMultiplicity &multiplicity = m_THMFit->FittedQuantities()[i].mult;
144 double dens = m_THMFit->model()->GetDensity(multiplicity.fPDGID, multiplicity.fFeedDown);
145 double ModelMult = dens * m_THMFit->model()->Parameters().V;
146 m_THMFit->ModelData(i) = ModelMult;
147 if (m_THMFit->FittedQuantities()[i].toFit)
148 chi2 += (ModelMult - multiplicity.fValue) * (ModelMult - multiplicity.fValue) / multiplicity.fError / multiplicity.fError;
153 printf(
"%15d ", m_THMFit->Iters());
154 printf(
"%15lf ", chi2);
155 if (m_THMFit->Parameters().T.toFit)
156 printf(
"%15lf ", par[0]);
157 if (m_THMFit->Parameters().muB.toFit)
158 printf(
"%15lf ", m_THMFit->model()->Parameters().muB);
159 if (m_THMFit->Parameters().muQ.toFit)
160 printf(
"%15lf ", m_THMFit->model()->Parameters().muQ);
161 if (m_THMFit->Parameters().muS.toFit)
162 printf(
"%15lf ", m_THMFit->model()->Parameters().muS);
163 if (m_THMFit->Parameters().muC.toFit)
164 printf(
"%15lf ", m_THMFit->model()->Parameters().muC);
165 if (m_THMFit->Parameters().R.toFit)
166 printf(
"%15lf ", par[3]);
167 if (m_THMFit->Parameters().Rc.toFit)
168 printf(
"%15lf ", par[4]);
169 if (m_THMFit->Parameters().gammaq.toFit)
170 printf(
"%15lf ", m_THMFit->model()->Parameters().gammaq);
171 if (m_THMFit->Parameters().gammaS.toFit)
172 printf(
"%15lf ", m_THMFit->model()->Parameters().gammaS);
173 if (m_THMFit->Parameters().gammaC.toFit)
174 printf(
"%15lf ", m_THMFit->model()->Parameters().gammaC);
175 if (m_THMFit->Parameters().Tkin.toFit)
176 printf(
"%15lf ", par[10]);
179 if (m_THMFit->model()->Ensemble() == ThermalModelBase::CE)
180 printf(
"B = %10.5lf\tQ = %10.5lf\tS = %10.5lf\tC = %10.5lf\n",
181 m_THMFit->model()->CalculateBaryonDensity() * m_THMFit->model()->Parameters().V,
182 m_THMFit->model()->CalculateChargeDensity() * m_THMFit->model()->Parameters().V,
183 m_THMFit->model()->CalculateStrangenessDensity() * m_THMFit->model()->Parameters().V,
184 m_THMFit->model()->CalculateCharmDensity() * m_THMFit->model()->Parameters().V);
187 m_THMFit->Chi2() =
chi2;
188 if (m_THMFit->model()->Ensemble() == ThermalModelBase::CE) {
189 m_THMFit->BT() = m_THMFit->model()->CalculateBaryonDensity() * m_THMFit->model()->Parameters().V;
190 m_THMFit->QT() = m_THMFit->model()->CalculateChargeDensity() * m_THMFit->model()->Parameters().V;
191 m_THMFit->ST() = m_THMFit->model()->CalculateStrangenessDensity() * m_THMFit->model()->Parameters().V;
192 m_THMFit->CT() = m_THMFit->model()->CalculateCharmDensity() * m_THMFit->model()->Parameters().V;
197 printf(
"**WARNING** chi2 evaluated to NaN\n");
203 double Up()
const {
return 1.;}
206 ThermalModelFit *m_THMFit;
215 m_model(model_), m_modelpce(NULL), m_Parameters(model_->
Parameters()), m_FixVcToV(true), m_VcOverV(1.),
216 m_YieldsAtTkin(false), m_SahaForNuclei(true), m_PCEFreezeLongLived(false), m_PCEWidthCut(0.015),
217 m_PCEAnnihilation(false), m_PCEPionAnnihilationNumber(5.)
228 m_ModelData.resize(m_Quantities.size(), 0.);
230 m_Parameters.
B = m_model->Parameters().B;
231 m_Parameters.Q = m_model->Parameters().Q;
232 m_Parameters.S = m_model->Parameters().S;
233 m_Parameters.C = m_model->Parameters().C;
236 if (m_PCEAnnihilation) {
243 m_modelpce =
new ThermalModelPCE(m_model, m_PCEFreezeLongLived, m_PCEWidthCut);
244 if (!m_SahaForNuclei)
245 m_modelpce->SetStabilityFlags(m_modelpce->ComputePCEStabilityFlags(m_model->TPS(), m_SahaForNuclei, m_PCEFreezeLongLived, m_PCEWidthCut));
250 FitFCN mfunc(
this, verbose);
251 std::vector<double>
params(11, 0.);
252 params[0] = m_Parameters.T.value;
253 params[1] = m_Parameters.muB.value;
254 params[2] = m_Parameters.gammaS.value;
255 params[3] = m_Parameters.R.value;
256 params[4] = m_Parameters.Rc.value;
257 params[5] = m_Parameters.gammaq.value;
258 params[6] = m_Parameters.muQ.value;
259 params[7] = m_Parameters.muS.value;
260 params[8] = m_Parameters.muC.value;
261 params[9] = m_Parameters.gammaC.value;
262 params[10] = m_Parameters.Tkin.value;
264 MnUserParameters upar;
265 upar.Add(
"T", m_Parameters.T.value, m_Parameters.T.error, m_Parameters.T.xmin, m_Parameters.T.xmax);
266 upar.Add(
"muB", m_Parameters.muB.value, m_Parameters.muB.error, m_Parameters.muB.xmin, m_Parameters.muB.xmax);
267 upar.Add(
"gammaS", m_Parameters.gammaS.value, m_Parameters.gammaS.error, m_Parameters.gammaS.xmin, m_Parameters.gammaS.xmax);
268 upar.Add(
"R", m_Parameters.R.value, m_Parameters.R.error, m_Parameters.R.xmin, m_Parameters.R.xmax);
269 upar.Add(
"Rc", m_Parameters.Rc.value, m_Parameters.Rc.error, m_Parameters.Rc.xmin, m_Parameters.Rc.xmax);
270 upar.Add(
"gammaq", m_Parameters.gammaq.value, m_Parameters.gammaq.error, m_Parameters.gammaq.xmin, m_Parameters.gammaq.xmax);
271 upar.Add(
"muQ", m_Parameters.muQ.value, m_Parameters.muQ.error, m_Parameters.muQ.xmin, m_Parameters.muQ.xmax);
272 upar.Add(
"muS", m_Parameters.muS.value, m_Parameters.muS.error, m_Parameters.muS.xmin, m_Parameters.muS.xmax);
273 upar.Add(
"muC", m_Parameters.muC.value, m_Parameters.muC.error, m_Parameters.muC.xmin, m_Parameters.muC.xmax);
274 upar.Add(
"gammaC", m_Parameters.gammaC.value, m_Parameters.gammaC.error, m_Parameters.gammaC.xmin, m_Parameters.gammaC.xmax);
275 upar.Add(
"Tkin", m_Parameters.Tkin.value, m_Parameters.Tkin.error, m_Parameters.Tkin.xmin, m_Parameters.Tkin.xmax);
281 if (m_Multiplicities.size() == 0)
282 m_Parameters.SetParameterFitFlag(
"R",
false);
286 m_Parameters.SetParameterFitFlag(
"Rc",
false);
290 || m_model->ConstrainMuB()
291 || !m_model->TPS()->hasBaryons())
292 m_Parameters.SetParameterFitFlag(
"muB",
false);
296 || m_model->ConstrainMuQ()
297 || !m_model->TPS()->hasCharged())
298 m_Parameters.SetParameterFitFlag(
"muQ",
false);
302 || m_model->ConstrainMuS()
303 || !m_model->TPS()->hasStrange())
304 m_Parameters.SetParameterFitFlag(
"muS",
false);
308 || m_model->ConstrainMuC()
309 || !m_model->TPS()->hasCharmed())
310 m_Parameters.SetParameterFitFlag(
"muC",
false);
313 if (!m_model->TPS()->hasStrange())
314 m_Parameters.SetParameterFitFlag(
"gammaS",
false);
317 if (!m_model->TPS()->hasCharmed())
318 m_Parameters.SetParameterFitFlag(
"gammaC",
false);
322 m_Parameters.SetParameterFitFlag(
"Tkin",
false);
324 if (!m_Parameters.T.toFit) { upar.Fix(
"T"); nparams--; }
325 if (!m_Parameters.R.toFit) { upar.Fix(
"R"); nparams--; }
326 if (!m_Parameters.Rc.toFit) { upar.Fix(
"Rc"); nparams--; }
327 if (!m_Parameters.muB.toFit) { upar.Fix(
"muB"); nparams--; }
328 if (!m_Parameters.muQ.toFit) { upar.Fix(
"muQ"); nparams--; }
329 if (!m_Parameters.muS.toFit) { upar.Fix(
"muS"); nparams--; }
330 if (!m_Parameters.muC.toFit) { upar.Fix(
"muC"); nparams--; }
331 if (!m_Parameters.gammaq.toFit) { upar.Fix(
"gammaq"); nparams--; }
332 if (!m_Parameters.gammaS.toFit) { upar.Fix(
"gammaS"); nparams--; }
333 if (!m_Parameters.gammaC.toFit) { upar.Fix(
"gammaC"); nparams--; }
334 if (!m_Parameters.Tkin.toFit) { upar.Fix(
"Tkin"); nparams--; }
346 printf(
"Starting a thermal fit...\n\n");
347 printf(
"%15s ",
"Iteration");
348 printf(
"%15s ",
"chi2");
349 if (m_Parameters.T.toFit)
350 printf(
"%15s ",
"T [GeV]");
351 if (m_Parameters.muB.toFit)
352 printf(
"%15s ",
"muB [GeV]");
353 if (m_Parameters.muQ.toFit)
354 printf(
"%15s ",
"muQ [GeV]");
355 if (m_Parameters.muS.toFit)
356 printf(
"%15s ",
"muS [GeV]");
357 if (m_Parameters.muC.toFit)
358 printf(
"%15s ",
"muC [GeV]");
359 if (m_Parameters.R.toFit)
360 printf(
"%15s ",
"R [fm]");
361 if (m_Parameters.Rc.toFit)
362 printf(
"%15s ",
"Rc [fm]");
363 if (m_Parameters.gammaq.toFit)
364 printf(
"%15s ",
"gammaq");
365 if (m_Parameters.gammaS.toFit)
366 printf(
"%15s ",
"gammaS");
367 if (m_Parameters.gammaC.toFit)
368 printf(
"%15s ",
"gammaC");
369 if (m_Parameters.Tkin.toFit)
370 printf(
"%15s ",
"Tkin [GeV]");
374 MnMigrad migrad(mfunc, upar);
376 FunctionMinimum min = migrad();
379 printf(
"\nMinimum found! Now calculating the error matrix...\n\n");
387 MnMinos mino(mfunc, min);
388 std::pair<double, double> errs;
389 if (m_Parameters.T.toFit) { errs = mino(0); ret.
T.
errm = abs(errs.first); ret.
T.
errp = abs(errs.second); }
390 if (m_Parameters.muB.toFit) { errs = mino(1); ret.
muB.
errm = abs(errs.first); ret.
muB.
errp = abs(errs.second); }
391 if (m_Parameters.gammaS.toFit) { errs = mino(2); ret.
gammaS.
errm = abs(errs.first); ret.
gammaS.
errp = abs(errs.second); }
392 if (m_Parameters.R.toFit) { errs = mino(3); ret.
R.
errm = abs(errs.first); ret.
R.
errp = abs(errs.second); }
393 if (m_Parameters.Rc.toFit) { errs = mino(4); ret.
Rc.
errm = abs(errs.first); ret.
Rc.
errp = abs(errs.second); }
394 if (m_Parameters.gammaq.toFit) { errs = mino(5); ret.
gammaq.
errm = abs(errs.first); ret.
gammaq.
errp = abs(errs.second); }
397 ret.
T.
value = (min.UserParameters()).Params()[0];
398 ret.
T.
error = (min.UserParameters()).Errors()[0];
399 ret.
muB.
value = (min.UserParameters()).Params()[1];
400 ret.
muB.
error = (min.UserParameters()).Errors()[1];
401 ret.
gammaS.
value = (min.UserParameters()).Params()[2];
402 ret.
gammaS.
error = (min.UserParameters()).Errors()[2];
403 ret.
R.
value = (min.UserParameters()).Params()[3];
404 ret.
R.
error = (min.UserParameters()).Errors()[3];
405 ret.
Rc.
value = (min.UserParameters()).Params()[4];
406 ret.
Rc.
error = (min.UserParameters()).Errors()[4];
407 ret.
gammaq.
value = (min.UserParameters()).Params()[5];
408 ret.
gammaq.
error = (min.UserParameters()).Errors()[5];
409 ret.
muQ.
value = (min.UserParameters()).Params()[6];
410 ret.
muQ.
error = (min.UserParameters()).Errors()[6];
411 ret.
muS.
value = (min.UserParameters()).Params()[7];
412 ret.
muS.
error = (min.UserParameters()).Errors()[7];
413 ret.
muC.
value = (min.UserParameters()).Params()[8];
414 ret.
muC.
error = (min.UserParameters()).Errors()[8];
415 ret.
gammaC.
value = (min.UserParameters()).Params()[9];
416 ret.
gammaC.
error = (min.UserParameters()).Errors()[9];
417 ret.
Tkin.
value = (min.UserParameters()).Params()[10];
418 ret.
Tkin.
error = (min.UserParameters()).Errors()[10];
471 ret.
T.
value = upar.Params()[0];
472 ret.
T.
error = upar.Errors()[0];
477 ret.
R.
value = upar.Params()[3];
478 ret.
R.
error = upar.Errors()[3];
479 ret.
Rc.
value = upar.Params()[4];
480 ret.
Rc.
error = upar.Errors()[4];
498 parames.
B = m_model->Parameters().B;
499 parames.
S = m_model->Parameters().S;
500 parames.
Q = m_model->Parameters().Q;
501 parames.
C = m_model->Parameters().C;
504 if (!ret.
muQ.
toFit && m_model->ConstrainMuQ()) {
505 ret.
muQ.
value = m_model->Parameters().muQ;
508 if (!ret.
muS.
toFit && m_model->ConstrainMuS()) {
509 ret.
muS.
value = m_model->Parameters().muS;
512 if (!ret.
muC.
toFit && m_model->ConstrainMuC()) {
513 ret.
muC.
value = m_model->Parameters().muC;
532 for (
size_t i = 0; i < m_Quantities.size(); ++i)
533 if (m_Quantities[i].toFit) ndf++;
551 if (m_modelpce != NULL) {
557 printf(
"Thermal fit finished\n\n");
560 throw std::runtime_error(
"Cannot fit without MINUIT2 library!");
565 m_model->SetParameters(m_Parameters.GetThermalModelParameters());
566 m_model->FixParameters();
567 m_model->CalculateDensities();
569 for (
size_t i = 0; i < m_Quantities.size(); ++i) {
572 int ind1 = m_model->TPS()->PdgToId(ratio.
fPDGID1);
573 int ind2 = m_model->TPS()->PdgToId(ratio.
fPDGID2);
576 std::cout << m_model->TPS()->Particles()[ind1].Name() <<
"/" << m_model->TPS()->Particles()[ind2].Name() <<
" = " <<
577 dens1 / dens2 <<
" " << ratio.
fValue <<
" " << ratio.
fError <<
"\n";
583 printf(
"%20s\n",
"Fit parameters");
584 for(
int i=0;i<6;++i) {
586 if (param.
name ==
"Tkin" && !m_YieldsAtTkin)
589 printf(
"%10s = %10lf %2s %lf\n", param.
name.c_str(), param.
value,
"+-", param.
error);
593 printf(
"%10s = %10lf\n",
"B", m_model->CalculateBaryonDensity() * m_model->Volume());
594 printf(
"%10s = %10lf\n",
"S", m_model->CalculateStrangenessDensity() * m_model->Volume());
595 printf(
"%10s = %10lf\n",
"Q", m_model->CalculateChargeDensity() * m_model->Volume());
608 for (
size_t i = 0; i < m_Quantities.size(); ++i) {
614 std::string tname = m_model->TPS()->GetNameFromPDG(mult.
fPDGID);
617 printf(
"%10s\t%11s\t%6lf %2s %lf\n",
"Npart",
"Experiment:",
619 else if (mult.
fPDGID == 33340)
620 printf(
"%10s\t%11s\t%6lf %2s %lf\n", (m_model->TPS()->ParticleByPDG(3334).Name() +
" + " + m_model->TPS()->ParticleByPDG(-3334).Name()).c_str(),
"Experiment:",
623 printf(
"%10s\t%11s\t%6lf %2s %lf\n", tname.c_str(),
"Experiment:", mult.
fValue,
"+-", mult.
fError);
624 printf(
"%10s\t%11s\t%6lf %2s %lf\n",
"",
"Model:", dens1 * m_model->Parameters().V,
"+-", 0.);
625 printf(
"%10s\t%11s\t%6lf\n",
"",
"Deviation:", (dens1 * m_model->Parameters().V - mult.
fValue) / mult.
fError);
639 for (
size_t i = 0; i < m_Quantities.size(); ++i) {
645 std::string tname = m_model->TPS()->GetNameFromPDG(mult.
fPDGID);
648 printf(
"%10s\t%11s\t%6lf %2s %lf\n",
"Npart",
"Experiment:",
650 else if (mult.
fPDGID == 33340)
651 printf(
"%10s\t%11s\t%6lf %2s %lf\n", (m_model->TPS()->ParticleByPDG(3334).Name() +
" + " + m_model->TPS()->ParticleByPDG(-3334).Name()).c_str(),
"Experiment:",
654 printf(
"%10s\t%11s\t%6lf %2s %lf\n", tname.c_str(),
"Experiment:", mult.
fValue,
"+-", mult.
fError);
655 printf(
"%10s\t%11s\t%6lf %2s %lf\n",
"",
"Model:", dens1 * m_model->Parameters().V,
"+-", 0.);
656 printf(
"%10s\t%11s\t%6lf\n",
"",
"Deviation:", (dens1 * m_model->Parameters().V - mult.
fValue) / mult.
fError);
662 for (
size_t i = 0; i < m_Quantities.size(); ++i) {
667 std::string name1 = m_model->TPS()->GetNameFromPDG(ratio.
fPDGID1);
668 std::string name2 = m_model->TPS()->GetNameFromPDG(ratio.
fPDGID2);
674 name1 = m_model->TPS()->ParticleByPDG(3334).Name() +
" + " + m_model->TPS()->ParticleByPDG(-3334).Name();
676 name2 = m_model->TPS()->ParticleByPDG(3334).Name() +
" + " + m_model->TPS()->ParticleByPDG(-3334).Name();
677 printf(
"%10s\t%11s\t%6lf %2s %lf\n", (std::string(name1 +
"/" + name2)).c_str(),
"Experiment:",
679 printf(
"%10s\t%11s\t%6lf %2s %lf\n",
"",
"Model:", dens1 / dens2,
"+-", 0.);
680 printf(
"%10s\t%11s\t%6lf\n",
"",
"Deviation:", (dens1 / dens2 - ratio.
fValue) / ratio.
fError);
687 FILE *f = fopen(filename.c_str(),
"w");
689 fprintf(f,
"%15s\t%25s\t%15s\t%15s\t%15s\t%15s\t%15s\t%15s\t%15s\t%15s\t%15s\n",
690 "N",
"Name",
"Data",
"Error",
"Fit",
"Deviation",
"Deviation2",
691 "Residual",
"ResidualError",
"Data/Model",
"Data/ModelError");
697 for(
size_t i=0;i<m_Multiplicities.size();++i) {
698 double dens1 = m_model->GetDensity(m_Multiplicities[i].fPDGID, m_Multiplicities[i].fFeedDown);
700 std::string tname = m_model->TPS()->GetNameFromPDG(m_Multiplicities[i].fPDGID);
701 if (m_Multiplicities[i].fPDGID==1) tname =
"Npart";
702 else if (m_Multiplicities[i].fPDGID==33340) tname = m_model->TPS()->ParticleByPDG(3334).Name() +
" + " + m_model->TPS()->ParticleByPDG(-3334).Name();
703 fprintf(f,
"%15d\t%25s\t%15lf\t%15lf\t%15lf\t%15lf\t%15lf\t%15lf\t%15lf\t%15lf\t%15lf\n",
static_cast<int>(i)+1,
704 tname.c_str(), m_Multiplicities[i].fValue, m_Multiplicities[i].fError, dens1 * m_model->Parameters().V,
705 (m_Multiplicities[i].fValue-dens1 * m_model->Parameters().V)/m_Multiplicities[i].fError,
706 -(m_Multiplicities[i].fValue-dens1 * m_model->Parameters().V)/m_Multiplicities[i].fError,
707 (dens1 * m_model->Parameters().V-m_Multiplicities[i].fValue)/(dens1 * m_model->Parameters().V),
708 m_Multiplicities[i].fError/(dens1 * m_model->Parameters().V),
709 m_Multiplicities[i].fValue/(dens1 * m_model->Parameters().V),
710 m_Multiplicities[i].fError/(dens1 * m_model->Parameters().V));
712 for(
size_t i=0;i<m_Ratios.size();++i) {
713 double dens1 = m_model->GetDensity(m_Ratios[i].fPDGID1, m_Ratios[i].fFeedDown1);
714 double dens2 = m_model->GetDensity(m_Ratios[i].fPDGID2, m_Ratios[i].fFeedDown2);
715 std::string name1 = m_model->TPS()->GetNameFromPDG(m_Ratios[i].fPDGID1);
716 std::string name2 = m_model->TPS()->GetNameFromPDG(m_Ratios[i].fPDGID2);
717 if (m_Ratios[i].fPDGID1==1) name1 =
"Npart";
718 if (m_Ratios[i].fPDGID2==1) name2 =
"Npart";
719 if (m_Ratios[i].fPDGID1==33340) name1 = m_model->TPS()->ParticleByPDG(3334).Name() +
" + " + m_model->TPS()->ParticleByPDG(-3334).Name();
720 if (m_Ratios[i].fPDGID2==33340) name2 = m_model->TPS()->ParticleByPDG(3334).Name() +
" + " + m_model->TPS()->ParticleByPDG(-3334).Name();
722 fprintf(f,
"%15d\t%25s\t%15lf\t%15lf\t%15lf\t%15lf\t%15lf\t%15lf\t%15lf\t%15lf\t%15lf\n",
static_cast<int>(i)+1,
723 (std::string(name1 +
"/" + name2)).c_str(), m_Ratios[i].fValue, m_Ratios[i].fError, dens1 / dens2,
724 (m_Ratios[i].fValue - dens1 / dens2)/m_Ratios[i].fError,
725 -(m_Ratios[i].fValue - dens1 / dens2)/m_Ratios[i].fError,
726 (dens1 / dens2-m_Ratios[i].fValue)/(dens1 / dens2),
727 m_Ratios[i].fError/(dens1 / dens2),
728 m_Ratios[i].fValue/(dens1 / dens2),
729 m_Ratios[i].fError/(dens1 / dens2));
736 FILE *f = fopen(filename.c_str(),
"w");
738 fprintf(f,
"%15s\t%25s\t%15s\t%15s\t%15s\t%15s\n",
"N",
"Name",
"Data",
"Error",
"Fit",
"Deviation");
743 for(
size_t i=0;i<m_Multiplicities.size();++i) {
745 double dens1 = m_model->GetDensity(m_Multiplicities[i].fPDGID, m_Multiplicities[i].fFeedDown);
746 std::string tname = m_model->TPS()->GetNameFromPDG(m_Multiplicities[i].fPDGID);
747 if (m_Multiplicities[i].fPDGID==1) tname =
"Npart";
748 else if (m_Multiplicities[i].fPDGID==33340) tname = m_model->TPS()->ParticleByPDG(3334).Name() +
" + " + m_model->TPS()->ParticleByPDG(-3334).Name();
749 fprintf(f,
"%15lf\t%25s\t%15lf\t%15lf\t%15lf\t%15lf\n", i+1 - 0.3, tname.c_str(), m_Multiplicities[i].fValue, m_Multiplicities[i].fError, dens1 * m_model->Parameters().V, (m_Multiplicities[i].fValue-dens1 * m_model->Parameters().V)/m_Multiplicities[i].fError);
750 fprintf(f,
"%15lf\t%25s\t%15lf\t%15lf\t%15lf\t%15lf\n", i+1 + 0.3, tname.c_str(), m_Multiplicities[i].fValue, m_Multiplicities[i].fError, dens1 * m_model->Parameters().V, (m_Multiplicities[i].fValue-dens1 * m_model->Parameters().V)/m_Multiplicities[i].fError);
752 for(
size_t i=0;i<m_Ratios.size();++i) {
753 double dens1 = m_model->GetDensity(m_Ratios[i].fPDGID1, m_Ratios[i].fFeedDown1);
754 double dens2 = m_model->GetDensity(m_Ratios[i].fPDGID2, m_Ratios[i].fFeedDown2);
756 std::string name1 = m_model->TPS()->GetNameFromPDG(m_Ratios[i].fPDGID1);
757 std::string name2 = m_model->TPS()->GetNameFromPDG(m_Ratios[i].fPDGID2);
758 if (m_Ratios[i].fPDGID1==1) name1 =
"Npart";
759 if (m_Ratios[i].fPDGID2==1) name2 =
"Npart";
760 if (m_Ratios[i].fPDGID1==33340) name1 = m_model->TPS()->ParticleByPDG(3334).Name() +
" + " + m_model->TPS()->ParticleByPDG(-3334).Name();
761 if (m_Ratios[i].fPDGID2==33340) name2 = m_model->TPS()->ParticleByPDG(3334).Name() +
" + " + m_model->TPS()->ParticleByPDG(-3334).Name();
763 fprintf(f,
"%15lf\t%25s\t%15lf\t%15lf\t%15lf\t%15lf\n", i+1 - 0.3, (std::string(name1 +
"/" + name2)).c_str(), m_Ratios[i].fValue, m_Ratios[i].fError, dens1 / dens2, (m_Ratios[i].fValue - dens1 / dens2)/m_Ratios[i].fError);
764 fprintf(f,
"%15lf\t%25s\t%15lf\t%15lf\t%15lf\t%15lf\n", i+1 + 0.3, (std::string(name1 +
"/" + name2)).c_str(), m_Ratios[i].fValue, m_Ratios[i].fError, dens1 / dens2, (m_Ratios[i].fValue - dens1 / dens2)/m_Ratios[i].fError);
771 FILE *f = fopen(filename.c_str(),
"w");
772 fprintf(f,
"\\begin{tabular}{|c|c|c|c|}\n");
773 fprintf(f,
"\\hline\n");
774 fprintf(f,
"\\multicolumn{4}{|c|}{%s} \\\\\n", name.c_str());
775 fprintf(f,
"\\hline\n");
776 fprintf(f,
"Yield & Measurement & Fit & Deviation \\\\\n");
777 fprintf(f,
"\\hline\n");
782 for(
size_t i=0;i<m_Multiplicities.size();++i) {
783 double dens1 = m_model->GetDensity(m_Multiplicities[i].fPDGID, m_Multiplicities[i].fFeedDown);
785 std::string tname = m_model->TPS()->GetNameFromPDG(m_Multiplicities[i].fPDGID);
787 if (m_Multiplicities[i].fPDGID==1) tname =
"Npart";
788 else if (m_Multiplicities[i].fPDGID==33340) tname = m_model->TPS()->ParticleByPDG(3334).Name() +
" + " + m_model->TPS()->ParticleByPDG(-3334).Name();
789 fprintf(f,
"$%s$ & $%.4lf \\pm %.4lf$ & $%.4lf$ & $%.4lf$ \\\\\n", tname.c_str(), m_Multiplicities[i].fValue, m_Multiplicities[i].fError, dens1 * m_model->Parameters().V, (dens1 * m_model->Parameters().V-m_Multiplicities[i].fValue)/m_Multiplicities[i].fError);
791 for(
size_t i=0;i<m_Ratios.size();++i) {
792 int ind1 = m_model->TPS()->PdgToId(m_Ratios[i].fPDGID1);
793 int ind2 = m_model->TPS()->PdgToId(m_Ratios[i].fPDGID2);
794 double dens1 = m_model->GetDensity(m_Ratios[i].fPDGID1, m_Ratios[i].fFeedDown1);
795 double dens2 = m_model->GetDensity(m_Ratios[i].fPDGID2, m_Ratios[i].fFeedDown2);
797 std::string name1 = m_model->TPS()->Particles()[ind1].Name();
798 std::string name2 = m_model->TPS()->Particles()[ind2].Name();
799 if (m_Ratios[i].fPDGID1==1) name1 =
"Npart";
800 if (m_Ratios[i].fPDGID2==1) name2 =
"Npart";
801 if (m_Ratios[i].fPDGID1==33340) name1 = m_model->TPS()->Particles()[m_model->TPS()->PdgToId(3334)].Name() +
" + " + m_model->TPS()->Particles()[m_model->TPS()->PdgToId(-3334)].Name();
802 if (m_Ratios[i].fPDGID2==33340) name2 = m_model->TPS()->Particles()[m_model->TPS()->PdgToId(3334)].Name() +
" + " + m_model->TPS()->Particles()[m_model->TPS()->PdgToId(-3334)].Name();
803 fprintf(f,
"$%s$ & $%.4lf \\pm %.4lf$ & $%.4lf$ & $%.4lf$ \\\\\n", (std::string(name1 +
"/" + name2)).c_str(), m_Ratios[i].fValue, m_Ratios[i].fError, dens1 / dens2 , (dens1 / dens2 - m_Ratios[i].fValue)/m_Ratios[i].fError);
805 fprintf(f,
"\\hline\n");
806 fprintf(f,
"\\end{tabular}\n");
808 fprintf(f,
"\\begin{tabular}{|c|c|}\n");
809 fprintf(f,
"\\hline\n");
810 fprintf(f,
"\\multicolumn{2}{|c|}{%s} \\\\\n", name.c_str());
811 fprintf(f,
"\\hline\n");
812 fprintf(f,
"Parameter & Fit result \\\\\n");
813 fprintf(f,
"\\hline\n");
814 for(
int i=0;i<6;++i) {
817 double tval = param.
value, terr = param.
error;
818 if (param.
name==
"T" || param.
name.substr(0,2)==
"mu") { tval *= 1000.; terr *= 1000.; }
819 fprintf(f,
"$%s$ & $%.2lf \\pm %.2lf$ \\\\\n", param.
name.c_str(), tval, terr);
822 fprintf(f,
"$%s$ & $%.2lf/%d$ \\\\\n",
"\\chi^2/N_{\\rm df}", m_Parameters.chi2ndf *
GetNdf(),
GetNdf());
823 fprintf(f,
"\\hline\n");
824 fprintf(f,
"\\end{tabular}\n");
830 FILE *f = fopen(filename.c_str(),
"w");
831 fprintf(f,
"\\begin{tabular}{|c|c|c|c|}\n");
832 fprintf(f,
"\\hline\n");
833 fprintf(f,
"\\multicolumn{4}{|c|}{%s} \\\\\n", name.c_str());
834 fprintf(f,
"\\hline\n");
835 fprintf(f,
"Yield & Measurement & Fit \\\\\n");
836 fprintf(f,
"\\hline\n");
842 std::vector<std::string> prt(0);
843 std::vector<long long> pdgs(0);
844 std::vector<int> fl(m_Multiplicities.size(), 0);
845 prt.push_back(
"\\pi^+"); pdgs.push_back(211);
846 prt.push_back(
"\\pi^-"); pdgs.push_back(-211);
847 prt.push_back(
"K^+"); pdgs.push_back(321);
848 prt.push_back(
"K^-"); pdgs.push_back(-321);
849 prt.push_back(
"p"); pdgs.push_back(2212);
850 prt.push_back(
"\\bar{p}"); pdgs.push_back(-2212);
851 prt.push_back(
"\\Lambda"); pdgs.push_back(3122);
852 prt.push_back(
"\\bar{\\Lambda}"); pdgs.push_back(-3122);
853 prt.push_back(
"\\Sigma^+"); pdgs.push_back(3222);
854 prt.push_back(
"\\bar{\\Sigma}^+"); pdgs.push_back(-3222);
855 prt.push_back(
"\\Sigma^-"); pdgs.push_back(3112);
856 prt.push_back(
"\\bar{\\Sigma}^-"); pdgs.push_back(-3112);
857 prt.push_back(
"\\Xi^0"); pdgs.push_back(3322);
858 prt.push_back(
"\\bar{\\Xi}^0"); pdgs.push_back(-3322);
859 prt.push_back(
"\\Xi^-"); pdgs.push_back(3312);
860 prt.push_back(
"\\bar{\\Xi}^-"); pdgs.push_back(-3312);
861 prt.push_back(
"\\Omega"); pdgs.push_back(3334);
862 prt.push_back(
"\\bar{\\Omega}"); pdgs.push_back(-3334);
863 prt.push_back(
"\\pi^0"); pdgs.push_back(111);
864 prt.push_back(
"K^0_S"); pdgs.push_back(310);
865 prt.push_back(
"\\eta"); pdgs.push_back(221);
866 prt.push_back(
"\\omega"); pdgs.push_back(223);
867 prt.push_back(
"K^{*+}"); pdgs.push_back(323);
868 prt.push_back(
"K^{*-}"); pdgs.push_back(-323);
869 prt.push_back(
"K^{*0}"); pdgs.push_back(313);
870 prt.push_back(
"\\bar{K^{*0}}"); pdgs.push_back(-313);
872 prt.push_back(
"\\rho^+"); pdgs.push_back(213);
873 prt.push_back(
"\\rho^-"); pdgs.push_back(-213);
874 prt.push_back(
"\\rho^0"); pdgs.push_back(113);
875 prt.push_back(
"\\eta'"); pdgs.push_back(331);
876 prt.push_back(
"\\phi"); pdgs.push_back(333);
877 prt.push_back(
"\\Lambda(1520)"); pdgs.push_back(3124);
881 prt.push_back(
"d"); pdgs.push_back(1000010020);
882 prt.push_back(
"^3He"); pdgs.push_back(1000020030);
883 prt.push_back(
"^3_{\\Lambda}H"); pdgs.push_back(1010010030);
884 prt.push_back(
"D^+"); pdgs.push_back(411);
885 prt.push_back(
"D^-"); pdgs.push_back(-411);
886 prt.push_back(
"D^0"); pdgs.push_back(421);
887 prt.push_back(
"\\bar{D}^0"); pdgs.push_back(-421);
889 for(
size_t i=0;i<prt.size();++i) {
892 for(
size_t j=0;j<m_Multiplicities.size();++j)
893 if (pdgs[i]==m_Multiplicities[j].fPDGID) { isexp =
true; fl[j] = 1; tj = j;
break; }
895 if (m_model->TPS()->PdgToId(pdgs[i]) == -1)
continue;
900 if (isexp) dens1 = m_model->GetDensity(pdgs[i], m_Multiplicities[tj].fFeedDown);
902 std::string tname = prt[i];
905 if (dens1 * m_model->Parameters().V>1.e-3) fprintf(f,
"$%s$ & & $%.3g$ \\\\\n", tname.c_str(), dens1 * m_model->Parameters().V);
908 sprintf(tnum,
"%.2E", dens1 * m_model->Parameters().V);
913 for(
int ii=0;ii<4;++ii) valst[ii] = tnum[ii];
915 for(
int ii=0;ii<4;++ii) stepst[ii] = tnum[5+ii];
919 fprintf(f,
"$%s$ & & $%.2lf \\cdot 10^{%d}$ \\\\\n", tname.c_str(), val, step);
923 if (m_Multiplicities[tj].fValue>0.999) fprintf(f,
"$%s$ & $%.4g \\pm %.4g$ & $%.4g$ \\\\\n", tname.c_str(), m_Multiplicities[tj].fValue, m_Multiplicities[tj].fError, dens1 * m_model->Parameters().V);
924 else if (dens1 * m_model->Parameters().V>1.e-3) fprintf(f,
"$%s$ & $%.3g \\pm %.3g$ & $%.3g$ \\\\\n", tname.c_str(), m_Multiplicities[tj].fValue, m_Multiplicities[tj].fError, dens1 * m_model->Parameters().V);
925 else fprintf(f,
"$%s$ & $%.6g \\pm %.6g$ & $%.3g$ \\\\\n", tname.c_str(), m_Multiplicities[tj].fValue, m_Multiplicities[tj].fError, dens1 * m_model->Parameters().V);
929 for(
size_t i=0;i<m_Multiplicities.size();++i)
931 double dens1 = m_model->GetDensity(m_Multiplicities[i].fPDGID, m_Multiplicities[i].fFeedDown);
933 std::string tname = m_model->TPS()->GetNameFromPDG(m_Multiplicities[i].fPDGID);
934 if (m_Multiplicities[i].fPDGID==1) tname =
"Npart";
935 else if (m_Multiplicities[i].fPDGID==33340) tname = m_model->TPS()->Particles()[m_model->TPS()->PdgToId(3334)].Name() +
" + " + m_model->TPS()->Particles()[m_model->TPS()->PdgToId(-3334)].Name();
936 fprintf(f,
"$%s$ & $%.4lf \\pm %.4lf$ & $%.4lf$ & $%.4lf$ \\\\\n", tname.c_str(), m_Multiplicities[i].fValue, m_Multiplicities[i].fError, dens1 * m_model->Parameters().V, (dens1 * m_model->Parameters().V-m_Multiplicities[i].fValue)/m_Multiplicities[i].fError);
938 for(
size_t i=0;i<m_Ratios.size();++i) {
939 double dens1 = m_model->GetDensity(m_Ratios[i].fPDGID1, m_Ratios[i].fFeedDown1);
940 double dens2 = m_model->GetDensity(m_Ratios[i].fPDGID2, m_Ratios[i].fFeedDown2);
942 std::string name1 = m_model->TPS()->GetNameFromPDG(m_Ratios[i].fPDGID1);
943 std::string name2 = m_model->TPS()->GetNameFromPDG(m_Ratios[i].fPDGID2);
944 if (m_Ratios[i].fPDGID1==1) name1 =
"Npart";
945 if (m_Ratios[i].fPDGID2==1) name2 =
"Npart";
946 if (m_Ratios[i].fPDGID1==33340) name1 = m_model->TPS()->Particles()[m_model->TPS()->PdgToId(3334)].Name() +
" + " + m_model->TPS()->Particles()[m_model->TPS()->PdgToId(-3334)].Name();
947 if (m_Ratios[i].fPDGID2==33340) name2 = m_model->TPS()->Particles()[m_model->TPS()->PdgToId(3334)].Name() +
" + " + m_model->TPS()->Particles()[m_model->TPS()->PdgToId(-3334)].Name();
948 fprintf(f,
"$%s$ & $%.4lf \\pm %.4lf$ & $%.4lf$ & $%.4lf$ \\\\\n", (std::string(name1 +
"/" + name2)).c_str(), m_Ratios[i].fValue, m_Ratios[i].fError, dens1 / dens2 , (dens1 / dens2 - m_Ratios[i].fValue)/m_Ratios[i].fError);
950 fprintf(f,
"\\hline\n");
951 fprintf(f,
"\\end{tabular}\n");
953 fprintf(f,
"\\begin{tabular}{|c|c|}\n");
954 fprintf(f,
"\\hline\n");
955 fprintf(f,
"\\multicolumn{2}{|c|}{%s} \\\\\n", name.c_str());
956 fprintf(f,
"\\hline\n");
957 fprintf(f,
"Parameter & Fit result \\\\\n");
958 fprintf(f,
"\\hline\n");
959 for(
int i=0;i<9;++i) {
962 double tval = param.
value, terr = param.
error, terrp = param.
errp, terrm = param.
errm;
963 if (param.
name==
"T" || param.
name.substr(0,2)==
"mu") { tval *= 1000.; terr *= 1000.; terrp *= 1000.; terrm *= 1000.; }
964 if (!asymm) fprintf(f,
"$%s$ & $%.3lf \\pm %.3lf$ \\\\\n", param.
name.c_str(), tval, terr);
965 else fprintf(f,
"$%s$ & $%.3lf^{+%.3lf}_{-%.3lf}$ \\\\\n", param.
name.c_str(), tval, terrp, terrm);
968 fprintf(f,
"$%s$ & $%.2lf/%d$ \\\\\n",
"\\chi^2/N_{\\rm df}", m_Parameters.chi2ndf *
GetNdf(),
GetNdf());
969 fprintf(f,
"\\hline\n");
970 fprintf(f,
"\\end{tabular}\n");
975 std::string ThermalModelFit::GetCurrentTime() {
977 struct tm * timeinfo;
981 timeinfo = localtime(&rawtime);
983 strftime(buffer,
sizeof(buffer),
"%d-%m-%Y at %I:%M:%S", timeinfo);
984 std::string str(buffer);
993 fout =
new std::ofstream(filename.c_str());
1006 *fout << comment << std::endl << std::endl;
1010 *fout <<
"Performed on " << GetCurrentTime() << std::endl << std::endl;
1013 *fout <<
"chi2/dof = " << m_Parameters.chi2 <<
"/" << m_Parameters.ndf <<
" = " << m_Parameters.chi2ndf << std::endl << std::endl;
1017 *fout <<
"Data description accuracy = ("
1019 << std::setprecision(2)
1020 << accuracy.first * 100. <<
" +- " << accuracy.second * 100. <<
") %" << std::endl << std::endl;
1022 fout->unsetf(std::ios_base::floatfield);
1023 *fout << std::setprecision(6);
1026 *fout <<
"Extracted parameters:" << std::endl;
1027 for (
int i = 0; i < 10 ; ++i) {
1031 std::string sunit =
"";
1032 std::string tname =
"";
1034 if (param.
name ==
"T" || param.
name.substr(0, 2) ==
"mu") {
1038 else if (param.
name ==
"R" || param.
name ==
"Rc") {
1041 tname = param.
name + sunit;
1055 if ((param.
name ==
"muS" || param.
name ==
"gammaS") && !m_model->TPS()->hasStrange())
1057 if (param.
name ==
"muQ" && !m_model->TPS()->hasCharged())
1059 if ((param.
name ==
"muC" || param.
name ==
"gammaC") && !m_model->TPS()->hasCharmed())
1063 double tval = param.
value, terr = param.
error, terrp = param.
errp, terrm = param.
errm;
1065 if (param.
name ==
"Tkin" && !m_YieldsAtTkin)
1068 if (param.
name !=
"R" && param.
name !=
"Rc") {
1070 *fout << std::setw(15) << tname
1072 << std::setw(15) << tval * tmn
1074 << std::left << std::setw(15) << terr * tmn << std::right
1078 *fout << std::setw(15) << tname
1080 << std::setw(15) << tval * tmn
1082 << std::left << std::setw(15) << terrp * tmn << std::right
1084 << std::left << std::setw(15) << terrm * tmn << std::right
1090 *fout << std::setw(15) << tname
1092 << std::setw(15) << tval * tmn
1094 << std::left << std::setw(15) << terr * tmn << std::right
1097 std::string tname2 =
"V[fm3]";
1098 if (param.
name ==
"Rc")
1100 *fout << std::setw(15) << tname2
1102 << std::setw(15) << 4. / 3. *
xMath::Pi() * pow(tval * tmn, 3)
1104 << std::left << std::setw(15) << 4. *
xMath::Pi() * pow(tval * tmn, 2) * terr * tmn << std::right
1109 *fout << std::setw(15) << tname
1111 << std::setw(15) << tval * tmn
1113 << std::left << std::setw(15) << terrp * tmn << std::right
1115 << std::left << std::setw(15) << terrm * tmn << std::right
1118 std::string tname2 =
"V[fm3]";
1119 if (param.
name ==
"Rc")
1121 *fout << std::setw(15) << tname2
1123 << std::setw(15) << 4. / 3. *
xMath::Pi() * pow(tval * tmn, 3)
1125 << std::left << std::setw(15) << 4. *
xMath::Pi() * pow(tval * tmn, 2) * terrp * tmn << std::right
1127 << std::left << std::setw(15) << 4. *
xMath::Pi() * pow(tval * tmn, 2) * terrm * tmn << std::right
1134 double tval = param.
value;
1135 if (param.
name !=
"R" && param.
name !=
"Rc")
1136 *fout << std::setw(15) << tname
1138 << std::setw(15) << tval * tmn
1139 <<
" (FIXED)" << std::endl;
1143 *fout << std::setw(15) << tname
1145 << std::setw(15) << tval * tmn
1146 <<
" (FIXED)" <<
"\t";
1147 std::string tname2 =
"V[fm3]";
1148 if (param.
name ==
"Rc")
1150 *fout << std::setw(15) << tname2
1152 << std::setw(15) << 4. / 3. *
xMath::Pi() * pow(tval * tmn, 3)
1153 <<
" (FIXED)" << std::endl;
1160 *fout << std::endl << std::endl;
1162 *fout <<
"Yields:" << std::endl;
1164 for (
size_t i = 0; i<m_Multiplicities.size(); ++i) {
1165 double dens1 = m_model->GetDensity(m_Multiplicities[i].fPDGID, m_Multiplicities[i].fFeedDown);
1167 std::string tname = m_model->TPS()->GetNameFromPDG(m_Multiplicities[i].fPDGID);
1168 if (m_Multiplicities[i].fPDGID == 1) tname =
"Npart";
1169 else if (m_Multiplicities[i].fPDGID == 33340) tname = m_model->TPS()->Particles()[m_model->TPS()->PdgToId(3334)].Name() +
" + " + m_model->TPS()->Particles()[m_model->TPS()->PdgToId(-3334)].Name();
1171 *fout << std::setw(25) << tname
1174 if (m_Multiplicities[i].fValue > 1.e-5 && m_Multiplicities[i].fError > 1.e-5)
1175 fout->unsetf(std::ios_base::floatfield);
1177 *fout << std::scientific;
1179 *fout << std::setw(15) << m_Multiplicities[i].fValue;
1181 *fout << std::left << std::setw(15) << m_Multiplicities[i].fError << std::right <<
" ";
1183 *fout << std::left << std::setw(15) << dens1 * m_model->Parameters().V << std::right <<
" ";
1185 fout->unsetf(std::ios_base::floatfield);
1187 *fout <<
"Std.dev.: ";
1188 *fout << std::left << std::setw(15) << (dens1* m_model->Parameters().V - m_Multiplicities[i].fValue) / m_Multiplicities[i].fError << std::right <<
" ";
1197 for (
size_t i = 0; i<m_Ratios.size(); ++i) {
1198 double dens1 = m_model->GetDensity(m_Ratios[i].fPDGID1, m_Ratios[i].fFeedDown1);
1199 double dens2 = m_model->GetDensity(m_Ratios[i].fPDGID2, m_Ratios[i].fFeedDown2);
1201 std::string name1 = m_model->TPS()->GetNameFromPDG(m_Ratios[i].fPDGID1);
1202 std::string name2 = m_model->TPS()->GetNameFromPDG(m_Ratios[i].fPDGID2);
1203 if (m_Ratios[i].fPDGID1 == 1) name1 =
"Npart";
1204 if (m_Ratios[i].fPDGID2 == 1) name2 =
"Npart";
1205 if (m_Ratios[i].fPDGID1 == 33340) name1 = m_model->TPS()->Particles()[m_model->TPS()->PdgToId(3334)].Name() +
" + " + m_model->TPS()->Particles()[m_model->TPS()->PdgToId(-3334)].Name();
1206 if (m_Ratios[i].fPDGID2 == 33340) name2 = m_model->TPS()->Particles()[m_model->TPS()->PdgToId(3334)].Name() +
" + " + m_model->TPS()->Particles()[m_model->TPS()->PdgToId(-3334)].Name();
1208 *fout << std::setw(25) << std::string(name1 +
"/" + name2)
1211 if (m_Ratios[i].fValue > 1.e-5 && m_Ratios[i].fError > 1.e-5)
1212 fout->unsetf(std::ios_base::floatfield);
1214 *fout << std::scientific;
1216 *fout << std::setw(15) << m_Ratios[i].fValue;
1218 *fout << std::left << std::setw(15) << m_Ratios[i].fError << std::right <<
" ";
1220 *fout << std::left << std::setw(15) << dens1 / dens2 << std::right <<
" ";
1222 fout->unsetf(std::ios_base::floatfield);
1224 *fout <<
"Std.dev.: ";
1225 *fout << std::left << std::setw(15) << (dens1 / dens2 - m_Ratios[i].fValue) / m_Ratios[i].fError << std::right <<
" ";
1236 if (filename !=
"" && fout != NULL) {
1241 using namespace std;
1245 double chi2total = 0.;
1246 std::vector<double> weights;
1247 std::vector<double> vals, errors;
1250 if (quantity.
toFit) {
1251 vals.push_back(fabs(m_ModelData[i] / quantity.
Value() - 1));
1252 errors.push_back(quantity.
ValueError() / quantity.
Value() * m_ModelData[i] / quantity.
Value());
1256 chi2total += chi2contrib;
1257 weights.push_back(chi2contrib);
1261 for (
size_t i = 0; i < weights.size(); ++i) {
1262 weights[i] /= chi2total;
1265 double mean = 0., error = 0.;
1266 for (
size_t i = 0; i < vals.size(); ++i) {
1267 mean += vals[i] * weights[i];
1268 error += errors[i] * weights[i];
1271 return make_pair(mean, error);
1275 std::vector<FittedQuantity> ret(0);
1277 fin.open(filename.c_str());
1278 if (fin.is_open()) {
1280 fin.getline(tmpc, 2000);
1281 string tmp = string(tmpc);
1291 fin.seekg(0, ios::beg);
1294 ret = loadExpDataFromFile_NewFormat(fin);
1296 ret = loadExpDataFromFile_OldFormat(fin);
1303 std::vector<FittedQuantity> ThermalModelFit::loadExpDataFromFile_OldFormat(std::fstream & fin)
1305 std::vector<FittedQuantity> ret(0);
1306 if (fin.is_open()) {
1309 fin.getline(tmpc, 2000);
1313 if (fields.size()<4)
break;
1314 int type = atoi(fields[0].c_str());
1316 double value = 0., error = 0., error2 = 0.;
1317 int feeddown1 = 1, feeddown2 = 1;
1320 value = atof(fields[3].c_str());
1321 if (fields.size() >= 5) error = atof(fields[4].c_str());
1322 if (fields.size() >= 6) {
1323 error2 = atof(fields[5].c_str());
1324 error = sqrt(error*error + error2*error2);
1326 if (fields.size() >= 7) feeddown1 = atoi(fields[6].c_str());
1327 if (fields.size() >= 8) feeddown2 = atoi(fields[7].c_str());
1330 value = atof(fields[2].c_str());
1331 error = atof(fields[3].c_str());
1332 if (fields.size() >= 5) {
1333 error2 = atof(fields[4].c_str());
1334 error = sqrt(error*error + error2*error2);
1336 if (fields.size() >= 6) feeddown1 = atoi(fields[5].c_str());
1339 if (type) ret.push_back(FittedQuantity(ExperimentRatio(pdgid1, pdgid2, value, error,
static_cast<Feeddown::Type>(feeddown1),
static_cast<Feeddown::Type>(feeddown2))));
1340 else ret.push_back(FittedQuantity(ExperimentMultiplicity(pdgid1, value, error,
static_cast<Feeddown::Type>(feeddown1))));
1342 fin.getline(tmpc, 500);
1350 std::vector<FittedQuantity> ThermalModelFit::loadExpDataFromFile_NewFormat(std::fstream & fin)
1352 std::vector<FittedQuantity> ret(0);
1353 if (fin.is_open()) {
1355 while (!fin.eof()) {
1356 fin.getline(cc, 2000);
1357 string tmp = string(cc);
1359 if (elems.size() < 1)
1362 istringstream iss(elems[0]);
1365 long long pdgid1, pdgid2;
1366 int feeddown1, feeddown2;
1367 double value, error;
1369 if (iss >> fitflag >> pdgid1 >> pdgid2 >> feeddown1 >> feeddown2 >> value >> error) {
1370 if (pdgid2 != 0) ret.push_back(FittedQuantity(ExperimentRatio(pdgid1, pdgid2, value, error,
static_cast<Feeddown::Type>(feeddown1),
static_cast<Feeddown::Type>(feeddown2))));
1371 else ret.push_back(FittedQuantity(ExperimentMultiplicity(pdgid1, value, error,
static_cast<Feeddown::Type>(feeddown1))));
1374 ret[ret.size() - 1].toFit =
true;
1376 ret[ret.size() - 1].toFit =
false;
1385 std::ofstream fout(filename.c_str());
1386 if (fout.is_open()) {
1388 << std::setw(14) <<
"is_fitted"
1389 << std::setw(15) <<
"pdg1"
1390 << std::setw(15) <<
"pdg2"
1391 << std::setw(15) <<
"feeddown1"
1392 << std::setw(15) <<
"feeddown2"
1393 << std::setw(15) <<
"value"
1394 << std::setw(15) <<
"error"
1396 for (
size_t i = 0; i < outQuantities.size(); ++i) {
1398 fout << std::setw(15) << static_cast<int>(outQuantities[i].toFit)
1399 << std::setw(15) << outQuantities[i].mult.fPDGID
1400 << std::setw(15) << 0
1401 << std::setw(15) << outQuantities[i].mult.fFeedDown
1402 << std::setw(15) << 0
1403 << std::setw(15) << outQuantities[i].mult.fValue
1404 << std::setw(15) << outQuantities[i].mult.fError
1408 fout << std::setw(15) << static_cast<int>(outQuantities[i].toFit)
1409 << std::setw(15) << outQuantities[i].ratio.fPDGID1
1410 << std::setw(15) << outQuantities[i].ratio.fPDGID2
1411 << std::setw(15) << outQuantities[i].ratio.fFeedDown1
1412 << std::setw(15) << outQuantities[i].ratio.fFeedDown2
1413 << std::setw(15) << outQuantities[i].ratio.fValue
1414 << std::setw(15) << outQuantities[i].ratio.fError
1421 printf(
"**WARNING** ThermalModelFit::saveExpDataToFile: Cannot open file for writing data!");
1427 if (!m_Parameters.T.toFit) nparams--;
1428 if (!m_Parameters.muB.toFit) nparams--;
1429 if (!m_Parameters.muS.toFit) nparams--;
1430 if (!m_Parameters.muQ.toFit) nparams--;
1431 if (!m_Parameters.muC.toFit) nparams--;
1432 if (!m_Parameters.gammaq.toFit) nparams--;
1433 if (!m_Parameters.gammaS.toFit) nparams--;
1434 if (!m_Parameters.gammaC.toFit) nparams--;
1435 if (!m_Parameters.R.toFit || (m_Multiplicities.size()==0 && m_model->Ensemble() ==
ThermalModelBase::GCE)) nparams--;
1437 if (!m_Parameters.Tkin.toFit || !
UseTkin()) nparams--;
1439 for (
size_t i = 0; i < m_Quantities.size(); ++i)
1440 if (m_Quantities[i].toFit) ndof++;
1441 return (ndof - nparams);
map< string, double > params
Contains some helper functions.
Abstract base class for an HRG model implementation.
@ SCE
Strangeness-canonical ensemble.
@ GCE
Grand canonical ensemble.
@ CCE
Charm-canonical ensemble.
void FixVcOverV(bool fix)
const std::vector< FittedQuantity > & FittedQuantities() const
Return a vector of the fitted quantities (data)
void PrintYieldsLatexAll(std::string filename="Yield.dat", std::string name="A+A", bool asymm=false)
void PrintYieldsLatex(std::string filename="Yield.dat", std::string name="A+A")
~ThermalModelFit(void)
Destroy the Thermal Model Fit object.
void PrintFitLog(std::string filename="", std::string comment="Thermal fit", bool asymm=false)
Prints the result of the fitting procedure to a file.
ThermalModelFit(ThermalModelBase *model)
Construct a new ThermalModelFit object.
void PrintParameters()
Print function.
static std::vector< FittedQuantity > loadExpDataFromFile(const std::string &filename)
Load the experimental data from a file.
void UseTkin(bool YieldsAtTkin)
Sets whether the yields should be evaluated at Tkin using partial chemical equilibrium.
int GetNdf() const
Number of degrees of freedom in the fit.
static void saveExpDataToFile(const std::vector< FittedQuantity > &outQuantities, const std::string &filename)
std::pair< double, double > ModelDescriptionAccuracy() const
Returns a relative error of the data description (and its uncertainty estimate)
const ThermalModelFitParameters & Parameters() const
ThermalModelFitParameters PerformFit(bool verbose=true, bool AsymmErrors=false)
The thermal fit procedure.
void PrintYieldsTable2(std::string filename="Yield.dat")
int ModelDataSize() const
void PrintMultiplicities()
void PrintYieldsTable(std::string filename="Yield.dat")
Class implementing HRG in partial chemical equilibrium with baryon annihilation.
Class implementing HRG in partial chemical equilibrium.
void UseSahaForNuclei(bool flag)
Whether the nuclear abundances are evaluated through the Saha equation.
std::vector< std::string > split(const std::string &s, char delim)
constexpr double Pi()
Pi constant.
The main namespace where all classes and functions of the Thermal-FIST library reside.
long long stringToLongLong(const std::string &str)
@ BaryonCharge
Baryon number.
@ StrangenessCharge
Strangeness.
Structure containing the experimental yield (multiplicity) to be fitted.
double fValue
Experimental value.
Feeddown::Type fFeedDown
The feeddown contributions to be included.
long long fPDGID
PDG code of the particle yield.
double fError
Experimental error.
Structure containing the experimental ratio of yields to be fitted.
Feeddown::Type fFeedDown2
The feeddown contributions to be included for the yield in the denominator.
long long fPDGID1
PDG code of the particle yield in the numerator.
double fValue
Experimental value of the yield ratio.
double fError
Experimental error of the yield ratio.
long long fPDGID2
PDG code of the particle yield in the denominator.
Feeddown::Type fFeedDown1
The feeddown contributions to be included for the yield in the numerator.
@ StabilityFlag
Feeddown from all particles marked as unstable.
Structure for an arbitrary fit parameter.
bool toFit
Whether the parameter is fitted or fixed.
double error
Parameter error (symmetric)
double errm
Asymmetric errors.
std::string name
Name of the parameter.
Structure describing the measurement to be fitted or compared to model.
bool toFit
Whether this quantity contributes to the of a fit.
double Value() const
Value of the measurement.
double ValueError() const
Error of the measurement.
Extended structure for calculating uncertainties in non-fit quantities resulting from uncertanties in...
Structure holding information about parameters of a thermal fit.
ThermalModelParameters GetThermalModelParameters()
Return ThermalModelParameters corresponding to the this ThermalModelFitParameters.
int B
Total charges (for CE)
int ndf
Number of degrees of freedom.
FitParameter Tkin
Since version 1.3: Kinetic freeze-out temperature.
double chi2
Value of the function.
FitParameter T
All the fit parameters.
std::vector< FitParameter * > ParameterList
Vector of pointer to all the parameters.
FitParameter GetParameter(const std::string &name) const
Get the FitParameter by its name.
Structure containing all thermal parameters of the model.