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();
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
00052
00053
00054
00055 if (fabs(residual) < 10.) {
00056 sum_x += residual;
00057 sum_xx += residual*residual;
00058 N++;
00059 }
00060 }
00061
00062 if (N < m_minHits) return false;
00063
00064
00065 double mean = sum_x/double(N);
00066 double stdev = sqrt(sum_xx/double(N) - pow(sum_x/double(N), 2));
00067
00068
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;
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 }