ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/JetFitAnalyzer/src/JetFitAnalyzer.cc
Revision: 1.7
Committed: Thu Nov 19 06:07:40 2009 UTC (15 years, 5 months ago) by dnisson
Content type: text/plain
Branch: MAIN
Changes since 1.6: +135 -68 lines
Log Message:
Splitting up par_init to make it easier to understand.

File Contents

# User Rev Content
1 dnisson 1.1 // -*- C++ -*-
2     //
3     // Package: JetFitAnalyzer
4     // Class: JetFitAnalyzer
5     //
6     /**\class JetFitAnalyzer JetFitAnalyzer.cc UserCode/JetFitAnalyzer/src/JetFitAnalyzer.cc
7    
8     Description: Base class for using jetfit with CMSSW
9    
10     Implementation:
11     o Method make_histo is used to prepare a histogram for analysis;
12     the user can read this from a file or generate from the actual event
13     o Method make_model_def is used to define a formula and initial
14     parameters for the model used
15     o Method analyze_results performs user analysis on results;
16     the user is given a trouble vector and the original histogram in
17     addition.
18     o The function pointer user_minuit defines what to do after each fit
19     is done. The pointer should be obtained in the subclass constructor.
20     */
21     //
22     // Original Author: David Nisson
23     // Created: Wed Aug 5 16:38:38 PDT 2009
24 dnisson 1.7 // $Id: JetFitAnalyzer.cc,v 1.6 2009/11/13 03:57:48 dnisson Exp $
25 dnisson 1.1 //
26     //
27    
28     #include "UserCode/JetFitAnalyzer/interface/JetFitAnalyzer.h"
29    
30 dnisson 1.6
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 dnisson 1.1 #include <vector>
42 dnisson 1.6 #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 dnisson 1.7 vector<vector<double> >
338     JetFitAnalyzer::ModelDefinition::subtractCurrentFit(VectorHisto energy) {
339     vector< vector<double> > subEnergy;
340    
341     double XbinSize = (energy.Xhi - energy.Xlo)
342 dnisson 1.6 / static_cast<double>(energy.bins.size());
343     double YbinSize = (energy.Xhi - energy.Xlo)
344     / static_cast<double>(energy.bins.at(0).size());
345 dnisson 1.7 vector< vector<double> > subEnergy(energy.bins.size());
346 dnisson 1.6 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 dnisson 1.7 subEnergy[i].resize(energy.bins[i].size());
351 dnisson 1.6 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 dnisson 1.7 return -1.0;
363 dnisson 1.6 }
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 dnisson 1.7 subEnergy[i][j] = energy.bins[i][j] - nu;
371 dnisson 1.6 }
372     catch (exception ex) {
373     cerr << "Exception in par_init" << endl;
374     }
375     }
376     else {
377 dnisson 1.7 subEnergy[i][j] = energy.bins[i][j];
378 dnisson 1.6 }
379     }
380     }
381    
382 dnisson 1.7 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 < get_n_special_par_sets(); i++) {
470     for (unsigned j = 0; j < nIndivPar; j++) {
471     unsigned ipar = i*nIndivPar + j; // index of parameter for MINUIT
472     if (ipar < npar)
473     get_special_par(i, j, pval[ipar], perr[ipar], plo[ipar], phi[ipar]);
474     else
475     j = nIndivPar; i = get_n_special_par_sets();
476     }
477     }
478     }
479    
480     void JetFitAnalyzer::ModelDefinition::findInitialValues(vector<TString> &pars,
481     double *pval,
482     double *perr,
483     double *plo,
484     double *phi,
485     int npar) {
486    
487     int npar1 = npar - get_formula()->GetNpar();
488     if (ngauss <= get_n_special_par_sets()) {
489     initParsFromModelDef(pars, pval, perr, plo, phi, npar, r);
490     }
491     else {
492     // try to get good initial parameters without model definitions
493 dnisson 1.6 for (int i = npar1; i < npar; i++) {
494     if (get_indiv_max_E() == i - npar1) {
495 dnisson 1.7 pval[i] = initNewN();
496 dnisson 1.6 perr[i] = mdef->chisquare_error(pval[i])*0.5;
497     plo[i] = 0.0;
498     phi[i] = 1.0e6;
499     }
500     else if (get_indiv_max_x() == i - npar1) {
501 dnisson 1.7 pval[i] = initNewMeanX();
502 dnisson 1.6 perr[i] = (energy.Xhi - energy.Xlo) / static_cast<double>(hist->GetXaxis()->GetNbins());
503     plo[i] = 0.0;
504     phi[i] = 0.0;
505     }
506     else if (get_indiv_max_y() == i - npar1) {
507 dnisson 1.7 pval[i] = initNewMeanY();
508 dnisson 1.6 perr[i] = (energy.Yhi - energy.Ylo) / static_cast<double>(hist->GetYaxis()->GetNbins());
509     plo[i] = 0.0;
510     phi[i] = 0.0;
511     }
512     else {
513     string dummy;
514     get_indiv_par(i-npar1, dummy, pval[i], perr[i], plo[i], phi[i]);
515     }
516     }
517     }
518 dnisson 1.7 }
519    
520     void JetFitAnalyzer::ModelDefinition::par_init(TH2 *hist, TMinuit *gMinuit, vector<TString> &pars,
521     double *pval, double *perr, double *plo, double *phi,
522     int npar, FitResults r) {
523     findInitialValues(pars, pval, perr, plo, phi, npar, r);
524 dnisson 1.6 for (int i = 0; i < n_pars_to_set; i++) {
525     double dummy;
526     string s;
527     int ipar = i + init_par_to_set;
528     get_indiv_par(i % get_formula()->GetNpar(), s,
529     dummy, dummy, dummy, dummy);
530     ostringstream par_oss;
531     par_oss << s << ipar / (get_formula()->GetNpar()) << flush;
532 dnisson 1.7 pars.at(ipar) = TString(par_oss.str());
533    
534 dnisson 1.6 int error_flag;
535 dnisson 1.7 gMinuit->mnparm(ipar, pars.at(ipar),
536     pval[ipar], perr[ipar], plo[ipar], phi[ipar], error_flag);
537 dnisson 1.6 }
538     }
539    
540     FitResults JetFitAnalyzer::fit_histo(TH2 *hist, vector<trouble> &t_vec,
541     void (*cc_minuit)(TMinuit *, TH2 *, int),
542     int start_ngauss,
543     int rebinX, int rebinY,
544     double P_cutoff_val) {
545     TMinuit *gMinuit = new TMinuit();
546     int npar_indiv = mdef->get_formula()->GetNpar();
547     int istat, erflg;
548     FitResults r;
549    
550     gMinuit->SetFCN(fcn);
551     gMinuit->mninit(5, 6, 7);
552    
553     // set error def and machine accuracy
554     double cs_err_def = 1.0;
555     double fcn_eps = 0.2;
556     gMinuit->mnexcm("SET ERR", &cs_err_def, 1, erflg);
557     gMinuit->mnexcm("SET EPS", &fcn_eps, 1, erflg);
558    
559     // rebin histogram
560     TH2 *hist_rebinned;
561     if (rebinX_ > 1 && rebinY_ > 1)
562     hist_rebinned = hist->Rebin2D(rebinX_, rebinY_);
563     else
564     hist_rebinned = hist;
565    
566     r.hist_rebinned = hist_rebinned;
567     // load histogram into energies vector
568     energy.bins.resize(hist_rebinned->GetXaxis()->GetNbins());
569     for (int i = 0; i < energy.bins.size(); i++) {
570     energy.bins[i].resize(hist_rebinned->GetYaxis()->GetNbins());
571     for (int j = 0; j < energy.bins[i].size(); j++) {
572     energy.bins[i][j] = hist_rebinned->GetBinContent(i+1, j+1);
573     }
574     }
575    
576     energy.Xlo = hist->GetXaxis()->GetXmin();
577     energy.Xhi = hist->GetXaxis()->GetXmax();
578     energy.Ylo = hist->GetYaxis()->GetXmin();
579     energy.Yhi = hist->GetYaxis()->GetXmax();
580    
581     if (start_ngauss < 1) {
582     start_ngauss = 1;
583     }
584    
585     for (mdef->set_ngauss(start_ngauss);
586     mdef->get_ngauss() <=
587     (MAX_GAUSS > start_ngauss ? MAX_GAUSS : start_ngauss);
588     mdef->set_ngauss(mdef->get_ngauss()+1)) {
589    
590     int ngauss = mdef->get_ngauss();
591     t_vec.resize(t_vec.size() + 1);
592     int npar = npar_indiv*mdef->get_ngauss();
593     double pval[256], perr[256], plo[256], phi[256];
594     if (npar > 256) {
595     cerr << "Parameter overload" << endl;
596     return r;
597     }
598     vector<TString> pars(npar);
599    
600     // initialize parameters
601     mdef->par_init(hist, gMinuit, pars, pval, perr, plo, phi, npar, r);
602    
603     // minimize
604     double chisquare, edm, errdef;
605     int nvpar, nparx;
606     trouble t;
607     t.occ = T_NULL;
608     t.istat = 3;
609     // fix sigmas of the Gaussians
610     for (int i = 0; i < ngauss; i++) {
611     double parno[2];
612     parno[0] = i*npar_indiv + 4;
613     gMinuit->mnexcm("FIX", parno, 1, erflg);
614     }
615     gMinuit->mnexcm("SIMPLEX", 0, 0, erflg);
616     gMinuit->mnexcm("MIGRAD", 0, 0, erflg);
617     gMinuit->mnstat(chisquare, edm, errdef, nvpar, nparx, istat);
618     if (istat == 3) {
619     /* we're not concerned about MINOS errors right now
620     gMinuit->mnexcm("MINOS", 0, 0, erflg);
621     gMinuit->mnstat(chisquare, edm, errdef, nvpar, nparx, istat);
622     if (istat != 3) {
623     t.occ = T_MINOS;
624     t.istat = istat;
625     }
626     */
627     }
628     else {
629     t.occ = T_MIGRAD;
630     t.istat = istat;
631     }
632    
633     try {
634     if (t_vec.size() < ngauss) {
635     t_vec.resize(ngauss);
636     }
637     t_vec.at(ngauss-1) = t;
638     }
639     catch (exception ex) {
640     cerr << "exception in fit_histo" << endl;
641     }
642    
643     // put parameters in map
644     for (int i = 0; i < npar && i < 256; i++) {
645     int iuint; // internal parameter number
646     gMinuit->mnpout(i, pars[i], pval[i], perr[i], plo[i], phi[i], iuint);
647     }
648     vector<double> pval_copy(npar);
649     vector<double> perr_copy(npar);
650     vector<double> plo_copy(npar);
651     vector<double> phi_copy(npar);
652     for (int i = 0; i < npar && i < 256; i++) {
653     pval_copy[i] = pval[i];
654     perr_copy[i] = perr[i];
655     plo_copy[i] = plo[i];
656     phi_copy[i] = phi[i];
657     }
658     r.pars.push_back(pars);
659     r.pval.push_back(pval_copy);
660     r.perr.push_back(perr_copy);
661     r.plo.push_back(plo_copy);
662     r.phi.push_back(phi_copy);
663    
664     // execute user minuit code
665     if (cc_minuit != 0)
666     (*cc_minuit)(gMinuit, hist_rebinned, ngauss);
667    
668     int ndof = 0;
669     if (!ignorezero)
670     ndof = energy.bins.size() * energy.bins[0].size();
671     else {
672     for (int i = 0; i < energy.bins.size(); i++) {
673     for (int j = 0; j < energy.bins[i].size(); j++) {
674     if (energy.bins[i][j] > 1.0e-30)
675     ndof++;
676     }
677     }
678     }
679     ndof -= npar;
680    
681     r.chisquare.push_back(chisquare);
682     double P = TMath::Prob(chisquare, ndof);
683     if (P > P_cutoff_val) {
684     break;
685     }
686     }
687    
688     delete gMinuit;
689     return r;
690     }
691 dnisson 1.1
692     JetFitAnalyzer::JetFitAnalyzer(const edm::ParameterSet& iConfig)
693     : user_minuit(0)
694     {
695     // get parameters from iConfig
696     ignorezero_ = iConfig.getUntrackedParameter("ignorezero", false);
697     rebinX_ = iConfig.getUntrackedParameter("rebinX", 1);
698     rebinY_ = iConfig.getUntrackedParameter("rebinY", 1);
699     P_cutoff_val_ = iConfig.getUntrackedParameter("P_cutoff_val", 0.5);
700    
701     jetfit::set_ignorezero(ignorezero_);
702     }
703    
704    
705     JetFitAnalyzer::~JetFitAnalyzer()
706     {
707    
708     // do anything here that needs to be done at desctruction time
709     // (e.g. close files, deallocate resources etc.)
710    
711     }
712    
713    
714     //
715     // member functions
716     //
717    
718     // ------------ method called to for each event ------------
719     void
720     JetFitAnalyzer::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup)
721     {
722     using namespace edm;
723    
724 dnisson 1.4 std::vector<jetfit::trouble> t;
725 dnisson 1.1
726     TH2D *histo = make_histo(iEvent, iSetup);
727 dnisson 1.2 if (histo != 0) {
728 dnisson 1.6 jetfit::ModelDefinition &_mdef = make_model_def(iEvent, iSetup, histo);
729 dnisson 1.5 jetfit::results r(fit_histo(histo, t, user_minuit,
730     _mdef.get_n_special_par_sets(),
731     rebinX_, rebinY_, P_cutoff_val_));
732 dnisson 1.2 analyze_results(r, t, histo);
733     }
734     else {
735 dnisson 1.3 std::cerr << "Fitting not performed" << std::endl;
736 dnisson 1.2 }
737 dnisson 1.1 }
738    
739    
740     // ------------ method called once each job just before starting event loop ------------
741     void
742     JetFitAnalyzer::beginJob(const edm::EventSetup&)
743     {
744     }
745    
746     // ------------ method called once each job just after ending the event loop ------------
747     void
748     JetFitAnalyzer::endJob() {
749     }
750    
751     //define this as a plug-in
752     // this is a base class-we can't do this DEFINE_FWK_MODULE(JetFitAnalyzer);