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