00001 #include "HistogramFitFCN.h"
00002
00003 #include <cmath>
00004 #include <iostream>
00005
00006 HistogramFitFCN::HistogramFitFCN(const TH1D* hTemplate,const TH1D* hPulse) : fTemplateHist(hTemplate), fPulseHist(hPulse) {
00007 }
00008
00009 HistogramFitFCN::~HistogramFitFCN() {
00010 }
00011
00012 void HistogramFitFCN::SetTemplateHist(const TH1D* hTemplate, double pedestal) {
00013 fTemplateHist = hTemplate;
00014 if(pedestal>0){
00015 fTemplatePedestal = pedestal;
00016 } else {
00017 fTemplatePedestal = fTemplateHist->GetBinContent(1);
00018 }
00019 }
00020
00021 void HistogramFitFCN::SetPulseHist(const TH1D* hPulse) {
00022 fPulseHist = hPulse;
00023 }
00024
00025 void HistogramFitFCN::SetTimeOffset(double time_offset) {
00026 fTimeOffset = time_offset;
00027 }
00028
00029 double HistogramFitFCN::operator() (const std::vector<double>& par) const {
00030
00031
00032
00033
00034
00035 double chi2 = 0.;
00036 double P = par[0];
00037 double A = par[1];
00038 int T_int = (int)fTimeOffset;
00039 double T_flt = fTimeOffset - (double)T_int;
00040
00041 bool print_dbg = false;
00042 if (strcmp(fTemplateHist->GetName(), "hTemplate_ScL") == 0) {
00043 print_dbg = false;
00044 }
00045
00046 if (print_dbg) {
00047 std::cout << "HistogramFitFCN::operator() (start):" << std::endl;
00048 std::cout << "\tpedestal = " << P
00049 << ", amplitude = " << A
00050 << ", time (integer part) = " << T_int
00051 << " and time (float part) = " << T_flt << std::endl;
00052 }
00053
00054 int half_range = 10*fRefineFactor;
00055 int bounds[2];
00056 bounds[0] = half_range+1;
00057 bounds[1] = std::min(fTemplateHist->GetNbinsX(), fPulseHist->GetNbinsX()) - half_range-1;
00058
00059 fNDoF = ((bounds[1] - bounds[0] + 1)/fRefineFactor) - par.size();
00060
00061 if (print_dbg) {
00062 std::cout << "NBinsX: hTemplate = " << fTemplateHist->GetNbinsX() << ", hPulse = " << fPulseHist->GetNbinsX() << std::endl;
00063 std::cout << "Bound Defns: " << std::endl;
00064 std::cout << "\tbounds[0] = " << bounds[0] << std::endl;
00065 std::cout << "\tbounds[1] = " << bounds[1] << std::endl;
00066 }
00067
00068
00069 if (print_dbg) {
00070 if (bounds[1] <= bounds[0])
00071 std::cout << "ERROR: Fit of two histograms involves shifting one out-of-bounds (no overlap)!" << std::endl;
00072 }
00073
00074 double f;
00075 double temp_ped=fTemplateHist->GetBinContent(1);
00076 for (int i = bounds[0]+(fRefineFactor/2.0); i <= bounds[1]-(fRefineFactor/2.0); i += fRefineFactor) {
00077
00078
00079
00080
00081
00082 f = fTemplateHist->GetBinContent(i - T_int) ;
00083 f += T_flt*(fTemplateHist->GetBinContent(i - T_int + 1) - f);
00084 if (print_dbg) {
00085 std::cout << "i = " << i << ", i - T_int = " << i-T_int << std::endl;
00086 std::cout << "f (before) = " << f << std::endl;
00087 }
00088 f = A * (f - temp_ped) + P;
00089 if (print_dbg) {
00090 std::cout << "f (after) = " << f << std::endl;
00091 }
00092
00093
00094 double delta = fPulseHist->GetBinContent(i) - f;
00095 if (print_dbg) {
00096 std::cout << "Pulse Value = " << fPulseHist->GetBinContent(i) << ", delta = " << delta << std::endl;
00097 }
00098 double hTemplate_bin_error = fTemplateHist->GetBinError(i - T_int);
00099
00100 chi2 += delta*delta / (A*hTemplate_bin_error*hTemplate_bin_error);
00101 if (print_dbg) {
00102 std::cout << "Template Error = " << hTemplate_bin_error << ", chi2 (added) = " << delta*delta/(hTemplate_bin_error*hTemplate_bin_error) << ", chi2 (total) = " << chi2 << std::endl;
00103 }
00104 }
00105
00106 if (print_dbg) {
00107 std::cout << "HistogramFitFCN::operator() (end): " << std::endl;
00108 std::cout << "\tFit:\tChi2 " << chi2 << "\tP "
00109 << P << "(" << par[0] << ")\tA " << A << "(" << par[1] << ")\tT " << T_int
00110 << std::endl << std::endl;
00111 }
00112 return chi2;
00113 }
00114
00115 double HistogramFitFCN::Up() const {
00116 return 1.;
00117 }