KaliVeda
Toolkit for HIC analysis
KVMultiGaussIsotopeFit.h
1 #ifndef __KVMULTIGAUSSISOTOPEFIT_H
2 #define __KVMULTIGAUSSISOTOPEFIT_H
3 
4 #include "TF1.h"
5 #include "TVirtualPad.h"
6 #include "TColor.h"
7 #include "TArrayI.h"
8 #include "KVNumberList.h"
9 #include "KVList.h"
10 
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 public:
122  KVMultiGaussIsotopeFit() : TF1() {}
123  KVMultiGaussIsotopeFit(int z, std::vector<int> alist)
124  : TF1(),
125  Z{z},
126  Alist{alist}
127  {
129  }
130  KVMultiGaussIsotopeFit(int z, int Ngauss, double PID_min, double PID_max, const KVNumberList& alist, std::vector<double> pidlist);
131  KVMultiGaussIsotopeFit(int z, int Ngauss, double PID_min, double PID_max, const KVNumberList& alist,
132  double bkg_cst, double bkg_slp, double gaus_wid,
133  double pidvsa_a0, double pidvsa_a1, double pidvsa_a2);
135 
136  void ReleaseCentroids()
137  {
139  SetParLimits(fit_param_index::pidvsA_a0, -50, 50);
140  SetParLimits(fit_param_index::pidvsA_a1, 1.e-2, 5.);
141  SetParLimits(fit_param_index::pidvsA_a2, -2.e-2, 5.);
142  }
143 
144  double GetPIDvsAfit_a0() const
145  {
147  return GetParameter(fit_param_index::pidvsA_a0);
148  }
149  double GetPIDvsAfit_a1() const
150  {
152  return GetParameter(fit_param_index::pidvsA_a1);
153  }
154  double GetPIDvsAfit_a2() const
155  {
157  return GetParameter(fit_param_index::pidvsA_a2);
158  }
159 
160  void UnDraw(TVirtualPad* pad = gPad) const;
161 
162  static void UnDrawGaussian(int z, int a, TVirtualPad* pad = gPad)
163  {
165 
166  auto old_fit = pad->FindObject(get_name_of_isotope_gaussian(z, a));
167  if (old_fit) delete old_fit;
168  }
169  static void UnDrawAnyGaussian(int z, TVirtualPad* pad = gPad)
170  {
172 
173  TIter it(pad->GetListOfPrimitives());
174  TObject* ob;
175  KVList to_delete;
176  while ((ob = it())) {
177  TString obname = ob->GetName();
178  if (obname.BeginsWith(get_root_name_of_isotope_gaussian(z))) to_delete.Add(ob);
179  }
180  }
181 
182  void DrawFitWithGaussians(Option_t* opt = "") const;
183 
184  int GetIsotopeWithMaxYield() const
185  {
187 
188  std::map<double, int> yields;
189  for (int i = 1; i <= Niso; ++i) yields[GetGaussianNorm(i)] = Alist[i - 1];
192  auto it = yields.rbegin();
193  return it->second;
194  }
195  int GetIsotopeIndexWithMaxYield() const
196  {
198 
199  std::map<double, int> yields;
200  for (int i = 1; i <= Niso; ++i) yields[GetGaussianNorm(i)] = i;
203  auto it = yields.rbegin();
204  return it->second;
205  }
206  int GetMostProbableA(double PID, double& P) const;
207  double GetMeanA(double PID) const;
208  std::map<int, double> GetADistribution(double PID) const;
209  int GetA(double PID, double& P) const;
210  double GetProbability(int A, double PID) const;
211  double GetInterpolatedA(double PID) const
212  {
215 
216  auto a = GetPIDvsAfit_a2();
217  auto b = GetPIDvsAfit_a1();
218  auto c = GetPIDvsAfit_a0() - PID;
219  return (TMath::Sqrt(b * b - 4.*a * c) - b) / 2. / a;
220  }
221 
222  static TString get_name_of_multifit(int z)
223  {
224  return Form("multigauss_fit_Z=%d", z);
225  }
226  static TString get_name_of_isotope_gaussian(int z, int a)
227  {
228  return Form("gauss_fit_Z=%d_A=%d", z, a);
229  }
230  static TString get_root_name_of_isotope_gaussian(int z)
231  {
232  return Form("gauss_fit_Z=%d_", z);
233  }
234 
235  double GetBackgroundConstant() const
236  {
238  return GetParameter(fit_param_index::bkg_cst);
239  }
240  double GetBackgroundSlope() const
241  {
243  return GetParameter(fit_param_index::bkg_slp);
244  }
245  double GetCentroid(int i) const
246  {
248  assert(i > 0 && i <= Niso);
249  return GetParameter(fit_param_index::pidvsA_a0)
250  + (GetParameter(fit_param_index::pidvsA_a1)
251  + GetParameter(fit_param_index::pidvsA_a2) * Alist[i - 1]) * Alist[i - 1];
252  }
253  double GetPIDFromInterpolatedA(double interpA)
254  {
258  return GetParameter(fit_param_index::pidvsA_a0)
259  + (GetParameter(fit_param_index::pidvsA_a1)
260  + GetParameter(fit_param_index::pidvsA_a2) * interpA) * interpA;
261  }
262  int GetNGaussians() const
263  {
265  return Niso;
266  }
267  double GetGaussianWidth(int) const
268  {
270  return GetParameter(fit_param_index::gauss_wid);
271  }
272  int GetGaussianA(int i) const
273  {
275  return Alist[i - 1];
276  }
277  double GetGaussianNorm(int i) const
278  {
280  assert(i > 0 && i <= Niso);
281  return GetParameter(get_gauss_norm_index(i));
282  }
283  void SetGaussianNorm(int i, double v)
284  {
286  assert(i > 0 && i <= Niso);
287  SetParameter(get_gauss_norm_index(i), v);
288  }
289 
290  void SetFitRange(double min, double max);
291 
292  double GetPIDmin() const
293  {
294  return PIDmin;
295  }
296  double GetPIDmax() const
297  {
298  return PIDmax;
299  }
300 
301  double GetMinSigma() const
302  {
303  return min_sigma;
304  }
305  double GetMaxSigma() const
306  {
307  return max_sigma;
308  }
309  void SetSigmaLimits(double smin, double smax)
310  {
311  min_sigma = smin;
312  max_sigma = smax;
313  SetParLimits(fit_param_index::gauss_wid, min_sigma, max_sigma);
314  }
315 
316  ClassDef(KVMultiGaussIsotopeFit, 1) //Function for fitting PID mass spectrum
317 };
318 
319 #endif
#define c(i)
constexpr Bool_t kTRUE
const char Option_t
#define ClassDef(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:28
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
virtual void Add(TObject *obj)
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