CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/Alignment/MuonAlignmentAlgorithms/interface/MuonResidualsFitter.h

Go to the documentation of this file.
00001 #ifndef Alignment_MuonAlignmentAlgorithms_MuonResidualsFitter_H
00002 #define Alignment_MuonAlignmentAlgorithms_MuonResidualsFitter_H
00003 
00010 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00011 
00012 #include "Alignment/MuonAlignmentAlgorithms/interface/MuonChamberResidual.h"
00013 #include "CommonTools/UtilAlgos/interface/TFileService.h"
00014 #include "Alignment/CommonAlignment/interface/Alignable.h"
00015 
00016 #include "TMinuit.h"
00017 #include "TH1F.h"
00018 #include "TProfile.h"
00019 #include "TF1.h"
00020 #include "TMath.h"
00021 
00022 #include <cstdio>
00023 #include <iostream>
00024 #include <string>
00025 #include <sstream>
00026 
00027 class MuonResidualsFitter {
00028 public:
00029   enum {
00030     kPureGaussian,
00031     kPowerLawTails,
00032     kROOTVoigt,
00033     kGaussPowerTails
00034   };
00035 
00036   enum {
00037     k1DOF,
00038     k5DOF,
00039     k6DOF,
00040     k6DOFrphi,
00041     kPositionFitter,
00042     kAngleFitter,
00043     kAngleBfieldFitter
00044   };
00045 
00046   MuonResidualsFitter(int residualsModel, int minHits, bool weightAlignment=true)
00047     : m_residualsModel(residualsModel), m_minHits(minHits), m_weightAlignment(weightAlignment), m_printLevel(0), m_strategy(2), m_loglikelihood(0.) {
00048     if (m_residualsModel != kPureGaussian  &&  m_residualsModel != kPowerLawTails  &&  m_residualsModel != kROOTVoigt  &&  m_residualsModel != kGaussPowerTails) throw cms::Exception("MuonResidualsFitter") << "unrecognized residualsModel";
00049   };
00050 
00051   virtual ~MuonResidualsFitter() {
00052     for (std::vector<double*>::const_iterator residual = residuals_begin();  residual != residuals_end();  ++residual) {
00053       delete [] (*residual);
00054     }
00055   };
00056 
00057   virtual int type() const = 0;
00058 
00059   int residualsModel() const { return m_residualsModel; };
00060   long numResiduals() const { return m_residuals.size(); };
00061   virtual int npar() = 0;
00062   virtual int ndata() = 0;
00063 
00064   void fix(int parNum, bool value=true) {
00065     assert(0 <= parNum  &&  parNum < npar());
00066     if (m_fixed.size() == 0) {
00067       for (int i = 0;  i < npar();  i++) {
00068         m_fixed.push_back(false);
00069       }
00070     }
00071     m_fixed[parNum] = value;
00072   };
00073 
00074   bool fixed(int parNum) {
00075     assert(0 <= parNum  &&  parNum < npar());
00076     if (m_fixed.size() == 0) return false;
00077     else return m_fixed[parNum];
00078   };
00079 
00080   void setPrintLevel(int printLevel) { m_printLevel = printLevel; };
00081   void setStrategy(int strategy) { m_strategy = strategy; };
00082 
00083   // an array of the actual residual and associated baggage (qoverpt, trackangle, trackposition)
00084   // arrays passed to fill() are "owned" by MuonResidualsFitter: MuonResidualsFitter will delete them, don't do it yourself!
00085   void fill(double *residual) {
00086     m_residuals.push_back(residual);
00087   };
00088 
00089   // this block of results is only valid if fit() returns true
00090   // also gamma is only valid if the model is kPowerLawTails or kROOTVoigt
00091   virtual bool fit(Alignable *ali) = 0;
00092   double value(int parNum) { assert(0 <= parNum  &&  parNum < npar());  return m_value[parNum]; };
00093   double errorerror(int parNum) { assert(0 <= parNum  &&  parNum < npar());  return m_error[parNum]; };
00094   double loglikelihood() { return m_loglikelihood; };
00095   long numsegments() {
00096     long num = 0;
00097     for (std::vector<double*>::const_iterator resiter = residuals_begin();  resiter != residuals_end();  ++resiter) {
00098       num++;
00099     }
00100     return num;
00101   };
00102   virtual double sumofweights() = 0;
00103 
00104   // demonstration plots; return reduced chi**2
00105   virtual double plot(std::string name, TFileDirectory *dir, Alignable *ali) = 0;
00106 
00107   // I/O of temporary files for collect mode
00108   void write(FILE *file, int which=0);
00109   void read(FILE *file, int which=0);
00110 
00111   // these are for the FCN to access what it needs to
00112   std::vector<double*>::const_iterator residuals_begin() const { return m_residuals.begin(); };
00113   std::vector<double*>::const_iterator residuals_end() const { return m_residuals.end(); };
00114 
00115   void plotsimple(std::string name, TFileDirectory *dir, int which, double multiplier);
00116   void plotweighted(std::string name, TFileDirectory *dir, int which, int whichredchi2, double multiplier);
00117 
00118 protected:
00119   void initialize_table();
00120   bool dofit(void (*fcn)(int&,double*,double&,double*,int), std::vector<int> &parNum, std::vector<std::string> &parName, std::vector<double> &start, std::vector<double> &step, std::vector<double> &low, std::vector<double> &high);
00121   virtual void inform(TMinuit *tMinuit) = 0;
00122 
00123   int m_residualsModel;
00124   int m_minHits;
00125   bool m_weightAlignment;
00126   std::vector<bool> m_fixed;
00127   int m_printLevel, m_strategy;
00128 
00129   std::vector<double*> m_residuals;
00130 
00131   std::vector<double> m_value;
00132   std::vector<double> m_error;
00133   double m_loglikelihood;
00134 };
00135 
00136 // A ROOT-sponsored hack to get information into the fit function
00137 class MuonResidualsFitterFitInfo: public TObject {
00138 public:
00139   MuonResidualsFitterFitInfo(MuonResidualsFitter *fitter)
00140     : m_fitter(fitter) {};
00141   MuonResidualsFitter *fitter() { return m_fitter; };
00142 private:
00143   MuonResidualsFitter *m_fitter;
00144 };
00145 
00146 // fit functions (these can't be put in the class; "MuonResidualsFitter_" prefix avoids namespace clashes)
00147 double MuonResidualsFitter_integrate_pureGaussian(double low, double high, double center, double sigma);
00148 double MuonResidualsFitter_logPureGaussian(double residual, double center, double sigma);
00149 Double_t MuonResidualsFitter_pureGaussian_TF1(Double_t *xvec, Double_t *par);
00150 double MuonResidualsFitter_compute_log_convolution(double toversigma, double gammaoversigma, double max=1000., double step=0.001, double power=4.);
00151 double MuonResidualsFitter_logPowerLawTails(double residual, double center, double sigma, double gamma);
00152 Double_t MuonResidualsFitter_powerLawTails_TF1(Double_t *xvec, Double_t *par);
00153 double MuonResidualsFitter_logROOTVoigt(double residual, double center, double sigma, double gamma);
00154 Double_t MuonResidualsFitter_ROOTVoigt_TF1(Double_t *xvec, Double_t *par);
00155 double MuonResidualsFitter_logGaussPowerTails(double residual, double center, double sigma);
00156 Double_t MuonResidualsFitter_GaussPowerTails_TF1(Double_t *xvec, Double_t *par);
00157 void MuonResidualsPositionFitter_FCN(int &npar, double *gin, double &fval, double *par, int iflag);
00158 void MuonResidualsAngleFitter_FCN(int &npar, double *gin, double &fval, double *par, int iflag);
00159 
00160 #endif // Alignment_MuonAlignmentAlgorithms_MuonResidualsFitter_H