CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_9_patch3/src/Alignment/MuonAlignmentAlgorithms/src/MuonResiduals1DOFFitter.cc

Go to the documentation of this file.
00001 #include "Alignment/MuonAlignmentAlgorithms/interface/MuonResiduals1DOFFitter.h"
00002 #include "TMath.h"
00003 
00004 static TMinuit *MuonResiduals1DOFFitter_TMinuit;
00005 static double MuonResiduals1DOFFitter_sum_of_weights;
00006 static double MuonResiduals1DOFFitter_number_of_hits;
00007 static bool MuonResiduals1DOFFitter_weightAlignment;
00008 
00009 void MuonResiduals1DOFFitter::inform(TMinuit *tMinuit) {
00010   MuonResiduals1DOFFitter_TMinuit = tMinuit;
00011 }
00012 
00013 void MuonResiduals1DOFFitter_FCN(int &npar, double *gin, double &fval, double *par, int iflag) {
00014   MuonResidualsFitterFitInfo *fitinfo = (MuonResidualsFitterFitInfo*)(MuonResiduals1DOFFitter_TMinuit->GetObjectFit());
00015   MuonResidualsFitter *fitter = fitinfo->fitter();
00016 
00017   fval = 0.;
00018   for (std::vector<double*>::const_iterator resiter = fitter->residuals_begin();  resiter != fitter->residuals_end();  ++resiter) {
00019     const double residual = (*resiter)[MuonResiduals1DOFFitter::kResid];
00020     const double redchi2 = (*resiter)[MuonResiduals1DOFFitter::kRedChi2];
00021 
00022     const double residpeak = par[MuonResiduals1DOFFitter::kAlign];
00023     const double residsigma = par[MuonResiduals1DOFFitter::kSigma];
00024     const double residgamma = par[MuonResiduals1DOFFitter::kGamma];
00025 
00026     double weight = (1./redchi2) * MuonResiduals1DOFFitter_number_of_hits / MuonResiduals1DOFFitter_sum_of_weights;
00027     if (!MuonResiduals1DOFFitter_weightAlignment) weight = 1.;
00028 
00029     if (!MuonResiduals1DOFFitter_weightAlignment  ||  TMath::Prob(redchi2*8, 8) < 0.99) {  // no spikes allowed
00030       if (fitter->residualsModel() == MuonResidualsFitter::kPureGaussian) {
00031         fval += -weight * MuonResidualsFitter_logPureGaussian(residual, residpeak, residsigma);
00032       }
00033       else if (fitter->residualsModel() == MuonResidualsFitter::kPowerLawTails) {
00034         fval += -weight * MuonResidualsFitter_logPowerLawTails(residual, residpeak, residsigma, residgamma);
00035       }
00036       else if (fitter->residualsModel() == MuonResidualsFitter::kROOTVoigt) {
00037         fval += -weight * MuonResidualsFitter_logROOTVoigt(residual, residpeak, residsigma, residgamma);
00038       }
00039       else if (fitter->residualsModel() == MuonResidualsFitter::kGaussPowerTails) {
00040         fval += -weight * MuonResidualsFitter_logGaussPowerTails(residual, residpeak, residsigma);
00041       }
00042       else { assert(false); }
00043 
00044     }
00045   }
00046 }
00047 
00048 double MuonResiduals1DOFFitter::sumofweights() {
00049   MuonResiduals1DOFFitter_sum_of_weights = 0.;
00050   MuonResiduals1DOFFitter_number_of_hits = 0.;
00051   MuonResiduals1DOFFitter_weightAlignment = m_weightAlignment;
00052   for (std::vector<double*>::const_iterator resiter = residuals_begin();  resiter != residuals_end();  ++resiter) {
00053     if (m_weightAlignment) {
00054        double redchi2 = (*resiter)[MuonResiduals1DOFFitter::kRedChi2];
00055        if (TMath::Prob(redchi2*8, 8) < 0.99) {  // no spikes allowed
00056           MuonResiduals1DOFFitter_sum_of_weights += 1./redchi2;
00057           MuonResiduals1DOFFitter_number_of_hits += 1.;
00058        }
00059     }
00060     else {
00061       MuonResiduals1DOFFitter_sum_of_weights += 1.;
00062       MuonResiduals1DOFFitter_number_of_hits += 1.;
00063     }
00064   }
00065   return MuonResiduals1DOFFitter_sum_of_weights;
00066 }
00067 
00068 bool MuonResiduals1DOFFitter::fit(Alignable *ali) {
00069   initialize_table();  // if not already initialized
00070   sumofweights();
00071 
00072   double resid_sum = 0.;
00073   double resid_sum2 = 0.;
00074   double resid_N = 0.;
00075   int N = 0;
00076 
00077   for (std::vector<double*>::const_iterator resiter = residuals_begin();  resiter != residuals_end();  ++resiter) {
00078     const double residual = (*resiter)[MuonResiduals1DOFFitter::kResid];
00079     const double redchi2 = (*resiter)[MuonResiduals1DOFFitter::kRedChi2];
00080     double weight = 1./redchi2;
00081     if (!m_weightAlignment) weight = 1.;
00082 
00083     if (!m_weightAlignment  ||  TMath::Prob(redchi2*8, 8) < 0.99) {  // no spikes allowed
00084       if (fabs(residual) < 10.) {   // 10 cm
00085         resid_sum += weight * residual;
00086         resid_sum2 += weight * residual * residual;
00087         resid_N += weight;
00088         N++;
00089       }
00090     }
00091   }
00092 
00093   double resid_mean = resid_sum/resid_N;
00094   double resid_stdev = sqrt(resid_sum2/resid_N - pow(resid_sum/resid_N, 2));
00095 
00096   resid_sum = 0.;
00097   resid_sum2 = 0.;
00098   resid_N = 0.;
00099 
00100   for (std::vector<double*>::const_iterator resiter = residuals_begin();  resiter != residuals_end();  ++resiter) {
00101     const double residual = (*resiter)[MuonResiduals1DOFFitter::kResid];
00102     const double redchi2 = (*resiter)[MuonResiduals1DOFFitter::kRedChi2];
00103     double weight = 1./redchi2;
00104     if (!m_weightAlignment) weight = 1.;
00105 
00106     if (!m_weightAlignment  ||  TMath::Prob(redchi2*8, 8) < 0.99) {  // no spikes allowed
00107       if (fabs(residual - resid_mean) < 2.5*resid_stdev) {
00108         resid_sum += weight * residual;
00109         resid_sum2 += weight * residual * residual;
00110         resid_N += weight;
00111       }
00112     }
00113   }
00114 
00115   resid_mean = resid_sum/resid_N;
00116   resid_stdev = sqrt(resid_sum2/resid_N - pow(resid_sum/resid_N, 2));
00117 
00118   std::vector<int> num;
00119   std::vector<std::string> name;
00120   std::vector<double> start;
00121   std::vector<double> step;
00122   std::vector<double> low;
00123   std::vector<double> high;
00124 
00125   if (fixed(kAlign)) {
00126   num.push_back(kAlign);          name.push_back(std::string("Align"));          start.push_back(0.);              step.push_back(0.01*resid_stdev);    low.push_back(0.);   high.push_back(0.);
00127   } else {
00128   num.push_back(kAlign);          name.push_back(std::string("Align"));          start.push_back(resid_mean);      step.push_back(0.01*resid_stdev);    low.push_back(0.);   high.push_back(0.);
00129   }
00130   num.push_back(kSigma);          name.push_back(std::string("Sigma"));          start.push_back(resid_stdev);     step.push_back(0.01*resid_stdev);    low.push_back(0.);   high.push_back(0.);
00131   if (residualsModel() != kPureGaussian && residualsModel() != kGaussPowerTails) {
00132   num.push_back(kGamma);          name.push_back(std::string("Gamma"));          start.push_back(0.1*resid_stdev); step.push_back(0.01*resid_stdev);    low.push_back(0.);   high.push_back(0.);
00133   }
00134 
00135   return dofit(&MuonResiduals1DOFFitter_FCN, num, name, start, step, low, high);
00136 }
00137 
00138 double MuonResiduals1DOFFitter::plot(std::string name, TFileDirectory *dir, Alignable *ali) {
00139   sumofweights();
00140 
00141   std::stringstream name_residual, name_residual_raw;
00142   name_residual << name << "_residual";
00143   name_residual_raw << name << "_residual_raw";
00144 
00145   double min_residual = -100.;     double max_residual = 100.;
00146   TH1F *hist_residual = dir->make<TH1F>(name_residual.str().c_str(), "", 100, min_residual, max_residual);
00147   TH1F *hist_residual_raw = dir->make<TH1F>(name_residual_raw.str().c_str(), "", 100, min_residual, max_residual);
00148 
00149   name_residual << "_fit";
00150   TF1 *fit_residual = NULL;
00151   if (residualsModel() == kPureGaussian) {
00152     fit_residual = new TF1(name_residual.str().c_str(), MuonResidualsFitter_pureGaussian_TF1, min_residual, max_residual, 3);
00153     fit_residual->SetParameters(MuonResiduals1DOFFitter_sum_of_weights * (max_residual - min_residual)/100., 10.*value(kAlign), 10.*value(kSigma));
00154   }
00155   else if (residualsModel() == kPowerLawTails) {
00156     fit_residual = new TF1(name_residual.str().c_str(), MuonResidualsFitter_powerLawTails_TF1, min_residual, max_residual, 4);
00157     fit_residual->SetParameters(MuonResiduals1DOFFitter_sum_of_weights * (max_residual - min_residual)/100., 10.*value(kAlign), 10.*value(kSigma), 10.*value(kGamma));
00158   }
00159   else if (residualsModel() == kROOTVoigt) {
00160     fit_residual = new TF1(name_residual.str().c_str(), MuonResidualsFitter_ROOTVoigt_TF1, min_residual, max_residual, 4);
00161     fit_residual->SetParameters(MuonResiduals1DOFFitter_sum_of_weights * (max_residual - min_residual)/100., 10.*value(kAlign), 10.*value(kSigma), 10.*value(kGamma));
00162   }
00163   else if (residualsModel() == kGaussPowerTails) {
00164     fit_residual = new TF1(name_residual.str().c_str(), MuonResidualsFitter_GaussPowerTails_TF1, min_residual, max_residual, 3);
00165     fit_residual->SetParameters(MuonResiduals1DOFFitter_sum_of_weights * (max_residual - min_residual)/100., 10.*value(kAlign), 10.*value(kSigma));
00166   }
00167   else { assert(false); }
00168 
00169   fit_residual->SetLineColor(2);  fit_residual->SetLineWidth(2);
00170   fit_residual->Write();
00171 
00172   for (std::vector<double*>::const_iterator resiter = residuals_begin();  resiter != residuals_end();  ++resiter) {
00173     const double resid = (*resiter)[MuonResiduals1DOFFitter::kResid];
00174     const double redchi2 = (*resiter)[MuonResiduals1DOFFitter::kRedChi2];
00175     double weight = 1./redchi2;
00176     if (!m_weightAlignment) weight = 1.;
00177 
00178     if (!m_weightAlignment  ||  TMath::Prob(redchi2*8, 8) < 0.99) {  // no spikes allowed
00179       hist_residual->Fill(10.*(resid + value(kAlign)), weight);
00180     }
00181 
00182     hist_residual_raw->Fill(10.*resid);
00183   }
00184 
00185   double chi2 = 0.;
00186   double ndof = 0.;
00187   for (int i = 1;  i <= hist_residual->GetNbinsX();  i++) {
00188     double xi = hist_residual->GetBinCenter(i);
00189     double yi = hist_residual->GetBinContent(i);
00190     double yerri = hist_residual->GetBinError(i);
00191     double yth = fit_residual->Eval(xi);
00192     if (yerri > 0.) {
00193       chi2 += pow((yth - yi)/yerri, 2);
00194       ndof += 1.;
00195     }
00196   }
00197   ndof -= npar();
00198 
00199   return (ndof > 0. ? chi2 / ndof : -1.);
00200 }