ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/JetFitAnalyzer/src/jetfit.cpp
(Generate patch)

Comparing UserCode/JetFitAnalyzer/src/jetfit.cpp (file contents):
Revision 1.1 by dnisson, Wed Sep 2 21:44:14 2009 UTC vs.
Revision 1.10 by dnisson, Wed Nov 11 01:46:56 2009 UTC

# Line 40 | Line 40 | namespace jetfit {
40    // configurable options
41    bool ignorezero = false; // ignore zero bins when fitting
42    
43  int ngauss; // number of Gaussians in current model
44  
43    struct histo {
44      vector< vector<double> > bins;
45      double Xlo, Xhi, Ylo, Yhi;
# Line 58 | Line 56 | namespace jetfit {
56      mdef = _mdef;
57    }
58  
59 <  int get_ngauss() {
59 >  int model_def::get_ngauss() {
60      return ngauss;
61    }
62    
63 <  void set_ngauss(int _ngauss) {
63 >  void model_def::set_ngauss(int _ngauss) {
64      ngauss = _ngauss;
65    }
66  
67    // fit function
68 <  double fit_fcn(double x, double y, double *xval) {
69 <    int npar_indiv = mdef->get_formula()->GetNpar();
68 >  double model_def::fit_fcn(double x, double y, double *xval) {
69 >    int npar_indiv = get_formula()->GetNpar();
70      double val = 0.0;
71      for (int i = 0; i < ngauss; i++) {
72 <      mdef->get_formula()->SetParameters(xval + i*npar_indiv);
72 >      get_formula()->SetParameters(xval + i*npar_indiv);
73        val += mdef->get_formula()->Eval(x, y);
74      }
75      return val;
# Line 79 | Line 77 | namespace jetfit {
77  
78    // TF2-compatible fit function
79    double fit_fcn_TF2(double *x, double *pval) {
80 <    double val = fit_fcn(x[0], x[1], pval);
80 >    double val = mdef->fit_fcn(x[0], x[1], pval);
81      return val;
82    }
83  
84 <  // Integral of model formula / chisquare sigma
85 <  double formula_int(double xlo, double xhi, double ylo, double yhi,
84 >  // Integral of (model formula)^2 / chisquare sigma
85 >  double model_def::formula_int(double xlo, double xhi, double ylo, double yhi,
86                       double *pval, double XbinSize, double YbinSize,
87                       double *xval) {
88      double xstep = (xhi - xlo) / static_cast<double>(20);
# Line 92 | Line 90 | namespace jetfit {
90  
91      double fsum = 0.0;
92      double pval_old[256];
93 <    int npar = mdef->get_formula()->GetNpar();
93 >    int npar = get_formula()->GetNpar();
94      if (npar > 256) {
95        cerr << "Parameter overload" << endl;
96        return 0.0;
97      }
98 <    mdef->get_formula()->GetParameters(pval_old);
99 <    mdef->get_formula()->SetParameters(pval);
98 >    get_formula()->GetParameters(pval_old);
99 >    get_formula()->SetParameters(pval);
100  
101      for (int i = 0; i < 20; i++) {
102        for (int j = 0; j < 20; j++) {
# Line 106 | Line 104 | namespace jetfit {
104          double y = (static_cast<double>(j) + 0.5)*ystep + ylo;
105          double sig_cut = 1.0e-5;
106          double nu = XbinSize * YbinSize * fit_fcn(x, y, xval);
107 <        double sigma = mdef->chisquare_error(nu) < sig_cut
108 <          ? sig_cut : mdef->chisquare_error(nu);
107 >        double sigma = fabs(chisquare_error(0.0)) < sig_cut
108 >          ? sig_cut : chisquare_error(0.0);
109  
110 <        fsum += xstep * ystep * mdef->get_formula()->Eval(x, y)
110 >        fsum += pow(xstep * ystep * get_formula()->Eval(x, y), 2.0)
111            / sigma / sigma;
112        }
113      }
114  
115 <    mdef->get_formula()->SetParameters(pval_old);
115 >    get_formula()->SetParameters(pval_old);
116      return fsum;
117    }
118  
# Line 130 | Line 128 | namespace jetfit {
128        // add errors in data points in histogram
129        for (int i = 0; i < energy.bins.size(); i++) {
130          for (int j = 0; j < energy.bins.at(i).size(); j++) {
131 <          double x = (static_cast<double>(i) + 0.5) * (energy.Xhi - energy.Xlo)
131 >          double x = (static_cast<double>(i) + 0.5) * (energy.Xhi - energy.Xlo)
132              / static_cast<double>(energy.bins.size()) + energy.Xlo;
133            double y = (static_cast<double>(j) + 0.5) * (energy.Yhi - energy.Ylo)
134              / static_cast<double>(energy.bins.at(i).size()) + energy.Ylo;
135 <          double nu = fit_fcn(x, y, xval) * XbinSize * YbinSize;
135 >          double nu = mdef->fit_fcn(x, y, xval) * XbinSize * YbinSize;
136            double sig_cut = 1.0e-5;
137 <          if (mdef->chisquare_error(nu) > sig_cut || !ignorezero)
137 >          if (fabs(mdef->chisquare_error(energy.bins.at(i).at(j))) > sig_cut || !ignorezero) {
138              chisquare += pow(energy.bins.at(i).at(j) - nu, 2.0)
139 <              / pow(mdef->chisquare_error(nu), 2.0);
140 <          else
139 >              / pow(mdef->chisquare_error(energy.bins.at(i).at(j)), 2.0);
140 >          }
141 >          else {
142              chisquare += pow(energy.bins.at(i).at(j) - nu, 2.0)
143                / pow(sig_cut, 2.0);
144 +          }
145          }
146        }
147 <
147 >      
148        // add errors due to Gaussians outside histogram
149 <      double eps = 0.1; // accuracy set for this function
150 <      for (int i = 0; i < ngauss; i++) {
151 <        double *pval = xval+i*mdef->get_formula()->GetNpar();
149 >      double eps = 0.01; // accuracy set for this function
150 >      for (int i = 0; i < mdef->get_ngauss(); i++) {
151 >        double *pval = xval+i*(mdef->get_formula()->GetNpar());
152          double par_x = pval[mdef->get_indiv_max_x()];
153          double par_y = pval[mdef->get_indiv_max_y()];
154          double par_sig = pval[3];
155 <        double cutoff_rad = -log(eps * 2.0 * PI * par_sig * par_sig
156 <          / pval[0]);
155 >        double cutoff_rad = sqrt(-log(eps * 2.0 * PI * par_sig * par_sig
156 >          / pval[0]) * 2.0 * par_sig * par_sig);
157  
158          bool left = par_x < energy.Xlo + cutoff_rad;
159          bool right = par_x > energy.Xhi - cutoff_rad;
160          bool top = par_y > energy.Yhi - cutoff_rad;
161 <        bool bottom = par_y > energy.Ylo + cutoff_rad;
161 >        bool bottom = par_y < energy.Ylo + cutoff_rad;
162  
163          if (left) {
164            double xlo = par_x - cutoff_rad;
165            double xhi = energy.Xlo;
166            double ylo = energy.Ylo;
167            double yhi = energy.Yhi;
168 <          chisquare += formula_int(xlo, xhi, ylo, yhi, pval,
168 >          chisquare += 2.0*mdef->formula_int(xlo, xhi, ylo, yhi, pval,
169                                     XbinSize, YbinSize, xval);
170          }
171          if (right) {
# Line 173 | Line 173 | namespace jetfit {
173            double xhi = par_x + cutoff_rad;
174            double ylo = energy.Ylo;
175            double yhi = energy.Yhi;
176 <          chisquare += formula_int(xlo, xhi, ylo, yhi, pval,
176 >          chisquare += 2.0*mdef->formula_int(xlo, xhi, ylo, yhi, pval,
177                                     XbinSize, YbinSize, xval);
178          }
179          if (top) {
# Line 181 | Line 181 | namespace jetfit {
181            double xhi = right ? par_x + cutoff_rad : energy.Xhi;
182            double ylo = energy.Yhi;
183            double yhi = par_y + cutoff_rad;
184 <          chisquare += formula_int(xlo, xhi, ylo, yhi, pval,
184 >          chisquare += 2.0*mdef->formula_int(xlo, xhi, ylo, yhi, pval,
185                                     XbinSize, YbinSize, xval);
186          }
187          if (bottom) {
# Line 189 | Line 189 | namespace jetfit {
189            double xhi = right ? par_x + cutoff_rad : energy.Xhi;
190            double ylo = par_y - cutoff_rad;
191            double yhi = energy.Ylo;
192 <          chisquare += formula_int(xlo, xhi, ylo, yhi, pval,
192 >          chisquare += 2.0*mdef->formula_int(xlo, xhi, ylo, yhi, pval,
193                                     XbinSize, YbinSize, xval);
194          }
195        }
196 <
196 >      
197        fcnval = chisquare;
198      }
199      catch (exception ex) {
# Line 481 | Line 481 | namespace jetfit {
481      }
482    }
483  
484 <  void par_init(TH2 *hist, TMinuit *gMinuit, vector<TString> &pars,
484 >  void fill_histo_with_vec(TH2 *hist, vector< vector<double> > &vec) {
485 >    for (int i = 0; i < vec.size(); i++) {
486 >      for (int j = 0; j < vec[i].size(); j++) {
487 >        hist->SetBinContent(i+1, j+1, vec[i][j]);
488 >      }
489 >    }
490 >  }
491 >
492 >  void model_def::par_init(TH2 *hist, TMinuit *gMinuit, vector<TString> &pars,
493                  double *pval, double *perr, double *plo, double *phi,
494                  int npar, results r) {
495 <    int npar1 = npar - mdef->get_formula()->GetNpar();
495 >    int npar1 = npar - get_formula()->GetNpar();
496      bool init_spec_pars = false;
497 <    if (ngauss <= mdef->get_n_special_par_sets()) {
497 >    if (ngauss <= get_n_special_par_sets()) {
498        init_spec_pars = true;
499        for (int k = 0; k < ngauss; k++) {
500 <        int ipar0 = k*mdef->get_formula()->GetNpar(); // index of par 0
501 <        for (int l = 0; l < mdef->get_formula()->GetNpar(); l++) {
500 >        int ipar0 = k*get_formula()->GetNpar(); // index of indiv par 0
501 >        for (int l = 0; l < get_formula()->GetNpar(); l++) {
502            int ipar = ipar0 + l;
503            if (ipar < npar)
504 <            mdef->get_special_par(k, l, pval[ipar], perr[ipar], plo[ipar],
504 >            get_special_par(k, l, pval[ipar], perr[ipar], plo[ipar],
505                                   phi[ipar]);
506            else
507              cerr << "WARNING: Attempt to set parameter out of index range!"
# Line 509 | Line 517 | namespace jetfit {
517        vector< vector<double> > sub_energy(energy.bins.size());
518        double max_sub, max_x = 0.0, max_y = 0.0;
519        double pval_other[256];
520 <      max_sub = -(numeric_limits<double>::infinity());
520 >      max_sub = -(numeric_limits<double>::max());
521        for (int i = 0; i < energy.bins.size(); i++) {
522          sub_energy[i].resize(energy.bins[i].size());
523          for (int j = 0; j < energy.bins[i].size(); j++) {
# Line 518 | Line 526 | namespace jetfit {
526            double y = static_cast<double>(j)*(energy.Yhi - energy.Ylo)
527              / static_cast<double>(energy.bins[i].size()) + energy.Ylo;
528            if (ngauss > 1) {
529 <            // subtract 4*sigma plus integral of fit function
529 >            // subtract integral of fit function
530              try {
531                int npval_other = r.pval.at(r.pval.size()-1).size();
532                if (npval_other > 256) {
# Line 531 | Line 539 | namespace jetfit {
539                ngauss--;
540                double nu = fit_fcn(x, y, pval_other) * XbinSize * YbinSize;
541                ngauss++;
542 <              sub_energy[i][j] = energy.bins[i][j] - nu
535 <                - 4.0*mdef->chisquare_error(nu);
542 >              sub_energy[i][j] = energy.bins[i][j] - nu;
543              }
544              catch (exception ex) {
545                cerr << "Exception in par_init" << endl;
# Line 541 | Line 548 | namespace jetfit {
548            else {
549              sub_energy[i][j] = energy.bins[i][j];
550            }
544          if (sub_energy[i][j] > max_sub) {
545            max_sub = sub_energy[i][j];
546            max_x = x;
547            max_y = y;
548          }
551          }
552        }
553 +      TH2D *hist_sub = new TH2D("hist_sub", "Subtracted histo",
554 +                                sub_energy.size(), energy.Xlo,
555 +                                energy.Xhi,
556 +                                sub_energy[0].size(), energy.Ylo,
557 +                                energy.Yhi);
558 +      fill_histo_with_vec(hist_sub, sub_energy);
559 +      max_sub = 0.0;
560 +      max_x = 0.0;
561 +      max_y = 0.0;
562 +      for (int i = 1; i <= hist_sub->GetXaxis()->GetNbins(); i++) {
563 +        for (int j = 1; j <= hist_sub->GetYaxis()->GetNbins(); j++) {
564 +          double nu = energy.bins[i-1][j-1] - sub_energy[i-1][j-1];
565 +          if (hist_sub->GetBinContent(i, j)
566 +              - 3.0*pow(chisquare_error(nu), 2.0) > max_sub) {
567 +            max_sub = hist_sub->GetBinContent(i, j);
568 +            max_x = static_cast<double>(i-1)*XbinSize
569 +              + hist_sub->GetXaxis()->GetXmin();
570 +            max_y = static_cast<double>(j-1)*YbinSize
571 +              + hist_sub->GetYaxis()->GetXmin();
572 +          }
573 +        }
574 +      }  
575  
576        for (int i = npar1; i < npar; i++) {
577 <        if (mdef->get_indiv_max_E() == i - npar1) {
578 <          double nu = 0.0;
579 <          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;
577 >        if (get_indiv_max_E() == i - npar1) {
578 >          pval[i] = max_sub / XbinSize / YbinSize;
579 >          perr[i] = mdef->chisquare_error(pval[i])*0.5;
580            plo[i] = 0.0;
581            phi[i] = 1.0e6;
582          }
583 <        else if (mdef->get_indiv_max_x() == i - npar1) {
583 >        else if (get_indiv_max_x() == i - npar1) {
584            pval[i] = max_x;
585            perr[i] = (energy.Xhi - energy.Xlo) / static_cast<double>(hist->GetXaxis()->GetNbins());
586            plo[i] = 0.0;
587            phi[i] = 0.0;
588          }
589 <        else if (mdef->get_indiv_max_y() == i - npar1) {
589 >        else if (get_indiv_max_y() == i - npar1) {
590            pval[i] = max_y;
591            perr[i] = (energy.Yhi - energy.Ylo) / static_cast<double>(hist->GetYaxis()->GetNbins());
592            plo[i] = 0.0;
# Line 575 | Line 594 | namespace jetfit {
594          }
595          else {
596            string dummy;
597 <          mdef->get_indiv_par(i-npar1, dummy, pval[i], perr[i], plo[i], phi[i]);
597 >          get_indiv_par(i-npar1, dummy, pval[i], perr[i], plo[i], phi[i]);
598          }
599        }
600      }
601 <    int n_pars_to_set = init_spec_pars ? ngauss*mdef->get_formula()->GetNpar()
601 >    int n_pars_to_set = init_spec_pars ? ngauss*get_formula()->GetNpar()
602        : npar - npar1;
603      int init_par_to_set = init_spec_pars ? 0 : npar1;
604      for (int i = 0; i < n_pars_to_set; i++) {
605        double dummy;
606        string s;
607        int ipar = i + init_par_to_set;
608 <      mdef->get_indiv_par(i % mdef->get_formula()->GetNpar(), s,
608 >      get_indiv_par(i % get_formula()->GetNpar(), s,
609                           dummy, dummy, dummy, dummy);
610        ostringstream par_oss;
611 <      par_oss << s << ipar / (mdef->get_formula()->GetNpar()) << flush;
611 >      par_oss << s << ipar / (get_formula()->GetNpar()) << flush;
612        try {
613          pars.at(ipar) = TString(par_oss.str());
614        }
# Line 606 | Line 625 | namespace jetfit {
625      }
626    }
627  
628 <  results fit_histo(TH2 *hist, vector<trouble> &t_vec,
629 <                 void (*cc_minuit)(TMinuit *, TH2 *, int),
630 <                 int start_ngauss,
631 <                    int rebinX, int rebinY,
632 <                    double P_cutoff_val) {
628 >  results model_def::fit_histo(TH2 *hist, vector<trouble> &t_vec,
629 >                               void (*cc_minuit)(TMinuit *, TH2 *, int),
630 >                               int start_ngauss,
631 >                               int rebinX, int rebinY,
632 >                               double P_cutoff_val) {
633 >    set_model_def(this);
634      TMinuit *gMinuit = new TMinuit();
635      int npar_indiv = mdef->get_formula()->GetNpar();
636      int istat, erflg;
637      results r;
638 +    r.moddef = this;
639  
640      gMinuit->SetFCN(fcn);
641      gMinuit->mninit(5, 6, 7);
# Line 654 | Line 675 | namespace jetfit {
675      for (ngauss = start_ngauss;
676           ngauss <= (MAX_GAUSS > start_ngauss ? MAX_GAUSS : start_ngauss);
677           ngauss++) {
678 +      
679        t_vec.resize(t_vec.size() + 1);
680        int npar = npar_indiv*ngauss;
681        double pval[256], perr[256], plo[256], phi[256];
# Line 665 | Line 687 | namespace jetfit {
687  
688        // initialize parameters
689        par_init(hist, gMinuit, pars, pval, perr, plo, phi, npar, r);
690 <  
690 >
691        // minimize
692        double chisquare, edm, errdef;
693        int nvpar, nparx;
694        trouble t;
695        t.occ = T_NULL;
696        t.istat = 3;
697 <      // fix the N values and sigmas of the Gaussians
697 >      // fix sigmas of the Gaussians
698        for (int i = 0; i < ngauss; i++) {
699          double parno[2];
700 <        parno[0] = i*npar_indiv + 1;
701 <        parno[1] = i*npar_indiv + 4;
680 <        gMinuit->mnexcm("FIX", parno, 2, erflg);
700 >        parno[0] = i*npar_indiv + 4;
701 >        gMinuit->mnexcm("FIX", parno, 1, erflg);
702        }
703        gMinuit->mnexcm("SIMPLEX", 0, 0, erflg);
704        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);
705        gMinuit->mnstat(chisquare, edm, errdef, nvpar, nparx, istat);
706        if (istat == 3) {
707          /* we're not concerned about MINOS errors right now
# Line 766 | Line 766 | namespace jetfit {
766        }
767        ndof -= npar;
768  
769 +      r.chisquare.push_back(chisquare);
770        double P = prob(chisquare, ndof);
770      cout << "P = "<<P << endl;
771        if (P > P_cutoff_val) {
772          break;
773        }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines