KaliVeda
Toolkit for HIC analysis
KVGaussFitMassModifier.cpp
1 #include "KVGaussFitMassModifier.h"
2 #include "KVMultiGaussIsotopeFit.h"
3 
4 
7 
9  : fGrid{gr}
10 {
11  // Prepare mass modification object for the multi-gaussian fit for element \f$Z\f$ in the given grid
12  fGrid->Initialize();
13  fItvs = gr->GetIntervalSet(Z);
14  fGfit = gr->GetMultiGaussFit(Z);
15 }
16 
17 
18 
27 
28 void KVGaussFitMassModifier::Modify(int deltaA, TH1* pid_dist, const KVNameValueList& mass_fit_parameters)
29 {
30  // \param[in] deltaA mass modification \f$\Delta A\f$ to apply to all isotopes of element, can be positive or negative
31  // \param[in] pid_dist a PID distribution corresponding to the grid being used
32  // \param[in] mass_fit_parameters parameters to control fit; by default KVMultiGaussIsotopeFit::mass_fit_parameters
33  //
34  // \note For any KVIDZAGrid, a 1-dimensional PID distribution to be used with multi-gaussian fits
35  // can be generated from a 2D identification map (e.g. \f$\Delta E-E\f$ matrix)
36  // using KVIDZAFromZGrid::LinearizeHistoToPID()
37 
38  KVNumberList alist;
39  std::vector<double> pidlist;
40  TIter nxt_int(fItvs->GetIntervals());
41  interval* intvl = nullptr;
42  while ((intvl = (interval*)nxt_int())) {
43  intvl->SetA(intvl->GetA()+deltaA); // retrieve & modify the A of each interval set
44  alist.Add(intvl->GetA());
45  pidlist.push_back(intvl->GetPID());
46  }
47  // set PIDlist & modified Alist in the fit object
48  fGfit->SetPIDlist(pidlist);
49  fGfit->SetAlist(alist.GetArray());
52 
53  bool fit_limited = false;
54  // check user fit parameters
55  if (mass_fit_parameters.GetBoolValue("Limit range of fit")) {
56  // if the user's range is not valid for the current interval set, we ignore it
57  if (mass_fit_parameters.GetDoubleValue("PID min for fit") >= fItvs->GetZ() - 0.5
58  && mass_fit_parameters.GetDoubleValue("PID max for fit") <= fItvs->GetZ() + 0.5)
59  {
60  fGfit->SetFitRange(mass_fit_parameters.GetDoubleValue("PID min for fit"),
61  mass_fit_parameters.GetDoubleValue("PID max for fit"));
62  fit_limited = true;
63  }
64  }
65  fGfit->SetSigmaLimits(mass_fit_parameters.GetDoubleValue("Minimum #sigma"),
66  mass_fit_parameters.GetDoubleValue("Maximum #sigma"));
67 
68  // refit the PID-A relationship
69  fGfit->FitCentroids();
70 
71  pid_dist->Fit(fGfit, "NR");
72 
73  // now release the centroids
74  fGfit->ReleaseCentroids();
75 
76  pid_dist->Fit(fGfit, "NRME");
77 
78  // if fit was limited to a range, remove the limits
79  if(fit_limited)
80  fGfit->SetFitRange(fItvs->GetZ() - 0.5,fItvs->GetZ() + 0.5);
81 
82  // set interval limits according to regions of most probable mass
83  int most_prob_A = 0;
84  nxt_int.Reset();
85  intvl = nullptr;
86  // minimum probability for which isotopes are taken into account
87  double min_proba = mass_fit_parameters.GetDoubleValue("Minimum probability [%]") / 100.;
88  double delta_pid = 0.001;
89  TList accepted_intervals;//any intervals not in this list at the end of the procedure will be removed
90  for (double pid = fGfit->GetPIDmin() ; pid <= fGfit->GetPIDmax(); pid += delta_pid) {
91  double proba;
92  auto Amax = fGfit->GetMostProbableA(pid, proba);
93  if(!Amax)
94  continue;
95  if (proba > min_proba) {
96  if (most_prob_A) {
97  if (*Amax > most_prob_A) {
98  intvl->SetPIDmax(pid - delta_pid);
99  most_prob_A = *Amax;
100  intvl = (interval*)nxt_int();
101  while (intvl->GetA() < most_prob_A) {
102  intvl = (interval*)nxt_int();
103  }
104  accepted_intervals.Add(intvl);
105  intvl->SetPIDmin(pid);
106  }
107  }
108  else {
109  most_prob_A = *Amax;
110  intvl = (interval*)nxt_int();
111  while (intvl->GetA() < most_prob_A) {
112  intvl = (interval*)nxt_int();
113  }
114  accepted_intervals.Add(intvl);
115  intvl->SetPIDmin(pid);
116  }
117  }
118  else if (most_prob_A) {
119  intvl->SetPIDmax(pid - delta_pid);
120  most_prob_A = 0;
121  }
122  }
123  nxt_int.Reset();
124  int ig(1);
125  // update PID positions from fitted centroids
126  nxt_int.Reset();
127  KVNumberList remaining_gaussians, remaining_alist;
128  auto vec_alist = alist.GetArray();
129  while ((intvl = (interval*)nxt_int())) {
130  // in case we removed some peaks
131  while (vec_alist[ig - 1] < intvl->GetA()) {
132  ++ig;
133  }
134  intvl->SetPID(fGfit->GetCentroid(ig));
135  remaining_gaussians.Add(ig);
136  remaining_alist.Add(intvl->GetA());
137  ++ig;
138  }
139  // save results in grid parameters
140  KVNumberList zlist;
141  if (fGrid->GetParameters()->HasStringParameter("MASSFITS"))
142  zlist.Set(fGrid->GetParameters()->GetStringValue("MASSFITS"));
143  zlist.Add(fItvs->GetZ());
144  fGrid->GetParameters()->SetValue("MASSFITS", zlist.AsString());
145  TString massfit = Form("MASSFIT_%d", fItvs->GetZ());
146  KVNameValueList fitparams;
147  fitparams.SetValue("Ng", alist.GetNValues());
148  fitparams.SetValue("Alist", alist.AsQuotedString());
149  fitparams.SetValue("PIDmin", fGfit->GetPIDmin());
150  fitparams.SetValue("PIDmax", fGfit->GetPIDmax());
151  fitparams.SetValue("Bkg_cst", fGfit->GetBackgroundConstant());
152  fitparams.SetValue("Bkg_slp", fGfit->GetBackgroundSlope());
153  fitparams.SetValue("GausWid", fGfit->GetGaussianWidth(0));
154  fitparams.SetValue("PIDvsA_a0", fGfit->GetPIDvsAfit_a0());
155  fitparams.SetValue("PIDvsA_a1", fGfit->GetPIDvsAfit_a1());
156  fitparams.SetValue("PIDvsA_a2", fGfit->GetPIDvsAfit_a2());
157  for (ig = 1; ig <= alist.GetNValues(); ++ig) {
158  fitparams.SetValue(Form("Norm_%d", ig), fGfit->GetGaussianNorm(ig));
159  }
160  auto sanitized = fitparams.Get().ReplaceAll("=", ":");
161  fGrid->GetParameters()->SetValue(massfit, sanitized);
162 }
163 
164 
166 
char * Form(const char *fmt,...)
Change isotope masses in a multi-gauss fit by fixed offset.
KVGaussFitMassModifier(KVIDZAFromZGrid *gr, int Z)
Prepare mass modification object for the multi-gaussian fit for element in the given grid.
void Modify(int deltaA, TH1 *pid_dist, const KVNameValueList &mass_fit_parameters)
const KVNameValueList * GetParameters() const
Definition: KVIDGraph.h:362
Hybrid charge & mass identification grid.
void Initialize() override
double GetGaussianWidth(int) const
void SetSigmaLimits(double smin, double smax)
void UpdateGaussianCentroidParameters()
Required in case the attribution of masses to the gaussians changes.
void SetFitRange(double min, double max)
Change range of fit.
void SetPIDlist(const std::vector< double > pidlist)
void SetAlist(const std::vector< int > alist)
std::optional< int > GetMostProbableA(double PID, double &P) const
double GetGaussianNorm(int i) const
void ReleaseCentroids()
Release the constraint on the positions of the centroids.
Handles lists of named parameters with different types, a list of KVNamedParameter objects.
Double_t GetDoubleValue(const Char_t *name) const
void SetValue(const Char_t *name, value_type value)
Bool_t HasStringParameter(const Char_t *name) const
Bool_t GetBoolValue(const Char_t *name) const
KVString Get() const
const Char_t * GetStringValue(const Char_t *name) const
Strings used to represent a set of ranges of values.
Definition: KVNumberList.h:86
const Char_t * AsQuotedString() const
const Char_t * AsString(Int_t maxchars=0) const
Int_t GetNValues() const
void Add(Int_t)
Add value 'n' to the list.
void Set(const TString &l)
Definition: KVNumberList.h:136
IntArray GetArray() const
virtual TFitResultPtr Fit(const char *formula, Option_t *option="", Option_t *goption="", Double_t xmin=0, Double_t xmax=0)
void Reset()
void Add(TObject *obj) override
TString & ReplaceAll(const char *s1, const char *s2)
KVList * GetIntervals()
bool SetPID(double pid)
double GetPID()
void SetPIDmin(double pidmin)
void SetA(int aa)
void SetPIDmax(double pidmax)
TGraphErrors * gr
ClassImp(TPyArg)