27 |
|
#include <Rtypes.h> |
28 |
|
#include <TFormula.h> |
29 |
|
#include <TSystem.h> |
30 |
+ |
#include <TMath.h> |
31 |
|
|
32 |
|
#include "UserCode/JetFitAnalyzer/interface/jetfit.h" |
33 |
|
|
41 |
|
// configurable options |
42 |
|
bool ignorezero = false; // ignore zero bins when fitting |
43 |
|
|
43 |
– |
int ngauss; // number of Gaussians in current model |
44 |
– |
|
44 |
|
struct histo { |
45 |
|
vector< vector<double> > bins; |
46 |
|
double Xlo, Xhi, Ylo, Yhi; |
57 |
|
mdef = _mdef; |
58 |
|
} |
59 |
|
|
60 |
< |
int get_ngauss() { |
60 |
> |
int model_def::get_ngauss() { |
61 |
|
return ngauss; |
62 |
|
} |
63 |
|
|
64 |
< |
void set_ngauss(int _ngauss) { |
64 |
> |
void model_def::set_ngauss(int _ngauss) { |
65 |
|
ngauss = _ngauss; |
66 |
|
} |
67 |
|
|
68 |
|
// fit function |
69 |
< |
double fit_fcn(double x, double y, double *xval) { |
70 |
< |
int npar_indiv = mdef->get_formula()->GetNpar(); |
69 |
> |
double model_def::fit_fcn(double x, double y, double *xval) { |
70 |
> |
int npar_indiv = get_formula()->GetNpar(); |
71 |
|
double val = 0.0; |
72 |
|
for (int i = 0; i < ngauss; i++) { |
73 |
< |
mdef->get_formula()->SetParameters(xval + i*npar_indiv); |
73 |
> |
get_formula()->SetParameters(xval + i*npar_indiv); |
74 |
|
val += mdef->get_formula()->Eval(x, y); |
75 |
|
} |
76 |
|
return val; |
78 |
|
|
79 |
|
// TF2-compatible fit function |
80 |
|
double fit_fcn_TF2(double *x, double *pval) { |
81 |
< |
double val = fit_fcn(x[0], x[1], pval); |
81 |
> |
double val = mdef->fit_fcn(x[0], x[1], pval); |
82 |
|
return val; |
83 |
|
} |
84 |
|
|
85 |
< |
// Integral of model formula / chisquare sigma |
86 |
< |
double formula_int(double xlo, double xhi, double ylo, double yhi, |
85 |
> |
// Integral of (model formula)^2 / chisquare sigma |
86 |
> |
double model_def::formula_int(double xlo, double xhi, double ylo, double yhi, |
87 |
|
double *pval, double XbinSize, double YbinSize, |
88 |
|
double *xval) { |
89 |
|
double xstep = (xhi - xlo) / static_cast<double>(20); |
91 |
|
|
92 |
|
double fsum = 0.0; |
93 |
|
double pval_old[256]; |
94 |
< |
int npar = mdef->get_formula()->GetNpar(); |
94 |
> |
int npar = get_formula()->GetNpar(); |
95 |
|
if (npar > 256) { |
96 |
|
cerr << "Parameter overload" << endl; |
97 |
|
return 0.0; |
98 |
|
} |
99 |
< |
mdef->get_formula()->GetParameters(pval_old); |
100 |
< |
mdef->get_formula()->SetParameters(pval); |
99 |
> |
get_formula()->GetParameters(pval_old); |
100 |
> |
get_formula()->SetParameters(pval); |
101 |
|
|
102 |
|
for (int i = 0; i < 20; i++) { |
103 |
|
for (int j = 0; j < 20; j++) { |
105 |
|
double y = (static_cast<double>(j) + 0.5)*ystep + ylo; |
106 |
|
double sig_cut = 1.0e-5; |
107 |
|
double nu = XbinSize * YbinSize * fit_fcn(x, y, xval); |
108 |
< |
double sigma = fabs(mdef->chisquare_error(nu)) < sig_cut |
109 |
< |
? sig_cut : mdef->chisquare_error(nu); |
108 |
> |
double sigma = fabs(chisquare_error(0.0)) < sig_cut |
109 |
> |
? sig_cut : chisquare_error(0.0); |
110 |
|
|
111 |
< |
fsum += xstep * ystep * mdef->get_formula()->Eval(x, y) |
111 |
> |
fsum += pow(xstep * ystep * get_formula()->Eval(x, y), 2.0) |
112 |
|
/ sigma / sigma; |
113 |
|
} |
114 |
|
} |
115 |
|
|
116 |
< |
mdef->get_formula()->SetParameters(pval_old); |
116 |
> |
get_formula()->SetParameters(pval_old); |
117 |
|
return fsum; |
118 |
|
} |
119 |
|
|
129 |
|
// add errors in data points in histogram |
130 |
|
for (int i = 0; i < energy.bins.size(); i++) { |
131 |
|
for (int j = 0; j < energy.bins.at(i).size(); j++) { |
132 |
< |
double x = (static_cast<double>(i) + 0.5) * (energy.Xhi - energy.Xlo) |
132 |
> |
double x = (static_cast<double>(i) + 0.5) * (energy.Xhi - energy.Xlo) |
133 |
|
/ static_cast<double>(energy.bins.size()) + energy.Xlo; |
134 |
|
double y = (static_cast<double>(j) + 0.5) * (energy.Yhi - energy.Ylo) |
135 |
|
/ static_cast<double>(energy.bins.at(i).size()) + energy.Ylo; |
136 |
< |
double nu = fit_fcn(x, y, xval) * XbinSize * YbinSize; |
136 |
> |
double nu = mdef->fit_fcn(x, y, xval) * XbinSize * YbinSize; |
137 |
|
double sig_cut = 1.0e-5; |
138 |
< |
if (fabs(mdef->chisquare_error(nu)) > sig_cut || !ignorezero) |
138 |
> |
if (fabs(mdef->chisquare_error(energy.bins.at(i).at(j))) > sig_cut || !ignorezero) { |
139 |
|
chisquare += pow(energy.bins.at(i).at(j) - nu, 2.0) |
140 |
< |
/ pow(mdef->chisquare_error(nu), 2.0); |
141 |
< |
else |
140 |
> |
/ pow(mdef->chisquare_error(energy.bins.at(i).at(j)), 2.0); |
141 |
> |
} |
142 |
> |
else { |
143 |
|
chisquare += pow(energy.bins.at(i).at(j) - nu, 2.0) |
144 |
|
/ pow(sig_cut, 2.0); |
145 |
+ |
} |
146 |
|
} |
147 |
|
} |
148 |
< |
|
148 |
> |
|
149 |
|
// add errors due to Gaussians outside histogram |
150 |
< |
double eps = 0.1; // accuracy set for this function |
151 |
< |
for (int i = 0; i < ngauss; i++) { |
152 |
< |
double *pval = xval+i*mdef->get_formula()->GetNpar(); |
150 |
> |
double eps = 0.01; // accuracy set for this function |
151 |
> |
for (int i = 0; i < mdef->get_ngauss(); i++) { |
152 |
> |
double *pval = xval+i*(mdef->get_formula()->GetNpar()); |
153 |
|
double par_x = pval[mdef->get_indiv_max_x()]; |
154 |
|
double par_y = pval[mdef->get_indiv_max_y()]; |
155 |
|
double par_sig = pval[3]; |
156 |
< |
double cutoff_rad = -log(eps * 2.0 * PI * par_sig * par_sig |
157 |
< |
/ pval[0]); |
156 |
> |
double cutoff_rad = sqrt(-log(eps * 2.0 * PI * par_sig * par_sig |
157 |
> |
/ pval[0]) * 2.0 * par_sig * par_sig); |
158 |
|
|
159 |
|
bool left = par_x < energy.Xlo + cutoff_rad; |
160 |
|
bool right = par_x > energy.Xhi - cutoff_rad; |
166 |
|
double xhi = energy.Xlo; |
167 |
|
double ylo = energy.Ylo; |
168 |
|
double yhi = energy.Yhi; |
169 |
< |
chisquare += formula_int(xlo, xhi, ylo, yhi, pval, |
169 |
> |
chisquare += 2.0*mdef->formula_int(xlo, xhi, ylo, yhi, pval, |
170 |
|
XbinSize, YbinSize, xval); |
171 |
|
} |
172 |
|
if (right) { |
174 |
|
double xhi = par_x + cutoff_rad; |
175 |
|
double ylo = energy.Ylo; |
176 |
|
double yhi = energy.Yhi; |
177 |
< |
chisquare += formula_int(xlo, xhi, ylo, yhi, pval, |
177 |
> |
chisquare += 2.0*mdef->formula_int(xlo, xhi, ylo, yhi, pval, |
178 |
|
XbinSize, YbinSize, xval); |
179 |
|
} |
180 |
|
if (top) { |
182 |
|
double xhi = right ? par_x + cutoff_rad : energy.Xhi; |
183 |
|
double ylo = energy.Yhi; |
184 |
|
double yhi = par_y + cutoff_rad; |
185 |
< |
chisquare += formula_int(xlo, xhi, ylo, yhi, pval, |
185 |
> |
chisquare += 2.0*mdef->formula_int(xlo, xhi, ylo, yhi, pval, |
186 |
|
XbinSize, YbinSize, xval); |
187 |
|
} |
188 |
|
if (bottom) { |
190 |
|
double xhi = right ? par_x + cutoff_rad : energy.Xhi; |
191 |
|
double ylo = par_y - cutoff_rad; |
192 |
|
double yhi = energy.Ylo; |
193 |
< |
chisquare += formula_int(xlo, xhi, ylo, yhi, pval, |
193 |
> |
chisquare += 2.0*mdef->formula_int(xlo, xhi, ylo, yhi, pval, |
194 |
|
XbinSize, YbinSize, xval); |
195 |
|
} |
196 |
|
} |
197 |
< |
|
197 |
> |
|
198 |
|
fcnval = chisquare; |
199 |
|
} |
200 |
|
catch (exception ex) { |
319 |
|
} |
320 |
|
} |
321 |
|
|
322 |
< |
// translation of CERN's ERFC function |
323 |
< |
double erfc(double x) { |
324 |
< |
bool lef = false; |
325 |
< |
double p2[5], q2[5]; |
325 |
< |
|
326 |
< |
const double z1 = 1.0, hf = z1/2.0, c1 = 0.56418958; |
327 |
< |
const double vmax = 7.0; |
328 |
< |
const double switch_ = 4.0; |
329 |
< |
|
330 |
< |
double p10 = 3.6767877, q10 = 3.2584593, p11 = -9.7970465e-2; |
331 |
< |
p2[0] = 7.3738883; |
332 |
< |
q2[0] = 7.3739609; |
333 |
< |
p2[1] = 6.8650185; |
334 |
< |
q2[1] = 1.5184908e1; |
335 |
< |
p2[2] = 3.0317993; |
336 |
< |
q2[2] = 1.2795530e1; |
337 |
< |
p2[3] = 5.6316962e-1; |
338 |
< |
q2[3] = 5.3542168; |
339 |
< |
p2[4] = 4.3187787e-5; |
340 |
< |
q2[4] = 1.0; |
341 |
< |
|
342 |
< |
double p30 = -1.2436854e-1, q30 = 4.4091706e-1, p31 = -9.6821036e-2; |
343 |
< |
|
344 |
< |
double v = fabs(x); |
345 |
< |
double y, h, hc, ap, aq; |
346 |
< |
if (v < hf) { |
347 |
< |
y = v*v; |
348 |
< |
h = x*(p10 + p11*y)/(q10 + y); |
349 |
< |
hc = 1.0 - h; |
350 |
< |
} |
351 |
< |
else { |
352 |
< |
if (v < switch_) { |
353 |
< |
ap = p2[4]; |
354 |
< |
aq = q2[4]; |
355 |
< |
for (int i = 3; i >= 0; i--) { |
356 |
< |
ap = p2[i] + v*ap; |
357 |
< |
aq = q2[i] + v*aq; |
358 |
< |
} |
359 |
< |
hc = exp(-v*v)*ap/aq; |
360 |
< |
h = 1.0 - hc; |
361 |
< |
} |
362 |
< |
else if (v < vmax) { |
363 |
< |
y = 1/v/v; |
364 |
< |
hc = exp(-v*v)*(c1 + y*(p30 + p31*y)/(q30 + y))/v; |
365 |
< |
h = 1.0 - hc; |
322 |
> |
void fill_histo_with_vec(TH2 *hist, vector< vector<double> > &vec) { |
323 |
> |
for (int i = 0; i < vec.size(); i++) { |
324 |
> |
for (int j = 0; j < vec[i].size(); j++) { |
325 |
> |
hist->SetBinContent(i+1, j+1, vec[i][j]); |
326 |
|
} |
367 |
– |
// for very big values we can save us any calculation |
368 |
– |
// and the FP-exceptions from exp |
369 |
– |
else { |
370 |
– |
h = 1.0; |
371 |
– |
hc = 0.0; |
372 |
– |
} |
373 |
– |
if (x < 0) { |
374 |
– |
h = -h; |
375 |
– |
hc = 2.0 - hc; |
376 |
– |
} |
377 |
– |
} |
378 |
– |
if (lef) { |
379 |
– |
return h; |
380 |
– |
} |
381 |
– |
else { |
382 |
– |
return hc; |
327 |
|
} |
328 |
|
} |
329 |
|
|
330 |
< |
// translation of CERN's PROB function |
387 |
< |
double prob(double x, int n) { |
388 |
< |
const char *name = "PROB"; |
389 |
< |
char errtxt[80]; |
390 |
< |
|
391 |
< |
const double r1 = 1.0, |
392 |
< |
hf = r1/2.0, th = r1/3.0, f1 = 2.0*r1/9.0; |
393 |
< |
const double c1 = 1.128379167095513; |
394 |
< |
const int nmax = 300; |
395 |
< |
// maximum chi2 per df for df >= 2., if chi2/df > chipdf prob=0 |
396 |
< |
const double chipdf = 100.0; |
397 |
< |
const double xmax = 174.673, xmax2 = 2.0*xmax; |
398 |
< |
const double xlim = 24.0; |
399 |
< |
const double eps = 1e-30; |
400 |
< |
|
401 |
< |
double y = x; |
402 |
< |
double u = hf*y; |
403 |
< |
double h, w, s, t, fi, e; |
404 |
< |
int m; |
405 |
< |
if (n < 0) { |
406 |
< |
h = 0.0; |
407 |
< |
sprintf(errtxt, "n = %d < 1", n); |
408 |
< |
cerr << "PROB: G100.1: "<<errtxt; |
409 |
< |
} |
410 |
< |
else if (y < 0.0) { |
411 |
< |
h = 0.0; |
412 |
< |
sprintf(errtxt, "x = %f < 0", n); |
413 |
< |
cerr << "PROB: G100.2: "<<errtxt; |
414 |
< |
} |
415 |
< |
else if (y == 0.0 || n/20 > y) { |
416 |
< |
h = 1.0; |
417 |
< |
} |
418 |
< |
else if (n == 1) { |
419 |
< |
w = sqrt(u); |
420 |
< |
if (w < xlim) { |
421 |
< |
h = erfc(w); |
422 |
< |
} |
423 |
< |
else { |
424 |
< |
h = 0.0; |
425 |
< |
} |
426 |
< |
} |
427 |
< |
else if (n > nmax) { |
428 |
< |
s = r1 / ((double)n); |
429 |
< |
t = f1 * s; |
430 |
< |
w = (pow(y*s, th) - (1.0 - t)) / sqrt(2.0*t); |
431 |
< |
if (w < -xlim) { |
432 |
< |
h = 1.0; |
433 |
< |
} |
434 |
< |
else if (w < xlim) { |
435 |
< |
h = hf * erfc(w); |
436 |
< |
} |
437 |
< |
else { |
438 |
< |
h = 0.0; |
439 |
< |
} |
440 |
< |
} |
441 |
< |
else { |
442 |
< |
m = n/2; |
443 |
< |
if (u < xmax2 && (y/n) <= chipdf) { |
444 |
< |
s = exp(-hf*u); |
445 |
< |
t = s; |
446 |
< |
e = s; |
447 |
< |
if (2*m == n) { |
448 |
< |
fi = 0.0; |
449 |
< |
for (int i = 1; i < m; i++) { |
450 |
< |
fi += 1.0; |
451 |
< |
t = u*t/fi; |
452 |
< |
s += t; |
453 |
< |
} |
454 |
< |
h = s*e; |
455 |
< |
} |
456 |
< |
else { |
457 |
< |
fi = 1.0; |
458 |
< |
for (int i = 1; i < m; i++) { |
459 |
< |
fi += 2.0; |
460 |
< |
t = t*y/fi; |
461 |
< |
s += t; |
462 |
< |
} |
463 |
< |
w = sqrt(u); |
464 |
< |
if (w < xlim) { |
465 |
< |
h = c1*w*s*e + erfc(w); |
466 |
< |
} |
467 |
< |
else { |
468 |
< |
h = 0.0; |
469 |
< |
} |
470 |
< |
} |
471 |
< |
} |
472 |
< |
else { |
473 |
< |
h = 0.0; |
474 |
< |
} |
475 |
< |
} |
476 |
< |
if (h > eps) { |
477 |
< |
return h; |
478 |
< |
} |
479 |
< |
else { |
480 |
< |
return 0.0; |
481 |
< |
} |
482 |
< |
} |
483 |
< |
|
484 |
< |
void par_init(TH2 *hist, TMinuit *gMinuit, vector<TString> &pars, |
330 |
> |
void model_def::par_init(TH2 *hist, TMinuit *gMinuit, vector<TString> &pars, |
331 |
|
double *pval, double *perr, double *plo, double *phi, |
332 |
|
int npar, results r) { |
333 |
< |
int npar1 = npar - mdef->get_formula()->GetNpar(); |
333 |
> |
int npar1 = npar - get_formula()->GetNpar(); |
334 |
|
bool init_spec_pars = false; |
335 |
< |
if (ngauss <= mdef->get_n_special_par_sets()) { |
335 |
> |
if (ngauss <= get_n_special_par_sets()) { |
336 |
|
init_spec_pars = true; |
337 |
|
for (int k = 0; k < ngauss; k++) { |
338 |
< |
int ipar0 = k*mdef->get_formula()->GetNpar(); // index of par 0 |
339 |
< |
for (int l = 0; l < mdef->get_formula()->GetNpar(); l++) { |
338 |
> |
int ipar0 = k*get_formula()->GetNpar(); // index of indiv par 0 |
339 |
> |
for (int l = 0; l < get_formula()->GetNpar(); l++) { |
340 |
|
int ipar = ipar0 + l; |
341 |
|
if (ipar < npar) |
342 |
< |
mdef->get_special_par(k, l, pval[ipar], perr[ipar], plo[ipar], |
342 |
> |
get_special_par(k, l, pval[ipar], perr[ipar], plo[ipar], |
343 |
|
phi[ipar]); |
344 |
|
else |
345 |
|
cerr << "WARNING: Attempt to set parameter out of index range!" |
355 |
|
vector< vector<double> > sub_energy(energy.bins.size()); |
356 |
|
double max_sub, max_x = 0.0, max_y = 0.0; |
357 |
|
double pval_other[256]; |
358 |
< |
max_sub = -(numeric_limits<double>::infinity()); |
358 |
> |
max_sub = -(numeric_limits<double>::max()); |
359 |
|
for (int i = 0; i < energy.bins.size(); i++) { |
360 |
|
sub_energy[i].resize(energy.bins[i].size()); |
361 |
|
for (int j = 0; j < energy.bins[i].size(); j++) { |
364 |
|
double y = static_cast<double>(j)*(energy.Yhi - energy.Ylo) |
365 |
|
/ static_cast<double>(energy.bins[i].size()) + energy.Ylo; |
366 |
|
if (ngauss > 1) { |
367 |
< |
// subtract 4*sigma plus integral of fit function |
367 |
> |
// subtract integral of fit function |
368 |
|
try { |
369 |
|
int npval_other = r.pval.at(r.pval.size()-1).size(); |
370 |
|
if (npval_other > 256) { |
377 |
|
ngauss--; |
378 |
|
double nu = fit_fcn(x, y, pval_other) * XbinSize * YbinSize; |
379 |
|
ngauss++; |
380 |
< |
sub_energy[i][j] = energy.bins[i][j] - nu |
535 |
< |
- 4.0*mdef->chisquare_error(nu); |
380 |
> |
sub_energy[i][j] = energy.bins[i][j] - nu; |
381 |
|
} |
382 |
|
catch (exception ex) { |
383 |
|
cerr << "Exception in par_init" << endl; |
386 |
|
else { |
387 |
|
sub_energy[i][j] = energy.bins[i][j]; |
388 |
|
} |
544 |
– |
if (sub_energy[i][j] > max_sub) { |
545 |
– |
max_sub = sub_energy[i][j]; |
546 |
– |
max_x = x; |
547 |
– |
max_y = y; |
548 |
– |
} |
389 |
|
} |
390 |
|
} |
391 |
+ |
TH2D *hist_sub = new TH2D("hist_sub", "Subtracted histo", |
392 |
+ |
sub_energy.size(), energy.Xlo, |
393 |
+ |
energy.Xhi, |
394 |
+ |
sub_energy[0].size(), energy.Ylo, |
395 |
+ |
energy.Yhi); |
396 |
+ |
fill_histo_with_vec(hist_sub, sub_energy); |
397 |
+ |
max_sub = 0.0; |
398 |
+ |
max_x = 0.0; |
399 |
+ |
max_y = 0.0; |
400 |
+ |
for (int i = 1; i <= hist_sub->GetXaxis()->GetNbins(); i++) { |
401 |
+ |
for (int j = 1; j <= hist_sub->GetYaxis()->GetNbins(); j++) { |
402 |
+ |
double nu = energy.bins[i-1][j-1] - sub_energy[i-1][j-1]; |
403 |
+ |
if (hist_sub->GetBinContent(i, j) |
404 |
+ |
- 3.0*pow(chisquare_error(nu), 2.0) > max_sub) { |
405 |
+ |
max_sub = hist_sub->GetBinContent(i, j); |
406 |
+ |
max_x = static_cast<double>(i-1)*XbinSize |
407 |
+ |
+ hist_sub->GetXaxis()->GetXmin(); |
408 |
+ |
max_y = static_cast<double>(j-1)*YbinSize |
409 |
+ |
+ hist_sub->GetYaxis()->GetXmin(); |
410 |
+ |
} |
411 |
+ |
} |
412 |
+ |
} |
413 |
|
|
414 |
|
for (int i = npar1; i < npar; i++) { |
415 |
< |
if (mdef->get_indiv_max_E() == i - npar1) { |
416 |
< |
double nu = 0.0; |
417 |
< |
if (ngauss > 1) { |
556 |
< |
nu = fit_fcn(max_x, max_y, pval_other) * XbinSize * YbinSize; |
557 |
< |
} |
558 |
< |
pval[i] = max_sub + (ngauss > 1 ? 4.0*mdef->chisquare_error(nu) |
559 |
< |
: 0.0); |
560 |
< |
perr[i] = mdef->chisquare_error(pval[i])*0.1; |
415 |
> |
if (get_indiv_max_E() == i - npar1) { |
416 |
> |
pval[i] = max_sub / XbinSize / YbinSize; |
417 |
> |
perr[i] = mdef->chisquare_error(pval[i])*0.5; |
418 |
|
plo[i] = 0.0; |
419 |
|
phi[i] = 1.0e6; |
420 |
|
} |
421 |
< |
else if (mdef->get_indiv_max_x() == i - npar1) { |
421 |
> |
else if (get_indiv_max_x() == i - npar1) { |
422 |
|
pval[i] = max_x; |
423 |
|
perr[i] = (energy.Xhi - energy.Xlo) / static_cast<double>(hist->GetXaxis()->GetNbins()); |
424 |
|
plo[i] = 0.0; |
425 |
|
phi[i] = 0.0; |
426 |
|
} |
427 |
< |
else if (mdef->get_indiv_max_y() == i - npar1) { |
427 |
> |
else if (get_indiv_max_y() == i - npar1) { |
428 |
|
pval[i] = max_y; |
429 |
|
perr[i] = (energy.Yhi - energy.Ylo) / static_cast<double>(hist->GetYaxis()->GetNbins()); |
430 |
|
plo[i] = 0.0; |
432 |
|
} |
433 |
|
else { |
434 |
|
string dummy; |
435 |
< |
mdef->get_indiv_par(i-npar1, dummy, pval[i], perr[i], plo[i], phi[i]); |
435 |
> |
get_indiv_par(i-npar1, dummy, pval[i], perr[i], plo[i], phi[i]); |
436 |
|
} |
437 |
|
} |
438 |
|
} |
439 |
< |
int n_pars_to_set = init_spec_pars ? ngauss*mdef->get_formula()->GetNpar() |
439 |
> |
int n_pars_to_set = init_spec_pars ? ngauss*get_formula()->GetNpar() |
440 |
|
: npar - npar1; |
441 |
|
int init_par_to_set = init_spec_pars ? 0 : npar1; |
442 |
|
for (int i = 0; i < n_pars_to_set; i++) { |
443 |
|
double dummy; |
444 |
|
string s; |
445 |
|
int ipar = i + init_par_to_set; |
446 |
< |
mdef->get_indiv_par(i % mdef->get_formula()->GetNpar(), s, |
446 |
> |
get_indiv_par(i % get_formula()->GetNpar(), s, |
447 |
|
dummy, dummy, dummy, dummy); |
448 |
|
ostringstream par_oss; |
449 |
< |
par_oss << s << ipar / (mdef->get_formula()->GetNpar()) << flush; |
449 |
> |
par_oss << s << ipar / (get_formula()->GetNpar()) << flush; |
450 |
|
try { |
451 |
|
pars.at(ipar) = TString(par_oss.str()); |
452 |
|
} |
464 |
|
} |
465 |
|
|
466 |
|
results fit_histo(TH2 *hist, vector<trouble> &t_vec, |
467 |
< |
void (*cc_minuit)(TMinuit *, TH2 *, int), |
468 |
< |
int start_ngauss, |
469 |
< |
int rebinX, int rebinY, |
470 |
< |
double P_cutoff_val) { |
467 |
> |
void (*cc_minuit)(TMinuit *, TH2 *, int), |
468 |
> |
int start_ngauss, |
469 |
> |
int rebinX, int rebinY, |
470 |
> |
double P_cutoff_val) { |
471 |
|
TMinuit *gMinuit = new TMinuit(); |
472 |
|
int npar_indiv = mdef->get_formula()->GetNpar(); |
473 |
|
int istat, erflg; |
508 |
|
start_ngauss = 1; |
509 |
|
} |
510 |
|
|
511 |
< |
for (ngauss = start_ngauss; |
512 |
< |
ngauss <= (MAX_GAUSS > start_ngauss ? MAX_GAUSS : start_ngauss); |
513 |
< |
ngauss++) { |
511 |
> |
for (mdef->set_ngauss(start_ngauss); |
512 |
> |
mdef->get_ngauss() <= |
513 |
> |
(MAX_GAUSS > start_ngauss ? MAX_GAUSS : start_ngauss); |
514 |
> |
mdef->set_ngauss(mdef->get_ngauss()+1)) { |
515 |
> |
|
516 |
> |
int ngauss = mdef->get_ngauss(); |
517 |
|
t_vec.resize(t_vec.size() + 1); |
518 |
< |
int npar = npar_indiv*ngauss; |
518 |
> |
int npar = npar_indiv*mdef->get_ngauss(); |
519 |
|
double pval[256], perr[256], plo[256], phi[256]; |
520 |
|
if (npar > 256) { |
521 |
|
cerr << "Parameter overload" << endl; |
524 |
|
vector<TString> pars(npar); |
525 |
|
|
526 |
|
// initialize parameters |
527 |
< |
par_init(hist, gMinuit, pars, pval, perr, plo, phi, npar, r); |
528 |
< |
|
527 |
> |
mdef->par_init(hist, gMinuit, pars, pval, perr, plo, phi, npar, r); |
528 |
> |
|
529 |
|
// minimize |
530 |
|
double chisquare, edm, errdef; |
531 |
|
int nvpar, nparx; |
532 |
|
trouble t; |
533 |
|
t.occ = T_NULL; |
534 |
|
t.istat = 3; |
535 |
< |
// fix the N values and sigmas of the Gaussians |
535 |
> |
// fix sigmas of the Gaussians |
536 |
|
for (int i = 0; i < ngauss; i++) { |
537 |
|
double parno[2]; |
538 |
< |
parno[0] = i*npar_indiv + 1; |
539 |
< |
parno[1] = i*npar_indiv + 4; |
680 |
< |
gMinuit->mnexcm("FIX", parno, 2, erflg); |
538 |
> |
parno[0] = i*npar_indiv + 4; |
539 |
> |
gMinuit->mnexcm("FIX", parno, 1, erflg); |
540 |
|
} |
541 |
|
gMinuit->mnexcm("SIMPLEX", 0, 0, erflg); |
542 |
|
gMinuit->mnexcm("MIGRAD", 0, 0, erflg); |
684 |
– |
// release N values, fix mu_x and mu_y |
685 |
– |
for (int i = 0; i < ngauss; i++) { |
686 |
– |
double parno[4]; |
687 |
– |
parno[0] = i*npar_indiv + 1; |
688 |
– |
parno[1] = i*npar_indiv + 2; |
689 |
– |
parno[2] = i*npar_indiv + 3; |
690 |
– |
parno[3] = i*npar_indiv + 4; |
691 |
– |
gMinuit->mnexcm("RELEASE", parno, 1, erflg); |
692 |
– |
gMinuit->mnexcm("FIX", parno+1, 2, erflg); |
693 |
– |
} |
694 |
– |
gMinuit->mnexcm("MIGRAD", 0, 0, erflg); |
695 |
– |
// release mu_x and mu_y |
696 |
– |
for (int i = 0; i < ngauss; i++) { |
697 |
– |
double parno[4]; |
698 |
– |
parno[0] = i*npar_indiv + 1; |
699 |
– |
parno[1] = i*npar_indiv + 2; |
700 |
– |
parno[2] = i*npar_indiv + 3; |
701 |
– |
parno[3] = i*npar_indiv + 4; |
702 |
– |
gMinuit->mnexcm("RELEASE", parno+1, 2, erflg); |
703 |
– |
} |
704 |
– |
gMinuit->mnexcm("MIGRAD", 0, 0, erflg); |
543 |
|
gMinuit->mnstat(chisquare, edm, errdef, nvpar, nparx, istat); |
544 |
|
if (istat == 3) { |
545 |
|
/* we're not concerned about MINOS errors right now |
605 |
|
ndof -= npar; |
606 |
|
|
607 |
|
r.chisquare.push_back(chisquare); |
608 |
< |
double P = prob(chisquare, ndof); |
608 |
> |
double P = TMath::Prob(chisquare, ndof); |
609 |
|
if (P > P_cutoff_val) { |
610 |
|
break; |
611 |
|
} |