CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/Alignment/MuonAlignmentAlgorithms/src/MuonResiduals5DOFFitter.cc

Go to the documentation of this file.
00001 // $Id: MuonResiduals5DOFFitter.cc,v 1.9 2011/10/12 23:44:11 khotilov Exp $
00002 
00003 #ifdef STANDALONE_FITTER
00004 #include "MuonResiduals5DOFFitter.h"
00005 #else
00006 #include "Alignment/MuonAlignmentAlgorithms/interface/MuonResiduals5DOFFitter.h"
00007 #endif
00008 
00009 #include "TH2F.h"
00010 #include "TMath.h"
00011 #include "TTree.h"
00012 #include "TFile.h"
00013 
00014 namespace
00015 {
00016   TMinuit *minuit;
00017 
00018   double sum_of_weights;
00019   double number_of_hits;
00020   bool weight_alignment;
00021 
00022   double residual_x(double delta_x, double delta_z,
00023                     double delta_phix, double delta_phiy, double delta_phiz,
00024                     double track_x, double track_y, double track_dxdz, double track_dydz,
00025                     double alpha, double resslope)
00026   {
00027     return delta_x
00028         - track_dxdz * delta_z
00029         - track_y * track_dxdz * delta_phix
00030         + track_x * track_dxdz * delta_phiy
00031         - track_y * delta_phiz
00032         + resslope * alpha;
00033   }
00034 
00035   double residual_dxdz(double delta_x, double delta_z,
00036                        double delta_phix, double delta_phiy, double delta_phiz,
00037                        double track_x, double track_y, double track_dxdz, double track_dydz)
00038   {
00039     return -track_dxdz * track_dydz * delta_phix
00040         + (1. + track_dxdz * track_dxdz) * delta_phiy
00041         - track_dydz * delta_phiz;
00042   }
00043 
00044   Double_t residual_x_trackx_TF1(Double_t *xx, Double_t *p) { return 10.*residual_x(p[0], p[2], p[3], p[4], p[5], xx[0], p[7], p[8], p[9], p[10], p[11]); }
00045   Double_t residual_x_tracky_TF1(Double_t *xx, Double_t *p) { return 10.*residual_x(p[0], p[2], p[3], p[4], p[5], p[6], xx[0], p[8], p[9], p[10], p[11]); }
00046   Double_t residual_x_trackdxdz_TF1(Double_t *xx, Double_t *p) { return 10.*residual_x(p[0], p[2], p[3], p[4], p[5], p[6], p[7], xx[0], p[9], p[10], p[11]); }
00047   Double_t residual_x_trackdydz_TF1(Double_t *xx, Double_t *p) { return 10.*residual_x(p[0], p[2], p[3], p[4], p[5], p[6], p[7], p[8], xx[0], p[10], p[11]); }
00048 
00049   Double_t residual_dxdz_trackx_TF1(Double_t *xx, Double_t *p) { return 1000.*residual_dxdz(p[0], p[2], p[3], p[4], p[5], xx[0], p[7], p[8], p[9]); }
00050   Double_t residual_dxdz_tracky_TF1(Double_t *xx, Double_t *p) { return 1000.*residual_dxdz(p[0], p[2], p[3], p[4], p[5], p[6], xx[0], p[8], p[9]); }
00051   Double_t residual_dxdz_trackdxdz_TF1(Double_t *xx, Double_t *p) { return 1000.*residual_dxdz(p[0], p[2], p[3], p[4], p[5], p[6], p[7], xx[0], p[9]); }
00052   Double_t residual_dxdz_trackdydz_TF1(Double_t *xx, Double_t *p) { return 1000.*residual_dxdz(p[0], p[2], p[3], p[4], p[5], p[6], p[7], p[8], xx[0]); }
00053 }
00054 
00055 
00056 void MuonResiduals5DOFFitter_FCN(int &npar, double *gin, double &fval, double *par, int iflag)
00057 {
00058   MuonResidualsFitterFitInfo *fitinfo = (MuonResidualsFitterFitInfo*)(minuit->GetObjectFit());
00059   MuonResidualsFitter *fitter = fitinfo->fitter();
00060 
00061   fval = 0.;
00062   for (std::vector<double*>::const_iterator resiter = fitter->residuals_begin();  resiter != fitter->residuals_end();  ++resiter)
00063   {
00064     const double residual = (*resiter)[MuonResiduals5DOFFitter::kResid];
00065     const double resslope = (*resiter)[MuonResiduals5DOFFitter::kResSlope];
00066     const double positionX = (*resiter)[MuonResiduals5DOFFitter::kPositionX];
00067     const double positionY = (*resiter)[MuonResiduals5DOFFitter::kPositionY];
00068     const double angleX = (*resiter)[MuonResiduals5DOFFitter::kAngleX];
00069     const double angleY = (*resiter)[MuonResiduals5DOFFitter::kAngleY];
00070     const double redchi2 = (*resiter)[MuonResiduals5DOFFitter::kRedChi2];
00071 
00072     const double alignx = par[MuonResiduals5DOFFitter::kAlignX];
00073     const double alignz = par[MuonResiduals5DOFFitter::kAlignZ];
00074     const double alignphix = par[MuonResiduals5DOFFitter::kAlignPhiX];
00075     const double alignphiy = par[MuonResiduals5DOFFitter::kAlignPhiY];
00076     const double alignphiz = par[MuonResiduals5DOFFitter::kAlignPhiZ];
00077     const double residsigma = par[MuonResiduals5DOFFitter::kResidSigma];
00078     const double resslopesigma = par[MuonResiduals5DOFFitter::kResSlopeSigma];
00079     const double alpha = par[MuonResiduals5DOFFitter::kAlpha];
00080     const double residgamma = par[MuonResiduals5DOFFitter::kResidGamma];
00081     const double resslopegamma = par[MuonResiduals5DOFFitter::kResSlopeGamma];
00082 
00083     double coeff = alpha;
00084     if (fitter->residualsModel() == MuonResidualsFitter::kPureGaussian ||
00085         fitter->residualsModel() == MuonResidualsFitter::kPureGaussian2D) coeff = 0.;
00086     double residpeak = residual_x(alignx, alignz, alignphix, alignphiy, alignphiz, positionX, positionY, angleX, angleY, coeff, resslope);
00087     double resslopepeak = residual_dxdz(alignx, alignz, alignphix, alignphiy, alignphiz, positionX, positionY, angleX, angleY);
00088 
00089     double weight = (1./redchi2) * number_of_hits / sum_of_weights;
00090     if (!weight_alignment) weight = 1.;
00091 
00092     if (!weight_alignment  ||  TMath::Prob(redchi2*8, 8) < 0.99)  // no spikes allowed
00093     {
00094       if (fitter->residualsModel() == MuonResidualsFitter::kPureGaussian) {
00095         if (fitter->useRes() == MuonResidualsFitter::k1111 || fitter->useRes() == MuonResidualsFitter::k1110 || fitter->useRes() == MuonResidualsFitter::k1010) {
00096           fval += -weight * MuonResidualsFitter_logPureGaussian(residual, residpeak, residsigma);
00097           fval += -weight * MuonResidualsFitter_logPureGaussian(resslope, resslopepeak, resslopesigma);
00098         }
00099         else if (fitter->useRes() == MuonResidualsFitter::k1100) {
00100           fval += -weight * MuonResidualsFitter_logPureGaussian(residual, residpeak, residsigma);
00101         }
00102         else if (fitter->useRes() == MuonResidualsFitter::k0010) {
00103           fval += -weight * MuonResidualsFitter_logPureGaussian(resslope, resslopepeak, resslopesigma);
00104         }
00105       }
00106       else if (fitter->residualsModel() == MuonResidualsFitter::kPureGaussian2D) {
00107         if (fitter->useRes() == MuonResidualsFitter::k1111 || fitter->useRes() == MuonResidualsFitter::k1110 || fitter->useRes() == MuonResidualsFitter::k1010) {
00108           fval += -weight * MuonResidualsFitter_logPureGaussian2D(residual, resslope, residpeak, resslopepeak, residsigma, resslopesigma, alpha);
00109         }
00110         else if (fitter->useRes() == MuonResidualsFitter::k1100) {
00111           fval += -weight * MuonResidualsFitter_logPureGaussian(residual, residpeak, residsigma);
00112         }
00113         else if (fitter->useRes() == MuonResidualsFitter::k0010) {
00114           fval += -weight * MuonResidualsFitter_logPureGaussian(resslope, resslopepeak, resslopesigma);
00115         }
00116       }
00117       else if (fitter->residualsModel() == MuonResidualsFitter::kPowerLawTails) {
00118         fval += -weight * MuonResidualsFitter_logPowerLawTails(residual, residpeak, residsigma, residgamma);
00119         fval += -weight * MuonResidualsFitter_logPowerLawTails(resslope, resslopepeak, resslopesigma, resslopegamma);
00120       }
00121       else if (fitter->residualsModel() == MuonResidualsFitter::kROOTVoigt) {
00122         fval += -weight * MuonResidualsFitter_logROOTVoigt(residual, residpeak, residsigma, residgamma);
00123         fval += -weight * MuonResidualsFitter_logROOTVoigt(resslope, resslopepeak, resslopesigma, resslopegamma);
00124       }
00125       else if (fitter->residualsModel() == MuonResidualsFitter::kGaussPowerTails) {
00126         fval += -weight * MuonResidualsFitter_logGaussPowerTails(residual, residpeak, residsigma);
00127         fval += -weight * MuonResidualsFitter_logGaussPowerTails(resslope, resslopepeak, resslopesigma);
00128       }
00129       else { assert(false); }
00130     }
00131   }
00132 }
00133 
00134 
00135 void MuonResiduals5DOFFitter::correctBField()
00136 {
00137   MuonResidualsFitter::correctBField(kPt, kCharge);
00138 }
00139 
00140 
00141 void MuonResiduals5DOFFitter::inform(TMinuit *tMinuit)
00142 {
00143   minuit = tMinuit;
00144 }
00145 
00146 
00147 double MuonResiduals5DOFFitter::sumofweights()
00148 {
00149   sum_of_weights = 0.;
00150   number_of_hits = 0.;
00151   weight_alignment = m_weightAlignment;
00152   for (std::vector<double*>::const_iterator resiter = residuals_begin();  resiter != residuals_end();  ++resiter) {
00153     if (m_weightAlignment) {
00154       double redchi2 = (*resiter)[MuonResiduals5DOFFitter::kRedChi2];
00155       if (TMath::Prob(redchi2*8, 8) < 0.99) {
00156         sum_of_weights += 1./redchi2;
00157         number_of_hits += 1.;
00158       }
00159     }
00160     else {
00161       sum_of_weights += 1.;
00162       number_of_hits += 1.;
00163     }
00164   }
00165   return sum_of_weights;
00166 }
00167 
00168 
00169 bool MuonResiduals5DOFFitter::fit(Alignable *ali)
00170 {
00171   initialize_table();  // if not already initialized
00172   sumofweights();
00173 
00174   double res_std = 0.5;
00175   double resslope_std = 0.005;
00176 
00177   int nums[10]          = {kAlignX, kAlignZ, kAlignPhiX, kAlignPhiY, kAlignPhiZ,    kResidSigma, kResSlopeSigma,   kAlpha,    kResidGamma, kResSlopeGamma};
00178   std::string names[10] = {"AlignX","AlignZ","AlignPhiX","AlignPhiY","AlignPhiZ",   "ResidSigma","ResSlopeSigma",  "Alpha",   "ResidGamma","ResSlopeGamma"};
00179   double starts[10]     = {0., 0., 0., 0., 0.,              res_std, resslope_std,               0.,     0.1*res_std, 0.1*resslope_std};
00180   double steps[10]      = {0.1, 0.1, 0.001, 0.001, 0.001,   0.001*res_std, 0.001*resslope_std,   0.001,  0.01*res_std, 0.01*resslope_std};
00181   double lows[10]       = {0., 0., 0., 0., 0.,    0., 0.,      -1.,   0., 0.};
00182   double highs[10]      = {0., 0., 0., 0., 0.,    10., 0.1,     1.,   0., 0.};
00183 
00184   std::vector<int> num(nums, nums+5);
00185   std::vector<std::string> name(names, names+5);
00186   std::vector<double> start(starts, starts+5);
00187   std::vector<double> step(steps, steps+5);
00188   std::vector<double> low(lows, lows+5);
00189   std::vector<double> high(highs, highs+5);
00190 
00191   bool add_alpha = ( residualsModel() == kPureGaussian2D);
00192   bool add_gamma = ( residualsModel() == kROOTVoigt || residualsModel() == kPowerLawTails);
00193 
00194   int idx[4], ni = 0;
00195   if (useRes() == k1111 || useRes() == k1110 || useRes() == k1010) {
00196     for(ni=0; ni<2; ni++) idx[ni] = ni+5;
00197     if (add_alpha) idx[ni++] = 7;
00198     else if (add_gamma) for(; ni<4; ni++) idx[ni] = ni+6;
00199     if (!add_alpha) fix(kAlpha);
00200   }
00201   else if (useRes() == k1100) {
00202     idx[ni++] = 5;
00203     if (add_gamma) idx[ni++] = 8;
00204     fix(kResSlopeSigma);
00205     fix(kAlpha);
00206   }
00207   else if (useRes() == k0010) {
00208     idx[ni++] = 6;
00209     if (add_gamma) idx[ni++] = 9;
00210     fix(kResidSigma);
00211     fix(kAlpha);
00212   }
00213   for (int i=0; i<ni; i++){
00214     num.push_back(nums[idx[i]]);
00215     name.push_back(names[idx[i]]);
00216     start.push_back(starts[idx[i]]);
00217     step.push_back(steps[idx[i]]);
00218     low.push_back(lows[idx[i]]);
00219     high.push_back(highs[idx[i]]);
00220   }
00221 
00222   return dofit(&MuonResiduals5DOFFitter_FCN, num, name, start, step, low, high);
00223 }
00224 
00225 
00226 double MuonResiduals5DOFFitter::plot(std::string name, TFileDirectory *dir, Alignable *ali)
00227 {
00228   sumofweights();
00229 
00230   double mean_residual = 0., mean_resslope = 0.;
00231   double mean_trackx = 0., mean_tracky = 0., mean_trackdxdz = 0., mean_trackdydz = 0.;
00232   double sum_w = 0.;
00233 
00234   for (std::vector<double*>::const_iterator rit = residuals_begin();  rit != residuals_end();  ++rit)
00235   {
00236     const double redchi2 = (*rit)[kRedChi2];
00237     double weight = 1./redchi2;
00238     if (!m_weightAlignment) weight = 1.;
00239 
00240     if (!m_weightAlignment  ||  TMath::Prob(redchi2*6, 6) < 0.99)  // no spikes allowed
00241     {
00242       double factor_w = 1./(sum_w + weight);
00243       mean_residual  = factor_w * (sum_w * mean_residual  + weight * (*rit)[kResid]);
00244       mean_resslope  = factor_w * (sum_w * mean_resslope  + weight * (*rit)[kResSlope]);
00245       mean_trackx    = factor_w * (sum_w * mean_trackx    + weight * (*rit)[kPositionX]);
00246       mean_tracky    = factor_w * (sum_w * mean_tracky    + weight * (*rit)[kPositionY]);
00247       mean_trackdxdz = factor_w * (sum_w * mean_trackdxdz + weight * (*rit)[kAngleX]);
00248       mean_trackdydz = factor_w * (sum_w * mean_trackdydz + weight * (*rit)[kAngleY]);
00249       sum_w += weight;
00250     }
00251   }
00252 
00253   std::string name_residual, name_resslope, name_residual_raw, name_resslope_raw, name_residual_cut, name_alpha;
00254   std::string name_residual_trackx, name_resslope_trackx;
00255   std::string name_residual_tracky, name_resslope_tracky;
00256   std::string name_residual_trackdxdz, name_resslope_trackdxdz;
00257   std::string name_residual_trackdydz, name_resslope_trackdydz;
00258 
00259   name_residual = name + "_residual";
00260   name_resslope = name + "_resslope";
00261   name_residual_raw = name + "_residual_raw";
00262   name_resslope_raw = name + "_resslope_raw";
00263   name_residual_cut = name + "_residual_cut";
00264   name_alpha = name + "_alpha";
00265   name_residual_trackx = name + "_residual_trackx";
00266   name_resslope_trackx = name + "_resslope_trackx";
00267   name_residual_tracky = name + "_residual_tracky";
00268   name_resslope_tracky = name + "_resslope_tracky";
00269   name_residual_trackdxdz = name + "_residual_trackdxdz";
00270   name_resslope_trackdxdz = name + "_resslope_trackdxdz";
00271   name_residual_trackdydz = name + "_residual_trackdydz";
00272   name_resslope_trackdydz = name + "_resslope_trackdydz";
00273 
00274   double width = ali->surface().width();
00275   double length = ali->surface().length();
00276   int    bins_residual = 150, bins_resslope = 100;
00277   double min_residual = -75.,    max_residual = 75.;
00278   double min_resslope = -50.,    max_resslope = 50.;
00279   double min_trackx = -width/2.,  max_trackx = width/2.;
00280   double min_tracky = -length/2., max_tracky = length/2.;
00281   double min_trackdxdz = -1.5,    max_trackdxdz = 1.5;
00282   double min_trackdydz = -1.5,    max_trackdydz = 1.5;
00283 
00284   TH1F *hist_residual = dir->make<TH1F>(name_residual.c_str(), "", bins_residual, min_residual, max_residual);
00285   TH1F *hist_resslope = dir->make<TH1F>(name_resslope.c_str(), "", bins_resslope, min_resslope, max_resslope);
00286   TH1F *hist_residual_raw = dir->make<TH1F>(name_residual_raw.c_str(), "", bins_residual, min_residual, max_residual);
00287   TH1F *hist_resslope_raw = dir->make<TH1F>(name_resslope_raw.c_str(), "", bins_resslope, min_resslope, max_resslope);
00288   TH1F *hist_residual_cut = dir->make<TH1F>(name_residual_cut.c_str(), "", bins_residual, min_residual, max_residual);
00289   TH2F *hist_alpha = dir->make<TH2F>(name_alpha.c_str(), "", 50, min_resslope, max_resslope, 50, -50., 50.);
00290 
00291   TProfile *hist_residual_trackx = dir->make<TProfile>(name_residual_trackx.c_str(), "", 50, min_trackx, max_trackx, min_residual, max_residual);
00292   TProfile *hist_resslope_trackx = dir->make<TProfile>(name_resslope_trackx.c_str(), "", 50, min_trackx, max_trackx, min_resslope, max_resslope);
00293   TProfile *hist_residual_tracky = dir->make<TProfile>(name_residual_tracky.c_str(), "", 50, min_tracky, max_tracky, min_residual, max_residual);
00294   TProfile *hist_resslope_tracky = dir->make<TProfile>(name_resslope_tracky.c_str(), "", 50, min_tracky, max_tracky, min_resslope, max_resslope);
00295   TProfile *hist_residual_trackdxdz = dir->make<TProfile>(name_residual_trackdxdz.c_str(), "", 250, min_trackdxdz, max_trackdxdz, min_residual, max_residual);
00296   TProfile *hist_resslope_trackdxdz = dir->make<TProfile>(name_resslope_trackdxdz.c_str(), "", 250, min_trackdxdz, max_trackdxdz, min_resslope, max_resslope);
00297   TProfile *hist_residual_trackdydz = dir->make<TProfile>(name_residual_trackdydz.c_str(), "", 250, min_trackdydz, max_trackdydz, min_residual, max_residual);
00298   TProfile *hist_resslope_trackdydz = dir->make<TProfile>(name_resslope_trackdydz.c_str(), "", 250, min_trackdydz, max_trackdydz, min_resslope, max_resslope);
00299 
00300   hist_residual_trackx->SetAxisRange(-10., 10., "Y");
00301   hist_resslope_trackx->SetAxisRange(-10., 10., "Y");
00302   hist_residual_tracky->SetAxisRange(-10., 10., "Y");
00303   hist_resslope_tracky->SetAxisRange(-10., 10., "Y");
00304   hist_residual_trackdxdz->SetAxisRange(-10., 10., "Y");
00305   hist_resslope_trackdxdz->SetAxisRange(-10., 10., "Y");
00306   hist_residual_trackdydz->SetAxisRange(-10., 10., "Y");
00307   hist_resslope_trackdydz->SetAxisRange(-10., 10., "Y");
00308 
00309   name_residual += "_fit";
00310   name_resslope += "_fit";
00311   name_alpha += "_fit";
00312   name_residual_trackx += "_fit";
00313   name_resslope_trackx += "_fit";
00314   name_residual_tracky += "_fit";
00315   name_resslope_tracky += "_fit";
00316   name_residual_trackdxdz += "_fit";
00317   name_resslope_trackdxdz += "_fit";
00318   name_residual_trackdydz += "_fit";
00319   name_resslope_trackdydz += "_fit";
00320 
00321   TF1 *fit_residual = NULL;
00322   TF1 *fit_resslope = NULL;
00323   if (residualsModel() == kPureGaussian || residualsModel() == kPureGaussian2D) {
00324     fit_residual = new TF1(name_residual.c_str(), MuonResidualsFitter_pureGaussian_TF1, min_residual, max_residual, 3);
00325     fit_residual->SetParameters(sum_of_weights * (max_residual - min_residual)/bins_residual, 10.*value(kAlignX), 10.*value(kResidSigma));
00326     const double er_res[3] = {0., 10.*errorerror(kAlignX), 10.*errorerror(kResidSigma)};
00327     fit_residual->SetParErrors(er_res);
00328     fit_resslope = new TF1(name_resslope.c_str(), MuonResidualsFitter_pureGaussian_TF1, min_resslope, max_resslope, 3);
00329     fit_resslope->SetParameters(sum_of_weights * (max_resslope - min_resslope)/bins_resslope, 1000.*value(kAlignPhiY), 1000.*value(kResSlopeSigma));
00330     const double er_resslope[3] = {0., 1000.*errorerror(kAlignPhiY), 1000.*errorerror(kResSlopeSigma)};
00331     fit_resslope->SetParErrors(er_resslope);
00332   }
00333   else if (residualsModel() == kPowerLawTails) {
00334     fit_residual = new TF1(name_residual.c_str(), MuonResidualsFitter_powerLawTails_TF1, min_residual, max_residual, 4);
00335     fit_residual->SetParameters(sum_of_weights * (max_residual - min_residual)/bins_residual, 10.*value(kAlignX), 10.*value(kResidSigma), 10.*value(kResidGamma));
00336     fit_resslope = new TF1(name_resslope.c_str(), MuonResidualsFitter_powerLawTails_TF1, min_resslope, max_resslope, 4);
00337     fit_resslope->SetParameters(sum_of_weights * (max_resslope - min_resslope)/bins_resslope, 1000.*value(kAlignPhiY), 1000.*value(kResSlopeSigma), 1000.*value(kResSlopeGamma));
00338   }
00339   else if (residualsModel() == kROOTVoigt) {
00340     fit_residual = new TF1(name_residual.c_str(), MuonResidualsFitter_ROOTVoigt_TF1, min_residual, max_residual, 4);
00341     fit_residual->SetParameters(sum_of_weights * (max_residual - min_residual)/bins_residual, 10.*value(kAlignX), 10.*value(kResidSigma), 10.*value(kResidGamma));
00342     fit_resslope = new TF1(name_resslope.c_str(), MuonResidualsFitter_ROOTVoigt_TF1, min_resslope, max_resslope, 4);
00343     fit_resslope->SetParameters(sum_of_weights * (max_resslope - min_resslope)/bins_resslope, 1000.*value(kAlignPhiY), 1000.*value(kResSlopeSigma), 1000.*value(kResSlopeGamma));
00344   }
00345   else if (residualsModel() == kGaussPowerTails) {
00346     fit_residual = new TF1(name_residual.c_str(), MuonResidualsFitter_GaussPowerTails_TF1, min_residual, max_residual, 3);
00347     fit_residual->SetParameters(sum_of_weights * (max_residual - min_residual)/bins_residual, 10.*value(kAlignX), 10.*value(kResidSigma));
00348     fit_resslope = new TF1(name_resslope.c_str(), MuonResidualsFitter_GaussPowerTails_TF1, min_resslope, max_resslope, 3);
00349     fit_resslope->SetParameters(sum_of_weights * (max_resslope - min_resslope)/bins_resslope, 1000.*value(kAlignPhiY), 1000.*value(kResSlopeSigma));
00350   }
00351   else { assert(false); }
00352 
00353   fit_residual->SetLineColor(2);  fit_residual->SetLineWidth(2);  fit_residual->Write();
00354   fit_resslope->SetLineColor(2);  fit_resslope->SetLineWidth(2);  fit_resslope->Write();
00355 
00356   TF1 *fit_alpha = new TF1(name_alpha.c_str(), "[0] + x*[1]", min_resslope, max_resslope);
00357   double a = 10.*value(kAlignX), b = 10.*value(kAlpha)/1000.;
00358   if (residualsModel() == kPureGaussian2D)
00359   {
00360     double sx = 10.*value(kResidSigma), sy = 1000.*value(kResSlopeSigma), r = value(kAlpha);
00361     a = mean_residual;
00362     b = 0.;
00363     if ( sx != 0. )
00364     {
00365       b = 1./(sy/sx*r);
00366       a = - b * mean_resslope;
00367     }
00368   }
00369   fit_alpha->SetParameters(a, b);
00370   fit_alpha->SetLineColor(2);  fit_alpha->SetLineWidth(2);  fit_alpha->Write();
00371 
00372   TProfile *fit_residual_trackx = dir->make<TProfile>(name_residual_trackx.c_str(), "", 50, min_trackx, max_trackx);
00373   TProfile *fit_resslope_trackx = dir->make<TProfile>(name_resslope_trackx.c_str(), "", 50, min_trackx, max_trackx);
00374   TProfile *fit_residual_tracky = dir->make<TProfile>(name_residual_tracky.c_str(), "", 50, min_tracky, max_tracky);
00375   TProfile *fit_resslope_tracky = dir->make<TProfile>(name_resslope_tracky.c_str(), "", 50, min_tracky, max_tracky);
00376   TProfile *fit_residual_trackdxdz = dir->make<TProfile>(name_residual_trackdxdz.c_str(), "", 250, min_trackdxdz, max_trackdxdz);
00377   TProfile *fit_resslope_trackdxdz = dir->make<TProfile>(name_resslope_trackdxdz.c_str(), "", 250, min_trackdxdz, max_trackdxdz);
00378   TProfile *fit_residual_trackdydz = dir->make<TProfile>(name_residual_trackdydz.c_str(), "", 250, min_trackdydz, max_trackdydz);
00379   TProfile *fit_resslope_trackdydz = dir->make<TProfile>(name_resslope_trackdydz.c_str(), "", 250, min_trackdydz, max_trackdydz);
00380 
00381   fit_residual_trackx->SetLineColor(2);     fit_residual_trackx->SetLineWidth(2);
00382   fit_resslope_trackx->SetLineColor(2);     fit_resslope_trackx->SetLineWidth(2);
00383   fit_residual_tracky->SetLineColor(2);     fit_residual_tracky->SetLineWidth(2);
00384   fit_resslope_tracky->SetLineColor(2);     fit_resslope_tracky->SetLineWidth(2);
00385   fit_residual_trackdxdz->SetLineColor(2);  fit_residual_trackdxdz->SetLineWidth(2);
00386   fit_resslope_trackdxdz->SetLineColor(2);  fit_resslope_trackdxdz->SetLineWidth(2);
00387   fit_residual_trackdydz->SetLineColor(2);  fit_residual_trackdydz->SetLineWidth(2);
00388   fit_resslope_trackdydz->SetLineColor(2);  fit_resslope_trackdydz->SetLineWidth(2);
00389 
00390   name_residual_trackx += "line";
00391   name_resslope_trackx += "line";
00392   name_residual_tracky += "line";
00393   name_resslope_tracky += "line";
00394   name_residual_trackdxdz += "line";
00395   name_resslope_trackdxdz += "line";
00396   name_residual_trackdydz += "line";
00397   name_resslope_trackdydz += "line";
00398 
00399   TF1 *fitline_residual_trackx = new TF1(name_residual_trackx.c_str(), residual_x_trackx_TF1, min_trackx, max_trackx, 12);
00400   TF1 *fitline_resslope_trackx = new TF1(name_resslope_trackx.c_str(), residual_dxdz_trackx_TF1, min_trackx, max_trackx, 12);
00401   TF1 *fitline_residual_tracky = new TF1(name_residual_tracky.c_str(), residual_x_tracky_TF1, min_tracky, max_tracky, 12);
00402   TF1 *fitline_resslope_tracky = new TF1(name_resslope_tracky.c_str(), residual_dxdz_tracky_TF1, min_tracky, max_tracky, 12);
00403   TF1 *fitline_residual_trackdxdz = new TF1(name_residual_trackdxdz.c_str(), residual_x_trackdxdz_TF1, min_trackdxdz, max_trackdxdz, 12);
00404   TF1 *fitline_resslope_trackdxdz = new TF1(name_resslope_trackdxdz.c_str(), residual_dxdz_trackdxdz_TF1, min_trackdxdz, max_trackdxdz, 12);
00405   TF1 *fitline_residual_trackdydz = new TF1(name_residual_trackdydz.c_str(), residual_x_trackdydz_TF1, min_trackdydz, max_trackdydz, 12);
00406   TF1 *fitline_resslope_trackdydz = new TF1(name_resslope_trackdydz.c_str(), residual_dxdz_trackdydz_TF1, min_trackdydz, max_trackdydz, 12);
00407 
00408   std::vector<TF1*> fitlines;
00409   fitlines.push_back(fitline_residual_trackx);
00410   fitlines.push_back(fitline_resslope_trackx);
00411   fitlines.push_back(fitline_residual_tracky);
00412   fitlines.push_back(fitline_resslope_tracky);
00413   fitlines.push_back(fitline_residual_trackdxdz);
00414   fitlines.push_back(fitline_resslope_trackdxdz);
00415   fitlines.push_back(fitline_residual_trackdydz);
00416   fitlines.push_back(fitline_resslope_trackdydz);
00417 
00418   double fitparameters[12] = {value(kAlignX), 0., value(kAlignZ), value(kAlignPhiX), value(kAlignPhiY), value(kAlignPhiZ),
00419                               mean_trackx, mean_tracky, mean_trackdxdz, mean_trackdydz, value(kAlpha), mean_resslope};
00420   if (residualsModel() == kPureGaussian2D) fitparameters[10] = 0.;
00421 
00422   for(std::vector<TF1*>::const_iterator itr = fitlines.begin(); itr != fitlines.end(); itr++)
00423   {
00424     (*itr)->SetParameters(fitparameters);
00425     (*itr)->SetLineColor(2);
00426     (*itr)->SetLineWidth(2);
00427     (*itr)->Write();
00428   }
00429 
00430   for (std::vector<double*>::const_iterator resiter = residuals_begin();  resiter != residuals_end();  ++resiter) {
00431     const double resid = (*resiter)[kResid];
00432     const double resslope = (*resiter)[kResSlope];
00433     const double positionX = (*resiter)[kPositionX];
00434     const double positionY = (*resiter)[kPositionY];
00435     const double angleX = (*resiter)[kAngleX];
00436     const double angleY = (*resiter)[kAngleY];
00437     const double redchi2 = (*resiter)[kRedChi2];
00438     double weight = 1./redchi2;
00439     if (!m_weightAlignment) weight = 1.;
00440 
00441     if (!m_weightAlignment  ||  TMath::Prob(redchi2*8, 8) < 0.99) {  // no spikes allowed
00442       hist_alpha->Fill(1000.*resslope, 10.*resid);
00443 
00444       double coeff = value(kAlpha);
00445       if (residualsModel() == kPureGaussian || residualsModel() == kPureGaussian2D) coeff = 0.;
00446       double geom_resid = residual_x(value(kAlignX), value(kAlignZ), value(kAlignPhiX), value(kAlignPhiY), value(kAlignPhiZ), positionX, positionY, angleX, angleY, coeff, resslope);
00447       hist_residual->Fill(10.*(resid - geom_resid + value(kAlignX)), weight);
00448       hist_residual_trackx->Fill(positionX, 10.*resid, weight);
00449       hist_residual_tracky->Fill(positionY, 10.*resid, weight);
00450       hist_residual_trackdxdz->Fill(angleX, 10.*resid, weight);
00451       hist_residual_trackdydz->Fill(angleY, 10.*resid, weight);
00452       fit_residual_trackx->Fill(positionX, 10.*geom_resid, weight);
00453       fit_residual_tracky->Fill(positionY, 10.*geom_resid, weight);
00454       fit_residual_trackdxdz->Fill(angleX, 10.*geom_resid, weight);
00455       fit_residual_trackdydz->Fill(angleY, 10.*geom_resid, weight);
00456 
00457       double geom_resslope = residual_dxdz(value(kAlignX), value(kAlignZ), value(kAlignPhiX), value(kAlignPhiY), value(kAlignPhiZ), positionX, positionY, angleX, angleY);
00458       hist_resslope->Fill(1000.*(resslope - geom_resslope + value(kAlignPhiY)), weight);
00459       hist_resslope_trackx->Fill(positionX, 1000.*resslope, weight);
00460       hist_resslope_tracky->Fill(positionY, 1000.*resslope, weight);
00461       hist_resslope_trackdxdz->Fill(angleX, 1000.*resslope, weight);
00462       hist_resslope_trackdydz->Fill(angleY, 1000.*resslope, weight);
00463       fit_resslope_trackx->Fill(positionX, 1000.*geom_resslope, weight);
00464       fit_resslope_tracky->Fill(positionY, 1000.*geom_resslope, weight);
00465       fit_resslope_trackdxdz->Fill(angleX, 1000.*geom_resslope, weight);
00466       fit_resslope_trackdydz->Fill(angleY, 1000.*geom_resslope, weight);
00467     }
00468 
00469     hist_residual_raw->Fill(10.*resid);
00470     hist_resslope_raw->Fill(1000.*resslope);
00471     if (fabs(resslope) < 0.005) hist_residual_cut->Fill(10.*resid);
00472   }
00473 
00474   double chi2 = 0.;
00475   double ndof = 0.;
00476   for (int i = 1;  i <= hist_residual->GetNbinsX();  i++) {
00477     double xi = hist_residual->GetBinCenter(i);
00478     double yi = hist_residual->GetBinContent(i);
00479     double yerri = hist_residual->GetBinError(i);
00480     double yth = fit_residual->Eval(xi);
00481     if (yerri > 0.) {
00482       chi2 += pow((yth - yi)/yerri, 2);
00483       ndof += 1.;
00484     }
00485   }
00486   for (int i = 1;  i <= hist_resslope->GetNbinsX();  i++) {
00487     double xi = hist_resslope->GetBinCenter(i);
00488     double yi = hist_resslope->GetBinContent(i);
00489     double yerri = hist_resslope->GetBinError(i);
00490     double yth = fit_resslope->Eval(xi);
00491     if (yerri > 0.) {
00492       chi2 += pow((yth - yi)/yerri, 2);
00493       ndof += 1.;
00494     }
00495   }
00496   ndof -= npar();
00497 
00498   return (ndof > 0. ? chi2 / ndof : -1.);
00499 }
00500 
00501 
00502 TTree * MuonResiduals5DOFFitter::readNtuple(std::string fname, unsigned int wheel, unsigned int station, unsigned int sector, unsigned int preselected)
00503 {
00504   TFile *f = new TFile(fname.c_str());
00505   TTree *t = (TTree*)f->Get("mual_ttree");
00506 
00507   // Create  new temporary file
00508   TFile *tmpf = new TFile("small_tree_fit.root","recreate");
00509   assert(tmpf!=0);
00510 
00511   // filter the tree (temporarily lives in the new file)
00512   TTree *tt = t->CopyTree(Form("is_dt && ring_wheel==%d && station==%d && sector==%d && select==%d", wheel, station, sector, (bool)preselected));
00513 
00514   MuonAlignmentTreeRow r;
00515   tt->SetBranchAddress("res_x", &r.res_x);
00516   tt->SetBranchAddress("res_slope_x", &r.res_slope_x);
00517   tt->SetBranchAddress("pos_x", &r.pos_x);
00518   tt->SetBranchAddress("pos_y", &r.pos_y);
00519   tt->SetBranchAddress("angle_x", &r.angle_x);
00520   tt->SetBranchAddress("angle_y", &r.angle_y);
00521   tt->SetBranchAddress("pz", &r.pz);
00522   tt->SetBranchAddress("pt", &r.pt);
00523   tt->SetBranchAddress("q", &r.q);
00524 
00525   Long64_t nentries = tt->GetEntries();
00526   for (Long64_t i=0;i<nentries; i++)
00527   {
00528     tt->GetEntry(i);
00529     double *rdata = new double[MuonResiduals5DOFFitter::kNData];
00530     rdata[kResid] = r.res_x;
00531     rdata[kResSlope] = r.res_slope_x;
00532     rdata[kPositionX] = r.pos_x;
00533     rdata[kPositionY] = r.pos_y;
00534     rdata[kAngleX] = r.angle_x;
00535     rdata[kAngleY] = r.angle_y;
00536     rdata[kRedChi2] = 0.1;
00537     rdata[kPz] = r.pz;
00538     rdata[kPt] = r.pt;
00539     rdata[kCharge] = r.q;
00540     fill(rdata);
00541   }
00542   delete f;
00543   //delete tmpf;
00544   return tt;
00545 }