CMS 3D CMS Logo

HDQMfitUtilities.cc
Go to the documentation of this file.
2 
3 namespace HDQMUtil {
4  //-----------------------------------------------------------------------------------------------
5  double langaufun(double *x, double *par) {
6  // Fit parameters:
7  // par[0]=Width (scale) parameter of Landau density
8  // par[1]=Most Probable (MP, location) parameter of Landau density
9  // par[2]=Total area (integral -inf to inf, normalization constant)
10  // par[3]=Width (sigma) of convoluted Gaussian function
11  //
12  // In the Landau distribution (represented by the CERNLIB approximation),
13  // the maximum is located at x=-0.22278298 with the location parameter=0.
14  // This shift is corrected within this function, so that the actual
15  // maximum is identical to the MP parameter.
16 
17  // Numeric constants
18  double invsq2pi = 0.3989422804014; // (2 pi)^(-1/2)
19  double mpshift = -0.22278298; // Landau maximum location
20 
21  // Control constants
22  double np = 100.0; // number of convolution steps
23  double sc = 5.0; // convolution extends to +-sc Gaussian sigmas
24 
25  // Variables
26  double xx;
27  double mpc;
28  double fland;
29  double sum = 0.0;
30  double xlow, xupp;
31  double step;
32  double i;
33 
34  // MP shift correction
35  mpc = par[1] - mpshift * par[0];
36 
37  // Range of convolution integral
38  xlow = x[0] - sc * par[3];
39  xupp = x[0] + sc * par[3];
40 
41  step = (xupp - xlow) / np;
42 
43  // Landau Distribution Production
44  for (i = 1.0; i <= np / 2; i++) {
45  xx = xlow + (i - .5) * step;
46  fland = TMath::Landau(xx, mpc, par[0]) / par[0];
47  sum += fland * TMath::Gaus(x[0], xx, par[3]);
48 
49  xx = xupp - (i - .5) * step;
50  fland = TMath::Landau(xx, mpc, par[0]) / par[0];
51  sum += fland * TMath::Gaus(x[0], xx, par[3]);
52  }
53 
54  return (par[2] * step * sum * invsq2pi / par[3]);
55  }
56 
57  //-----------------------------------------------------------------------------------------------
58  int32_t langaupro(double *params, double &maxx, double &FWHM) {
59  edm::LogInfo("fitUtility") << "inside langaupro " << std::endl;
60  // Seaches for the location (x value) at the maximum of the
61  // Landau and its full width at half-maximum.
62  //
63  // The search is probably not very efficient, but it's a first try.
64 
65  double p, x, fy, fxr, fxl;
66  double step;
67  double l, lold, dl;
68  int32_t i = 0;
69  const int32_t MAXCALLS = 10000;
70  const double dlStop = 1e-3; // relative change < .001
71 
72  // Search for maximum
73  p = params[1] - 0.1 * params[0];
74  step = 0.05 * params[0];
75  lold = -2.0;
76  l = -1.0;
77 
78  dl = (l - lold) / lold; // FIXME catch divide by zero
79  while ((TMath::Abs(dl) > dlStop) && (i < MAXCALLS)) {
80  i++;
81 
82  lold = l;
83  x = p + step;
84  l = langaufun(&x, params);
85  dl = (l - lold) / lold; // FIXME catch divide by zero
86 
87  if (l < lold)
88  step = -step / 10;
89 
90  p += step;
91  }
92 
93  if (i == MAXCALLS)
94  return (-1);
95 
96  maxx = x;
97 
98  fy = l / 2;
99 
100  // Search for right x location of fy
101  p = maxx + params[0];
102  step = params[0];
103  lold = -2.0;
104  l = -1e300;
105  i = 0;
106 
107  dl = (l - lold) / lold; // FIXME catch divide by zero
108  while ((TMath::Abs(dl) > dlStop) && (i < MAXCALLS)) {
109  i++;
110 
111  lold = l;
112  x = p + step;
113  l = TMath::Abs(langaufun(&x, params) - fy);
114  dl = (l - lold) / lold; // FIXME catch divide by zero
115 
116  if (l > lold)
117  step = -step / 10;
118 
119  p += step;
120  }
121 
122  if (i == MAXCALLS)
123  return (-2);
124 
125  fxr = x;
126 
127  // Search for left x location of fy
128  p = maxx - 0.5 * params[0];
129  step = -params[0];
130  lold = -2.0;
131  l = -1e300;
132  i = 0;
133 
134  dl = (l - lold) / lold; // FIXME catch divide by zero
135  while ((TMath::Abs(dl) > dlStop) && (i < MAXCALLS)) {
136  i++;
137 
138  lold = l;
139  x = p + step;
140  l = TMath::Abs(langaufun(&x, params) - fy);
141  dl = (l - lold) / lold; // FIXME catch divide by zero
142 
143  if (l > lold)
144  step = -step / 10;
145 
146  p += step;
147  }
148 
149  if (i == MAXCALLS)
150  return (-3);
151 
152  fxl = x;
153 
154  FWHM = fxr - fxl;
155  return (0);
156  }
157 
158  //-----------------------------------------------------------------------------------------------
159  double Gauss(double *x, double *par) {
160  // The noise function: a gaussian
161 
162  double arg = 0;
163  if (par[2])
164  arg = (x[0] - par[1]) / par[2];
165 
166  double noise = par[0] * TMath::Exp(-0.5 * arg * arg);
167  return noise;
168  }
169 
170 } // namespace HDQMUtil
171 
172 //-----------------------------------------------------------------------------------------------
173 HDQMfitUtilities::HDQMfitUtilities() : langausFit(nullptr), gausFit(nullptr) { init(); }
174 
175 //-----------------------------------------------------------------------------------------------
177  pLanGausS[0] = 0;
178  pLanGausS[1] = 0;
179  pLanGausS[2] = 0;
180  pLanGausS[3] = 0;
181  epLanGausS[0] = 0;
182  epLanGausS[1] = 0;
183  epLanGausS[2] = 0;
184  epLanGausS[3] = 0;
185  pGausS[0] = 0;
186  pGausS[1] = 0;
187  pGausS[2] = 0;
188  epGausS[0] = 0;
189  epGausS[1] = 0;
190  epGausS[2] = 0;
191  pLanConv[0] = 0;
192  pLanConv[1] = 0;
193 
194  // if ( langausFit!=0 ) delete langausFit;
195  // if ( gausFit!=0 ) delete gausFit;
196 
197  chi2GausS = -9999.;
198  nDofGausS = -9999;
199 }
200 
201 //-----------------------------------------------------------------------------------------------
203  if (langausFit != nullptr)
204  delete langausFit;
205  if (gausFit != nullptr)
206  delete gausFit;
207 }
208 
209 //-----------------------------------------------------------------------------------------------
210 double HDQMfitUtilities::doLanGaussFit(TH1F *htoFit) {
211  init();
212 
213  // if (htoFit->GetEntries()!=0) {
214  // Check for the entries excluding over/underflows
215  if (htoFit->Integral() != 0) {
216  edm::LogInfo("fitUtility") << "Fitting " << htoFit->GetTitle() << std::endl;
217  // Setting fit range and start values
218  double fr[2];
219  double sv[4], pllo[4], plhi[4];
220  fr[0] = 0.5 * htoFit->GetMean();
221  fr[1] = 3.0 * htoFit->GetMean();
222 
223  // (EM) parameters setting good for signal only
224  int32_t imax = htoFit->GetMaximumBin();
225  double xmax = htoFit->GetBinCenter(imax);
226  double ymax = htoFit->GetBinContent(imax);
227  int32_t i[2];
228  int32_t iArea[2];
229 
230  i[0] = htoFit->GetXaxis()->FindBin(fr[0]);
231  i[1] = htoFit->GetXaxis()->FindBin(fr[1]);
232 
233  iArea[0] = htoFit->GetXaxis()->FindBin(fr[0]);
234  iArea[1] = htoFit->GetXaxis()->FindBin(fr[1]);
235  double AreaFWHM = htoFit->Integral(iArea[0], iArea[1], "width");
236 
237  sv[1] = xmax;
238  sv[2] = htoFit->Integral(i[0], i[1], "width");
239  sv[3] = AreaFWHM / (4 * ymax);
240  sv[0] = sv[3];
241 
242  plhi[0] = 25.0;
243  plhi[1] = 200.0;
244  plhi[2] = 1000000.0;
245  plhi[3] = 50.0;
246  pllo[0] = 1.5;
247  pllo[1] = 10.0;
248  pllo[2] = 1.0;
249  pllo[3] = 1.0;
250 
251  Char_t FunName[100];
252  sprintf(FunName, "FitfcnLG_%s", htoFit->GetName());
253 
254  langausFit = new TF1(FunName, HDQMUtil::langaufun, fr[0], fr[1], 4);
255  langausFit->SetParameters(sv);
256  langausFit->SetParNames("Width", "MP", "Area", "GSigma");
257 
258  for (int32_t i = 0; i < 4; i++) {
259  langausFit->SetParLimits(i, pllo[i], plhi[i]);
260  }
261 
262  try {
263  htoFit->Fit(langausFit, "R0"); // "R" fit in a range,"0" quiet fit
264 
265  langausFit->SetRange(fr[0], fr[1]);
266  langausFit->GetParameters(pLanGausS);
267  std::memcpy((void *)epLanGausS, (void *)langausFit->GetParErrors(), 4 * sizeof(double));
268 
269  chi2GausS = langausFit->GetChisquare(); // obtain chi^2
270  nDofGausS = langausFit->GetNDF(); // obtain ndf
271 
272  double sPeak, sFWHM;
273  HDQMUtil::langaupro(pLanGausS, sPeak, sFWHM);
274  pLanConv[0] = sPeak;
275  pLanConv[1] = sFWHM;
276  edm::LogInfo("fitUtility") << "langaupro: max " << sPeak << std::endl;
277  edm::LogInfo("fitUtility") << "langaupro: FWHM " << sFWHM << std::endl;
278  } catch (cms::Exception &iException) {
279  edm::LogError("fitUtility") << "problem in fitting " << htoFit->GetTitle()
280  << " \n\tDefault values of the parameters will be used";
281  pLanGausS[0] = -9999;
282  pLanGausS[1] = -9999;
283  pLanGausS[2] = -9999;
284  pLanGausS[3] = -9999;
285  epLanGausS[0] = -9999;
286  epLanGausS[1] = -9999;
287  epLanGausS[2] = -9999;
288  epLanGausS[3] = -9999;
289  pLanConv[0] = -9999;
290  pLanConv[1] = -9999;
291  chi2GausS = -9999;
292  nDofGausS = -9999;
293  }
294  } else {
295  pLanGausS[0] = -9999;
296  pLanGausS[1] = -9999;
297  pLanGausS[2] = -9999;
298  pLanGausS[3] = -9999;
299  epLanGausS[0] = -9999;
300  epLanGausS[1] = -9999;
301  epLanGausS[2] = -9999;
302  epLanGausS[3] = -9999;
303  pLanConv[0] = -9999;
304  pLanConv[1] = -9999;
305  chi2GausS = -9999;
306  nDofGausS = -9999;
307  }
308 
309  return htoFit->GetEntries();
310 }
311 
312 //-----------------------------------------------------------------------------------------------
313 double HDQMfitUtilities::doGaussFit(TH1F *htoFit) {
314  init();
315  // if (htoFit->GetEntries()!=0) {
316  if (htoFit->Integral() != 0) {
317  // Setting fit range and start values
318  double fr[2];
319  double sv[3], pllo[3], plhi[3];
320  fr[0] = htoFit->GetMean() - 5 * htoFit->GetRMS();
321  fr[1] = htoFit->GetMean() + 5 * htoFit->GetRMS();
322 
323  int32_t imax = htoFit->GetMaximumBin();
324  double xmax = htoFit->GetBinCenter(imax);
325  double ymax = htoFit->GetBinContent(imax);
326  int32_t i[2];
327  int32_t iArea[2];
328 
329  i[0] = htoFit->GetXaxis()->FindBin(fr[0]);
330  i[1] = htoFit->GetXaxis()->FindBin(fr[1]);
331 
332  iArea[0] = htoFit->GetXaxis()->FindBin(fr[0]);
333  iArea[1] = htoFit->GetXaxis()->FindBin(fr[1]);
334  double AreaFWHM = htoFit->Integral(iArea[0], iArea[1], "width");
335 
336  sv[2] = AreaFWHM / (4 * ymax);
337  sv[1] = xmax;
338  sv[0] = htoFit->Integral(i[0], i[1], "width");
339 
340  plhi[0] = 1000000.0;
341  plhi[1] = 10.0;
342  plhi[2] = 10.;
343  pllo[0] = 1.5;
344  pllo[1] = 0.1;
345  pllo[2] = 0.3;
346  Char_t FunName[100];
347  sprintf(FunName, "FitfcnLG_%s", htoFit->GetName());
348  gausFit = new TF1(FunName, HDQMUtil::Gauss, fr[0], fr[1], 3);
349  gausFit->SetParameters(sv);
350  gausFit->SetParNames("Constant", "GaussPeak", "Sigma");
351 
352  for (int32_t i = 0; i < 3; i++) {
353  gausFit->SetParLimits(i, pllo[i], plhi[i]);
354  }
355 
356  try {
357  htoFit->Fit(gausFit, "R0");
358 
359  gausFit->SetRange(fr[0], fr[1]);
360  gausFit->GetParameters(pGausS);
361  std::memcpy((void *)epGausS, (void *)gausFit->GetParErrors(), 3 * sizeof(double));
362 
363  chi2GausS = langausFit->GetChisquare(); // obtain chi^2
364  nDofGausS = langausFit->GetNDF(); // obtain ndf
365  } catch (cms::Exception &iException) {
366  edm::LogError("fitUtility") << "problem in fitting " << htoFit->GetTitle()
367  << " \n\tDefault values of the parameters will be used";
368  pGausS[0] = -9999;
369  pGausS[1] = -9999;
370  pGausS[2] = -9999;
371  epGausS[0] = -9999;
372  epGausS[1] = -9999;
373  epGausS[2] = -9999;
374  chi2GausS = -9999;
375  nDofGausS = -9999;
376  }
377 
378  } else {
379  pGausS[0] = -9999;
380  pGausS[1] = -9999;
381  pGausS[2] = -9999;
382  epGausS[0] = -9999;
383  epGausS[1] = -9999;
384  epGausS[2] = -9999;
385  chi2GausS = -9999;
386  nDofGausS = -9999;
387  }
388 
389  return htoFit->GetEntries();
390 }
391 
392 //-----------------------------------------------------------------------------------------------
394  if (s == "landau_width")
395  return pLanGausS[0];
396  else if (s == "mpv")
397  return pLanGausS[1];
398  else if (s == "area")
399  return pLanGausS[2];
400  else if (s == "gauss_sigma")
401  return pLanGausS[3];
402  else
403  return -99999;
404 }
405 
407  if (s == "landau_width")
408  return epLanGausS[0];
409  else if (s == "mpv")
410  return epLanGausS[1];
411  else if (s == "area")
412  return epLanGausS[2];
413  else if (s == "gauss_sigma")
414  return epLanGausS[3];
415  else
416  return -99999;
417 }
418 
420  if (s == "mpv")
421  return pLanConv[0];
422  else if (s == "fwhm")
423  return pLanConv[1];
424  else
425  return -99999;
426 }
427 
429  if (s == "area")
430  return pGausS[0];
431  else if (s == "mean")
432  return pGausS[1];
433  else if (s == "sigma")
434  return pGausS[2];
435  else
436  return -99999;
437 }
438 
440  if (s == "area")
441  return epGausS[0];
442  else if (s == "mean")
443  return epGausS[1];
444  else if (s == "sigma")
445  return epGausS[2];
446  else
447  return -99999;
448 }
int32_t langaupro(double *params, double &maxx, double &FWHM)
double getLanGaussParErr(std::string s)
#define nullptr
double doGaussFit(MonitorElement *ME)
double getLanGaussConv(std::string s)
A arg
Definition: Factorize.h:38
int np
Definition: AMPTWrapper.h:33
double getGaussParErr(std::string s)
T Abs(T a)
Definition: MathUtil.h:49
double Gauss(double *x, double *par)
double getLanGaussPar(std::string s)
double langaufun(double *x, double *par)
double getGaussPar(std::string s)
step
Definition: StallMonitor.cc:94
double doLanGaussFit(MonitorElement *ME)