KaliVeda  1.13/01
Heavy-Ion Analysis Toolkit
KVMultiGaussIsotopeFit.h
Go to the documentation of this file.
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 
49 class KVMultiGaussIsotopeFit : public TF1 {
51  bkg_cst = 1,
52  bkg_slp = 2,
53  gauss_wid = 3,
54  pidvsA_a0 = 4,
55  pidvsA_a1 = 5,
56  pidvsA_a2 = 6
57  };
58  double centroid_fit(double* x, double* p)
59  {
60  /*
61  centroids of gaussians are expected to increase linearly with mass A
62  x[0]=A
63  p[0]=offset
64  p[1]=slope
65  */
66  return p[0] + p[1] * x[0] + p[2] * x[0] * x[0];
67  }
68 
69  double FitFunc(double* x, double* p)
70  {
71  /*
72  x[0] = PID
73  p[0] = number of gaussians = Ng (fixed)
74  p[1],p[2] = background parameters: exp(p[1]+p[2]*x)
75  p[3] = sigma for all gaussians
76  p[4],p[5],p[6] = offset & slope for centroid PID vs. A correlation
77  p[7]...p[6+Ng] = norm of each gaussian
78  p[6+Ng+1]...p[6+2*Ng] = A of each gaussian
79 
80  Total number of parameters is 7+2*Ng
81  */
82  int Ng = p[0];
83  double background = TMath::Exp(p[fit_param_index::bkg_cst] + p[fit_param_index::bkg_slp] * x[0]);
84  for (int i = 1; i <= Ng; ++i) {
85  background +=
87  &p[fit_param_index::pidvsA_a0]), p[fit_param_index::gauss_wid], kTRUE);
88  }
89  return background;
90  }
91  int get_gauss_norm_index(int ig) const
92  {
93  return 6 + ig;
94  }
95  int get_mass_index(int ig, int ng) const
96  {
97  return 6 + ng + ig;
98  }
99  int total_number_parameters(int ng) const
100  {
101  return 7 + 2 * ng;
102  }
103  int Z;
104  int Niso;
105  double PIDmin, PIDmax;
106  std::vector<int> Alist;
107  std::vector<double> PIDlist;
108  double min_sigma = 1.e-2; // lower limit for width of gaussians
109  double max_sigma = 1.e-1; // upper limit for width of gaussians
110 
111  double evaluate_gaussian(int i, double pid) const
112  {
115  }
116 public:
118  KVMultiGaussIsotopeFit(int z, std::vector<int> alist)
119  : TF1(),
120  Z{z},
121  Alist{alist}
122  {
124  }
125  KVMultiGaussIsotopeFit(int z, int Ngauss, double PID_min, double PID_max, const KVNumberList& alist, std::vector<double> pidlist);
126  KVMultiGaussIsotopeFit(int z, int Ngauss, double PID_min, double PID_max, const KVNumberList& alist,
127  double bkg_cst, double bkg_slp, double gaus_wid,
128  double pidvsa_a0, double pidvsa_a1, double pidvsa_a2);
130 
132  {
134  SetParLimits(fit_param_index::pidvsA_a0, -50, 50);
135  SetParLimits(fit_param_index::pidvsA_a1, 1.e-2, 5.);
136  SetParLimits(fit_param_index::pidvsA_a2, -2.e-2, 5.);
137  }
138 
139  double GetPIDvsAfit_a0() const
140  {
142  return GetParameter(fit_param_index::pidvsA_a0);
143  }
144  double GetPIDvsAfit_a1() const
145  {
147  return GetParameter(fit_param_index::pidvsA_a1);
148  }
149  double GetPIDvsAfit_a2() const
150  {
152  return GetParameter(fit_param_index::pidvsA_a2);
153  }
154 
155  void UnDraw(TVirtualPad* pad = gPad) const;
156 
157  static void UnDrawGaussian(int z, int a, TVirtualPad* pad = gPad)
158  {
160 
161  auto old_fit = pad->FindObject(get_name_of_isotope_gaussian(z, a));
162  if (old_fit) delete old_fit;
163  }
164  static void UnDrawAnyGaussian(int z, TVirtualPad* pad = gPad)
165  {
167 
168  TIter it(pad->GetListOfPrimitives());
169  TObject* ob;
170  KVList to_delete;
171  while ((ob = it())) {
172  TString obname = ob->GetName();
173  if (obname.BeginsWith(get_root_name_of_isotope_gaussian(z))) to_delete.Add(ob);
174  }
175  }
176 
177  void DrawFitWithGaussians(Option_t* opt = "") const;
178 
179  int GetMostProbableA(double PID, double& P) const;
180  double GetMeanA(double PID) const;
181  std::map<int, double> GetADistribution(double PID) const;
182  int GetA(double PID, double& P) const;
183  double GetProbability(int A, double PID) const;
184  double GetInterpolatedA(double PID) const
185  {
188 
189  auto a = GetPIDvsAfit_a2();
190  auto b = GetPIDvsAfit_a1();
191  auto c = GetPIDvsAfit_a0() - PID;
192  return (TMath::Sqrt(b * b - 4.*a * c) - b) / 2. / a;
193  }
194 
196  {
197  return Form("multigauss_fit_Z=%d", z);
198  }
200  {
201  return Form("gauss_fit_Z=%d_A=%d", z, a);
202  }
204  {
205  return Form("gauss_fit_Z=%d_", z);
206  }
207 
208  double GetBackgroundConstant() const
209  {
211  return GetParameter(fit_param_index::bkg_cst);
212  }
213  double GetBackgroundSlope() const
214  {
216  return GetParameter(fit_param_index::bkg_slp);
217  }
218  double GetCentroid(int i) const
219  {
221  assert(i > 0 && i <= Niso);
222  return GetParameter(fit_param_index::pidvsA_a0)
223  + (GetParameter(fit_param_index::pidvsA_a1)
224  + GetParameter(fit_param_index::pidvsA_a2) * Alist[i - 1]) * Alist[i - 1];
225  }
226  double GetGaussianWidth(int) const
227  {
229  return GetParameter(fit_param_index::gauss_wid);
230  }
231  double GetGaussianNorm(int i) const
232  {
234  assert(i > 0 && i <= Niso);
236  }
237  void SetGaussianNorm(int i, double v)
238  {
240  assert(i > 0 && i <= Niso);
242  }
243 
244  void SetFitRange(double min, double max);
245 
246  double GetPIDmin() const
247  {
248  return PIDmin;
249  }
250  double GetPIDmax() const
251  {
252  return PIDmax;
253  }
254 
255  double GetMinSigma() const
256  {
257  return min_sigma;
258  }
259  double GetMaxSigma() const
260  {
261  return max_sigma;
262  }
263  void SetSigmaLimits(double smin, double smax)
264  {
265  min_sigma = smin;
266  max_sigma = smax;
267  SetParLimits(fit_param_index::gauss_wid, min_sigma, max_sigma);
268  }
269 
270  ClassDef(KVMultiGaussIsotopeFit, 1) //Function for fitting PID mass spectrum
271 };
272 
273 #endif
#define b(i)
#define c(i)
const Bool_t kTRUE
const char Option_t
#define ClassDef(name, id)
char * Form(const char *fmt,...)
Extended TList class which owns its objects by default.
Definition: KVList.h:27
Function for fitting PID mass spectra.
double FitFunc(double *x, double *p)
static TString get_name_of_isotope_gaussian(int z, int a)
static TString get_name_of_multifit(int z)
int get_mass_index(int ig, int ng) const
double GetGaussianWidth(int) const
static TString get_root_name_of_isotope_gaussian(int z)
double evaluate_gaussian(int i, double pid) const
double GetCentroid(int i) const
int Z
atomic number of the isotopes
KVMultiGaussIsotopeFit(int z, std::vector< int > alist)
void SetSigmaLimits(double smin, double smax)
int get_gauss_norm_index(int ig) const
std::map< int, double > GetADistribution(double PID) const
void SetFitRange(double min, double max)
Change range of fit.
void SetGaussianNorm(int i, double v)
double GetInterpolatedA(double PID) const
int GetA(double PID, double &P) const
int total_number_parameters(int ng) const
int GetMostProbableA(double PID, double &P) const
double GetProbability(int A, double PID) const
double GetGaussianNorm(int i) const
static void UnDrawAnyGaussian(int z, TVirtualPad *pad=gPad)
double centroid_fit(double *x, double *p)
int Niso
number of isotopes to fit = number of gaussians
double PIDmax
PID limits for current set of isotopes.
void UnDraw(TVirtualPad *pad=gPad) const
Remove the graphical representation of this fit from the given pad.
static void UnDrawGaussian(int z, int a, TVirtualPad *pad=gPad)
double GetMeanA(double PID) const
void DrawFitWithGaussians(Option_t *opt="") const
Draw the overall fit plus the individual gaussians for each isotope.
std::vector< int > Alist
list of masses of isotopes (in increasing order)
std::vector< double > PIDlist
list of initial centroid (PID) of each isotope (in increasing order)
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:83
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)
v
auto * a