CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/Alignment/MuonAlignmentAlgorithms/src/MuonResidualsPositionFitter.cc

Go to the documentation of this file.
00001 #include "Alignment/MuonAlignmentAlgorithms/interface/MuonResidualsPositionFitter.h"
00002 
00003 static TMinuit *MuonResidualsPositionFitter_TMinuit;
00004 
00005 void MuonResidualsPositionFitter::inform(TMinuit *tMinuit) {
00006   MuonResidualsPositionFitter_TMinuit = tMinuit;
00007 }
00008 
00009 void MuonResidualsPositionFitter_FCN(int &npar, double *gin, double &fval, double *par, int iflag) {
00010   MuonResidualsFitterFitInfo *fitinfo = (MuonResidualsFitterFitInfo*)(MuonResidualsPositionFitter_TMinuit->GetObjectFit());
00011   MuonResidualsFitter *fitter = fitinfo->fitter();
00012 
00013   fval = 0.;
00014   for (std::vector<double*>::const_iterator resiter = fitter->residuals_begin();  resiter != fitter->residuals_end();  ++resiter) {
00015     const double residual = (*resiter)[MuonResidualsPositionFitter::kResidual];
00016     const double angleerror = (*resiter)[MuonResidualsPositionFitter::kAngleError];
00017     const double trackangle = (*resiter)[MuonResidualsPositionFitter::kTrackAngle];
00018     const double trackposition = (*resiter)[MuonResidualsPositionFitter::kTrackPosition];
00019       
00020     double center = 0.;
00021     center += par[MuonResidualsPositionFitter::kPosition];
00022     center += par[MuonResidualsPositionFitter::kZpos] * trackangle;
00023     center += par[MuonResidualsPositionFitter::kPhiz] * trackposition;
00024     center += par[MuonResidualsPositionFitter::kScattering] * angleerror;
00025 
00026     if (fitter->residualsModel() == MuonResidualsFitter::kPureGaussian) {
00027       fval += -MuonResidualsFitter_logPureGaussian(residual, center, par[MuonResidualsPositionFitter::kSigma]);
00028     }
00029     else if (fitter->residualsModel() == MuonResidualsFitter::kPowerLawTails) {
00030       fval += -MuonResidualsFitter_logPowerLawTails(residual, center, par[MuonResidualsPositionFitter::kSigma], par[MuonResidualsPositionFitter::kGamma]);
00031     }
00032     else if (fitter->residualsModel() == MuonResidualsFitter::kROOTVoigt) {
00033       fval += -MuonResidualsFitter_logROOTVoigt(residual, center, par[MuonResidualsPositionFitter::kSigma], par[MuonResidualsPositionFitter::kGamma]);
00034     }
00035     else if (fitter->residualsModel() == MuonResidualsFitter::kGaussPowerTails) {
00036       fval += -MuonResidualsFitter_logGaussPowerTails(residual, center, par[MuonResidualsPositionFitter::kSigma]);
00037     }
00038     else { assert(false); }
00039   }
00040 }
00041 
00042 bool MuonResidualsPositionFitter::fit(Alignable *ali) {
00043   initialize_table();  // if not already initialized
00044 
00045   double sum_x = 0.;
00046   double sum_xx = 0.;
00047   int N = 0;
00048 
00049   for (std::vector<double*>::const_iterator resiter = residuals_begin();  resiter != residuals_end();  ++resiter) {
00050     const double residual = (*resiter)[kResidual];
00051     //    const double angleerror = (*resiter)[kAngleError];
00052     //    const double trackangle = (*resiter)[kTrackAngle];
00053     //    const double trackposition = (*resiter)[kTrackPosition];
00054 
00055     if (fabs(residual) < 10.) {  // truncate at 100 mm
00056       sum_x += residual;
00057       sum_xx += residual*residual;
00058       N++;
00059     }
00060   }
00061 
00062   if (N < m_minHits) return false;
00063 
00064   // truncated mean and stdev to seed the fit
00065   double mean = sum_x/double(N);
00066   double stdev = sqrt(sum_xx/double(N) - pow(sum_x/double(N), 2));
00067 
00068   // refine the standard deviation calculation
00069   sum_x = 0.;
00070   sum_xx = 0.;
00071   N = 0;
00072   for (std::vector<double*>::const_iterator resiter = residuals_begin();  resiter != residuals_end();  ++resiter) {
00073     const double residual = (*resiter)[kResidual];
00074     if (mean - 1.5*stdev < residual  &&  residual < mean + 1.5*stdev) {
00075       sum_x += residual;
00076       sum_xx += residual*residual;
00077       N++;
00078     }
00079   }
00080   mean = sum_x/double(N);
00081   stdev = sqrt(sum_xx/double(N) - pow(sum_x/double(N), 2));
00082 
00083   sum_x = 0.;
00084   sum_xx = 0.;
00085   N = 0;
00086   for (std::vector<double*>::const_iterator resiter = residuals_begin();  resiter != residuals_end();  ++resiter) {
00087     const double residual = (*resiter)[kResidual];
00088     if (mean - 1.5*stdev < residual  &&  residual < mean + 1.5*stdev) {
00089       sum_x += residual;
00090       sum_xx += residual*residual;
00091       N++;
00092     }
00093   }
00094   mean = sum_x/double(N);
00095   stdev = sqrt(sum_xx/double(N) - pow(sum_x/double(N), 2));
00096 
00097   std::vector<int> parNum;
00098   std::vector<std::string> parName;
00099   std::vector<double> start;
00100   std::vector<double> step;
00101   std::vector<double> low;
00102   std::vector<double> high;
00103 
00104   parNum.push_back(kPosition);    parName.push_back(std::string("position"));    start.push_back(mean);   step.push_back(0.1);             low.push_back(0.);    high.push_back(0.);
00105   parNum.push_back(kZpos);        parName.push_back(std::string("zpos"));        start.push_back(0.);       step.push_back(0.1);             low.push_back(0.);    high.push_back(0.);
00106   parNum.push_back(kPhiz);        parName.push_back(std::string("phiz"));        start.push_back(0.);       step.push_back(0.1);             low.push_back(0.);    high.push_back(0.);
00107   parNum.push_back(kScattering);  parName.push_back(std::string("scattering"));  start.push_back(0.);       step.push_back(0.1*1000.);       low.push_back(0.);    high.push_back(0.);
00108   parNum.push_back(kSigma);       parName.push_back(std::string("sigma"));       start.push_back(stdev);  step.push_back(0.1*stdev);     low.push_back(0.);    high.push_back(0.);
00109   if (residualsModel() != kPureGaussian && residualsModel() != kGaussPowerTails) {
00110   parNum.push_back(kGamma);       parName.push_back(std::string("gamma"));       start.push_back(stdev);  step.push_back(0.1*stdev);     low.push_back(0.);    high.push_back(0.);
00111   }
00112 
00113   return dofit(&MuonResidualsPositionFitter_FCN, parNum, parName, start, step, low, high);
00114 }
00115 
00116 double MuonResidualsPositionFitter::plot(std::string name, TFileDirectory *dir, Alignable *ali) {
00117   std::stringstream raw_name, narrowed_name, angleerror_name, trackangle_name, trackposition_name;
00118   raw_name << name << "_raw";
00119   narrowed_name << name << "_narrowed";
00120   angleerror_name << name << "_angleerror";
00121   trackangle_name << name << "_trackangle";
00122   trackposition_name << name << "_trackposition";
00123 
00124   TH1F *raw_hist = dir->make<TH1F>(raw_name.str().c_str(), (raw_name.str() + std::string(" (mm)")).c_str(), 100, -100., 100.);
00125   TH1F *narrowed_hist = dir->make<TH1F>(narrowed_name.str().c_str(), (narrowed_name.str() + std::string(" (mm)")).c_str(), 100, -100., 100.);
00126   TProfile *angleerror_hist = dir->make<TProfile>(angleerror_name.str().c_str(), (angleerror_name.str() + std::string(" (mm)")).c_str(), 100, -30., 30.);
00127   TProfile *trackangle_hist = dir->make<TProfile>(trackangle_name.str().c_str(), (trackangle_name.str() + std::string(" (mm)")).c_str(), 100, -0.5, 0.5);
00128   TProfile *trackposition_hist = dir->make<TProfile>(trackposition_name.str().c_str(), (trackposition_name.str() + std::string(" (mm)")).c_str(), 100, -300., 300.);
00129 
00130   angleerror_hist->SetAxisRange(-100., 100., "Y");
00131   trackangle_hist->SetAxisRange(-10., 10., "Y");
00132   trackposition_hist->SetAxisRange(-10., 10., "Y");
00133 
00134   narrowed_name << "fit";
00135   angleerror_name << "fit";
00136   trackangle_name << "fit";
00137   trackposition_name << "fit";
00138 
00139   double scale_factor = double(numResiduals()) * (100. - -100.)/100;   // (max - min)/nbins
00140 
00141   TF1 *narrowed_fit = NULL;
00142   if (residualsModel() == kPureGaussian) {
00143     narrowed_fit = new TF1(narrowed_name.str().c_str(), MuonResidualsFitter_pureGaussian_TF1, -100., 100., 3);
00144     narrowed_fit->SetParameters(scale_factor, value(kPosition) * 10., value(kSigma) * 10.);
00145     narrowed_fit->Write();
00146   }
00147   else if (residualsModel() == kPowerLawTails) {
00148     narrowed_fit = new TF1(narrowed_name.str().c_str(), MuonResidualsFitter_powerLawTails_TF1, -100., 100., 4);
00149     narrowed_fit->SetParameters(scale_factor, value(kPosition) * 10., value(kSigma) * 10., value(kGamma) * 10.);
00150     narrowed_fit->Write();
00151   }
00152   else if (residualsModel() == kROOTVoigt) {
00153     narrowed_fit = new TF1(narrowed_name.str().c_str(), MuonResidualsFitter_ROOTVoigt_TF1, -100., 100., 4);
00154     narrowed_fit->SetParameters(scale_factor, value(kPosition) * 10., value(kSigma) * 10., value(kGamma) * 10.);
00155     narrowed_fit->Write();
00156   }
00157   else if (residualsModel() == kGaussPowerTails) {
00158     narrowed_fit = new TF1(narrowed_name.str().c_str(), MuonResidualsFitter_GaussPowerTails_TF1, -100., 100., 3);
00159     narrowed_fit->SetParameters(scale_factor, value(kPosition) * 10., value(kSigma) * 10.);
00160     narrowed_fit->Write();
00161   }
00162 
00163   TF1 *angleerror_fit = new TF1(angleerror_name.str().c_str(), "[0]+x*[1]", -30., 30.);
00164   angleerror_fit->SetParameters(value(kPosition) * 10., value(kScattering) * 10./1000.);
00165   angleerror_fit->Write();
00166 
00167   TF1 *trackangle_fit = new TF1(trackangle_name.str().c_str(), "[0]+x*[1]", -0.5, 0.5);
00168   trackangle_fit->SetParameters(value(kPosition) * 10., value(kZpos) * 10.);
00169   trackangle_fit->Write();
00170 
00171   TF1 *trackposition_fit = new TF1(trackposition_name.str().c_str(), "[0]+x*[1]", -300., 300.);
00172   trackposition_fit->SetParameters(value(kPosition) * 10., value(kPhiz) * 10.);
00173   trackposition_fit->Write();
00174 
00175   for (std::vector<double*>::const_iterator resiter = residuals_begin();  resiter != residuals_end();  ++resiter) {
00176     const double raw_residual = (*resiter)[kResidual];
00177     const double angleerror = (*resiter)[kAngleError];
00178     const double trackangle = (*resiter)[kTrackAngle];
00179     const double trackposition = (*resiter)[kTrackPosition];
00180 
00181     double angleerror_correction = value(kScattering) * angleerror;
00182     double trackangle_correction = value(kZpos) * trackangle;
00183     double trackposition_correction = value(kPhiz) * trackposition;
00184 
00185     double corrected_residual = raw_residual - angleerror_correction - trackangle_correction - trackposition_correction;
00186 
00187     raw_hist->Fill(raw_residual * 10.);
00188     narrowed_hist->Fill(corrected_residual * 10.);
00189     
00190     angleerror_hist->Fill(angleerror*1000., (raw_residual - trackangle_correction - trackposition_correction) * 10.);
00191     trackangle_hist->Fill(trackangle, (raw_residual - angleerror_correction - trackposition_correction) * 10.);
00192     trackposition_hist->Fill(trackposition, (raw_residual - angleerror_correction - trackangle_correction) * 10.);
00193   }
00194 
00195   return 0.;
00196 }