27 |
|
|
28 |
|
#include "UserCode/JetFitAnalyzer/interface/JetFitAnalyzer.h" |
29 |
|
|
30 |
< |
#include <vector> |
30 |
> |
|
31 |
> |
#include <cstdlib> |
32 |
> |
#include <cmath> |
33 |
> |
#include <ctime> |
34 |
> |
#include <cstdio> |
35 |
> |
#include <cstring> |
36 |
> |
#include <cctype> |
37 |
|
#include <iostream> |
38 |
+ |
#include <fstream> |
39 |
+ |
#include <sstream> |
40 |
+ |
#include <string> |
41 |
+ |
#include <vector> |
42 |
+ |
#include <set> |
43 |
+ |
#include <map> |
44 |
+ |
#include <limits> |
45 |
+ |
#include <exception> |
46 |
+ |
|
47 |
+ |
#include <TMinuit.h> |
48 |
+ |
#include <TH1.h> |
49 |
+ |
#include <TH2.h> |
50 |
+ |
#include <TF2.h> |
51 |
+ |
#include <TRandom3.h> |
52 |
+ |
#include <Rtypes.h> |
53 |
+ |
#include <TFormula.h> |
54 |
+ |
#include <TSystem.h> |
55 |
+ |
#include <TMath.h> |
56 |
+ |
|
57 |
+ |
#include "UserCode/JetFitAnalyzer/interface/jetfit.h" |
58 |
+ |
|
59 |
+ |
#define PI 3.141592653 |
60 |
+ |
|
61 |
+ |
#define MAX_GAUSS 3 |
62 |
+ |
|
63 |
+ |
using namespace std; |
64 |
+ |
|
65 |
+ |
JetFitAnalyzer::ModelDefinition *mdef; |
66 |
+ |
|
67 |
+ |
JetFitAnalyzer::ModelDefinition& curr_ModelDefinition() { |
68 |
+ |
return *mdef; |
69 |
+ |
} |
70 |
+ |
|
71 |
+ |
void JetFitAnalyzer::set_ModelDefinition(ModelDefinition *_mdef) { |
72 |
+ |
mdef = _mdef; |
73 |
+ |
} |
74 |
+ |
|
75 |
+ |
int JetFitAnalyzer::ModelDefinition::get_ngauss() { |
76 |
+ |
return ngauss; |
77 |
+ |
} |
78 |
+ |
|
79 |
+ |
void JetFitAnalyzer::ModelDefinition::set_ngauss(int _ngauss) { |
80 |
+ |
ngauss = _ngauss; |
81 |
+ |
} |
82 |
+ |
|
83 |
+ |
// fit function |
84 |
+ |
double JetFitAnalyzer::ModelDefinition::fit_fcn(double x, double y, double *xval) { |
85 |
+ |
int npar_indiv = get_formula()->GetNpar(); |
86 |
+ |
double val = 0.0; |
87 |
+ |
for (int i = 0; i < ngauss; i++) { |
88 |
+ |
get_formula()->SetParameters(xval + i*npar_indiv); |
89 |
+ |
val += mdef->get_formula()->Eval(x, y); |
90 |
+ |
} |
91 |
+ |
return val; |
92 |
+ |
} |
93 |
+ |
|
94 |
+ |
// TF2-compatible fit function |
95 |
+ |
double JetFitAnalyzer::fit_fcn_TF2(double *x, double *pval) { |
96 |
+ |
double val = mdef->fit_fcn(x[0], x[1], pval); |
97 |
+ |
return val; |
98 |
+ |
} |
99 |
+ |
|
100 |
+ |
// Integral of (model formula)^2 / chisquare sigma |
101 |
+ |
double JetFitAnalyzer::ModelDefinition::formula_int(double xlo, double xhi, double ylo, double yhi, |
102 |
+ |
double *pval, double XbinSize, double YbinSize, |
103 |
+ |
double *xval) { |
104 |
+ |
double xstep = (xhi - xlo) / static_cast<double>(20); |
105 |
+ |
double ystep = (yhi - ylo) / static_cast<double>(20); |
106 |
+ |
|
107 |
+ |
double fsum = 0.0; |
108 |
+ |
double pval_old[256]; |
109 |
+ |
int npar = get_formula()->GetNpar(); |
110 |
+ |
if (npar > 256) { |
111 |
+ |
cerr << "Parameter overload" << endl; |
112 |
+ |
return 0.0; |
113 |
+ |
} |
114 |
+ |
get_formula()->GetParameters(pval_old); |
115 |
+ |
get_formula()->SetParameters(pval); |
116 |
+ |
|
117 |
+ |
for (int i = 0; i < 20; i++) { |
118 |
+ |
for (int j = 0; j < 20; j++) { |
119 |
+ |
double x = (static_cast<double>(i) + 0.5)*xstep + xlo; |
120 |
+ |
double y = (static_cast<double>(j) + 0.5)*ystep + ylo; |
121 |
+ |
double sig_cut = 1.0e-5; |
122 |
+ |
double nu = XbinSize * YbinSize * fit_fcn(x, y, xval); |
123 |
+ |
double sigma = fabs(chisquare_error(0.0)) < sig_cut |
124 |
+ |
? sig_cut : chisquare_error(0.0); |
125 |
+ |
|
126 |
+ |
fsum += pow(xstep * ystep * get_formula()->Eval(x, y), 2.0) |
127 |
+ |
/ sigma / sigma; |
128 |
+ |
} |
129 |
+ |
} |
130 |
+ |
|
131 |
+ |
get_formula()->SetParameters(pval_old); |
132 |
+ |
return fsum; |
133 |
+ |
} |
134 |
+ |
|
135 |
+ |
// MINUIT objective function |
136 |
+ |
void fcn(int &npar, double *grad, double &fcnval, double *xval, int iflag) |
137 |
+ |
{ |
138 |
+ |
double chisquare = 0.0; |
139 |
+ |
double XbinSize = (energy.Xhi - energy.Xlo) |
140 |
+ |
/ static_cast<double>(energy.bins.size()); |
141 |
+ |
double YbinSize = (energy.Yhi - energy.Ylo) |
142 |
+ |
/ static_cast<double>(energy.bins.at(0).size()); |
143 |
+ |
try { |
144 |
+ |
// add errors in data points in histogram |
145 |
+ |
for (int i = 0; i < energy.bins.size(); i++) { |
146 |
+ |
for (int j = 0; j < energy.bins.at(i).size(); j++) { |
147 |
+ |
double x = (static_cast<double>(i) + 0.5) * (energy.Xhi - energy.Xlo) |
148 |
+ |
/ static_cast<double>(energy.bins.size()) + energy.Xlo; |
149 |
+ |
double y = (static_cast<double>(j) + 0.5) * (energy.Yhi - energy.Ylo) |
150 |
+ |
/ static_cast<double>(energy.bins.at(i).size()) + energy.Ylo; |
151 |
+ |
double nu = mdef->fit_fcn(x, y, xval) * XbinSize * YbinSize; |
152 |
+ |
double sig_cut = 1.0e-5; |
153 |
+ |
if (fabs(mdef->chisquare_error(energy.bins.at(i).at(j))) > sig_cut || !ignorezero_) { |
154 |
+ |
chisquare += pow(energy.bins.at(i).at(j) - nu, 2.0) |
155 |
+ |
/ pow(mdef->chisquare_error(energy.bins.at(i).at(j)), 2.0); |
156 |
+ |
} |
157 |
+ |
else { |
158 |
+ |
chisquare += pow(energy.bins.at(i).at(j) - nu, 2.0) |
159 |
+ |
/ pow(sig_cut, 2.0); |
160 |
+ |
} |
161 |
+ |
} |
162 |
+ |
} |
163 |
+ |
|
164 |
+ |
// add errors due to Gaussians outside histogram |
165 |
+ |
double eps = 0.01; // accuracy set for this function |
166 |
+ |
for (int i = 0; i < mdef->get_ngauss(); i++) { |
167 |
+ |
double *pval = xval+i*(mdef->get_formula()->GetNpar()); |
168 |
+ |
double par_x = pval[mdef->get_indiv_max_x()]; |
169 |
+ |
double par_y = pval[mdef->get_indiv_max_y()]; |
170 |
+ |
double par_sig = pval[3]; |
171 |
+ |
double cutoff_rad = sqrt(-log(eps * 2.0 * PI * par_sig * par_sig |
172 |
+ |
/ pval[0]) * 2.0 * par_sig * par_sig); |
173 |
+ |
|
174 |
+ |
bool left = par_x < energy.Xlo + cutoff_rad; |
175 |
+ |
bool right = par_x > energy.Xhi - cutoff_rad; |
176 |
+ |
bool top = par_y > energy.Yhi - cutoff_rad; |
177 |
+ |
bool bottom = par_y < energy.Ylo + cutoff_rad; |
178 |
+ |
|
179 |
+ |
if (left) { |
180 |
+ |
double xlo = par_x - cutoff_rad; |
181 |
+ |
double xhi = energy.Xlo; |
182 |
+ |
double ylo = energy.Ylo; |
183 |
+ |
double yhi = energy.Yhi; |
184 |
+ |
chisquare += 2.0*mdef->formula_int(xlo, xhi, ylo, yhi, pval, |
185 |
+ |
XbinSize, YbinSize, xval); |
186 |
+ |
} |
187 |
+ |
if (right) { |
188 |
+ |
double xlo = energy.Xhi; |
189 |
+ |
double xhi = par_x + cutoff_rad; |
190 |
+ |
double ylo = energy.Ylo; |
191 |
+ |
double yhi = energy.Yhi; |
192 |
+ |
chisquare += 2.0*mdef->formula_int(xlo, xhi, ylo, yhi, pval, |
193 |
+ |
XbinSize, YbinSize, xval); |
194 |
+ |
} |
195 |
+ |
if (top) { |
196 |
+ |
double xlo = left ? par_x - cutoff_rad : energy.Xlo; |
197 |
+ |
double xhi = right ? par_x + cutoff_rad : energy.Xhi; |
198 |
+ |
double ylo = energy.Yhi; |
199 |
+ |
double yhi = par_y + cutoff_rad; |
200 |
+ |
chisquare += 2.0*mdef->formula_int(xlo, xhi, ylo, yhi, pval, |
201 |
+ |
XbinSize, YbinSize, xval); |
202 |
+ |
} |
203 |
+ |
if (bottom) { |
204 |
+ |
double xlo = left ? par_x - cutoff_rad : energy.Xlo; |
205 |
+ |
double xhi = right ? par_x + cutoff_rad : energy.Xhi; |
206 |
+ |
double ylo = par_y - cutoff_rad; |
207 |
+ |
double yhi = energy.Ylo; |
208 |
+ |
chisquare += 2.0*mdef->formula_int(xlo, xhi, ylo, yhi, pval, |
209 |
+ |
XbinSize, YbinSize, xval); |
210 |
+ |
} |
211 |
+ |
} |
212 |
+ |
|
213 |
+ |
fcnval = chisquare; |
214 |
+ |
} |
215 |
+ |
catch (exception ex) { |
216 |
+ |
cerr << "Exception in jetfit::fcn" << endl; |
217 |
+ |
} |
218 |
+ |
} |
219 |
+ |
|
220 |
+ |
TFormula * JetFitAnalyzer::ModelDefinition::get_formula() { |
221 |
+ |
return indiv_formula; |
222 |
+ |
} |
223 |
+ |
|
224 |
+ |
void JetFitAnalyzer::ModelDefinition::set_formula(TFormula *new_formula) { |
225 |
+ |
indiv_formula = new_formula; |
226 |
+ |
} |
227 |
+ |
|
228 |
+ |
void JetFitAnalyzer::ModelDefinition::get_indiv_par(int i, string &name, double &start, double &step, |
229 |
+ |
double &lo, double &hi) { |
230 |
+ |
try { |
231 |
+ |
name = indiv_par_names.at(i); |
232 |
+ |
start = indiv_par_starts.at(i); |
233 |
+ |
step = indiv_par_start_steps.at(i); |
234 |
+ |
lo = indiv_par_lo.at(i); |
235 |
+ |
hi = indiv_par_hi.at(i); |
236 |
+ |
} catch (exception ex) { |
237 |
+ |
cerr << "exception in jetfit::ModelDefinition::get_indiv_par" << endl; |
238 |
+ |
} |
239 |
+ |
} |
240 |
+ |
|
241 |
+ |
void JetFitAnalyzer::ModelDefinition::set_indiv_par(int i, string name, double start, double step, |
242 |
+ |
double lo, double hi) { |
243 |
+ |
if (indiv_par_names.size() < i+1) { |
244 |
+ |
indiv_par_names.resize(i+1); |
245 |
+ |
indiv_par_starts.resize(i+1); |
246 |
+ |
indiv_par_start_steps.resize(i+1); |
247 |
+ |
indiv_par_lo.resize(i+1); |
248 |
+ |
indiv_par_hi.resize(i+1); |
249 |
+ |
} |
250 |
+ |
try { |
251 |
+ |
indiv_par_names.at(i) = name; |
252 |
+ |
indiv_par_starts.at(i) = start; |
253 |
+ |
indiv_par_start_steps.at(i) = step; |
254 |
+ |
indiv_par_lo.at(i) = lo; |
255 |
+ |
indiv_par_hi.at(i) = hi; |
256 |
+ |
} |
257 |
+ |
catch (exception ex) { |
258 |
+ |
cerr << "exception in jetfit::ModelDefinition::set_indiv_par" << endl; |
259 |
+ |
} |
260 |
+ |
} |
261 |
+ |
|
262 |
+ |
int JetFitAnalyzer::ModelDefinition::get_indiv_max_E() { |
263 |
+ |
return indiv_max_E; |
264 |
+ |
} |
265 |
+ |
|
266 |
+ |
void JetFitAnalyzer::ModelDefinition::set_indiv_max_E(int _new_max_E) { |
267 |
+ |
indiv_max_E = _new_max_E; |
268 |
+ |
} |
269 |
+ |
|
270 |
+ |
int JetFitAnalyzer::ModelDefinition::get_indiv_max_x() { |
271 |
+ |
return indiv_max_x; |
272 |
+ |
} |
273 |
+ |
|
274 |
+ |
void JetFitAnalyzer::ModelDefinition::set_indiv_max_x(int new_max_x) { |
275 |
+ |
indiv_max_x = new_max_x; |
276 |
+ |
} |
277 |
+ |
|
278 |
+ |
int JetFitAnalyzer::ModelDefinition::get_indiv_max_y() { |
279 |
+ |
return indiv_max_y; |
280 |
+ |
} |
281 |
+ |
|
282 |
+ |
void JetFitAnalyzer::ModelDefinition::set_indiv_max_y(int new_max_y) { |
283 |
+ |
indiv_max_y = new_max_y; |
284 |
+ |
} |
285 |
+ |
|
286 |
+ |
unsigned JetFitAnalyzer::ModelDefinition::get_n_special_par_sets() { |
287 |
+ |
return special_par_starts.size(); |
288 |
+ |
} |
289 |
+ |
|
290 |
+ |
void JetFitAnalyzer::ModelDefinition::get_special_par(int g, int i, double &pstart, |
291 |
+ |
double &perr, double &plo, double &phi) { |
292 |
+ |
try { |
293 |
+ |
pstart = special_par_starts.at(g).at(i); |
294 |
+ |
perr = special_par_start_steps.at(g).at(i); |
295 |
+ |
plo = special_par_lo.at(g).at(i); |
296 |
+ |
phi = special_par_hi.at(g).at(i); |
297 |
+ |
} catch (exception ex) { |
298 |
+ |
cerr << "Exception in ModelDefinition::get_special_par" << endl; |
299 |
+ |
} |
300 |
+ |
} |
301 |
+ |
|
302 |
+ |
void JetFitAnalyzer::ModelDefinition::set_special_par(int g, int i, double pstart, |
303 |
+ |
double perr, double plo, double phi) { |
304 |
+ |
if (g+1 > special_par_starts.size()) { |
305 |
+ |
special_par_starts.resize(g+1); |
306 |
+ |
special_par_start_steps.resize(g+1); |
307 |
+ |
special_par_lo.resize(g+1); |
308 |
+ |
special_par_hi.resize(g+1); |
309 |
+ |
} |
310 |
+ |
|
311 |
+ |
try { |
312 |
+ |
if (i+1 > special_par_starts.at(g).size()) { |
313 |
+ |
special_par_starts.at(g).resize(i+1); |
314 |
+ |
special_par_start_steps.at(g).resize(i+1); |
315 |
+ |
special_par_lo.at(g).resize(i+1); |
316 |
+ |
special_par_hi.at(g).resize(i+1); |
317 |
+ |
} |
318 |
+ |
|
319 |
+ |
special_par_starts.at(g).at(i) = pstart; |
320 |
+ |
special_par_start_steps.at(g).at(i) = perr; |
321 |
+ |
special_par_lo.at(g).at(i) = plo; |
322 |
+ |
special_par_hi.at(g).at(i) = phi; |
323 |
+ |
} |
324 |
+ |
catch (exception ex) { |
325 |
+ |
cerr << "exception in jetfit::ModelDefinition::set_special_par" << endl; |
326 |
+ |
} |
327 |
+ |
} |
328 |
+ |
|
329 |
+ |
void JetFitAnalyzer::fill_histo_with_vec(TH2 *hist, vector< vector<double> > &vec) { |
330 |
+ |
for (int i = 0; i < vec.size(); i++) { |
331 |
+ |
for (int j = 0; j < vec[i].size(); j++) { |
332 |
+ |
hist->SetBinContent(i+1, j+1, vec[i][j]); |
333 |
+ |
} |
334 |
+ |
} |
335 |
+ |
} |
336 |
+ |
|
337 |
+ |
vector<vector<double> > |
338 |
+ |
JetFitAnalyzer::ModelDefinition::subtractCurrentFit(VectorHisto energy) { |
339 |
+ |
vector< vector<double> > subEnergy; |
340 |
+ |
|
341 |
+ |
double XbinSize = (energy.Xhi - energy.Xlo) |
342 |
+ |
/ static_cast<double>(energy.bins.size()); |
343 |
+ |
double YbinSize = (energy.Xhi - energy.Xlo) |
344 |
+ |
/ static_cast<double>(energy.bins.at(0).size()); |
345 |
+ |
vector< vector<double> > subEnergy(energy.bins.size()); |
346 |
+ |
double max_sub, max_x = 0.0, max_y = 0.0; |
347 |
+ |
double pval_other[256]; |
348 |
+ |
max_sub = -(numeric_limits<double>::max()); |
349 |
+ |
for (int i = 0; i < energy.bins.size(); i++) { |
350 |
+ |
subEnergy[i].resize(energy.bins[i].size()); |
351 |
+ |
for (int j = 0; j < energy.bins[i].size(); j++) { |
352 |
+ |
double x = static_cast<double>(i)*(energy.Xhi - energy.Xlo) |
353 |
+ |
/ static_cast<double>(energy.bins.size()) + energy.Xlo; |
354 |
+ |
double y = static_cast<double>(j)*(energy.Yhi - energy.Ylo) |
355 |
+ |
/ static_cast<double>(energy.bins[i].size()) + energy.Ylo; |
356 |
+ |
if (ngauss > 1) { |
357 |
+ |
// subtract integral of fit function |
358 |
+ |
try { |
359 |
+ |
int npval_other = r.pval.at(r.pval.size()-1).size(); |
360 |
+ |
if (npval_other > 256) { |
361 |
+ |
cerr << "Parameter overload" << endl; |
362 |
+ |
return -1.0; |
363 |
+ |
} |
364 |
+ |
for (int k = 0; k < npval_other; k++) { |
365 |
+ |
pval_other[k] = r.pval[r.pval.size()-1][k]; |
366 |
+ |
} |
367 |
+ |
ngauss--; |
368 |
+ |
double nu = fit_fcn(x, y, pval_other) * XbinSize * YbinSize; |
369 |
+ |
ngauss++; |
370 |
+ |
subEnergy[i][j] = energy.bins[i][j] - nu; |
371 |
+ |
} |
372 |
+ |
catch (exception ex) { |
373 |
+ |
cerr << "Exception in par_init" << endl; |
374 |
+ |
} |
375 |
+ |
} |
376 |
+ |
else { |
377 |
+ |
subEnergy[i][j] = energy.bins[i][j]; |
378 |
+ |
} |
379 |
+ |
} |
380 |
+ |
} |
381 |
+ |
|
382 |
+ |
return subEnergy; |
383 |
+ |
} |
384 |
+ |
|
385 |
+ |
void JetFitAnalyzer::ModelDefinition::initNewMeanY() { |
386 |
+ |
vector< vector<double> > subEnergy = subtractCurrentFit(energy); |
387 |
+ |
|
388 |
+ |
TH2D *hist_sub = new TH2D("hist_sub", "Subtracted histo", |
389 |
+ |
subEnergy.size(), energy.Xlo, |
390 |
+ |
energy.Xhi, |
391 |
+ |
subEnergy[0].size(), energy.Ylo, |
392 |
+ |
energy.Yhi); |
393 |
+ |
fill_histo_with_vec(hist_sub, subEnergy); |
394 |
+ |
max_sub = 0.0; |
395 |
+ |
max_x = 0.0; |
396 |
+ |
max_y = 0.0; |
397 |
+ |
for (int i = 1; i <= hist_sub->GetXaxis()->GetNbins(); i++) { |
398 |
+ |
for (int j = 1; j <= hist_sub->GetYaxis()->GetNbins(); j++) { |
399 |
+ |
double nu = energy.bins[i-1][j-1] - subEnergy[i-1][j-1]; |
400 |
+ |
if (hist_sub->GetBinContent(i, j) |
401 |
+ |
- 3.0*pow(chisquare_error(nu), 2.0) > max_sub) { |
402 |
+ |
max_sub = hist_sub->GetBinContent(i, j); |
403 |
+ |
max_y = static_cast<double>(j-1)*YbinSize |
404 |
+ |
+ hist_sub->GetYaxis()->GetXmin(); |
405 |
+ |
} |
406 |
+ |
} |
407 |
+ |
} |
408 |
+ |
return max_y; |
409 |
+ |
} |
410 |
+ |
|
411 |
+ |
void JetFitAnalyzer::ModelDefinition::initNewN() { |
412 |
+ |
vector< vector<double> > subEnergy = subtractCurrentFit(energy); |
413 |
+ |
|
414 |
+ |
TH2D *hist_sub = new TH2D("hist_sub", "Subtracted histo", |
415 |
+ |
subEnergy.size(), energy.Xlo, |
416 |
+ |
energy.Xhi, |
417 |
+ |
subEnergy[0].size(), energy.Ylo, |
418 |
+ |
energy.Yhi); |
419 |
+ |
fill_histo_with_vec(hist_sub, subEnergy); |
420 |
+ |
max_sub = 0.0; |
421 |
+ |
max_x = 0.0; |
422 |
+ |
max_y = 0.0; |
423 |
+ |
for (int i = 1; i <= hist_sub->GetXaxis()->GetNbins(); i++) { |
424 |
+ |
for (int j = 1; j <= hist_sub->GetYaxis()->GetNbins(); j++) { |
425 |
+ |
double nu = energy.bins[i-1][j-1] - subEnergy[i-1][j-1]; |
426 |
+ |
if (hist_sub->GetBinContent(i, j) |
427 |
+ |
- 3.0*pow(chisquare_error(nu), 2.0) > max_sub) { |
428 |
+ |
max_sub = hist_sub->GetBinContent(i, j); |
429 |
+ |
} |
430 |
+ |
} |
431 |
+ |
} |
432 |
+ |
return max_sub / XbinSize / YbinSize; |
433 |
+ |
} |
434 |
+ |
|
435 |
+ |
void JetFitAnalyzer::ModelDefinition::initNewMeanX() { |
436 |
+ |
vector< vector<double> > subEnergy = subtractCurrentFit(energy); |
437 |
+ |
|
438 |
+ |
TH2D *hist_sub = new TH2D("hist_sub", "Subtracted histo", |
439 |
+ |
subEnergy.size(), energy.Xlo, |
440 |
+ |
energy.Xhi, |
441 |
+ |
subEnergy[0].size(), energy.Ylo, |
442 |
+ |
energy.Yhi); |
443 |
+ |
fill_histo_with_vec(hist_sub, subEnergy); |
444 |
+ |
max_sub = 0.0; |
445 |
+ |
max_x = 0.0; |
446 |
+ |
max_y = 0.0; |
447 |
+ |
for (int i = 1; i <= hist_sub->GetXaxis()->GetNbins(); i++) { |
448 |
+ |
for (int j = 1; j <= hist_sub->GetYaxis()->GetNbins(); j++) { |
449 |
+ |
double nu = energy.bins[i-1][j-1] - subEnergy[i-1][j-1]; |
450 |
+ |
if (hist_sub->GetBinContent(i, j) |
451 |
+ |
- 3.0*pow(chisquare_error(nu), 2.0) > max_sub) { |
452 |
+ |
max_sub = hist_sub->GetBinContent(i, j); |
453 |
+ |
max_x = static_cast<double>(i-1)*XbinSize |
454 |
+ |
+ hist_sub->GetXaxis()->GetXmin(); |
455 |
+ |
} |
456 |
+ |
} |
457 |
+ |
} |
458 |
+ |
return max_x; |
459 |
+ |
} |
460 |
+ |
|
461 |
+ |
void JetFitAnalyzer::ModelDefinition::initParsFromModelDef(vector<TString> &pars, |
462 |
+ |
double *pval, |
463 |
+ |
double *perr, |
464 |
+ |
double *plo, |
465 |
+ |
double *phi, |
466 |
+ |
int npar, |
467 |
+ |
FitResults r) { |
468 |
+ |
unsigned nIndivPar = getFormula()->GetNpar(); |
469 |
+ |
for (unsigned i = 0;i < nIndivPar; i++) { |
470 |
+ |
get_indiv_par(i, pars[i], pval[i], perr[i], plo[i], phi[i]); |
471 |
+ |
} |
472 |
+ |
} |
473 |
+ |
|
474 |
+ |
void JetFitAnalyzer::ModelDefinition::findInitialValues(vector<TString> &pars, |
475 |
+ |
double *pval, |
476 |
+ |
double *perr, |
477 |
+ |
double *plo, |
478 |
+ |
double *phi, |
479 |
+ |
int npar) { |
480 |
+ |
|
481 |
+ |
int npar1 = npar - get_formula()->GetNpar(); |
482 |
+ |
if (ngauss <= 1) { |
483 |
+ |
initParsFromModelDef(pars, pval, perr, plo, phi, npar, r); |
484 |
+ |
} |
485 |
+ |
else { |
486 |
+ |
// try to get good initial parameters without model definitions |
487 |
+ |
for (int i = npar1; i < npar; i++) { |
488 |
+ |
if (get_indiv_max_E() == i - npar1) { |
489 |
+ |
pval[i] = initNewN(); |
490 |
+ |
perr[i] = mdef->chisquare_error(pval[i])*0.5; |
491 |
+ |
plo[i] = 0.0; |
492 |
+ |
phi[i] = 1.0e6; |
493 |
+ |
} |
494 |
+ |
else if (get_indiv_max_x() == i - npar1) { |
495 |
+ |
pval[i] = initNewMeanX(); |
496 |
+ |
perr[i] = (energy.Xhi - energy.Xlo) / static_cast<double>(hist->GetXaxis()->GetNbins()); |
497 |
+ |
plo[i] = 0.0; |
498 |
+ |
phi[i] = 0.0; |
499 |
+ |
} |
500 |
+ |
else if (get_indiv_max_y() == i - npar1) { |
501 |
+ |
pval[i] = initNewMeanY(); |
502 |
+ |
perr[i] = (energy.Yhi - energy.Ylo) / static_cast<double>(hist->GetYaxis()->GetNbins()); |
503 |
+ |
plo[i] = 0.0; |
504 |
+ |
phi[i] = 0.0; |
505 |
+ |
} |
506 |
+ |
else { |
507 |
+ |
string dummy; |
508 |
+ |
get_indiv_par(i-npar1, dummy, pval[i], perr[i], plo[i], phi[i]); |
509 |
+ |
} |
510 |
+ |
} |
511 |
+ |
} |
512 |
+ |
} |
513 |
+ |
|
514 |
+ |
void JetFitAnalyzer::ModelDefinition::par_init(TH2 *hist, TMinuit *gMinuit, vector<TString> &pars, |
515 |
+ |
double *pval, double *perr, double *plo, double *phi, |
516 |
+ |
int npar, FitResults r) { |
517 |
+ |
findInitialValues(pars, pval, perr, plo, phi, npar, r); |
518 |
+ |
for (int i = 0; i < n_pars_to_set; i++) { |
519 |
+ |
double dummy; |
520 |
+ |
string s; |
521 |
+ |
int ipar = i + init_par_to_set; |
522 |
+ |
get_indiv_par(i % get_formula()->GetNpar(), s, |
523 |
+ |
dummy, dummy, dummy, dummy); |
524 |
+ |
ostringstream par_oss; |
525 |
+ |
par_oss << s << ipar / (get_formula()->GetNpar()) << flush; |
526 |
+ |
pars.at(ipar) = TString(par_oss.str()); |
527 |
+ |
|
528 |
+ |
int error_flag; |
529 |
+ |
gMinuit->mnparm(ipar, pars.at(ipar), |
530 |
+ |
pval[ipar], perr[ipar], plo[ipar], phi[ipar], error_flag); |
531 |
+ |
} |
532 |
+ |
} |
533 |
+ |
|
534 |
+ |
FitResults JetFitAnalyzer::fit_histo(TH2 *hist, vector<trouble> &t_vec, |
535 |
+ |
void (*cc_minuit)(TMinuit *, TH2 *, int), |
536 |
+ |
int start_ngauss, |
537 |
+ |
int rebinX, int rebinY, |
538 |
+ |
double P_cutoff_val) { |
539 |
+ |
TMinuit *gMinuit = new TMinuit(); |
540 |
+ |
int npar_indiv = mdef->get_formula()->GetNpar(); |
541 |
+ |
int istat, erflg; |
542 |
+ |
FitResults r; |
543 |
+ |
|
544 |
+ |
gMinuit->SetFCN(fcn); |
545 |
+ |
gMinuit->mninit(5, 6, 7); |
546 |
+ |
|
547 |
+ |
// set error def and machine accuracy |
548 |
+ |
double cs_err_def = 1.0; |
549 |
+ |
double fcn_eps = 0.2; |
550 |
+ |
gMinuit->mnexcm("SET ERR", &cs_err_def, 1, erflg); |
551 |
+ |
gMinuit->mnexcm("SET EPS", &fcn_eps, 1, erflg); |
552 |
+ |
|
553 |
+ |
// rebin histogram |
554 |
+ |
TH2 *hist_rebinned; |
555 |
+ |
if (rebinX_ > 1 && rebinY_ > 1) |
556 |
+ |
hist_rebinned = hist->Rebin2D(rebinX_, rebinY_); |
557 |
+ |
else |
558 |
+ |
hist_rebinned = hist; |
559 |
+ |
|
560 |
+ |
r.hist_rebinned = hist_rebinned; |
561 |
+ |
// load histogram into energies vector |
562 |
+ |
energy.bins.resize(hist_rebinned->GetXaxis()->GetNbins()); |
563 |
+ |
for (int i = 0; i < energy.bins.size(); i++) { |
564 |
+ |
energy.bins[i].resize(hist_rebinned->GetYaxis()->GetNbins()); |
565 |
+ |
for (int j = 0; j < energy.bins[i].size(); j++) { |
566 |
+ |
energy.bins[i][j] = hist_rebinned->GetBinContent(i+1, j+1); |
567 |
+ |
} |
568 |
+ |
} |
569 |
+ |
|
570 |
+ |
energy.Xlo = hist->GetXaxis()->GetXmin(); |
571 |
+ |
energy.Xhi = hist->GetXaxis()->GetXmax(); |
572 |
+ |
energy.Ylo = hist->GetYaxis()->GetXmin(); |
573 |
+ |
energy.Yhi = hist->GetYaxis()->GetXmax(); |
574 |
+ |
|
575 |
+ |
if (start_ngauss < 1) { |
576 |
+ |
start_ngauss = 1; |
577 |
+ |
} |
578 |
+ |
|
579 |
+ |
for (mdef->set_ngauss(start_ngauss); |
580 |
+ |
mdef->get_ngauss() <= |
581 |
+ |
(MAX_GAUSS > start_ngauss ? MAX_GAUSS : start_ngauss); |
582 |
+ |
mdef->set_ngauss(mdef->get_ngauss()+1)) { |
583 |
+ |
|
584 |
+ |
int ngauss = mdef->get_ngauss(); |
585 |
+ |
t_vec.resize(t_vec.size() + 1); |
586 |
+ |
int npar = npar_indiv*mdef->get_ngauss(); |
587 |
+ |
double pval[256], perr[256], plo[256], phi[256]; |
588 |
+ |
if (npar > 256) { |
589 |
+ |
cerr << "Parameter overload" << endl; |
590 |
+ |
return r; |
591 |
+ |
} |
592 |
+ |
vector<TString> pars(npar); |
593 |
+ |
|
594 |
+ |
// initialize parameters |
595 |
+ |
mdef->par_init(hist, gMinuit, pars, pval, perr, plo, phi, npar, r); |
596 |
+ |
|
597 |
+ |
// minimize |
598 |
+ |
double chisquare, edm, errdef; |
599 |
+ |
int nvpar, nparx; |
600 |
+ |
trouble t; |
601 |
+ |
t.occ = T_NULL; |
602 |
+ |
t.istat = 3; |
603 |
+ |
// fix sigmas of the Gaussians |
604 |
+ |
for (int i = 0; i < ngauss; i++) { |
605 |
+ |
double parno[2]; |
606 |
+ |
parno[0] = i*npar_indiv + 4; |
607 |
+ |
gMinuit->mnexcm("FIX", parno, 1, erflg); |
608 |
+ |
} |
609 |
+ |
gMinuit->mnexcm("SIMPLEX", 0, 0, erflg); |
610 |
+ |
gMinuit->mnexcm("MIGRAD", 0, 0, erflg); |
611 |
+ |
gMinuit->mnstat(chisquare, edm, errdef, nvpar, nparx, istat); |
612 |
+ |
if (istat == 3) { |
613 |
+ |
/* we're not concerned about MINOS errors right now |
614 |
+ |
gMinuit->mnexcm("MINOS", 0, 0, erflg); |
615 |
+ |
gMinuit->mnstat(chisquare, edm, errdef, nvpar, nparx, istat); |
616 |
+ |
if (istat != 3) { |
617 |
+ |
t.occ = T_MINOS; |
618 |
+ |
t.istat = istat; |
619 |
+ |
} |
620 |
+ |
*/ |
621 |
+ |
} |
622 |
+ |
else { |
623 |
+ |
t.occ = T_MIGRAD; |
624 |
+ |
t.istat = istat; |
625 |
+ |
} |
626 |
+ |
|
627 |
+ |
try { |
628 |
+ |
if (t_vec.size() < ngauss) { |
629 |
+ |
t_vec.resize(ngauss); |
630 |
+ |
} |
631 |
+ |
t_vec.at(ngauss-1) = t; |
632 |
+ |
} |
633 |
+ |
catch (exception ex) { |
634 |
+ |
cerr << "exception in fit_histo" << endl; |
635 |
+ |
} |
636 |
+ |
|
637 |
+ |
// put parameters in map |
638 |
+ |
for (int i = 0; i < npar && i < 256; i++) { |
639 |
+ |
int iuint; // internal parameter number |
640 |
+ |
gMinuit->mnpout(i, pars[i], pval[i], perr[i], plo[i], phi[i], iuint); |
641 |
+ |
} |
642 |
+ |
vector<double> pval_copy(npar); |
643 |
+ |
vector<double> perr_copy(npar); |
644 |
+ |
vector<double> plo_copy(npar); |
645 |
+ |
vector<double> phi_copy(npar); |
646 |
+ |
for (int i = 0; i < npar && i < 256; i++) { |
647 |
+ |
pval_copy[i] = pval[i]; |
648 |
+ |
perr_copy[i] = perr[i]; |
649 |
+ |
plo_copy[i] = plo[i]; |
650 |
+ |
phi_copy[i] = phi[i]; |
651 |
+ |
} |
652 |
+ |
r.pars.push_back(pars); |
653 |
+ |
r.pval.push_back(pval_copy); |
654 |
+ |
r.perr.push_back(perr_copy); |
655 |
+ |
r.plo.push_back(plo_copy); |
656 |
+ |
r.phi.push_back(phi_copy); |
657 |
+ |
|
658 |
+ |
// execute user minuit code |
659 |
+ |
if (cc_minuit != 0) |
660 |
+ |
(*cc_minuit)(gMinuit, hist_rebinned, ngauss); |
661 |
+ |
|
662 |
+ |
int ndof = 0; |
663 |
+ |
if (!ignorezero) |
664 |
+ |
ndof = energy.bins.size() * energy.bins[0].size(); |
665 |
+ |
else { |
666 |
+ |
for (int i = 0; i < energy.bins.size(); i++) { |
667 |
+ |
for (int j = 0; j < energy.bins[i].size(); j++) { |
668 |
+ |
if (energy.bins[i][j] > 1.0e-30) |
669 |
+ |
ndof++; |
670 |
+ |
} |
671 |
+ |
} |
672 |
+ |
} |
673 |
+ |
ndof -= npar; |
674 |
+ |
|
675 |
+ |
r.chisquare.push_back(chisquare); |
676 |
+ |
double P = TMath::Prob(chisquare, ndof); |
677 |
+ |
if (P > P_cutoff_val) { |
678 |
+ |
break; |
679 |
+ |
} |
680 |
+ |
} |
681 |
+ |
|
682 |
+ |
delete gMinuit; |
683 |
+ |
return r; |
684 |
+ |
} |
685 |
|
|
686 |
|
JetFitAnalyzer::JetFitAnalyzer(const edm::ParameterSet& iConfig) |
687 |
|
: user_minuit(0) |
715 |
|
{ |
716 |
|
using namespace edm; |
717 |
|
|
718 |
< |
jetfit::results r; std::vector<jetfit::trouble> t; |
718 |
> |
std::vector<jetfit::trouble> t; |
719 |
|
|
720 |
|
TH2D *histo = make_histo(iEvent, iSetup); |
721 |
|
if (histo != 0) { |
722 |
< |
jetfit::model_def &_mdef = make_model_def(iEvent, iSetup, histo); |
723 |
< |
jetfit::set_model_def(&_mdef); |
724 |
< |
r = jetfit::fit_histo(histo, t, user_minuit, _mdef.get_n_special_par_sets(), |
725 |
< |
rebinX_, rebinY_, P_cutoff_val_); |
722 |
> |
jetfit::ModelDefinition &_mdef = make_model_def(iEvent, iSetup, histo); |
723 |
> |
jetfit::results r(fit_histo(histo, t, user_minuit, |
724 |
> |
_mdef.get_n_special_par_sets(), |
725 |
> |
rebinX_, rebinY_, P_cutoff_val_)); |
726 |
|
analyze_results(r, t, histo); |
727 |
|
} |
728 |
|
else { |