CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/Alignment/MuonAlignmentAlgorithms/src/MuonResidualsAngleFitter.cc

Go to the documentation of this file.
00001 #include "Alignment/MuonAlignmentAlgorithms/interface/MuonResidualsAngleFitter.h"
00002 
00003 static TMinuit *MuonResidualsAngleFitter_TMinuit;
00004 
00005 void MuonResidualsAngleFitter::inform(TMinuit *tMinuit) {
00006   MuonResidualsAngleFitter_TMinuit = tMinuit;
00007 }
00008 
00009 void MuonResidualsAngleFitter_FCN(int &npar, double *gin, double &fval, double *par, int iflag) {
00010   MuonResidualsFitterFitInfo *fitinfo = (MuonResidualsFitterFitInfo*)(MuonResidualsAngleFitter_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)[MuonResidualsAngleFitter::kResidual];
00016     const double xangle = (*resiter)[MuonResidualsAngleFitter::kXAngle];
00017     const double yangle = (*resiter)[MuonResidualsAngleFitter::kYAngle];
00018     
00019     double center = 0.;
00020     center += par[MuonResidualsAngleFitter::kAngle];
00021     center += par[MuonResidualsAngleFitter::kXControl] * xangle;
00022     center += par[MuonResidualsAngleFitter::kYControl] * yangle;
00023     
00024     if (fitter->residualsModel() == MuonResidualsFitter::kPureGaussian) {
00025       fval += -MuonResidualsFitter_logPureGaussian(residual, center, par[MuonResidualsAngleFitter::kSigma]);
00026     }
00027     else if (fitter->residualsModel() == MuonResidualsFitter::kPowerLawTails) {
00028       fval += -MuonResidualsFitter_logPowerLawTails(residual, center, par[MuonResidualsAngleFitter::kSigma], par[MuonResidualsAngleFitter::kGamma]);
00029     }
00030     else if (fitter->residualsModel() == MuonResidualsFitter::kROOTVoigt) {
00031       fval += -MuonResidualsFitter_logROOTVoigt(residual, center, par[MuonResidualsAngleFitter::kSigma], par[MuonResidualsAngleFitter::kGamma]);
00032     }
00033     else if (fitter->residualsModel() == MuonResidualsFitter::kGaussPowerTails) {
00034       fval += -MuonResidualsFitter_logGaussPowerTails(residual, center, par[MuonResidualsAngleFitter::kSigma]);
00035     }
00036     else { assert(false); }
00037   }
00038 }
00039 
00040 bool MuonResidualsAngleFitter::fit(Alignable *ali) {
00041   initialize_table();  // if not already initialized
00042 
00043   double sum_x = 0.;
00044   double sum_xx = 0.;
00045   int N = 0;
00046 
00047   for (std::vector<double*>::const_iterator resiter = residuals_begin();  resiter != residuals_end();  ++resiter) {
00048     const double residual = (*resiter)[kResidual];
00049 //     const double xangle = (*resiter)[kXAngle];
00050 //     const double yangle = (*resiter)[kYAngle];
00051 
00052     if (fabs(residual) < 0.1) {  // truncate at 100 mrad
00053       sum_x += residual;
00054       sum_xx += residual*residual;
00055       N++;
00056     }
00057   }
00058 
00059   if (N < m_minHits) return false;
00060 
00061   // truncated mean and stdev to seed the fit
00062   double mean = sum_x/double(N);
00063   double stdev = sqrt(sum_xx/double(N) - pow(sum_x/double(N), 2));
00064 
00065   // refine the standard deviation calculation
00066   sum_x = 0.;
00067   sum_xx = 0.;
00068   N = 0;
00069   for (std::vector<double*>::const_iterator resiter = residuals_begin();  resiter != residuals_end();  ++resiter) {
00070     const double residual = (*resiter)[kResidual];
00071     if (mean - 1.5*stdev < residual  &&  residual < mean + 1.5*stdev) {
00072       sum_x += residual;
00073       sum_xx += residual*residual;
00074       N++;
00075     }
00076   }
00077   mean = sum_x/double(N);
00078   stdev = sqrt(sum_xx/double(N) - pow(sum_x/double(N), 2));
00079 
00080   sum_x = 0.;
00081   sum_xx = 0.;
00082   N = 0;
00083   for (std::vector<double*>::const_iterator resiter = residuals_begin();  resiter != residuals_end();  ++resiter) {
00084     const double residual = (*resiter)[kResidual];
00085     if (mean - 1.5*stdev < residual  &&  residual < mean + 1.5*stdev) {
00086       sum_x += residual;
00087       sum_xx += residual*residual;
00088       N++;
00089     }
00090   }
00091   mean = sum_x/double(N);
00092   stdev = sqrt(sum_xx/double(N) - pow(sum_x/double(N), 2));
00093 
00094   std::vector<int> parNum;
00095   std::vector<std::string> parName;
00096   std::vector<double> start;
00097   std::vector<double> step;
00098   std::vector<double> low;
00099   std::vector<double> high;
00100 
00101   parNum.push_back(kAngle);     parName.push_back(std::string("angle"));     start.push_back(mean);     step.push_back(0.1);               low.push_back(0.);    high.push_back(0.);
00102   parNum.push_back(kXControl);  parName.push_back(std::string("xcontrol"));  start.push_back(0.);       step.push_back(0.1);               low.push_back(0.);    high.push_back(0.);
00103   parNum.push_back(kYControl);  parName.push_back(std::string("ycontrol"));  start.push_back(0.);       step.push_back(0.1);               low.push_back(0.);    high.push_back(0.);
00104   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.);
00105   if (residualsModel() != kPureGaussian && residualsModel() != kGaussPowerTails) {
00106   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.);
00107   }
00108 
00109   return dofit(&MuonResidualsAngleFitter_FCN, parNum, parName, start, step, low, high);
00110 }
00111 
00112 double MuonResidualsAngleFitter::plot(std::string name, TFileDirectory *dir, Alignable *ali) {
00113   std::stringstream raw_name, narrowed_name, xcontrol_name, ycontrol_name;
00114   raw_name << name << "_raw";
00115   narrowed_name << name << "_narrowed";
00116   xcontrol_name << name << "_xcontrol";
00117   ycontrol_name << name << "_ycontrol";
00118 
00119   TH1F *raw_hist = dir->make<TH1F>(raw_name.str().c_str(), (raw_name.str() + std::string(" (mrad)")).c_str(), 100, -100., 100.);
00120   TH1F *narrowed_hist = dir->make<TH1F>(narrowed_name.str().c_str(), (narrowed_name.str() + std::string(" (mrad)")).c_str(), 100, -100., 100.);
00121   TProfile *xcontrol_hist = dir->make<TProfile>(xcontrol_name.str().c_str(), (xcontrol_name.str() + std::string(" (mrad)")).c_str(), 100, -1., 1.);
00122   TProfile *ycontrol_hist = dir->make<TProfile>(ycontrol_name.str().c_str(), (ycontrol_name.str() + std::string(" (mrad)")).c_str(), 100, -1., 1.);
00123 
00124   narrowed_name << "fit";
00125   xcontrol_name << "fit";
00126   ycontrol_name << "fit";
00127 
00128   double scale_factor = double(numResiduals()) * (100. - -100.)/100;   // (max - min)/nbins
00129 
00130   TF1 *narrowed_fit = NULL;
00131   if (residualsModel() == kPureGaussian) {
00132     narrowed_fit = new TF1(narrowed_name.str().c_str(), MuonResidualsFitter_pureGaussian_TF1, -100., 100., 3);
00133     narrowed_fit->SetParameters(scale_factor, value(kAngle) * 1000., value(kSigma) * 1000.);
00134     narrowed_fit->Write();
00135   }
00136   else if (residualsModel() == kPowerLawTails) {
00137     narrowed_fit = new TF1(narrowed_name.str().c_str(), MuonResidualsFitter_powerLawTails_TF1, -100., 100., 4);
00138     narrowed_fit->SetParameters(scale_factor, value(kAngle) * 1000., value(kSigma) * 1000., value(kGamma) * 1000.);
00139     narrowed_fit->Write();
00140   }
00141   else if (residualsModel() == kROOTVoigt) {
00142     narrowed_fit = new TF1(narrowed_name.str().c_str(), MuonResidualsFitter_ROOTVoigt_TF1, -100., 100., 4);
00143     narrowed_fit->SetParameters(scale_factor, value(kAngle) * 1000., value(kSigma) * 1000., value(kGamma) * 1000.);
00144     narrowed_fit->Write();
00145   }
00146   else if (residualsModel() == kGaussPowerTails) {
00147     narrowed_fit = new TF1(narrowed_name.str().c_str(), MuonResidualsFitter_GaussPowerTails_TF1, -100., 100., 3);
00148     narrowed_fit->SetParameters(scale_factor, value(kAngle) * 1000., value(kSigma) * 1000.);
00149     narrowed_fit->Write();
00150   }
00151 
00152   TF1 *xcontrol_fit = new TF1(xcontrol_name.str().c_str(), "[0]+x*[1]", -1., 1.);
00153   xcontrol_fit->SetParameters(value(kAngle) * 1000., value(kXControl) * 1000.);
00154   xcontrol_fit->Write();
00155 
00156   TF1 *ycontrol_fit = new TF1(ycontrol_name.str().c_str(), "[0]+x*[1]", -1., 1.);
00157   ycontrol_fit->SetParameters(value(kAngle) * 1000., value(kYControl) * 1000.);
00158   ycontrol_fit->Write();
00159 
00160   for (std::vector<double*>::const_iterator resiter = residuals_begin();  resiter != residuals_end();  ++resiter) {
00161     const double raw_residual = (*resiter)[kResidual];
00162     const double xangle = (*resiter)[kXAngle];
00163     const double yangle = (*resiter)[kYAngle];
00164 
00165     double xangle_correction = value(kXControl) * xangle;
00166     double yangle_correction = value(kYControl) * yangle;
00167     double corrected_residual = raw_residual - xangle_correction - yangle_correction;
00168 
00169     raw_hist->Fill(raw_residual * 1000.);
00170     narrowed_hist->Fill(corrected_residual * 1000.);
00171 
00172     xcontrol_hist->Fill(xangle, (raw_residual - yangle_correction) * 1000.);
00173     ycontrol_hist->Fill(yangle, (raw_residual - xangle_correction) * 1000.);
00174   }
00175 
00176   return 0.;
00177 }