CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/Alignment/OfflineValidation/plugins/TrackerOfflineValidation.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:    TrackerOfflineValidation
00004 // Class:      TrackerOfflineValidation
00005 // 
00013 //
00014 // Original Author:  Erik Butz
00015 //         Created:  Tue Dec 11 14:03:05 CET 2007
00016 // $Id: TrackerOfflineValidation.cc,v 1.52 2011/09/15 08:06:07 mussgill Exp $
00017 //
00018 //
00019 
00020 // system include files
00021 #include <memory>
00022 #include <map>
00023 #include <sstream>
00024 #include <math.h>
00025 #include <utility>
00026 #include <vector>
00027 #include <iostream>
00028 
00029 // ROOT includes
00030 #include "TH1.h"
00031 #include "TH2.h"
00032 #include "TProfile.h"
00033 #include "TFile.h"
00034 #include "TTree.h"
00035 #include "TF1.h"
00036 #include "TMath.h"
00037 
00038 // user include files
00039 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00040 #include "FWCore/Framework/interface/Frameworkfwd.h"
00041 #include "FWCore/Framework/interface/EDAnalyzer.h"
00042 #include "FWCore/Framework/interface/EventSetup.h"
00043 #include "FWCore/Framework/interface/Event.h"
00044 #include "FWCore/Framework/interface/MakerMacros.h"
00045 #include "FWCore/Framework/interface/ESHandle.h"
00046 #include "FWCore/ServiceRegistry/interface/Service.h"
00047 
00048 #include "DataFormats/DetId/interface/DetId.h"
00049 #include "DataFormats/SiPixelDetId/interface/PXBDetId.h"
00050 #include "DataFormats/SiPixelDetId/interface/PXFDetId.h"
00051 #include "DataFormats/SiStripDetId/interface/TECDetId.h"
00052 #include "DataFormats/SiStripDetId/interface/TIBDetId.h"
00053 #include "DataFormats/SiStripDetId/interface/TIDDetId.h"
00054 #include "DataFormats/SiStripDetId/interface/TOBDetId.h"
00055 #include "DataFormats/SiPixelDetId/interface/PixelSubdetector.h"
00056 #include "DataFormats/Math/interface/deltaPhi.h"
00057 
00058 #include "CommonTools/UtilAlgos/interface/TFileService.h"
00059 #include "CommonTools/Utils/interface/TFileDirectory.h"
00060 
00061 #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
00062 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
00063 #include "Geometry/CommonDetUnit/interface/GeomDetUnit.h"
00064 
00065 #include "DQMServices/Core/interface/DQMStore.h"
00066 #include "DQMServices/Core/interface/MonitorElement.h"
00067 
00068 #include "Alignment/CommonAlignment/interface/Alignable.h"
00069 #include "Alignment/CommonAlignment/interface/Utilities.h"
00070 #include "Alignment/CommonAlignment/interface/AlignableObjectId.h"
00071 #include "Alignment/TrackerAlignment/interface/AlignableTracker.h"
00072 #include "Alignment/TrackerAlignment/interface/TrackerAlignableId.h"
00073 
00074 #include "Alignment/OfflineValidation/interface/TrackerValidationVariables.h"
00075 #include "Alignment/OfflineValidation/interface/TkOffTreeVariables.h"
00076 
00077 //
00078 // class declaration
00079 //
00080 class TrackerOfflineValidation : public edm::EDAnalyzer {
00081 public:
00082   explicit TrackerOfflineValidation(const edm::ParameterSet&);
00083   ~TrackerOfflineValidation();
00084   
00085   enum HistogrammType { XResidual, NormXResidual, 
00086                         YResidual, /*NormYResidual, */
00087                         XprimeResidual, NormXprimeResidual, 
00088                         YprimeResidual, NormYprimeResidual,
00089                         XResidualProfile, YResidualProfile };
00090   
00091 private:
00092 
00093   struct ModuleHistos{
00094     ModuleHistos() :  ResHisto(), NormResHisto(), ResYHisto(), /*NormResYHisto(),*/
00095                       ResXprimeHisto(), NormResXprimeHisto(), 
00096                       ResYprimeHisto(), NormResYprimeHisto(),
00097                       ResXvsXProfile(), ResXvsYProfile(),
00098                       ResYvsXProfile(), ResYvsYProfile(),
00099                       LocalX(), LocalY() {} 
00100     TH1* ResHisto;
00101     TH1* NormResHisto;
00102     TH1* ResYHisto;
00103     /* TH1* NormResYHisto; */
00104     TH1* ResXprimeHisto;
00105     TH1* NormResXprimeHisto;
00106     TH1* ResYprimeHisto;
00107     TH1* NormResYprimeHisto;
00108 
00109     TProfile* ResXvsXProfile;
00110     TProfile* ResXvsYProfile;
00111     TProfile* ResYvsXProfile;
00112     TProfile* ResYvsYProfile;
00113 
00114     TH1* LocalX;
00115     TH1* LocalY;
00116   };
00117   
00118   // container struct to organize collection of histogramms during endJob
00119   struct SummaryContainer{
00120     SummaryContainer() : sumXResiduals_(), summaryXResiduals_(), 
00121                          sumNormXResiduals_(), summaryNormXResiduals_(),
00122                          sumYResiduals_(), summaryYResiduals_() ,
00123                          sumNormYResiduals_(), summaryNormYResiduals_() {}
00124     
00125     TH1* sumXResiduals_;
00126     TH1* summaryXResiduals_;
00127     TH1* sumNormXResiduals_;
00128     TH1* summaryNormXResiduals_;
00129     TH1* sumYResiduals_;
00130     TH1* summaryYResiduals_;
00131     TH1* sumNormYResiduals_;
00132     TH1* summaryNormYResiduals_;
00133   };
00134   
00135   
00136   struct DirectoryWrapper{
00137     DirectoryWrapper(const DirectoryWrapper& upDir,const std::string& newDir,
00138                      const std::string& basedir,bool useDqmMode)
00139       : tfd(0),
00140         dqmMode(useDqmMode),
00141         theDbe(0) {
00142       if (newDir.length()!=0){
00143         if(upDir.directoryString.length()!=0)directoryString=upDir.directoryString+"/"+newDir;
00144         else directoryString = newDir;
00145       }
00146       else
00147         directoryString=upDir.directoryString;
00148 
00149       if (!dqmMode){
00150         if (newDir.length()==0) tfd.reset(&(*upDir.tfd));
00151         else
00152           tfd.reset(new TFileDirectory(upDir.tfd->mkdir(newDir)));
00153       }
00154       else {
00155         theDbe=edm::Service<DQMStore>().operator->();
00156       }
00157     }
00158     
00159     DirectoryWrapper(const std::string& newDir,const std::string& basedir,bool useDqmMode)
00160       : tfd(0),
00161         dqmMode(useDqmMode),
00162         theDbe(0) {
00163       if (!dqmMode){
00164         edm::Service<TFileService> fs;
00165         if (newDir.length()==0){
00166           tfd.reset(new TFileDirectory(static_cast<TFileDirectory&>(*fs)));
00167         }
00168         else {
00169           tfd.reset(new TFileDirectory(fs->mkdir(newDir)));
00170           directoryString=newDir;
00171         }
00172       }
00173       else {
00174         if (newDir.length()!=0){
00175           if(basedir.length()!=0)directoryString=basedir+"/"+newDir;
00176           else directoryString = newDir;
00177         }
00178         else directoryString=basedir;
00179         theDbe=edm::Service<DQMStore>().operator->();
00180       }
00181     }
00182     // Generalization of Histogram Booking; allows switch between TFileService and DQMStore
00183     template <typename T> TH1* make(const char* name,const char* title,int nBinX,double minBinX,double maxBinX);
00184     template <typename T> TH1* make(const char* name,const char* title,int nBinX,double *xBins);//variable bin size in x for profile histo 
00185     template <typename T> TH1* make(const char* name,const char* title,int nBinX,double minBinX,double maxBinX,int nBinY,double minBinY,double maxBinY);
00186     template <typename T> TH1* make(const char* name,const char* title,int nBinX,double minBinX,double maxBinX,double minBinY,double maxBinY);  // at present not used
00187     
00188     std::auto_ptr<TFileDirectory> tfd;
00189     std::string directoryString;
00190     const bool dqmMode;
00191     DQMStore* theDbe;
00192   };
00193   
00194   
00195   // 
00196   // ------------- private member function -------------
00197   // 
00198   virtual void analyze(const edm::Event&, const edm::EventSetup&);
00199   virtual void endJob();
00200   
00201   virtual void checkBookHists(const edm::EventSetup& setup);
00202 
00203   void bookGlobalHists(DirectoryWrapper& tfd);
00204   void bookDirHists(DirectoryWrapper& tfd, const Alignable& ali, const AlignableObjectId& aliobjid);
00205   void bookHists(DirectoryWrapper& tfd, const Alignable& ali, align::StructureType type, int i, 
00206                  const AlignableObjectId& aliobjid);
00207  
00208   void collateSummaryHists( DirectoryWrapper& tfd, const Alignable& ali, int i, 
00209                             const AlignableObjectId& aliobjid, 
00210                             std::vector<TrackerOfflineValidation::SummaryContainer>& vLevelProfiles);
00211   
00212   void fillTree(TTree& tree, const std::map<int, TrackerOfflineValidation::ModuleHistos>& moduleHist_, 
00213                 TkOffTreeVariables& treeMem, const TrackerGeometry& tkgeom);
00214   
00215   TrackerOfflineValidation::SummaryContainer bookSummaryHists(DirectoryWrapper& tfd, 
00216                                                               const Alignable& ali, 
00217                                                               align::StructureType type, int i, 
00218                                                               const AlignableObjectId& aliobjid); 
00219 
00220   ModuleHistos& getHistStructFromMap(const DetId& detid); 
00221 
00222   bool isBarrel(uint32_t subDetId);
00223   bool isEndCap(uint32_t subDetId);
00224   bool isPixel(uint32_t subDetId);
00225   bool isDetOrDetUnit(align::StructureType type);
00226 
00227   TH1* bookTH1F(bool isTransient, DirectoryWrapper& tfd, const char* histName, const char* histTitle, 
00228                 int nBinsX, double lowX, double highX);
00229 
00230   TProfile* bookTProfile(bool isTransient, DirectoryWrapper& tfd, const char* histName, const char* histTitle, 
00231                          int nBinsX, double lowX, double highX);
00232 
00233   TProfile* bookTProfile(bool isTransient, DirectoryWrapper& tfd, const char* histName, const char* histTitle, 
00234                          int nBinsX, double lowX, double highX, double lowY, double highY);
00235 
00236   void getBinning(uint32_t subDetId, TrackerOfflineValidation::HistogrammType residualtype, 
00237                   int& nBinsX, double& lowerBoundX, double& upperBoundX);
00238 
00239   void summarizeBinInContainer(int bin, SummaryContainer& targetContainer, 
00240                                SummaryContainer& sourceContainer);
00241 
00242   void summarizeBinInContainer(int bin, uint32_t subDetId, SummaryContainer& targetContainer, 
00243                                ModuleHistos& sourceContainer);
00244 
00245   void setSummaryBin(int bin, TH1* targetHist, TH1* sourceHist);
00246     
00247   float Fwhm(const TH1* hist) const;
00248   std::pair<float,float> fitResiduals(TH1* hist) const; //, float meantmp, float rmstmp);
00249   float getMedian( const TH1* hist) const; 
00250   
00251   // From MillePedeAlignmentMonitor: Get Index for Arbitary vector<class> by name
00252   template <class OBJECT_TYPE> int GetIndex(const std::vector<OBJECT_TYPE*>& vec, const TString& name);
00253   
00254   
00255   // ---------- member data ---------------------------
00256 
00257   const edm::ParameterSet parSet_;
00258   edm::ESHandle<TrackerGeometry> tkGeom_;
00259   const TrackerGeometry *bareTkGeomPtr_; // ugly hack to book hists only once, but check 
00260 
00261   // parameters from cfg to steer
00262   const bool lCoorHistOn_;
00263   const bool moduleLevelHistsTransient_;
00264   const bool moduleLevelProfiles_;
00265   const bool stripYResiduals_;
00266   const bool useFwhm_;
00267   const bool useFit_;
00268   const bool useOverflowForRMS_;
00269   const bool dqmMode_;
00270   const std::string moduleDirectory_;
00271   
00272   // a vector to keep track which pointers should be deleted at the very end
00273   std::vector<TH1*> vDeleteObjects_;
00274 
00275   std::vector<TH1*> vTrackHistos_;
00276   std::vector<TH1*> vTrackProfiles_;
00277   std::vector<TH1*> vTrack2DHistos_;
00278   
00279   std::map<int,TrackerOfflineValidation::ModuleHistos> mPxbResiduals_;
00280   std::map<int,TrackerOfflineValidation::ModuleHistos> mPxeResiduals_;
00281   std::map<int,TrackerOfflineValidation::ModuleHistos> mTibResiduals_;
00282   std::map<int,TrackerOfflineValidation::ModuleHistos> mTidResiduals_;
00283   std::map<int,TrackerOfflineValidation::ModuleHistos> mTobResiduals_;
00284   std::map<int,TrackerOfflineValidation::ModuleHistos> mTecResiduals_;
00285 };
00286 
00287 
00288 //
00289 // constants, enums and typedefs
00290 //
00291 
00292 //
00293 // static data member definitions
00294 //
00295 
00296 template <class OBJECT_TYPE>  
00297 int TrackerOfflineValidation::GetIndex(const std::vector<OBJECT_TYPE*> &vec, const TString &name)
00298 {
00299   int result = 0;
00300   for (typename std::vector<OBJECT_TYPE*>::const_iterator iter = vec.begin(), iterEnd = vec.end();
00301        iter != iterEnd; ++iter, ++result) {
00302     if (*iter && (*iter)->GetName() == name) return result;
00303   }
00304   edm::LogError("Alignment") << "@SUB=TrackerOfflineValidation::GetIndex" << " could not find " << name;
00305   return -1;
00306 }
00307 
00308 
00309 template <> TH1* TrackerOfflineValidation::DirectoryWrapper::make<TH1F>(const char* name,const char* title,int nBinX,double minBinX,double maxBinX){
00310   if(dqmMode){theDbe->setCurrentFolder(directoryString); return theDbe->book1D(name,title,nBinX,minBinX,maxBinX)->getTH1();}
00311   else{return tfd->make<TH1F>(name,title,nBinX,minBinX,maxBinX);}
00312 }
00313 
00314 template <> TH1* TrackerOfflineValidation::DirectoryWrapper::make<TProfile>(const char* name,const char* title,int nBinX,double *xBins){
00315   if(dqmMode){
00316     theDbe->setCurrentFolder(directoryString);
00317     //DQM profile requires y-bins for construction... using TProfile creator by hand...
00318     TProfile *tmpProfile=new TProfile(name,title,nBinX,xBins);
00319     tmpProfile->SetDirectory(0);
00320     return theDbe->bookProfile(name,tmpProfile)->getTH1();
00321   }
00322   else{return tfd->make<TProfile>(name,title,nBinX,xBins);}
00323 }
00324 
00325 template <> TH1* TrackerOfflineValidation::DirectoryWrapper::make<TProfile>(const char* name,const char* title,int nBinX,double minBinX,double maxBinX){
00326   if(dqmMode){
00327     theDbe->setCurrentFolder(directoryString);
00328     //DQM profile requires y-bins for construction... using TProfile creator by hand...
00329     TProfile *tmpProfile=new TProfile(name,title,nBinX,minBinX,maxBinX);
00330     tmpProfile->SetDirectory(0);
00331     return theDbe->bookProfile(name,tmpProfile)->getTH1();
00332   }
00333   else{return tfd->make<TProfile>(name,title,nBinX,minBinX,maxBinX);}
00334 }
00335 
00336 template <> TH1* TrackerOfflineValidation::DirectoryWrapper::make<TProfile>(const char* name ,const char* title,int nbinX,double minX ,double maxX,double minY,double maxY){
00337   if(dqmMode){
00338     theDbe->setCurrentFolder(directoryString);
00339     int dummy(0); // DQMProfile wants Y channels... does not use them!
00340     return (theDbe->bookProfile(name,title,nbinX,minX,maxX,dummy,minY,maxY)->getTH1());
00341   }
00342   else{
00343     return tfd->make<TProfile>(name,title,nbinX,minX,maxX,minY,maxY);
00344   }
00345 }
00346 
00347 template <> TH1* TrackerOfflineValidation::DirectoryWrapper::make<TH2F>(const char* name,const char* title,int nBinX,double minBinX,double maxBinX,int nBinY,double minBinY,double maxBinY){
00348   if(dqmMode){theDbe->setCurrentFolder(directoryString); return theDbe->book2D(name,title,nBinX,minBinX,maxBinX,nBinY,minBinY,maxBinY)->getTH1();}
00349   else{return tfd->make<TH2F>(name,title,nBinX,minBinX,maxBinX,nBinY,minBinY,maxBinY);}
00350 }
00351 
00352 
00353 //
00354 // constructors and destructor
00355 //
00356 TrackerOfflineValidation::TrackerOfflineValidation(const edm::ParameterSet& iConfig)
00357   : parSet_(iConfig), bareTkGeomPtr_(0), lCoorHistOn_(parSet_.getParameter<bool>("localCoorHistosOn")),
00358     moduleLevelHistsTransient_(parSet_.getParameter<bool>("moduleLevelHistsTransient")),
00359     moduleLevelProfiles_(parSet_.getParameter<bool>("moduleLevelProfiles")),
00360     stripYResiduals_(parSet_.getParameter<bool>("stripYResiduals")), 
00361     useFwhm_(parSet_.getParameter<bool>("useFwhm")),
00362     useFit_(parSet_.getParameter<bool>("useFit")),
00363     useOverflowForRMS_(parSet_.getParameter<bool>("useOverflowForRMS")),
00364     dqmMode_(parSet_.getParameter<bool>("useInDqmMode")),
00365     moduleDirectory_(parSet_.getParameter<std::string>("moduleDirectoryInOutput"))
00366 {
00367 }
00368 
00369 
00370 TrackerOfflineValidation::~TrackerOfflineValidation()
00371 {
00372    // do anything here that needs to be done at desctruction time
00373    // (e.g. close files, deallocate resources etc.)
00374   for( std::vector<TH1*>::const_iterator it = vDeleteObjects_.begin(), itEnd = vDeleteObjects_.end(); 
00375        it != itEnd;
00376        ++it) delete *it;
00377 }
00378 
00379 
00380 //
00381 // member functions
00382 //
00383 
00384 
00385 // ------------ method called once each job just before starting event loop  ------------
00386 void
00387 TrackerOfflineValidation::checkBookHists(const edm::EventSetup& es)
00388 {
00389   es.get<TrackerDigiGeometryRecord>().get( tkGeom_ );
00390   const TrackerGeometry *newBareTkGeomPtr = &(*tkGeom_);
00391   if (newBareTkGeomPtr == bareTkGeomPtr_) return; // already booked hists, nothing changed
00392 
00393   if (!bareTkGeomPtr_) { // pointer not yet set: called the first time => book hists
00394     AlignableObjectId aliobjid;
00395     
00396     // construct alignable tracker to get access to alignable hierarchy 
00397     AlignableTracker aliTracker(&(*tkGeom_));
00398     
00399     edm::LogInfo("TrackerOfflineValidation") << "There are " << newBareTkGeomPtr->detIds().size()
00400                                              << " dets in the Geometry record.\n"
00401                                              << "Out of these "<<newBareTkGeomPtr->detUnitIds().size()
00402                                              <<" are detUnits";
00403     
00404     // Book Histogramms for global track quantities
00405     std::string globDir("GlobalTrackVariables");
00406     DirectoryWrapper trackglobal(globDir,moduleDirectory_,dqmMode_);
00407     this->bookGlobalHists(trackglobal);
00408     
00409     // recursively book histogramms on lowest level
00410     DirectoryWrapper tfdw("",moduleDirectory_,dqmMode_);
00411     this->bookDirHists(tfdw, aliTracker, aliobjid);
00412   }
00413   else { // histograms booked, but changed TrackerGeometry?
00414     edm::LogWarning("GeometryChange") << "@SUB=checkBookHists"
00415                                       << "TrackerGeometry changed, but will not re-book hists!";
00416   }
00417   bareTkGeomPtr_ = newBareTkGeomPtr;
00418 }
00419 
00420 
00421 void 
00422 TrackerOfflineValidation::bookGlobalHists(DirectoryWrapper& tfd )
00423 {
00424 
00425   vTrackHistos_.push_back(tfd.make<TH1F>("h_tracketa",
00426                                          "Track #eta;#eta_{Track};Number of Tracks",
00427                                          90,-3.,3.));
00428   vTrackHistos_.push_back(tfd.make<TH1F>("h_trackphi",
00429                                          "Track #phi;#phi_{Track};Number of Tracks",
00430                                          90,-3.15,3.15));
00431   vTrackHistos_.push_back(tfd.make<TH1F>("h_trackNumberOfValidHits",
00432                                          "Track # of valid hits;# of valid hits _{Track};Number of Tracks",
00433                                         40,0.,40.));
00434   vTrackHistos_.push_back(tfd.make<TH1F>("h_trackNumberOfLostHits",
00435                                          "Track # of lost hits;# of lost hits _{Track};Number of Tracks",
00436                                         10,0.,10.));
00437   vTrackHistos_.push_back(tfd.make<TH1F>("h_curvature",
00438                                          "Curvature #kappa;#kappa_{Track};Number of Tracks",
00439                                          100,-.05,.05));
00440   vTrackHistos_.push_back(tfd.make<TH1F>("h_curvature_pos",
00441                                          "Curvature |#kappa| Positive Tracks;|#kappa_{pos Track}|;Number of Tracks",
00442                                          100,.0,.05));
00443   vTrackHistos_.push_back(tfd.make<TH1F>("h_curvature_neg",
00444                                          "Curvature |#kappa| Negative Tracks;|#kappa_{neg Track}|;Number of Tracks",
00445                                          100,.0,.05));
00446   vTrackHistos_.push_back(tfd.make<TH1F>("h_diff_curvature",
00447                                          "Curvature |#kappa| Tracks Difference;|#kappa_{Track}|;# Pos Tracks - # Neg Tracks",
00448                                          100,.0,.05));
00449   vTrackHistos_.push_back(tfd.make<TH1F>("h_chi2",
00450                                          "#chi^{2};#chi^{2}_{Track};Number of Tracks",
00451                                          500,-0.01,500.));
00452   vTrackHistos_.push_back(tfd.make<TH1F>("h_chi2Prob",
00453                                          "#chi^{2} probability;#chi^{2}prob_{Track};Number of Tracks",
00454                                         100,0.0,1.));          
00455   vTrackHistos_.push_back(tfd.make<TH1F>("h_normchi2",
00456                                          "#chi^{2}/ndof;#chi^{2}/ndof;Number of Tracks",
00457                                          100,-0.01,10.));     
00458   vTrackHistos_.push_back(tfd.make<TH1F>("h_pt",
00459                                          "p_{T}^{track};p_{T}^{track} [GeV];Number of Tracks",
00460                                          250,0.,250));           
00461   vTrackHistos_.push_back(tfd.make<TH1F>("h_ptResolution",
00462                                          "#delta{p_{T}/p_{T}^{track}};#delta_{p_{T}/p_{T}^{track}};Number of Tracks",
00463                                          100,0.,0.5));           
00464 
00465   vTrackProfiles_.push_back(tfd.make<TProfile>("p_d0_vs_phi",
00466                                                "Transverse Impact Parameter vs. #phi;#phi_{Track};#LT d_{0} #GT [cm]",
00467                                                100,-3.15,3.15));
00468   vTrackProfiles_.push_back(tfd.make<TProfile>("p_dz_vs_phi",
00469                                                "Longitudinal Impact Parameter vs. #phi;#phi_{Track};#LT d_{z} #GT [cm]",
00470                                                100,-3.15,3.15));
00471   vTrackProfiles_.push_back(tfd.make<TProfile>("p_d0_vs_eta",
00472                                                "Transverse Impact Parameter vs. #eta;#eta_{Track};#LT d_{0} #GT [cm]",
00473                                                100,-3.15,3.15));
00474   vTrackProfiles_.push_back(tfd.make<TProfile>("p_dz_vs_eta",
00475                                                "Longitudinal Impact Parameter vs. #eta;#eta_{Track};#LT d_{z} #GT [cm]",
00476                                                100,-3.15,3.15));
00477   vTrackProfiles_.push_back(tfd.make<TProfile>("p_chi2_vs_phi",
00478                                                "#chi^{2} vs. #phi;#phi_{Track};#LT #chi^{2} #GT",
00479                                                100,-3.15,3.15));
00480   vTrackProfiles_.push_back(tfd.make<TProfile>("p_chi2Prob_vs_phi",
00481                                                "#chi^{2} probablility vs. #phi;#phi_{Track};#LT #chi^{2} probability#GT",
00482                                                100,-3.15,3.15));
00483   vTrackProfiles_.push_back(tfd.make<TProfile>("p_chi2Prob_vs_d0",
00484                                                "#chi^{2} probablility vs. |d_{0}|;|d_{0}|[cm];#LT #chi^{2} probability#GT",
00485                                                100,0,80));
00486   vTrackProfiles_.push_back(tfd.make<TProfile>("p_normchi2_vs_phi",
00487                                                "#chi^{2}/ndof vs. #phi;#phi_{Track};#LT #chi^{2}/ndof #GT",
00488                                                100,-3.15,3.15));
00489   vTrackProfiles_.push_back(tfd.make<TProfile>("p_chi2_vs_eta",
00490                                                "#chi^{2} vs. #eta;#eta_{Track};#LT #chi^{2} #GT",
00491                                                100,-3.15,3.15));
00492   //variable binning for chi2/ndof vs. pT
00493   double xBins[19]={0.,0.15,0.5,1.,1.5,2.,2.5,3.,3.5,4.,4.5,5.,7.,10.,15.,25.,40.,100.,200.};
00494   vTrackProfiles_.push_back(tfd.make<TProfile>("p_normchi2_vs_pt",
00495                                                "norm #chi^{2} vs. p_{T}_{Track}; p_{T}_{Track};#LT #chi^{2}/ndof #GT",
00496                                                18,xBins));
00497 
00498   vTrackProfiles_.push_back(tfd.make<TProfile>("p_normchi2_vs_p",
00499                                                "#chi^{2}/ndof vs. p_{Track};p_{Track};#LT #chi^{2}/ndof #GT",
00500                                                 18,xBins));
00501   vTrackProfiles_.push_back(tfd.make<TProfile>("p_chi2Prob_vs_eta",
00502                                                "#chi^{2} probability vs. #eta;#eta_{Track};#LT #chi^{2} probability #GT",
00503                                                100,-3.15,3.15));   
00504   vTrackProfiles_.push_back(tfd.make<TProfile>("p_normchi2_vs_eta",
00505                                                "#chi^{2}/ndof vs. #eta;#eta_{Track};#LT #chi^{2}/ndof #GT",
00506                                                100,-3.15,3.15));
00507   vTrackProfiles_.push_back(tfd.make<TProfile>("p_kappa_vs_phi",
00508                                                "#kappa vs. #phi;#phi_{Track};#kappa",
00509                                                100,-3.15,3.15));
00510   vTrackProfiles_.push_back(tfd.make<TProfile>("p_kappa_vs_eta",
00511                                                "#kappa vs. #eta;#eta_{Track};#kappa",
00512                                                100,-3.15,3.15));
00513   vTrackProfiles_.push_back(tfd.make<TProfile>("p_ptResolution_vs_phi",
00514                                                "#delta_{p_{T}}/p_{T}^{track};#phi^{track};#delta_{p_{T}}/p_{T}^{track}",
00515                                                100, -3.15,3.15));
00516   vTrackProfiles_.push_back(tfd.make<TProfile>("p_ptResolution_vs_eta",
00517                                                "#delta_{p_{T}}/p_{T}^{track};#eta^{track};#delta_{p_{T}}/p_{T}^{track}",
00518                                                100, -3.15,3.15));
00519 
00520   vTrack2DHistos_.push_back(tfd.make<TH2F>("h2_d0_vs_phi",
00521                                            "Transverse Impact Parameter vs. #phi;#phi_{Track};d_{0} [cm]",
00522                                            100, -3.15, 3.15, 100,-1.,1.) );
00523   vTrack2DHistos_.push_back(tfd.make<TH2F>("h2_dz_vs_phi",
00524                                            "Longitudinal Impact Parameter vs. #phi;#phi_{Track};d_{z} [cm]",
00525                                            100, -3.15, 3.15, 100,-100.,100.));
00526   vTrack2DHistos_.push_back(tfd.make<TH2F>("h2_d0_vs_eta",
00527                                            "Transverse Impact Parameter vs. #eta;#eta_{Track};d_{0} [cm]",
00528                                            100, -3.15, 3.15, 100,-1.,1.));
00529   vTrack2DHistos_.push_back(tfd.make<TH2F>("h2_dz_vs_eta",
00530                                            "Longitudinal Impact Parameter vs. #eta;#eta_{Track};d_{z} [cm]",
00531                                            100, -3.15, 3.15, 100,-100.,100.));
00532   vTrack2DHistos_.push_back(tfd.make<TH2F>("h2_chi2_vs_phi",
00533                                            "#chi^{2} vs. #phi;#phi_{Track};#chi^{2}",
00534                                            100, -3.15, 3.15, 500, 0., 500.));
00535   vTrack2DHistos_.push_back(tfd.make<TH2F>("h2_chi2Prob_vs_phi",
00536                                            "#chi^{2} probability vs. #phi;#phi_{Track};#chi^{2} probability",
00537                                            100, -3.15, 3.15, 100, 0., 1.));
00538   vTrack2DHistos_.push_back(tfd.make<TH2F>("h2_chi2Prob_vs_d0",
00539                                            "#chi^{2} probability vs. |d_{0}|;|d_{0}| [cm];#chi^{2} probability",
00540                                            100, 0, 80, 100, 0., 1.));
00541   vTrack2DHistos_.push_back(tfd.make<TH2F>("h2_normchi2_vs_phi",
00542                                            "#chi^{2}/ndof vs. #phi;#phi_{Track};#chi^{2}/ndof",
00543                                            100, -3.15, 3.15, 100, 0., 10.));
00544   vTrack2DHistos_.push_back(tfd.make<TH2F>("h2_chi2_vs_eta",
00545                                            "#chi^{2} vs. #eta;#eta_{Track};#chi^{2}",
00546                                            100, -3.15, 3.15, 500, 0., 500.));  
00547   vTrack2DHistos_.push_back(tfd.make<TH2F>("h2_chi2Prob_vs_eta",
00548                                            "#chi^{2} probaility vs. #eta;#eta_{Track};#chi^{2} probability",
00549                                            100, -3.15, 3.15, 100, 0., 1.));  
00550   vTrack2DHistos_.push_back(tfd.make<TH2F>("h2_normchi2_vs_eta",
00551                                            "#chi^{2}/ndof vs. #eta;#eta_{Track};#chi^{2}/ndof",
00552                                            100,-3.15,3.15, 100, 0., 10.));
00553   vTrack2DHistos_.push_back(tfd.make<TH2F>("h2_kappa_vs_phi",
00554                                            "#kappa vs. #phi;#phi_{Track};#kappa",
00555                                            100,-3.15,3.15, 100, .0,.05));
00556   vTrack2DHistos_.push_back(tfd.make<TH2F>("h2_kappa_vs_eta",
00557                                            "#kappa vs. #eta;#eta_{Track};#kappa",
00558                                            100,-3.15,3.15, 100, .0,.05));
00559   vTrack2DHistos_.push_back(tfd.make<TH2F>("h2_normchi2_vs_kappa",
00560                                            "#kappa vs. #chi^{2}/ndof;#chi^{2}/ndof;#kappa",
00561                                            100,0.,10, 100,-.03,.03));
00562 
00563   /****************** Definition of 2-D Histos of ResX vs momenta ****************************/
00564   vTrack2DHistos_.push_back(tfd.make<TH2F>("p_vs_resXprime_pixB",
00565                                            "#momentum vs. #resX in pixB;#momentum;#resX",
00566                                            15,0.,15., 200, -0.1,0.1));                     
00567   vTrack2DHistos_.push_back(tfd.make<TH2F>("p_vs_resXprime_pixE",
00568                                            "#momentum vs. #resX in pixE;#momentum;#resX",
00569                                            15,0.,15., 200, -0.1,0.1)); 
00570   vTrack2DHistos_.push_back(tfd.make<TH2F>("p_vs_resXprime_TIB",
00571                                            "#momentum vs. #resX in TIB;#momentum;#resX",
00572                                            15,0.,15., 200, -0.1,0.1)); 
00573   vTrack2DHistos_.push_back(tfd.make<TH2F>("p_vs_resXprime_TID",
00574                                            "#momentum vs. #resX in TID;#momentum;#resX",
00575                                            15,0.,15., 200, -0.1,0.1)); 
00576   vTrack2DHistos_.push_back(tfd.make<TH2F>("p_vs_resXprime_TOB",
00577                                            "#momentum vs. #resX in TOB;#momentum;#resX",
00578                                            15,0.,15., 200, -0.1,0.1));
00579   vTrack2DHistos_.push_back(tfd.make<TH2F>("p_vs_resXprime_TEC",
00580                                            "#momentum vs. #resX in TEC;#momentum;#resX",
00581                                            15,0.,15., 200, -0.1,0.1));  
00582 
00583   /****************** Definition of 2-D Histos of ResY vs momenta ****************************/
00584   vTrack2DHistos_.push_back(tfd.make<TH2F>("p_vs_resYprime_pixB",
00585                                            "#momentum vs. #resY in pixB;#momentum;#resY",
00586                                            15,0.,15., 200, -0.1,0.1));                     
00587   vTrack2DHistos_.push_back(tfd.make<TH2F>("p_vs_resYprime_pixE",
00588                                            "#momentum vs. #resY in pixE;#momentum;#resY",
00589                                            15,0.,15., 200, -0.1,0.1)); 
00590 
00591 }
00592 
00593 
00594 void
00595 TrackerOfflineValidation::bookDirHists(DirectoryWrapper& tfd, const Alignable& ali, const AlignableObjectId& aliobjid)
00596 {
00597   std::vector<Alignable*> alivec(ali.components());
00598   for(int i=0, iEnd = ali.components().size();i < iEnd; ++i) {
00599     std::string structurename  = aliobjid.typeToName((alivec)[i]->alignableObjectId());
00600     LogDebug("TrackerOfflineValidation") << "StructureName = " << structurename;
00601     std::stringstream dirname;
00602     dirname << structurename;
00603     // add no suffix counter to Strip and Pixel, just aesthetics
00604     if (structurename != "Strip" && structurename != "Pixel") dirname << "_" << i+1;
00605 
00606     if (structurename.find("Endcap",0) != std::string::npos ) {
00607       DirectoryWrapper f(tfd,dirname.str(),moduleDirectory_,dqmMode_);
00608       bookHists(f, *(alivec)[i], ali.alignableObjectId() , i, aliobjid);
00609       bookDirHists( f, *(alivec)[i], aliobjid);
00610     } else if( !(this->isDetOrDetUnit( (alivec)[i]->alignableObjectId()) )
00611               || alivec[i]->components().size() > 1) {      
00612       DirectoryWrapper f(tfd,dirname.str(),moduleDirectory_,dqmMode_);
00613       bookHists(tfd, *(alivec)[i], ali.alignableObjectId() , i, aliobjid);
00614       bookDirHists( f, *(alivec)[i], aliobjid);
00615     } else {
00616       bookHists(tfd, *(alivec)[i], ali.alignableObjectId() , i, aliobjid);
00617     }
00618   }
00619 }
00620 
00621 
00622 void 
00623 TrackerOfflineValidation::bookHists(DirectoryWrapper& tfd, const Alignable& ali, align::StructureType type, int i, const AlignableObjectId& aliobjid)
00624 {
00625   TrackerAlignableId aliid;
00626   const DetId id = ali.id();
00627 
00628   // comparing subdetandlayer to subdetIds gives a warning at compile time
00629   // -> subdetandlayer could also be pair<uint,uint> but this has to be adapted
00630   // in AlignableObjId 
00631   std::pair<int,int> subdetandlayer = aliid.typeAndLayerFromDetId(id);
00632 
00633   align::StructureType subtype = align::invalid;
00634   
00635   // are we on or just above det, detunit level respectively?
00636   if (type == align::AlignableDetUnit )subtype = type;
00637   else if( this->isDetOrDetUnit(ali.alignableObjectId()) ) subtype = ali.alignableObjectId();
00638   
00639   // construct histogramm title and name
00640   std::stringstream histoname, histotitle, normhistoname, normhistotitle, 
00641     yhistoname, yhistotitle,
00642     xprimehistoname, xprimehistotitle, normxprimehistoname, normxprimehistotitle,
00643     yprimehistoname, yprimehistotitle, normyprimehistoname, normyprimehistotitle,
00644     localxname, localxtitle, localyname, localytitle,
00645     resxvsxprofilename, resxvsxprofiletitle, resyvsxprofilename, resyvsxprofiletitle,
00646     resxvsyprofilename, resxvsyprofiletitle, resyvsyprofilename, resyvsyprofiletitle; 
00647   
00648   std::string wheel_or_layer;
00649 
00650   if( this->isEndCap(static_cast<uint32_t>(subdetandlayer.first)) ) wheel_or_layer = "_wheel_";
00651   else if ( this->isBarrel(static_cast<uint32_t>(subdetandlayer.first)) ) wheel_or_layer = "_layer_";
00652   else edm::LogWarning("TrackerOfflineValidation") << "@SUB=TrackerOfflineValidation::bookHists" 
00653                                                    << "Unknown subdetid: " <<  subdetandlayer.first;     
00654   
00655   histoname << "h_residuals_subdet_" << subdetandlayer.first 
00656             << wheel_or_layer << subdetandlayer.second << "_module_" << id.rawId();
00657   yhistoname << "h_y_residuals_subdet_" << subdetandlayer.first 
00658              << wheel_or_layer << subdetandlayer.second << "_module_" << id.rawId();
00659   xprimehistoname << "h_xprime_residuals_subdet_" << subdetandlayer.first 
00660                   << wheel_or_layer << subdetandlayer.second << "_module_" << id.rawId();
00661   yprimehistoname << "h_yprime_residuals_subdet_" << subdetandlayer.first 
00662                   << wheel_or_layer << subdetandlayer.second << "_module_" << id.rawId();
00663   normhistoname << "h_normresiduals_subdet_" << subdetandlayer.first 
00664                 << wheel_or_layer << subdetandlayer.second << "_module_" << id.rawId();
00665   normxprimehistoname << "h_normxprimeresiduals_subdet_" << subdetandlayer.first 
00666                       << wheel_or_layer << subdetandlayer.second << "_module_" << id.rawId();
00667   normyprimehistoname << "h_normyprimeresiduals_subdet_" << subdetandlayer.first 
00668                       << wheel_or_layer << subdetandlayer.second << "_module_" << id.rawId();
00669   histotitle << "X Residual for module " << id.rawId() << ";x_{tr} - x_{hit} [cm]";
00670   yhistotitle << "Y Residual for module " << id.rawId() << ";y_{tr} - y_{hit} [cm]";
00671   normhistotitle << "Normalized Residual for module " << id.rawId() << ";x_{tr} - x_{hit}/#sigma";
00672   xprimehistotitle << "X' Residual for module " << id.rawId() << ";(x_{tr} - x_{hit})' [cm]";
00673   normxprimehistotitle << "Normalized X' Residual for module " << id.rawId() << ";(x_{tr} - x_{hit})'/#sigma";
00674   yprimehistotitle << "Y' Residual for module " << id.rawId() << ";(y_{tr} - y_{hit})' [cm]";
00675   normyprimehistotitle << "Normalized Y' Residual for module " << id.rawId() << ";(y_{tr} - y_{hit})'/#sigma";
00676   
00677   if ( moduleLevelProfiles_ ) {
00678     localxname << "h_localx_subdet_" << subdetandlayer.first 
00679                << wheel_or_layer << subdetandlayer.second << "_module_" << id.rawId();
00680     localyname << "h_localy_subdet_" << subdetandlayer.first 
00681                << wheel_or_layer << subdetandlayer.second << "_module_" << id.rawId();
00682     localxtitle << "u local for module " << id.rawId() << "; u_{tr,r}";
00683     localytitle << "v local for module " << id.rawId() << "; v_{tr,r}";
00684 
00685     resxvsxprofilename << "p_residuals_x_vs_x_subdet_" << subdetandlayer.first 
00686                        << wheel_or_layer << subdetandlayer.second << "_module_" << id.rawId();
00687     resyvsxprofilename << "p_residuals_y_vs_x_subdet_" << subdetandlayer.first 
00688                        << wheel_or_layer << subdetandlayer.second << "_module_" << id.rawId();
00689     resxvsyprofilename << "p_residuals_x_vs_y_subdet_" << subdetandlayer.first 
00690                        << wheel_or_layer << subdetandlayer.second << "_module_" << id.rawId();
00691     resyvsyprofilename << "p_residuals_y_vs_y_subdet_" << subdetandlayer.first 
00692                        << wheel_or_layer << subdetandlayer.second << "_module_" << id.rawId();
00693     resxvsxprofiletitle << "U Residual vs u for module " << id.rawId() << "; u_{tr,r} ;(u_{tr} - u_{hit})/tan#alpha [cm]";
00694     resyvsxprofiletitle << "V Residual vs u for module " << id.rawId() << "; u_{tr,r} ;(v_{tr} - v_{hit})/tan#beta  [cm]";
00695     resxvsyprofiletitle << "U Residual vs v for module " << id.rawId() << "; v_{tr,r} ;(u_{tr} - u_{hit})/tan#alpha [cm]";
00696     resyvsyprofiletitle << "V Residual vs v for module " << id.rawId() << "; v_{tr,r} ;(v_{tr} - v_{hit})/tan#beta  [cm]";
00697   }
00698   
00699   if( this->isDetOrDetUnit( subtype ) ) {
00700     ModuleHistos &histStruct = this->getHistStructFromMap(id);
00701     int nbins = 0;
00702     double xmin = 0., xmax = 0.;
00703     double ymin = -0.1, ymax = 0.1;
00704 
00705     // do not allow transient hists in DQM mode
00706     bool moduleLevelHistsTransient(moduleLevelHistsTransient_);
00707     if (dqmMode_) moduleLevelHistsTransient = false;
00708     
00709     // decide via cfg if hists in local coordinates should be booked 
00710     if(lCoorHistOn_) {
00711       this->getBinning(id.subdetId(), XResidual, nbins, xmin, xmax);
00712       histStruct.ResHisto = this->bookTH1F(moduleLevelHistsTransient, tfd, 
00713                                            histoname.str().c_str(),histotitle.str().c_str(),                 
00714                                            nbins, xmin, xmax);
00715       this->getBinning(id.subdetId(), NormXResidual, nbins, xmin, xmax);
00716       histStruct.NormResHisto = this->bookTH1F(moduleLevelHistsTransient, tfd,
00717                                                normhistoname.str().c_str(),normhistotitle.str().c_str(),
00718                                                nbins, xmin, xmax);
00719     } 
00720     this->getBinning(id.subdetId(), XprimeResidual, nbins, xmin, xmax);
00721     histStruct.ResXprimeHisto = this->bookTH1F(moduleLevelHistsTransient, tfd, 
00722                                                xprimehistoname.str().c_str(),xprimehistotitle.str().c_str(),
00723                                                nbins, xmin, xmax);
00724     this->getBinning(id.subdetId(), NormXprimeResidual, nbins, xmin, xmax);
00725     histStruct.NormResXprimeHisto = this->bookTH1F(moduleLevelHistsTransient, tfd, 
00726                                                    normxprimehistoname.str().c_str(),normxprimehistotitle.str().c_str(),
00727                                                    nbins, xmin, xmax);
00728 
00729     if ( moduleLevelProfiles_ ) {
00730       this->getBinning(id.subdetId(), XResidualProfile, nbins, xmin, xmax);      
00731 
00732       histStruct.LocalX = this->bookTH1F(moduleLevelHistsTransient, tfd,
00733                                          localxname.str().c_str(),localxtitle.str().c_str(),
00734                                          nbins, xmin, xmax);
00735       histStruct.LocalY = this->bookTH1F(moduleLevelHistsTransient, tfd,
00736                                          localyname.str().c_str(),localytitle.str().c_str(),
00737                                          nbins, xmin, xmax);
00738       histStruct.ResXvsXProfile = this->bookTProfile(moduleLevelHistsTransient, tfd,
00739                                                      resxvsxprofilename.str().c_str(),resxvsxprofiletitle.str().c_str(),
00740                                                      nbins, xmin, xmax, ymin, ymax);
00741       histStruct.ResXvsXProfile->Sumw2(); // to be filled with weights, so uncertainties need sum of square of weights
00742       histStruct.ResXvsYProfile = this->bookTProfile(moduleLevelHistsTransient, tfd,
00743                                                      resxvsyprofilename.str().c_str(),resxvsyprofiletitle.str().c_str(),
00744                                                      nbins, xmin, xmax, ymin, ymax);
00745       histStruct.ResXvsYProfile->Sumw2(); // to be filled with weights, so uncertainties need sum of square of weights
00746     }
00747 
00748     if( this->isPixel(subdetandlayer.first) || stripYResiduals_ ) {
00749       this->getBinning(id.subdetId(), YprimeResidual, nbins, xmin, xmax);
00750       histStruct.ResYprimeHisto = this->bookTH1F(moduleLevelHistsTransient, tfd,
00751                                                  yprimehistoname.str().c_str(),yprimehistotitle.str().c_str(),
00752                                                  nbins, xmin, xmax);
00753       if (lCoorHistOn_) { // un-primed y-residual
00754         this->getBinning(id.subdetId(), YResidual, nbins, xmin, xmax);
00755         histStruct.ResYHisto = this->bookTH1F(moduleLevelHistsTransient, tfd, 
00756                                               yhistoname.str().c_str(), yhistotitle.str().c_str(),
00757                                               nbins, xmin, xmax);
00758       }
00759       this->getBinning(id.subdetId(), NormYprimeResidual, nbins, xmin, xmax);
00760       histStruct.NormResYprimeHisto = this->bookTH1F(moduleLevelHistsTransient, tfd, 
00761                                                      normyprimehistoname.str().c_str(),normyprimehistotitle.str().c_str(),
00762                                                      nbins, xmin, xmax);
00763       // Here we could add un-primed normalised y-residuals if(lCoorHistOn_)...
00764       if ( moduleLevelProfiles_ ) {
00765         this->getBinning(id.subdetId(), YResidualProfile, nbins, xmin, xmax);      
00766         
00767         histStruct.ResYvsXProfile = this->bookTProfile(moduleLevelHistsTransient, tfd,
00768                                                        resyvsxprofilename.str().c_str(),resyvsxprofiletitle.str().c_str(),
00769                                                        nbins, xmin, xmax, ymin, ymax);
00770         histStruct.ResYvsXProfile->Sumw2(); // to be filled with weights, so uncertainties need sum of square of weights
00771         histStruct.ResYvsYProfile = this->bookTProfile(moduleLevelHistsTransient, tfd,
00772                                                        resyvsyprofilename.str().c_str(),resyvsyprofiletitle.str().c_str(),
00773                                                        nbins, xmin, xmax, ymin, ymax);
00774         histStruct.ResYvsYProfile->Sumw2(); // to be filled with weights, so uncertainties need sum of square of weights
00775       }
00776     }
00777   }
00778 }
00779 
00780 
00781 TH1* TrackerOfflineValidation::bookTH1F(bool isTransient, DirectoryWrapper& tfd, const char* histName, const char* histTitle, 
00782                                         int nBinsX, double lowX, double highX)
00783 {
00784   if (isTransient) {
00785     vDeleteObjects_.push_back(new TH1F(histName, histTitle, nBinsX, lowX, highX));
00786     return vDeleteObjects_.back(); // return last element of vector
00787   } 
00788   else
00789     return tfd.make<TH1F>(histName, histTitle, nBinsX, lowX, highX);
00790 }
00791 
00792 TProfile* TrackerOfflineValidation::bookTProfile(bool isTransient, DirectoryWrapper& tfd, const char* histName, const char* histTitle, 
00793                                                  int nBinsX, double lowX, double highX)
00794 {
00795   if (isTransient) {
00796     TProfile * profile = new TProfile(histName, histTitle, nBinsX, lowX, highX);
00797     vDeleteObjects_.push_back(profile);
00798     return profile;
00799   }
00800   else
00801     return (TProfile*)tfd.make<TProfile>(histName, histTitle, nBinsX, lowX, highX);
00802 }
00803 
00804 
00805 TProfile* TrackerOfflineValidation::bookTProfile(bool isTransient, DirectoryWrapper& tfd, const char* histName, const char* histTitle, 
00806                                                  int nBinsX, double lowX, double highX, double lowY, double highY)
00807 {
00808   if (isTransient) {
00809     TProfile * profile = new TProfile(histName, histTitle, nBinsX, lowX, highX, lowY, highY);
00810     vDeleteObjects_.push_back(profile);
00811     return profile;
00812   }
00813   else
00814     return (TProfile*)tfd.make<TProfile>(histName, histTitle, nBinsX, lowX, highX, lowY, highY);
00815 }
00816 
00817 bool TrackerOfflineValidation::isBarrel(uint32_t subDetId)
00818 {
00819   return (subDetId == StripSubdetector::TIB ||
00820           subDetId == StripSubdetector::TOB ||
00821           subDetId == PixelSubdetector::PixelBarrel );
00822 }
00823 
00824 
00825 bool TrackerOfflineValidation::isEndCap(uint32_t subDetId)
00826 {
00827   return ( subDetId == StripSubdetector::TID ||
00828            subDetId == StripSubdetector::TEC ||
00829            subDetId == PixelSubdetector::PixelEndcap );
00830 }
00831 
00832 
00833 bool TrackerOfflineValidation::isPixel(uint32_t subDetId)
00834 {
00835   return (subDetId == PixelSubdetector::PixelBarrel ||
00836           subDetId == PixelSubdetector::PixelEndcap );
00837 }
00838 
00839 
00840 bool TrackerOfflineValidation::isDetOrDetUnit(align::StructureType type)
00841 {
00842   return ( type == align::AlignableDet ||
00843            type == align::AlignableDetUnit );
00844 }
00845 
00846 
00847 void 
00848 TrackerOfflineValidation::getBinning(uint32_t subDetId, 
00849                                      TrackerOfflineValidation::HistogrammType residualType, 
00850                                      int& nBinsX, double& lowerBoundX, double& upperBoundX)
00851 {
00852   // determine if 
00853   const bool isPixel = this->isPixel(subDetId);
00854   
00855   edm::ParameterSet binningPSet;
00856   
00857   switch(residualType) 
00858     {
00859     case XResidual :
00860       if(isPixel) binningPSet = parSet_.getParameter<edm::ParameterSet>("TH1XResPixelModules");                
00861       else binningPSet        = parSet_.getParameter<edm::ParameterSet>("TH1XResStripModules");                
00862       break;
00863     case NormXResidual : 
00864       if(isPixel) binningPSet = parSet_.getParameter<edm::ParameterSet>("TH1NormXResPixelModules");             
00865       else binningPSet        = parSet_.getParameter<edm::ParameterSet>("TH1NormXResStripModules");                
00866       break;
00867     case XprimeResidual :
00868       if(isPixel) binningPSet = parSet_.getParameter<edm::ParameterSet>("TH1XprimeResPixelModules");                
00869       else binningPSet        = parSet_.getParameter<edm::ParameterSet>("TH1XprimeResStripModules");                
00870       break;
00871     case NormXprimeResidual :
00872       if(isPixel) binningPSet = parSet_.getParameter<edm::ParameterSet>("TH1NormXprimeResPixelModules");
00873       else binningPSet        = parSet_.getParameter<edm::ParameterSet>("TH1NormXprimeResStripModules");
00874       break;
00875     case YResidual : // borrow y-residual binning from yprime
00876     case YprimeResidual :
00877       if(isPixel) binningPSet = parSet_.getParameter<edm::ParameterSet>("TH1YResPixelModules");                
00878       else binningPSet        = parSet_.getParameter<edm::ParameterSet>("TH1YResStripModules");                
00879       break; 
00880       /* case NormYResidual :*/
00881     case NormYprimeResidual :
00882       if(isPixel) binningPSet = parSet_.getParameter<edm::ParameterSet>("TH1NormYResPixelModules");             
00883       else binningPSet        = parSet_.getParameter<edm::ParameterSet>("TH1NormYResStripModules");  
00884       break;
00885     case XResidualProfile :
00886       if(isPixel) binningPSet = parSet_.getParameter<edm::ParameterSet>("TProfileXResPixelModules");                
00887       else binningPSet        = parSet_.getParameter<edm::ParameterSet>("TProfileXResStripModules");                
00888       break;
00889     case YResidualProfile :
00890       if(isPixel) binningPSet = parSet_.getParameter<edm::ParameterSet>("TProfileYResPixelModules");                
00891       else binningPSet        = parSet_.getParameter<edm::ParameterSet>("TProfileYResStripModules");                
00892       break;
00893     }
00894   nBinsX      = binningPSet.getParameter<int32_t>("Nbinx");                    
00895   lowerBoundX = binningPSet.getParameter<double>("xmin");                      
00896   upperBoundX = binningPSet.getParameter<double>("xmax");     
00897 }
00898 
00899 
00900 void 
00901 TrackerOfflineValidation::setSummaryBin(int bin, TH1* targetHist, TH1* sourceHist)
00902 {
00903   if(targetHist && sourceHist) {
00904     targetHist->SetBinContent(bin, sourceHist->GetMean(1));
00905     if(useFwhm_) targetHist->SetBinError(bin, Fwhm(sourceHist)/2.);
00906     else targetHist->SetBinError(bin, sourceHist->GetRMS(1) );
00907   }
00908   else return;
00909 }
00910 
00911 
00912 void 
00913 TrackerOfflineValidation::summarizeBinInContainer( int bin, SummaryContainer& targetContainer, 
00914                                                    SummaryContainer& sourceContainer)
00915 {
00916   this->setSummaryBin(bin, targetContainer.summaryXResiduals_, sourceContainer.sumXResiduals_);
00917   this->setSummaryBin(bin, targetContainer.summaryNormXResiduals_, sourceContainer.sumNormXResiduals_);
00918   // If no y-residual hists, just returns:
00919   this->setSummaryBin(bin, targetContainer.summaryYResiduals_, sourceContainer.sumYResiduals_);
00920   this->setSummaryBin(bin, targetContainer.summaryNormYResiduals_, sourceContainer.sumNormYResiduals_);
00921 }
00922 
00923 
00924 void 
00925 TrackerOfflineValidation::summarizeBinInContainer( int bin, uint32_t subDetId, 
00926                                                    SummaryContainer& targetContainer, 
00927                                                    ModuleHistos& sourceContainer)
00928 {
00929   // takes two summary Containers and sets summaryBins for all histograms
00930   this->setSummaryBin(bin, targetContainer.summaryXResiduals_, sourceContainer.ResXprimeHisto);
00931   this->setSummaryBin(bin, targetContainer.summaryNormXResiduals_, sourceContainer.NormResXprimeHisto);
00932   if( this->isPixel(subDetId) || stripYResiduals_ ) {
00933     this->setSummaryBin(bin, targetContainer.summaryYResiduals_, sourceContainer.ResYprimeHisto);
00934     this->setSummaryBin(bin, targetContainer.summaryNormYResiduals_, sourceContainer.NormResYprimeHisto);
00935   }
00936 }
00937 
00938 
00939 TrackerOfflineValidation::ModuleHistos& 
00940 TrackerOfflineValidation::getHistStructFromMap(const DetId& detid)
00941 {
00942   // get a struct with histograms from the respective map
00943   // if no object exist, the reference is automatically created by the map
00944   // throw exception if non-tracker id is passed
00945   uint subdetid = detid.subdetId();
00946   if(subdetid == PixelSubdetector::PixelBarrel ) {
00947     return mPxbResiduals_[detid.rawId()];
00948   } else if (subdetid == PixelSubdetector::PixelEndcap) {
00949     return mPxeResiduals_[detid.rawId()];
00950   } else if(subdetid  == StripSubdetector::TIB) {
00951     return mTibResiduals_[detid.rawId()];
00952   } else if(subdetid  == StripSubdetector::TID) {
00953     return mTidResiduals_[detid.rawId()];
00954   } else if(subdetid  == StripSubdetector::TOB) {
00955     return mTobResiduals_[detid.rawId()];
00956   } else if(subdetid  == StripSubdetector::TEC) {
00957     return mTecResiduals_[detid.rawId()];
00958   } else {
00959     throw cms::Exception("Geometry Error")
00960       << "[TrackerOfflineValidation] Error, tried to get reference for non-tracker subdet " << subdetid 
00961       << " from detector " << detid.det();
00962     return mPxbResiduals_[0];
00963   }
00964 }
00965 
00966 
00967 // ------------ method called to for each event  ------------
00968 void
00969 TrackerOfflineValidation::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup)
00970 {
00971   if (useOverflowForRMS_)TH1::StatOverflows(kTRUE);
00972   this->checkBookHists(iSetup); // check whether hists are booked and do so if not yet done
00973   
00974   TrackerValidationVariables avalidator_(iSetup,parSet_);
00975     
00976   std::vector<TrackerValidationVariables::AVTrackStruct> vTrackstruct;
00977   avalidator_.fillTrackQuantities(iEvent, vTrackstruct);
00978   
00979   for (std::vector<TrackerValidationVariables::AVTrackStruct>::const_iterator itT = vTrackstruct.begin();        
00980        itT != vTrackstruct.end();
00981        ++itT) {
00982     
00983     // Fill 1D track histos
00984     static const int etaindex = this->GetIndex(vTrackHistos_,"h_tracketa");
00985     vTrackHistos_[etaindex]->Fill(itT->eta);
00986     static const int phiindex = this->GetIndex(vTrackHistos_,"h_trackphi");
00987     vTrackHistos_[phiindex]->Fill(itT->phi);
00988     static const int numOfValidHitsindex = this->GetIndex(vTrackHistos_,"h_trackNumberOfValidHits");
00989     vTrackHistos_[numOfValidHitsindex]->Fill(itT->numberOfValidHits);
00990     static const int numOfLostHitsindex = this->GetIndex(vTrackHistos_,"h_trackNumberOfLostHits");
00991     vTrackHistos_[numOfLostHitsindex]->Fill(itT->numberOfLostHits);
00992     static const int kappaindex = this->GetIndex(vTrackHistos_,"h_curvature");
00993     vTrackHistos_[kappaindex]->Fill(itT->kappa);
00994     static const int kappaposindex = this->GetIndex(vTrackHistos_,"h_curvature_pos");
00995     if (itT->charge > 0)
00996       vTrackHistos_[kappaposindex]->Fill(fabs(itT->kappa));
00997     static const int kappanegindex = this->GetIndex(vTrackHistos_,"h_curvature_neg");
00998     if (itT->charge < 0)
00999       vTrackHistos_[kappanegindex]->Fill(fabs(itT->kappa));
01000     static const int normchi2index = this->GetIndex(vTrackHistos_,"h_normchi2");
01001     vTrackHistos_[normchi2index]->Fill(itT->normchi2);
01002     static const int chi2index = this->GetIndex(vTrackHistos_,"h_chi2");
01003     vTrackHistos_[chi2index]->Fill(itT->chi2);
01004     static const int chi2Probindex = this->GetIndex(vTrackHistos_,"h_chi2Prob");
01005     vTrackHistos_[chi2Probindex]->Fill(itT->chi2Prob);
01006     static const int ptindex = this->GetIndex(vTrackHistos_,"h_pt");
01007     vTrackHistos_[ptindex]->Fill(itT->pt);
01008     if (itT->ptError != 0.) {
01009       static const int ptResolutionindex = this->GetIndex(vTrackHistos_,"h_ptResolution");
01010       vTrackHistos_[ptResolutionindex]->Fill(itT->ptError/itT->pt);
01011     }
01012     // Fill track profiles
01013     static const int d0phiindex = this->GetIndex(vTrackProfiles_,"p_d0_vs_phi");
01014     vTrackProfiles_[d0phiindex]->Fill(itT->phi,itT->d0);
01015     static const int dzphiindex = this->GetIndex(vTrackProfiles_,"p_dz_vs_phi");
01016     vTrackProfiles_[dzphiindex]->Fill(itT->phi,itT->dz);
01017     static const int d0etaindex = this->GetIndex(vTrackProfiles_,"p_d0_vs_eta");
01018     vTrackProfiles_[d0etaindex]->Fill(itT->eta,itT->d0);
01019     static const int dzetaindex = this->GetIndex(vTrackProfiles_,"p_dz_vs_eta");
01020     vTrackProfiles_[dzetaindex]->Fill(itT->eta,itT->dz);
01021     static const int chiphiindex = this->GetIndex(vTrackProfiles_,"p_chi2_vs_phi");
01022     vTrackProfiles_[chiphiindex]->Fill(itT->phi,itT->chi2);
01023     static const int chiProbphiindex = this->GetIndex(vTrackProfiles_,"p_chi2Prob_vs_phi");
01024     vTrackProfiles_[chiProbphiindex]->Fill(itT->phi,itT->chi2Prob);
01025     static const int chiProbabsd0index = this->GetIndex(vTrackProfiles_,"p_chi2Prob_vs_d0");
01026     vTrackProfiles_[chiProbabsd0index]->Fill(fabs(itT->d0),itT->chi2Prob);
01027     static const int normchiphiindex = this->GetIndex(vTrackProfiles_,"p_normchi2_vs_phi");
01028     vTrackProfiles_[normchiphiindex]->Fill(itT->phi,itT->normchi2);
01029     static const int chietaindex = this->GetIndex(vTrackProfiles_,"p_chi2_vs_eta");
01030     vTrackProfiles_[chietaindex]->Fill(itT->eta,itT->chi2);
01031     static const int normchiptindex = this->GetIndex(vTrackProfiles_,"p_normchi2_vs_pt");
01032     vTrackProfiles_[normchiptindex]->Fill(itT->pt,itT->normchi2);
01033     static const int normchipindex = this->GetIndex(vTrackProfiles_,"p_normchi2_vs_p");
01034     vTrackProfiles_[normchipindex]->Fill(itT->p,itT->normchi2);
01035     static const int chiProbetaindex = this->GetIndex(vTrackProfiles_,"p_chi2Prob_vs_eta");
01036     vTrackProfiles_[chiProbetaindex]->Fill(itT->eta,itT->chi2Prob);
01037     static const int normchietaindex = this->GetIndex(vTrackProfiles_,"p_normchi2_vs_eta");
01038     vTrackProfiles_[normchietaindex]->Fill(itT->eta,itT->normchi2);
01039     static const int kappaphiindex = this->GetIndex(vTrackProfiles_,"p_kappa_vs_phi");
01040     vTrackProfiles_[kappaphiindex]->Fill(itT->phi,itT->kappa);
01041     static const int kappaetaindex = this->GetIndex(vTrackProfiles_,"p_kappa_vs_eta");
01042     vTrackProfiles_[kappaetaindex]->Fill(itT->eta,itT->kappa);
01043     static const int ptResphiindex = this->GetIndex(vTrackProfiles_,"p_ptResolution_vs_phi");
01044     vTrackProfiles_[ptResphiindex]->Fill(itT->phi,itT->ptError/itT->pt);
01045     static const int ptResetaindex = this->GetIndex(vTrackProfiles_,"p_ptResolution_vs_eta");
01046     vTrackProfiles_[ptResetaindex]->Fill(itT->eta,itT->ptError/itT->pt);
01047 
01048     // Fill 2D track histos
01049     static const int d0phiindex_2d = this->GetIndex(vTrack2DHistos_,"h2_d0_vs_phi");
01050     vTrack2DHistos_[d0phiindex_2d]->Fill(itT->phi,itT->d0);
01051     static const int dzphiindex_2d = this->GetIndex(vTrack2DHistos_,"h2_dz_vs_phi");
01052     vTrack2DHistos_[dzphiindex_2d]->Fill(itT->phi,itT->dz);
01053     static const int d0etaindex_2d = this->GetIndex(vTrack2DHistos_,"h2_d0_vs_eta");
01054     vTrack2DHistos_[d0etaindex_2d]->Fill(itT->eta,itT->d0);
01055     static const int dzetaindex_2d = this->GetIndex(vTrack2DHistos_,"h2_dz_vs_eta");
01056     vTrack2DHistos_[dzetaindex_2d]->Fill(itT->eta,itT->dz);
01057     static const int chiphiindex_2d = this->GetIndex(vTrack2DHistos_,"h2_chi2_vs_phi");
01058     vTrack2DHistos_[chiphiindex_2d]->Fill(itT->phi,itT->chi2);
01059     static const int chiProbphiindex_2d = this->GetIndex(vTrack2DHistos_,"h2_chi2Prob_vs_phi");
01060     vTrack2DHistos_[chiProbphiindex_2d]->Fill(itT->phi,itT->chi2Prob);
01061     static const int chiProbabsd0index_2d = this->GetIndex(vTrack2DHistos_,"h2_chi2Prob_vs_d0");
01062     vTrack2DHistos_[chiProbabsd0index_2d]->Fill(fabs(itT->d0),itT->chi2Prob);
01063     static const int normchiphiindex_2d = this->GetIndex(vTrack2DHistos_,"h2_normchi2_vs_phi");
01064     vTrack2DHistos_[normchiphiindex_2d]->Fill(itT->phi,itT->normchi2);
01065     static const int chietaindex_2d = this->GetIndex(vTrack2DHistos_,"h2_chi2_vs_eta");
01066     vTrack2DHistos_[chietaindex_2d]->Fill(itT->eta,itT->chi2);
01067     static const int chiProbetaindex_2d = this->GetIndex(vTrack2DHistos_,"h2_chi2Prob_vs_eta");
01068     vTrack2DHistos_[chiProbetaindex_2d]->Fill(itT->eta,itT->chi2Prob);
01069     static const int normchietaindex_2d = this->GetIndex(vTrack2DHistos_,"h2_normchi2_vs_eta");
01070     vTrack2DHistos_[normchietaindex_2d]->Fill(itT->eta,itT->normchi2);
01071     static const int kappaphiindex_2d = this->GetIndex(vTrack2DHistos_,"h2_kappa_vs_phi");
01072     vTrack2DHistos_[kappaphiindex_2d]->Fill(itT->phi,itT->kappa);
01073     static const int kappaetaindex_2d = this->GetIndex(vTrack2DHistos_,"h2_kappa_vs_eta");
01074     vTrack2DHistos_[kappaetaindex_2d]->Fill(itT->eta,itT->kappa);
01075     static const int normchi2kappa_2d = this->GetIndex(vTrack2DHistos_,"h2_normchi2_vs_kappa");
01076     vTrack2DHistos_[normchi2kappa_2d]->Fill(itT->normchi2,itT->kappa);
01077 
01078     // hit quantities: residuals, normalized residuals
01079     for (std::vector<TrackerValidationVariables::AVHitStruct>::const_iterator itH = itT->hits.begin();
01080          itH != itT->hits.end();
01081          ++itH) {
01082       
01083       DetId detid(itH->rawDetId);
01084       ModuleHistos &histStruct = this->getHistStructFromMap(detid);
01085 
01086       // fill histos in local coordinates if set in cf
01087       if (lCoorHistOn_) {
01088         histStruct.ResHisto->Fill(itH->resX);
01089         if(itH->resErrX != 0) histStruct.NormResHisto->Fill(itH->resX/itH->resErrX);
01090         if (this->isPixel(detid.subdetId()) || stripYResiduals_ ) {
01091           histStruct.ResYHisto->Fill(itH->resY);
01092           // here add un-primed normalised y-residuals if wanted
01093         }
01094       }
01095       if (itH->resXprime != -999.) {
01096         histStruct.ResXprimeHisto->Fill(itH->resXprime);
01097 
01098         /******************************* Fill 2-D histo ResX vs momenta *****************************/
01099         if (detid.subdetId() == PixelSubdetector::PixelBarrel) { 
01100           static const int resXvsPindex_2d = this->GetIndex(vTrack2DHistos_,"p_vs_resXprime_pixB");
01101           vTrack2DHistos_[resXvsPindex_2d]->Fill(itT->p,itH->resXprime);
01102         }       
01103         if (detid.subdetId() == PixelSubdetector::PixelEndcap) { 
01104           static const int resXvsPindex_2d = this->GetIndex(vTrack2DHistos_,"p_vs_resXprime_pixE");
01105           vTrack2DHistos_[resXvsPindex_2d]->Fill(itT->p,itH->resXprime);
01106         }
01107         if (detid.subdetId() == StripSubdetector::TIB) { 
01108           static const int resXvsPindex_2d = this->GetIndex(vTrack2DHistos_,"p_vs_resXprime_TIB");
01109           vTrack2DHistos_[resXvsPindex_2d]->Fill(itT->p,itH->resXprime);
01110         }
01111         if (detid.subdetId() == StripSubdetector::TID) { 
01112           static const int resXvsPindex_2d = this->GetIndex(vTrack2DHistos_,"p_vs_resXprime_TID");
01113           vTrack2DHistos_[resXvsPindex_2d]->Fill(itT->p,itH->resXprime);
01114         }
01115         if (detid.subdetId() == StripSubdetector::TOB) { 
01116           static const int resXvsPindex_2d = this->GetIndex(vTrack2DHistos_,"p_vs_resXprime_TOB");
01117           vTrack2DHistos_[resXvsPindex_2d]->Fill(itT->p,itH->resXprime);
01118         }
01119         if (detid.subdetId() == StripSubdetector::TEC) {   
01120           static const int resXvsPindex_2d = this->GetIndex(vTrack2DHistos_,"p_vs_resXprime_TEC");
01121           vTrack2DHistos_[resXvsPindex_2d]->Fill(itT->p,itH->resXprime);
01122         }
01123         /******************************************/
01124 
01125         if ( moduleLevelProfiles_ && itH->inside ) {
01126           float tgalpha = tan(itH->localAlpha);
01127           if ( fabs(tgalpha)!=0 ){
01128             histStruct.LocalX->Fill(itH->localXnorm, tgalpha*tgalpha); 
01129             histStruct.LocalY->Fill(itH->localYnorm, tgalpha*tgalpha); 
01130 /*           if (this->isEndCap(detid.subdetId()) && !this->isPixel(detid.subdetId())) {
01131              if((itH->resX)*(itH->resXprime)>0){
01132             histStruct.ResXvsXProfile->Fill(itH->localXnorm, itH->resXatTrkY/tgalpha, tgalpha*tgalpha);
01133             histStruct.ResXvsYProfile->Fill(itH->localYnorm, itH->resXatTrkY/tgalpha, tgalpha*tgalpha);
01134              } else {
01135             histStruct.ResXvsXProfile->Fill(itH->localXnorm, (-1)*itH->resXatTrkY/tgalpha, tgalpha*tgalpha);
01136             histStruct.ResXvsYProfile->Fill(itH->localYnorm, (-1)*itH->resXatTrkY/tgalpha, tgalpha*tgalpha);
01137                }
01138 
01139           }else {  
01140 */
01141             histStruct.ResXvsXProfile->Fill(itH->localXnorm, itH->resXatTrkY/tgalpha, tgalpha*tgalpha); 
01142             histStruct.ResXvsYProfile->Fill(itH->localYnorm, itH->resXatTrkY/tgalpha, tgalpha*tgalpha); 
01143 
01144 //          }
01145 
01146           }
01147         }
01148 
01149         if(itH->resXprimeErr != 0 && itH->resXprimeErr != -999 ) {      
01150           histStruct.NormResXprimeHisto->Fill(itH->resXprime/itH->resXprimeErr);
01151         }
01152       }     
01153       
01154       if (itH->resYprime != -999.) {
01155         if (this->isPixel(detid.subdetId()) || stripYResiduals_ ) {
01156           histStruct.ResYprimeHisto->Fill(itH->resYprime);
01157 
01158           /******************************* Fill 2-D histo ResY vs momenta *****************************/
01159           if (detid.subdetId() == PixelSubdetector::PixelBarrel) { 
01160             static const int resYvsPindex_2d = this->GetIndex(vTrack2DHistos_,"p_vs_resYprime_pixB");
01161             vTrack2DHistos_[resYvsPindex_2d]->Fill(itT->p,itH->resYprime);
01162           }     
01163           if (detid.subdetId() == PixelSubdetector::PixelEndcap) { 
01164             static const int resYvsPindex_2d = this->GetIndex(vTrack2DHistos_,"p_vs_resYprime_pixE");
01165             vTrack2DHistos_[resYvsPindex_2d]->Fill(itT->p,itH->resYprime);
01166           }
01167           /******************************************/
01168 
01169           if ( moduleLevelProfiles_ && itH->inside ) {
01170             float tgbeta = tan(itH->localBeta);
01171             if ( fabs(tgbeta)!=0 ){
01172 /*           if (this->isEndCap(detid.subdetId()) && !this->isPixel(detid.subdetId())) {
01173             
01174             if((itH->resY)*(itH->resYprime)>0){
01175             histStruct.ResYvsXProfile->Fill(itH->localXnorm, itH->resYprime/tgbeta, tgbeta*tgbeta);
01176             histStruct.ResYvsYProfile->Fill(itH->localYnorm, itH->resYprime/tgbeta, tgbeta*tgbeta);
01177              } else {
01178             histStruct.ResYvsXProfile->Fill(itH->localXnorm, (-1)*itH->resYprime/tgbeta, tgbeta*tgbeta);
01179             histStruct.ResYvsYProfile->Fill(itH->localYnorm, (-1)*itH->resYprime/tgbeta, tgbeta*tgbeta);
01180                }
01181 
01182           }else {  
01183 */
01184               histStruct.ResYvsXProfile->Fill(itH->localXnorm, itH->resY/tgbeta, tgbeta*tgbeta); 
01185               histStruct.ResYvsYProfile->Fill(itH->localYnorm, itH->resY/tgbeta, tgbeta*tgbeta); 
01186 //              }
01187             }
01188           }
01189 
01190           if (itH->resYprimeErr != 0 && itH->resYprimeErr != -999. ) {  
01191             histStruct.NormResYprimeHisto->Fill(itH->resYprime/itH->resYprimeErr);
01192           } 
01193         }
01194       }
01195       
01196     } // finish loop over hit quantities
01197   } // finish loop over track quantities
01198 
01199   if (useOverflowForRMS_) TH1::StatOverflows(kFALSE);  
01200 }
01201 
01202 
01203 // ------------ method called once each job just after ending the event loop  ------------
01204 void 
01205 TrackerOfflineValidation::endJob()
01206 {
01207 
01208   if (!tkGeom_.product()) return;
01209 
01210   AlignableTracker aliTracker(&(*tkGeom_));
01211   
01212   AlignableObjectId aliobjid;
01213   
01214   static const int kappadiffindex = this->GetIndex(vTrackHistos_,"h_diff_curvature");
01215   vTrackHistos_[kappadiffindex]->Add(vTrackHistos_[this->GetIndex(vTrackHistos_,"h_curvature_neg")],
01216                                      vTrackHistos_[this->GetIndex(vTrackHistos_,"h_curvature_pos")],-1,1);
01217  
01218   // Collate Information for Subdetectors
01219   // create summary histogramms recursively
01220   std::vector<TrackerOfflineValidation::SummaryContainer> vTrackerprofiles;
01221   DirectoryWrapper f("",moduleDirectory_,dqmMode_);
01222   this->collateSummaryHists(f,(aliTracker), 0, aliobjid, vTrackerprofiles);
01223   
01224   if (dqmMode_) return;
01225   // Should be excluded in dqmMode, since TTree is not usable
01226   // In dqmMode tree operations are are sourced out to the additional module TrackerOfflineValidationSummary
01227   
01228   edm::Service<TFileService> fs;
01229   TTree *tree = fs->make<TTree>("TkOffVal","TkOffVal");
01230  
01231   TkOffTreeVariables *treeMemPtr = new TkOffTreeVariables;
01232   // We create branches for all members of 'TkOffTreeVariables' (even if not needed).
01233   // This works because we have a dictionary for 'TkOffTreeVariables'
01234   // (see src/classes_def.xml and src/classes.h):
01235   tree->Branch("TkOffTreeVariables", &treeMemPtr); // address of pointer!
01236  
01237   this->fillTree(*tree, mPxbResiduals_, *treeMemPtr, *tkGeom_);
01238   this->fillTree(*tree, mPxeResiduals_, *treeMemPtr, *tkGeom_);
01239   this->fillTree(*tree, mTibResiduals_, *treeMemPtr, *tkGeom_);
01240   this->fillTree(*tree, mTidResiduals_, *treeMemPtr, *tkGeom_);
01241   this->fillTree(*tree, mTobResiduals_, *treeMemPtr, *tkGeom_);
01242   this->fillTree(*tree, mTecResiduals_, *treeMemPtr, *tkGeom_);
01243 
01244   delete treeMemPtr; treeMemPtr = 0;
01245 }
01246 
01247 
01248 void
01249 TrackerOfflineValidation::collateSummaryHists( DirectoryWrapper& tfd, const Alignable& ali, int i, 
01250                                                const AlignableObjectId& aliobjid, 
01251                                                std::vector<TrackerOfflineValidation::SummaryContainer>& vLevelProfiles)
01252 {
01253   std::vector<Alignable*> alivec(ali.components());
01254   if( this->isDetOrDetUnit((alivec)[0]->alignableObjectId()) ) return;
01255   
01256   for(int iComp=0, iCompEnd = ali.components().size();iComp < iCompEnd; ++iComp) {
01257     std::vector< TrackerOfflineValidation::SummaryContainer > vProfiles;        
01258     std::string structurename  = aliobjid.typeToName((alivec)[iComp]->alignableObjectId());
01259     
01260     LogDebug("TrackerOfflineValidation") << "StructureName = " << structurename;
01261     std::stringstream dirname;
01262     dirname << structurename;
01263     
01264     // add no suffix counter to strip and pixel -> just aesthetics
01265     if (structurename != "Strip" && structurename != "Pixel") dirname << "_" << iComp+1;
01266     
01267     if(  !(this->isDetOrDetUnit( (alivec)[iComp]->alignableObjectId()) )
01268          || (alivec)[0]->components().size() > 1 ) {
01269       DirectoryWrapper f(tfd,dirname.str(),moduleDirectory_,dqmMode_);
01270       this->collateSummaryHists( f, *(alivec)[iComp], i, aliobjid, vProfiles);
01271       vLevelProfiles.push_back(this->bookSummaryHists(tfd, *(alivec[iComp]), ali.alignableObjectId(), iComp+1, aliobjid));
01272       TH1 *hY = vLevelProfiles[iComp].sumYResiduals_;
01273       TH1 *hNormY = vLevelProfiles[iComp].sumNormYResiduals_;
01274       for(uint n = 0; n < vProfiles.size(); ++n) {
01275         this->summarizeBinInContainer(n+1, vLevelProfiles[iComp], vProfiles[n] );
01276         vLevelProfiles[iComp].sumXResiduals_->Add(vProfiles[n].sumXResiduals_);
01277         vLevelProfiles[iComp].sumNormXResiduals_->Add(vProfiles[n].sumNormXResiduals_);
01278         if (hY)     hY->Add(vProfiles[n].sumYResiduals_);         // only if existing
01279         if (hNormY) hNormY->Add(vProfiles[n].sumNormYResiduals_); // dito (pxl, stripYResiduals_)
01280       }
01281       if(dqmMode_)continue;  // No fits in dqmMode
01282       //add fit values to stat box
01283       this->fitResiduals(vLevelProfiles[iComp].sumXResiduals_);
01284       this->fitResiduals(vLevelProfiles[iComp].sumNormXResiduals_);
01285       if (hY)     this->fitResiduals(hY);     // only if existing (pixel or stripYResiduals_)
01286       if (hNormY) this->fitResiduals(hNormY); // dito
01287     } else {
01288       // nothing to be done for det or detunits
01289       continue;
01290     }
01291   }
01292 }
01293 
01294 
01295 TrackerOfflineValidation::SummaryContainer 
01296 TrackerOfflineValidation::bookSummaryHists(DirectoryWrapper& tfd, const Alignable& ali, 
01297                                            align::StructureType type, int i, 
01298                                            const AlignableObjectId& aliobjid)
01299 {
01300   const uint aliSize = ali.components().size();
01301   const align::StructureType alitype = ali.alignableObjectId();
01302   const align::StructureType subtype = ali.components()[0]->alignableObjectId();
01303   const char *aliTypeName = aliobjid.typeToName(alitype).c_str(); // lifetime of char* OK
01304   const char *aliSubtypeName = aliobjid.typeToName(subtype).c_str();
01305   const char *typeName = aliobjid.typeToName(type).c_str();
01306 
01307   const DetId aliDetId = ali.id(); 
01308   // y residuals only if pixel or specially requested for strip:
01309   const bool bookResidY = this->isPixel(aliDetId.subdetId()) || stripYResiduals_;
01310 
01311   SummaryContainer sumContainer;
01312   
01313   // Book summary hists with one bin per component, 
01314   // but special case for Det with two DetUnit that we want to summarize one level up 
01315   // (e.g. in TOBRods with 12 bins for 6 stereo and 6 rphi DetUnit.)
01316   //    component of ali is not Det or Det with just one components
01317   const uint subcompSize = ali.components()[0]->components().size();
01318   if (subtype != align::AlignableDet || subcompSize == 1) { // Det with 1 comp. should not exist anymore...
01319     const TString title(Form("Summary for substructures in %s %d;%s;",aliTypeName,i,aliSubtypeName));
01320     
01321     sumContainer.summaryXResiduals_ = tfd.make<TH1F>(Form("h_summaryX%s_%d",aliTypeName,i), 
01322                                                      title + "#LT #Delta x' #GT",
01323                                                      aliSize, 0.5, aliSize+0.5);
01324     sumContainer.summaryNormXResiduals_ = tfd.make<TH1F>(Form("h_summaryNormX%s_%d",aliTypeName,i), 
01325                                                          title + "#LT #Delta x'/#sigma #GT",
01326                                                          aliSize,0.5,aliSize+0.5);
01327     
01328     if (bookResidY) {
01329       sumContainer.summaryYResiduals_ = tfd.make<TH1F>(Form("h_summaryY%s_%d",aliTypeName,i), 
01330                                                        title + "#LT #Delta y' #GT",
01331                                                        aliSize, 0.5, aliSize+0.5);
01332       sumContainer.summaryNormYResiduals_ = tfd.make<TH1F>(Form("h_summaryNormY%s_%d",aliTypeName,i), 
01333                                                            title + "#LT #Delta y'/#sigma #GT",
01334                                                            aliSize,0.5,aliSize+0.5);
01335     }
01336     
01337   } else if (subtype == align::AlignableDet && subcompSize > 1) { // fixed: was aliSize before
01338     if (subcompSize != 2) { // strange... expect only 2 DetUnits in DS layers
01339       // this 2 is hardcoded factor 2 in binning below and also assumed later on
01340       edm::LogError("Alignment") << "@SUB=bookSummaryHists"
01341                                  << "Det with " << subcompSize << " components";
01342     }
01343     // title contains x-title
01344     const TString title(Form("Summary for substructures in %s %d;%s;", aliTypeName, i,
01345                              aliobjid.typeToName(ali.components()[0]->components()[0]->alignableObjectId()).c_str()));
01346     
01347     sumContainer.summaryXResiduals_ 
01348       = tfd.make<TH1F>(Form("h_summaryX%s_%d", aliTypeName, i), 
01349                        title + "#LT #Delta x' #GT", (2*aliSize), 0.5, 2*aliSize+0.5);
01350     sumContainer.summaryNormXResiduals_ 
01351       = tfd.make<TH1F>(Form("h_summaryNormX%s_%d", aliTypeName, i), 
01352                        title + "#LT #Delta x'/#sigma #GT", (2*aliSize), 0.5, 2*aliSize+0.5);
01353 
01354     if (bookResidY) {
01355       sumContainer.summaryYResiduals_ 
01356         = tfd.make<TH1F>(Form("h_summaryY%s_%d", aliTypeName, i), 
01357                          title + "#LT #Delta y' #GT", (2*aliSize), 0.5, 2*aliSize+0.5);
01358       sumContainer.summaryNormYResiduals_ 
01359         = tfd.make<TH1F>(Form("h_summaryNormY%s_%d", aliTypeName, i), 
01360                          title + "#LT #Delta y'/#sigma #GT", (2*aliSize), 0.5, 2*aliSize+0.5);
01361     }
01362 
01363   } else {
01364     edm::LogError("TrackerOfflineValidation") << "@SUB=TrackerOfflineValidation::bookSummaryHists" 
01365                                               << "No summary histogramm for hierarchy level " 
01366                                               << aliTypeName << " in subdet " << aliDetId.subdetId();
01367   }
01368 
01369   // Now book hists that just sum up the residual histograms from lower levels.
01370   // Axis title is copied from lowest level module of structure.
01371   // Should be safe that y-hists are only touched if non-null pointers...
01372   int nbins = 0;
01373   double xmin = 0., xmax = 0.;
01374   const TString sumTitle(Form("Residual for %s %d in %s;", aliTypeName, i, typeName));
01375   const ModuleHistos &xTitHists = this->getHistStructFromMap(aliDetId); // for x-axis titles
01376   this->getBinning(aliDetId.subdetId(), XprimeResidual, nbins, xmin, xmax);
01377   
01378   sumContainer.sumXResiduals_ = tfd.make<TH1F>(Form("h_Xprime_%s_%d", aliTypeName, i),
01379                                                sumTitle + xTitHists.ResXprimeHisto->GetXaxis()->GetTitle(),
01380                                                nbins, xmin, xmax);
01381   
01382   this->getBinning(aliDetId.subdetId(), NormXprimeResidual, nbins, xmin, xmax);
01383   sumContainer.sumNormXResiduals_ = tfd.make<TH1F>(Form("h_NormXprime_%s_%d",aliTypeName,i), 
01384                                                    sumTitle + xTitHists.NormResXprimeHisto->GetXaxis()->GetTitle(),
01385                                                    nbins, xmin, xmax);
01386   if (bookResidY) {
01387     this->getBinning(aliDetId.subdetId(), YprimeResidual, nbins, xmin, xmax);
01388     sumContainer.sumYResiduals_ = tfd.make<TH1F>(Form("h_Yprime_%s_%d",aliTypeName,i), 
01389                                                  sumTitle + xTitHists.ResYprimeHisto->GetXaxis()->GetTitle(),
01390                                                  nbins, xmin, xmax);
01391     
01392     this->getBinning(aliDetId.subdetId(), NormYprimeResidual, nbins, xmin, xmax);
01393     sumContainer.sumNormYResiduals_ = tfd.make<TH1F>(Form("h_NormYprime_%s_%d",aliTypeName,i), 
01394                                                      sumTitle + xTitHists.NormResYprimeHisto->GetXaxis()->GetTitle(),
01395                                                      nbins, xmin, xmax);
01396   }
01397   
01398   // If we are at the lowest level, we already sum up and fill the summary.
01399 
01400   // special case I: For DetUnits and Dets with only one subcomponent start filling summary histos
01401   if( ( subtype == align::AlignableDet && subcompSize == 1) || subtype  == align::AlignableDetUnit ) {
01402     for(uint k = 0; k < aliSize; ++k) {
01403       DetId detid = ali.components()[k]->id();
01404       ModuleHistos &histStruct = this->getHistStructFromMap(detid);
01405       this->summarizeBinInContainer(k+1, detid.subdetId() ,sumContainer, histStruct );
01406       sumContainer.sumXResiduals_->Add(histStruct.ResXprimeHisto);
01407       sumContainer.sumNormXResiduals_->Add(histStruct.NormResXprimeHisto);
01408       if( this->isPixel(detid.subdetId()) || stripYResiduals_ ) {
01409         sumContainer.sumYResiduals_->Add(histStruct.ResYprimeHisto);
01410         sumContainer.sumNormYResiduals_->Add(histStruct.NormResYprimeHisto);
01411       }
01412     }
01413   } else if( subtype == align::AlignableDet && subcompSize > 1) { // fixed: was aliSize before
01414     // special case II: Fill summary histos for dets with two detunits 
01415     for(uint k = 0; k < aliSize; ++k) {
01416       for(uint j = 0; j < subcompSize; ++j) { // assumes all have same size (as binning does)
01417         DetId detid = ali.components()[k]->components()[j]->id();
01418         ModuleHistos &histStruct = this->getHistStructFromMap(detid);   
01419         this->summarizeBinInContainer(2*k+j+1, detid.subdetId() ,sumContainer, histStruct );
01420         sumContainer.sumXResiduals_->Add( histStruct.ResXprimeHisto);
01421         sumContainer.sumNormXResiduals_->Add( histStruct.NormResXprimeHisto);
01422         if( this->isPixel(detid.subdetId()) || stripYResiduals_ ) {
01423           sumContainer.sumYResiduals_->Add( histStruct.ResYprimeHisto);
01424           sumContainer.sumNormYResiduals_->Add( histStruct.NormResYprimeHisto);
01425         }
01426       }
01427     }
01428   }
01429   return sumContainer;
01430 }
01431 
01432 
01433 float 
01434 TrackerOfflineValidation::Fwhm (const TH1* hist) const
01435 {
01436   float max = hist->GetMaximum();
01437   int left = -1, right = -1;
01438   for(unsigned int i = 1, iEnd = hist->GetNbinsX(); i <= iEnd; ++i) {
01439     if(hist->GetBinContent(i) < max/2. && hist->GetBinContent(i+1) > max/2. && left == -1) {
01440       if(max/2. - hist->GetBinContent(i) < hist->GetBinContent(i+1) - max/2.) {
01441         left = i;
01442         ++i;
01443       } else {
01444         left = i+1;
01445         ++i;
01446       }
01447     }
01448     if(left != -1 && right == -1) {
01449       if(hist->GetBinContent(i) > max/2. && hist->GetBinContent(i+1) < max/2.) {
01450         if( hist->GetBinContent(i) - max/2. < max/2. - hist->GetBinContent(i+1)) {
01451           right = i;
01452         } else {
01453           right = i+1;
01454         }
01455         
01456       }
01457     }
01458   }
01459   return hist->GetXaxis()->GetBinCenter(right) - hist->GetXaxis()->GetBinCenter(left);
01460 }
01461 
01462 
01463 void 
01464 TrackerOfflineValidation::fillTree(TTree& tree,
01465                                    const std::map<int, TrackerOfflineValidation::ModuleHistos>& moduleHist_,
01466                                    TkOffTreeVariables &treeMem, const TrackerGeometry& tkgeom)
01467 {
01468  
01469   for(std::map<int, TrackerOfflineValidation::ModuleHistos>::const_iterator it = moduleHist_.begin(), 
01470         itEnd= moduleHist_.end(); it != itEnd;++it ) { 
01471     treeMem.clear(); // make empty/default
01472     
01473     //variables concerning the tracker components/hierarchy levels
01474     DetId detId_ = it->first;
01475     treeMem.moduleId = detId_;
01476     treeMem.subDetId = detId_.subdetId();
01477     treeMem.isDoubleSide =0;
01478 
01479     if(treeMem.subDetId == PixelSubdetector::PixelBarrel){
01480       PXBDetId pxbId(detId_);
01481       unsigned int whichHalfBarrel(1), rawId(detId_.rawId());  //DetId does not know about halfBarrels is PXB ...
01482       if( (rawId>=302056964 && rawId<302059300) || (rawId>=302123268 && rawId<302127140) ||
01483           (rawId>=302189572 && rawId<302194980) ) whichHalfBarrel=2;
01484       treeMem.layer = pxbId.layer(); 
01485       treeMem.half = whichHalfBarrel;
01486       treeMem.rod = pxbId.ladder();     // ... so, ladder is not per halfBarrel-Layer, but per barrel-layer!
01487       treeMem.module = pxbId.module();
01488     } else if(treeMem.subDetId == PixelSubdetector::PixelEndcap){
01489       PXFDetId pxfId(detId_); 
01490       unsigned int whichHalfCylinder(1), rawId(detId_.rawId());  //DetId does not kmow about halfCylinders in PXF
01491       if( (rawId>=352394500 && rawId<352406032) || (rawId>=352460036 && rawId<352471568) ||
01492           (rawId>=344005892 && rawId<344017424) || (rawId>=344071428 && rawId<344082960) ) whichHalfCylinder=2;
01493       treeMem.layer = pxfId.disk(); 
01494       treeMem.side = pxfId.side();
01495       treeMem.half = whichHalfCylinder;
01496       treeMem.blade = pxfId.blade(); 
01497       treeMem.panel = pxfId.panel();
01498       treeMem.module = pxfId.module();
01499     } else if(treeMem.subDetId == StripSubdetector::TIB){
01500       TIBDetId tibId(detId_); 
01501       unsigned int whichHalfShell(1), rawId(detId_.rawId());  //DetId does not kmow about halfShells in TIB
01502        if ( (rawId>=369120484 && rawId<369120688) || (rawId>=369121540 && rawId<369121776) ||
01503             (rawId>=369136932 && rawId<369137200) || (rawId>=369137988 && rawId<369138288) ||
01504             (rawId>=369153396 && rawId<369153744) || (rawId>=369154436 && rawId<369154800) ||
01505             (rawId>=369169844 && rawId<369170256) || (rawId>=369170900 && rawId<369171344) ||
01506             (rawId>=369124580 && rawId<369124784) || (rawId>=369125636 && rawId<369125872) ||
01507             (rawId>=369141028 && rawId<369141296) || (rawId>=369142084 && rawId<369142384) ||
01508             (rawId>=369157492 && rawId<369157840) || (rawId>=369158532 && rawId<369158896) ||
01509             (rawId>=369173940 && rawId<369174352) || (rawId>=369174996 && rawId<369175440) ) whichHalfShell=2;
01510       treeMem.layer = tibId.layer(); 
01511       treeMem.side = tibId.string()[0];
01512       treeMem.half = whichHalfShell;
01513       treeMem.rod = tibId.string()[2]; 
01514       treeMem.outerInner = tibId.string()[1]; 
01515       treeMem.module = tibId.module();
01516       treeMem.isStereo = tibId.stereo();
01517       treeMem.isDoubleSide = tibId.isDoubleSide();
01518     } else if(treeMem.subDetId == StripSubdetector::TID){
01519       TIDDetId tidId(detId_); 
01520       treeMem.layer = tidId.wheel(); 
01521       treeMem.side = tidId.side();
01522       treeMem.ring = tidId.ring(); 
01523       treeMem.outerInner = tidId.module()[0]; 
01524       treeMem.module = tidId.module()[1];
01525       treeMem.isStereo = tidId.stereo();
01526       treeMem.isDoubleSide = tidId.isDoubleSide();
01527     } else if(treeMem.subDetId == StripSubdetector::TOB){
01528       TOBDetId tobId(detId_); 
01529       treeMem.layer = tobId.layer(); 
01530       treeMem.side = tobId.rod()[0];
01531       treeMem.rod = tobId.rod()[1]; 
01532       treeMem.module = tobId.module();
01533       treeMem.isStereo = tobId.stereo();
01534       treeMem.isDoubleSide = tobId.isDoubleSide();
01535     } else if(treeMem.subDetId == StripSubdetector::TEC) {
01536       TECDetId tecId(detId_); 
01537       treeMem.layer = tecId.wheel(); 
01538       treeMem.side  = tecId.side();
01539       treeMem.ring  = tecId.ring(); 
01540       treeMem.petal = tecId.petal()[1]; 
01541       treeMem.outerInner = tecId.petal()[0];
01542       treeMem.module = tecId.module();
01543       treeMem.isStereo = tecId.stereo();
01544       treeMem.isDoubleSide = tecId.isDoubleSide(); 
01545     }
01546     
01547     //variables concerning the tracker geometry
01548     const Surface::PositionType &gPModule = tkgeom.idToDet(detId_)->position();
01549     treeMem.posPhi = gPModule.phi();
01550     treeMem.posEta = gPModule.eta();
01551     treeMem.posR   = gPModule.perp();
01552     treeMem.posX   = gPModule.x();
01553     treeMem.posY   = gPModule.y();
01554     treeMem.posZ   = gPModule.z();
01555  
01556     const Surface& surface =  tkgeom.idToDet(detId_)->surface();
01557     
01558     //global Orientation of local coordinate system of dets/detUnits   
01559     LocalPoint  lUDirection(1.,0.,0.), lVDirection(0.,1.,0.), lWDirection(0.,0.,1.);
01560     GlobalPoint gUDirection = surface.toGlobal(lUDirection),
01561                 gVDirection = surface.toGlobal(lVDirection),
01562                 gWDirection = surface.toGlobal(lWDirection);
01563     double dR(999.), dPhi(999.), dZ(999.);
01564     if(treeMem.subDetId==PixelSubdetector::PixelBarrel || treeMem.subDetId==StripSubdetector::TIB || treeMem.subDetId==StripSubdetector::TOB){
01565       dR = gWDirection.perp() - gPModule.perp();
01566       dPhi = deltaPhi(gUDirection.phi(),gPModule.phi());
01567       dZ = gVDirection.z() - gPModule.z();
01568       if(dZ>=0.)treeMem.rOrZDirection = 1; else treeMem.rOrZDirection = -1;
01569     }else if(treeMem.subDetId==PixelSubdetector::PixelEndcap){
01570       dR = gUDirection.perp() - gPModule.perp();
01571       dPhi = deltaPhi(gVDirection.phi(),gPModule.phi());
01572       dZ = gWDirection.z() - gPModule.z();
01573       if(dR>=0.)treeMem.rOrZDirection = 1; else treeMem.rOrZDirection = -1;
01574     }else if(treeMem.subDetId==StripSubdetector::TID || treeMem.subDetId==StripSubdetector::TEC){
01575       dR = gVDirection.perp() - gPModule.perp();
01576       dPhi = deltaPhi(gUDirection.phi(),gPModule.phi());
01577       dZ = gWDirection.z() - gPModule.z();
01578       if(dR>=0.)treeMem.rOrZDirection = 1; else treeMem.rOrZDirection = -1;
01579     }
01580     if(dR>=0.)treeMem.rDirection = 1; else treeMem.rDirection = -1;
01581     if(dPhi>=0.)treeMem.phiDirection = 1; else treeMem.phiDirection = -1;
01582     if(dZ>=0.)treeMem.zDirection = 1; else treeMem.zDirection = -1;
01583     
01584     //mean and RMS values (extracted from histograms(Xprime on module level)
01585     treeMem.entries = static_cast<UInt_t>(it->second.ResXprimeHisto->GetEntries());
01586     treeMem.meanX = it->second.ResXprimeHisto->GetMean();
01587     treeMem.rmsX  = it->second.ResXprimeHisto->GetRMS();
01588     //treeMem.sigmaX = Fwhm(it->second.ResXprimeHisto)/2.355;
01589     
01590     if (useFit_) {
01591       //call fit function which returns mean and sigma from the fit
01592       //for absolute residuals
01593       std::pair<float,float> fitResult1 = this->fitResiduals(it->second.ResXprimeHisto);
01594       treeMem.fitMeanX = fitResult1.first;
01595       treeMem.fitSigmaX = fitResult1.second;
01596       //for normalized residuals
01597       std::pair<float,float> fitResult2 = this->fitResiduals(it->second.NormResXprimeHisto);
01598       treeMem.fitMeanNormX = fitResult2.first;
01599       treeMem.fitSigmaNormX = fitResult2.second;
01600     }
01601     
01602     //get median for absolute residuals
01603     treeMem.medianX   = this->getMedian(it->second.ResXprimeHisto);
01604 
01605     int numberOfBins=it->second.ResXprimeHisto->GetNbinsX();
01606     treeMem.numberOfUnderflows = it->second.ResXprimeHisto->GetBinContent(0);
01607     treeMem.numberOfOverflows = it->second.ResXprimeHisto->GetBinContent(numberOfBins+1);
01608     treeMem.numberOfOutliers =  it->second.ResXprimeHisto->GetBinContent(0)+it->second.ResXprimeHisto->GetBinContent(numberOfBins+1);
01609     
01610     //mean and RMS values (extracted from histograms(normalized Xprime on module level)
01611     treeMem.meanNormX = it->second.NormResXprimeHisto->GetMean();
01612     treeMem.rmsNormX = it->second.NormResXprimeHisto->GetRMS();
01613 
01614     double stats[20];
01615     it->second.NormResXprimeHisto->GetStats(stats);
01616     // GF  treeMem.chi2PerDofX = stats[3]/(stats[0]-1);
01617     if (stats[0]) treeMem.chi2PerDofX = stats[3]/stats[0];
01618     
01619     treeMem.sigmaNormX = Fwhm(it->second.NormResXprimeHisto)/2.355;
01620     treeMem.histNameX = it->second.ResXprimeHisto->GetName();
01621     treeMem.histNameNormX = it->second.NormResXprimeHisto->GetName();
01622     
01623     // fill tree variables in local coordinates if set in cfg
01624     if(lCoorHistOn_) {
01625       treeMem.meanLocalX = it->second.ResHisto->GetMean();
01626       treeMem.rmsLocalX = it->second.ResHisto->GetRMS();
01627       treeMem.meanNormLocalX = it->second.NormResHisto->GetMean();
01628       treeMem.rmsNormLocalX = it->second.NormResHisto->GetRMS();
01629 
01630       treeMem.histNameLocalX = it->second.ResHisto->GetName();
01631       treeMem.histNameNormLocalX = it->second.NormResHisto->GetName();
01632       if (it->second.ResYHisto) treeMem.histNameLocalY = it->second.ResYHisto->GetName();
01633     }
01634 
01635     // mean and RMS values in local y (extracted from histograms(normalized Yprime on module level)
01636     // might exist in pixel only
01637     if (it->second.ResYprimeHisto) {//(stripYResiduals_){
01638       TH1 *h = it->second.ResYprimeHisto;
01639       treeMem.meanY = h->GetMean();
01640       treeMem.rmsY  = h->GetRMS();
01641       
01642       if (useFit_) { // fit function which returns mean and sigma from the fit
01643         std::pair<float,float> fitMeanSigma = this->fitResiduals(h);
01644         treeMem.fitMeanY  = fitMeanSigma.first;
01645         treeMem.fitSigmaY = fitMeanSigma.second;
01646       }
01647       
01648       //get median for absolute residuals
01649       treeMem.medianY   = this->getMedian(h);
01650 
01651       treeMem.histNameY = h->GetName();
01652     }
01653     if (it->second.NormResYprimeHisto) {
01654       TH1 *h = it->second.NormResYprimeHisto;
01655       treeMem.meanNormY = h->GetMean();
01656       treeMem.rmsNormY  = h->GetRMS();
01657       h->GetStats(stats); // stats buffer defined above
01658       if (stats[0]) treeMem.chi2PerDofY = stats[3]/stats[0];
01659 
01660       if (useFit_) { // fit function which returns mean and sigma from the fit
01661         std::pair<float,float> fitMeanSigma = this->fitResiduals(h);
01662         treeMem.fitMeanNormY  = fitMeanSigma.first;
01663         treeMem.fitSigmaNormY = fitMeanSigma.second;
01664       }
01665       treeMem.histNameNormY = h->GetName();
01666     }
01667 
01668     if (moduleLevelProfiles_) {
01669       if (it->second.ResXvsXProfile) {
01670         TH1 *h = it->second.ResXvsXProfile;
01671         treeMem.meanResXvsX = h->GetMean();
01672         treeMem.rmsResXvsX  = h->GetRMS();
01673         treeMem.profileNameResXvsX = h->GetName();
01674       } 
01675       if (it->second.ResXvsYProfile) {
01676         TH1 *h = it->second.ResXvsYProfile;
01677         treeMem.meanResXvsY = h->GetMean();
01678         treeMem.rmsResXvsY  = h->GetRMS();
01679         treeMem.profileNameResXvsY = h->GetName();
01680       } 
01681       if (it->second.ResYvsXProfile) {
01682         TH1 *h = it->second.ResYvsXProfile;
01683         treeMem.meanResYvsX = h->GetMean();
01684         treeMem.rmsResYvsX  = h->GetRMS();
01685         treeMem.profileNameResYvsX = h->GetName();
01686       } 
01687       if (it->second.ResYvsYProfile) {
01688         TH1 *h = it->second.ResYvsYProfile;
01689         treeMem.meanResYvsY = h->GetMean();
01690         treeMem.rmsResYvsY  = h->GetRMS();
01691         treeMem.profileNameResYvsY = h->GetName();
01692       }
01693     }
01694 
01695     tree.Fill();
01696   }
01697 }
01698 
01699 
01700 std::pair<float,float> 
01701 TrackerOfflineValidation::fitResiduals(TH1* hist) const
01702 {
01703   std::pair<float,float> fitResult(9999., 9999.);
01704   if (!hist || hist->GetEntries() < 20) return fitResult;
01705 
01706   float mean  = hist->GetMean();
01707   float sigma = hist->GetRMS();
01708 
01709   try { // for < CMSSW_2_2_0 since ROOT warnings from fit are converted to exceptions
01710     // Remove the try/catch for more recent CMSSW!
01711     // first fit: two RMS around mean
01712     TF1 func("tmp", "gaus", mean - 2.*sigma, mean + 2.*sigma); 
01713     if (0 == hist->Fit(&func,"QNR")) { // N: do not blow up file by storing fit!
01714       mean  = func.GetParameter(1);
01715       sigma = func.GetParameter(2);
01716       // second fit: three sigma of first fit around mean of first fit
01717       func.SetRange(mean - 3.*sigma, mean + 3.*sigma);
01718       // I: integral gives more correct results if binning is too wide
01719       // L: Likelihood can treat empty bins correctly (if hist not weighted...)
01720       if (0 == hist->Fit(&func, "Q0LR")) {
01721         if (hist->GetFunction(func.GetName())) { // Take care that it is later on drawn:
01722           hist->GetFunction(func.GetName())->ResetBit(TF1::kNotDraw);
01723         }
01724         fitResult.first = func.GetParameter(1);
01725         fitResult.second = func.GetParameter(2);
01726       }
01727     }
01728   } catch (cms::Exception const & e) {
01729     edm::LogWarning("Alignment") << "@SUB=TrackerOfflineValidation::fitResiduals"
01730                                  << "Caught this exception during ROOT fit: "
01731                                  << e.what();
01732   }
01733   return fitResult;
01734 }
01735 
01736 
01737 float 
01738 TrackerOfflineValidation::getMedian(const TH1* histo) const
01739 {
01740   float median = 999;
01741   int nbins = histo->GetNbinsX();
01742 
01743   //extract median from histogram
01744   double *x = new double[nbins];
01745   double *y = new double[nbins];
01746   for (int j = 0; j < nbins; j++) {
01747     x[j] = histo->GetBinCenter(j+1);
01748     y[j] = histo->GetBinContent(j+1);
01749   }
01750   median = TMath::Median(nbins, x, y);
01751   
01752   delete[] x; x = 0;
01753   delete [] y; y = 0;  
01754 
01755   return median;
01756 
01757 }
01758 //define this as a plug-in
01759 DEFINE_FWK_MODULE(TrackerOfflineValidation);