KaliVeda
Toolkit for HIC analysis
KVMultiGaussIsotopeFit.h
1 #ifndef __KVMULTIGAUSSISOTOPEFIT_H
2 #define __KVMULTIGAUSSISOTOPEFIT_H
3 
4 #include <optional>
5 #include "TF1.h"
6 #include "TVirtualPad.h"
7 #include "TColor.h"
8 #include "TArrayI.h"
9 #include "KVNumberList.h"
10 #include "KVList.h"
11 #include <KVNameValueList.h>
12 
51 class KVMultiGaussIsotopeFit : public TF1 {
53  bkg_cst = 1,
54  bkg_slp = 2,
55  gauss_wid = 3,
56  pidvsA_a0 = 4,
57  pidvsA_a1 = 5,
58  pidvsA_a2 = 6
59  };
60  double centroid_fit(double* x, double* p)
61  {
69 
70  return p[0] + p[1] * x[0] + p[2] * x[0] * x[0];
71  }
72 
73  double FitFunc(double* x, double* p)
74  {
86 
87  int Ng = p[0];
88  double background = TMath::Exp(p[fit_param_index::bkg_cst] + p[fit_param_index::bkg_slp] * x[0]);
89  for (int i = 1; i <= Ng; ++i) {
90  background +=
91  p[get_gauss_norm_index(i)] * TMath::Gaus(x[0], centroid_fit(&p[get_mass_index(i, Ng)],
92  &p[fit_param_index::pidvsA_a0]), p[fit_param_index::gauss_wid], kTRUE);
93  }
94  return background;
95  }
96  int get_gauss_norm_index(int ig) const
97  {
98  return 6 + ig;
99  }
100  int get_mass_index(int ig, int ng) const
101  {
102  return 6 + ng + ig;
103  }
104  int total_number_parameters(int ng) const
105  {
106  return 7 + 2 * ng;
107  }
108  int Z;
109  int Niso;
110  double PIDmin, PIDmax;
111  std::vector<int> Alist;
112  std::vector<double> PIDlist;
113  double min_sigma = 1.e-2; // lower limit for width of gaussians
114  double max_sigma = 1.e-1; // upper limit for width of gaussians
115 
116  double evaluate_gaussian(int i, double pid) const
117  {
119  return GetGaussianNorm(i) * TMath::Gaus(pid, GetCentroid(i), GetGaussianWidth(i), kTRUE);
120  }
121  std::optional<double> get_total_fit_for_pid(double PID) const;
122 public:
123  KVMultiGaussIsotopeFit() : TF1() {}
124  KVMultiGaussIsotopeFit(int z, std::vector<int> alist)
125  : TF1(),
126  Z{z},
127  Alist{alist}
128  {
130  }
131  KVMultiGaussIsotopeFit(int z, int Ngauss, double PID_min, double PID_max, const KVNumberList& alist, std::vector<double> pidlist);
132  KVMultiGaussIsotopeFit(int z, int Ngauss, double PID_min, double PID_max, const KVNumberList& alist,
133  double bkg_cst, double bkg_slp, double gaus_wid,
134  double pidvsa_a0, double pidvsa_a1, double pidvsa_a2);
136 
137  void ReleaseCentroids()
138  {
140  SetParLimits(fit_param_index::pidvsA_a0, -50, 50);
141  SetParLimits(fit_param_index::pidvsA_a1, 1.e-2, 5.);
142  SetParLimits(fit_param_index::pidvsA_a2, -2.e-2, 5.);
143  }
144 
145  double GetPIDvsAfit_a0() const
146  {
148  return GetParameter(fit_param_index::pidvsA_a0);
149  }
150  double GetPIDvsAfit_a1() const
151  {
153  return GetParameter(fit_param_index::pidvsA_a1);
154  }
155  double GetPIDvsAfit_a2() const
156  {
158  return GetParameter(fit_param_index::pidvsA_a2);
159  }
160 
161  void UnDraw(TVirtualPad* pad = gPad) const;
162 
163  static void UnDrawGaussian(int z, int a, TVirtualPad* pad = gPad)
164  {
166 
167  auto old_fit = pad->FindObject(get_name_of_isotope_gaussian(z, a));
168  if (old_fit) delete old_fit;
169  }
170  static void UnDrawAnyGaussian(int z, TVirtualPad* pad = gPad)
171  {
173 
174  TIter it(pad->GetListOfPrimitives());
175  TObject* ob;
176  KVList to_delete;
177  while ((ob = it())) {
178  TString obname = ob->GetName();
179  if (obname.BeginsWith(get_root_name_of_isotope_gaussian(z))) to_delete.Add(ob);
180  }
181  }
182 
183  void DrawFitWithGaussians(Option_t* opt = "") const;
184 
185  int GetIsotopeWithMaxYield() const
186  {
188 
189  std::map<double, int> yields;
190  for (int i = 1; i <= Niso; ++i) yields[GetGaussianNorm(i)] = Alist[i - 1];
193  auto it = yields.rbegin();
194  return it->second;
195  }
196  int GetIsotopeIndexWithMaxYield() const
197  {
199 
200  std::map<double, int> yields;
201  for (int i = 1; i <= Niso; ++i) yields[GetGaussianNorm(i)] = i;
204  auto it = yields.rbegin();
205  return it->second;
206  }
207  std::optional<int> GetMostProbableA(double PID, double& P) const;
208  std::optional<double> GetMeanA(double PID) const;
209  std::optional<std::map<int, double> > GetADistribution(double PID) const;
210  std::optional<int> GetA(double PID, double& P) const;
211  double GetProbability(int A, double PID) const;
212  double GetInterpolatedA(double PID) const
213  {
216 
217  auto a = GetPIDvsAfit_a2();
218  auto b = GetPIDvsAfit_a1();
219  auto c = GetPIDvsAfit_a0() - PID;
220  return (TMath::Sqrt(b * b - 4.*a * c) - b) / 2. / a;
221  }
222 
223  static TString get_name_of_multifit(int z)
224  {
225  return Form("multigauss_fit_Z=%d", z);
226  }
227  static TString get_name_of_isotope_gaussian(int z, int a)
228  {
229  return Form("gauss_fit_Z=%d_A=%d", z, a);
230  }
231  static TString get_root_name_of_isotope_gaussian(int z)
232  {
233  return Form("gauss_fit_Z=%d_", z);
234  }
235 
236  double GetBackgroundConstant() const
237  {
239  return GetParameter(fit_param_index::bkg_cst);
240  }
241  double GetBackgroundSlope() const
242  {
244  return GetParameter(fit_param_index::bkg_slp);
245  }
246  double GetCentroid(int i) const
247  {
249  assert(i > 0 && i <= Niso);
250  return GetParameter(fit_param_index::pidvsA_a0)
251  + (GetParameter(fit_param_index::pidvsA_a1)
252  + GetParameter(fit_param_index::pidvsA_a2) * Alist[i - 1]) * Alist[i - 1];
253  }
254  double GetPIDFromInterpolatedA(double interpA)
255  {
259  return GetParameter(fit_param_index::pidvsA_a0)
260  + (GetParameter(fit_param_index::pidvsA_a1)
261  + GetParameter(fit_param_index::pidvsA_a2) * interpA) * interpA;
262  }
263  int GetNGaussians() const
264  {
266  return Niso;
267  }
268  double GetGaussianWidth(int) const
269  {
271  return GetParameter(fit_param_index::gauss_wid);
272  }
273  int GetGaussianA(int i) const
274  {
276  return Alist[i - 1];
277  }
278  double GetGaussianNorm(int i) const
279  {
281  assert(i > 0 && i <= Niso);
282  return GetParameter(get_gauss_norm_index(i));
283  }
284  void SetGaussianNorm(int i, double v)
285  {
287  assert(i > 0 && i <= Niso);
288  SetParameter(get_gauss_norm_index(i), v);
289  }
290 
291  void SetFitRange(double min, double max);
292 
293  double GetPIDmin() const
294  {
295  return PIDmin;
296  }
297  double GetPIDmax() const
298  {
299  return PIDmax;
300  }
301 
302  double GetMinSigma() const
303  {
304  return min_sigma;
305  }
306  double GetMaxSigma() const
307  {
308  return max_sigma;
309  }
310  void SetSigmaLimits(double smin, double smax)
311  {
312  min_sigma = smin;
313  max_sigma = smax;
314  SetParLimits(fit_param_index::gauss_wid, min_sigma, max_sigma);
315  }
316  void PositiveBkgSlope(bool yes = true);
317 
318  ClassDefOverride(KVMultiGaussIsotopeFit, 1) //Function for fitting PID mass spectrum
319 };
320 
321 #endif
#define c(i)
constexpr Bool_t kTRUE
const char Option_t
#define ClassDefOverride(name, id)
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t b
char * Form(const char *fmt,...)
Extended TList class which owns its objects by default.
Definition: KVList.h:22
Function for fitting PID mass spectra.
double FitFunc(double *x, double *p)
double centroid_fit(double *x, double *p)
Handles lists of named parameters with different types, a list of KVNamedParameter objects.
Strings used to represent a set of ranges of values.
Definition: KVNumberList.h:85
void Add(TObject *obj) override
virtual Double_t GetParameter(const TString &name) const
virtual void SetParLimits(Int_t ipar, Double_t parmin, Double_t parmax)
virtual void SetParameter(const TString &name, Double_t value)
virtual const char * GetName() const
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Double_t x[n]
Double_t Gaus(Double_t x, Double_t mean=0, Double_t sigma=1, Bool_t norm=kFALSE)
Double_t Exp(Double_t x)
Double_t Sqrt(Double_t x)
TArc a