CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/Alignment/OfflineValidation/plugins/TrackerOfflineValidationSummary.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:    TrackerOfflineValidationSummary
00004 // Class:      TrackerOfflineValidationSummary
00005 // 
00013 //
00014 // Original Author:  Johannes Hauk
00015 //         Created:  Sat Aug 22 10:31:34 CEST 2009
00016 // $Id: TrackerOfflineValidationSummary.cc,v 1.8 2013/01/07 20:46:23 wmtan Exp $
00017 //
00018 //
00019 
00020 
00021 // system include files
00022 #include <memory>
00023 
00024 // user include files
00025 #include "FWCore/Framework/interface/Frameworkfwd.h"
00026 #include "FWCore/Framework/interface/EDAnalyzer.h"
00027 
00028 #include "FWCore/Framework/interface/Event.h"
00029 #include "FWCore/Framework/interface/MakerMacros.h"
00030 
00031 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00032 
00033 
00034 #include "FWCore/Framework/interface/ESHandle.h"
00035 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
00036 #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
00037 #include "Alignment/TrackerAlignment/interface/AlignableTracker.h"
00038 #include "Alignment/CommonAlignment/interface/AlignableObjectId.h"
00039 
00040 
00041 #include "TTree.h"
00042 //#include "Alignment/OfflineValidation/interface/TrackerValidationVariables.h"
00043 #include "Alignment/OfflineValidation/interface/TkOffTreeVariables.h"
00044 
00045 #include "DataFormats/SiPixelDetId/interface/PixelSubdetector.h"
00046 #include "DataFormats/SiStripDetId/interface/StripSubdetector.h"
00047 #include "DataFormats/TrackerCommon/interface/TrackerTopology.h"
00048 #include "Geometry/Records/interface/IdealGeometryRecord.h"
00049 #include "DataFormats/GeometrySurface/interface/Surface.h"
00050 #include "Geometry/CommonDetUnit/interface/GeomDet.h"
00051 #include "DataFormats/Math/interface/deltaPhi.h"
00052 #include "TH1.h"
00053 #include "TMath.h"
00054 
00055 #include "DQMServices/Core/interface/DQMStore.h"
00056 #include "DQMServices/Core/interface/MonitorElement.h"
00057 #include "FWCore/ServiceRegistry/interface/Service.h"
00058 
00059 //
00060 // class decleration
00061 //
00062 
00063 class TrackerOfflineValidationSummary : public edm::EDAnalyzer {
00064    public:
00065       explicit TrackerOfflineValidationSummary(const edm::ParameterSet&);
00066       ~TrackerOfflineValidationSummary();
00067 
00068 
00069    private:
00070       
00071       struct ModuleHistos{
00072         ModuleHistos() :  ResHisto(), NormResHisto(), ResXprimeHisto(), NormResXprimeHisto(), 
00073                           ResYprimeHisto(), NormResYprimeHisto() {} 
00074         TH1* ResHisto;
00075         TH1* NormResHisto;
00076         TH1* ResXprimeHisto;
00077         TH1* NormResXprimeHisto;
00078         TH1* ResYprimeHisto;
00079         TH1* NormResYprimeHisto;
00080       };
00081       
00083       struct HarvestingHistos{
00084         HarvestingHistos() : DmrXprime(), DmrYprime() {}
00085         TH1* DmrXprime;
00086         TH1* DmrYprime;
00087       };
00088       
00089       struct HarvestingHierarchy{
00090         HarvestingHierarchy() {}
00091         HarvestingHierarchy(const std::string& name, const std::string& component, const std::vector<unsigned int>& entries) : hierarchyName(name), componentName(component), treeEntries(entries) {}
00092         // Needed for naming of histogram according to residual histograms
00093         std::string hierarchyName;
00094         // "Pixel" or "Strip"
00095         std::string componentName;
00096         // Modules belonging to selected hierarchy
00097         std::vector<unsigned int> treeEntries;
00098         HarvestingHistos harvestingHistos;
00099       };
00100       
00101       virtual void analyze(const edm::Event& evt, const edm::EventSetup&);
00102       virtual void endJob() ;
00103       
00104       void fillTree(TTree& tree, std::map<int, TrackerOfflineValidationSummary::ModuleHistos>& moduleHist, 
00105                 TkOffTreeVariables& treeMem, const TrackerGeometry& tkgeom,
00106                 std::map<std::string,std::string>& substructureName, const TrackerTopology* tTopo);
00107       
00108       std::pair<float,float> fitResiduals(TH1* hist)const;
00109       float getMedian(const TH1* hist)const;
00110       
00111       const std::string associateModuleHistsWithTree(const TkOffTreeVariables& treeMem, TrackerOfflineValidationSummary::ModuleHistos& moduleHists, std::map<std::string,std::string>& substructureName);
00112       
00113       void collateHarvestingHists(TTree& tree);
00114       void applyHarvestingHierarchy(TTree& treeMem);
00115       void bookHarvestingHists();
00116       void getBinning(const std::string& binningPSetName, int& nBinsX, double& lowerBoundX, double& upperBoundX)const;
00117       void fillHarvestingHists(TTree& tree);
00118       
00119       // ----------member data ---------------------------
00120       
00121       const edm::ParameterSet parSet_;
00122       edm::ESHandle<TrackerGeometry> tkGeom_;
00123       
00124       // parameters from cfg to steer
00125       const std::string moduleDirectory_;
00126       const bool useFit_;
00127       
00128       DQMStore* dbe_;
00129       
00130       bool moduleMapsInitialized;
00131       
00132       std::map<int,TrackerOfflineValidationSummary::ModuleHistos> mPxbResiduals_;
00133       std::map<int,TrackerOfflineValidationSummary::ModuleHistos> mPxeResiduals_;
00134       std::map<int,TrackerOfflineValidationSummary::ModuleHistos> mTibResiduals_;
00135       std::map<int,TrackerOfflineValidationSummary::ModuleHistos> mTidResiduals_;
00136       std::map<int,TrackerOfflineValidationSummary::ModuleHistos> mTobResiduals_;
00137       std::map<int,TrackerOfflineValidationSummary::ModuleHistos> mTecResiduals_;
00138       
00139       std::vector<HarvestingHierarchy> vHarvestingHierarchy_;
00140 
00141       const edm::EventSetup *lastSetup_;
00142 };
00143 
00144 //
00145 // constants, enums and typedefs
00146 //
00147 
00148 //
00149 // static data member definitions
00150 //
00151 
00152 //
00153 // constructors and destructor
00154 //
00155 TrackerOfflineValidationSummary::TrackerOfflineValidationSummary(const edm::ParameterSet& iConfig):
00156    parSet_(iConfig), moduleDirectory_(parSet_.getParameter<std::string>("moduleDirectoryInOutput")),
00157    useFit_(parSet_.getParameter<bool>("useFit")), dbe_(0), moduleMapsInitialized(false), lastSetup_(nullptr)
00158 {
00159   //now do what ever initialization is needed
00160   dbe_ = edm::Service<DQMStore>().operator->();
00161 }
00162 
00163 
00164 TrackerOfflineValidationSummary::~TrackerOfflineValidationSummary()
00165 {
00166  
00167    // do anything here that needs to be done at desctruction time
00168    // (e.g. close files, deallocate resources etc.)
00169 
00170 }
00171 
00172 
00173 //
00174 // member functions
00175 //
00176 
00177 // ------------ method called to for each event  ------------
00178 void
00179 TrackerOfflineValidationSummary::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup)
00180 {
00181   lastSetup_ = &iSetup;
00182 
00183   // Access of EventSetup is needed to get the list of silicon-modules and their IDs
00184   // Since they do not change, it is accessed only once
00185   if(moduleMapsInitialized)return;
00186   iSetup.get<TrackerDigiGeometryRecord>().get( tkGeom_ );
00187   const TrackerGeometry* bareTkGeomPtr = &(*tkGeom_);
00188   const TrackingGeometry::DetIdContainer& detIdContainer = bareTkGeomPtr->detIds();
00189   std::vector<DetId>::const_iterator iDet;
00190   for(iDet = detIdContainer.begin(); iDet != detIdContainer.end(); ++iDet){
00191     const DetId& detId = *iDet;
00192     const uint32_t rawId = detId.rawId();
00193     const unsigned int subdetId = detId.subdetId();
00194     if     (subdetId == PixelSubdetector::PixelBarrel) mPxbResiduals_[rawId];
00195     else if(subdetId == PixelSubdetector::PixelEndcap) mPxeResiduals_[rawId];
00196     else if(subdetId  == StripSubdetector::TIB) mTibResiduals_[rawId];
00197     else if(subdetId  == StripSubdetector::TID) mTidResiduals_[rawId];
00198     else if(subdetId  == StripSubdetector::TOB) mTobResiduals_[rawId];
00199     else if(subdetId  == StripSubdetector::TEC) mTecResiduals_[rawId];
00200     else {
00201       throw cms::Exception("Geometry Error")
00202         << "[TrackerOfflineValidationSummary] Error, tried to get reference for non-tracker subdet " << subdetId 
00203         << " from detector " << detId.det();
00204     }
00205   }
00206   moduleMapsInitialized = true;
00207 }
00208 
00209 
00210 // ------------ method called once each job just after ending the event loop  ------------
00211 void 
00212 TrackerOfflineValidationSummary::endJob()
00213 {
00214   //Retrieve tracker topology from geometry
00215   edm::ESHandle<TrackerTopology> tTopoHandle;
00216   lastSetup_->get<IdealGeometryRecord>().get(tTopoHandle);
00217   const TrackerTopology* const tTopo = tTopoHandle.product();
00218 
00219   AlignableTracker aliTracker(&(*tkGeom_), tTopo);
00220   
00221   TTree* tree = new TTree("TkOffVal","TkOffVal");
00222   
00223   TkOffTreeVariables *treeMemPtr = new TkOffTreeVariables;
00224   // We create branches for all members of 'TkOffTreeVariables' (even if not needed).
00225   // This works because we have a dictionary for 'TkOffTreeVariables'
00226   // (see src/classes_def.xml and src/classes.h):
00227   tree->Branch("TkOffTreeVariables", &treeMemPtr); // address of pointer!
00228   // second branch needed for assigning names and titles to harvesting histograms consistent to others
00229   std::map<std::string,std::string> *substructureName = new std::map<std::string,std::string>;
00230   tree->Branch("SubstructureName", &substructureName, 32000, 00);  // SplitLevel must be set to zero
00231   
00232   
00233   this->fillTree(*tree, mPxbResiduals_, *treeMemPtr, *tkGeom_, *substructureName, tTopo);
00234   this->fillTree(*tree, mPxeResiduals_, *treeMemPtr, *tkGeom_, *substructureName, tTopo);
00235   this->fillTree(*tree, mTibResiduals_, *treeMemPtr, *tkGeom_, *substructureName, tTopo);
00236   this->fillTree(*tree, mTidResiduals_, *treeMemPtr, *tkGeom_, *substructureName, tTopo);
00237   this->fillTree(*tree, mTobResiduals_, *treeMemPtr, *tkGeom_, *substructureName, tTopo);
00238   this->fillTree(*tree, mTecResiduals_, *treeMemPtr, *tkGeom_, *substructureName, tTopo);
00239   
00240   //dbe_->showDirStructure();
00241   //dbe_->save("dqmOut.root");
00242   
00243   // Method for filling histograms which show summarized values (mean, rms, median ...)
00244   // of the module-based histograms from TrackerOfflineValidation
00245   this->collateHarvestingHists(*tree);
00246   
00247   delete tree; tree = 0;
00248   delete treeMemPtr; treeMemPtr = 0;
00249   delete substructureName; substructureName = 0;
00250 }
00251 
00252 
00253 void 
00254 TrackerOfflineValidationSummary::fillTree(TTree& tree, std::map<int, TrackerOfflineValidationSummary::ModuleHistos>& moduleHist,
00255                                           TkOffTreeVariables& treeMem, const TrackerGeometry& tkgeom,
00256                                           std::map<std::string,std::string>& substructureName,
00257                                           const TrackerTopology* tTopo)
00258 {
00259   for(std::map<int, TrackerOfflineValidationSummary::ModuleHistos>::iterator it = moduleHist.begin(), 
00260         itEnd= moduleHist.end(); it != itEnd;++it ) { 
00261     treeMem.clear(); // make empty/default
00262     
00263     //variables concerning the tracker components/hierarchy levels
00264     const DetId detId = it->first;
00265     treeMem.moduleId = detId;
00266     treeMem.subDetId = detId.subdetId();
00267 
00268     if(treeMem.subDetId == PixelSubdetector::PixelBarrel){
00269       
00270       unsigned int whichHalfBarrel(1), rawId(detId.rawId());  //DetId does not know about halfBarrels is PXB ...
00271       if( (rawId>=302056964 && rawId<302059300) || (rawId>=302123268 && rawId<302127140) || (rawId>=302189572 && rawId<302194980) )whichHalfBarrel=2;
00272       treeMem.layer = tTopo->pxbLayer(detId);
00273       treeMem.half = whichHalfBarrel; 
00274       treeMem.rod = tTopo->pxbLadder(detId);     // ... so, ladder is not per halfBarrel-Layer, but per barrel-layer! Needs complicated calculation in associateModuleHistsWithTree()
00275       treeMem.module = tTopo->pxbModule(detId);
00276     } else if(treeMem.subDetId == PixelSubdetector::PixelEndcap){
00277        
00278       unsigned int whichHalfCylinder(1), rawId(detId.rawId());  //DetId does not kmow about halfCylinders in PXF
00279       if( (rawId>=352394500 && rawId<352406032) || (rawId>=352460036 && rawId<352471568) || (rawId>=344005892 && rawId<344017424) || (rawId>=344071428 && rawId<344082960) )whichHalfCylinder=2;
00280       treeMem.layer = tTopo->pxfDisk(detId); 
00281       treeMem.side = tTopo->pxfSide(detId);
00282       treeMem.half = whichHalfCylinder;
00283       treeMem.blade = tTopo->pxfBlade(detId); 
00284       treeMem.panel = tTopo->pxfPanel(detId);
00285       treeMem.module = tTopo->pxfModule(detId);
00286     } else if(treeMem.subDetId == StripSubdetector::TIB){
00287        
00288       unsigned int whichHalfShell(1), rawId(detId.rawId());  //DetId does not kmow about halfShells in TIB
00289        if ( (rawId>=369120484 && rawId<369120688) || (rawId>=369121540 && rawId<369121776) || (rawId>=369136932 && rawId<369137200) || (rawId>=369137988 && rawId<369138288) ||
00290             (rawId>=369153396 && rawId<369153744) || (rawId>=369154436 && rawId<369154800) || (rawId>=369169844 && rawId<369170256) || (rawId>=369170900 && rawId<369171344) ||
00291             (rawId>=369124580 && rawId<369124784) || (rawId>=369125636 && rawId<369125872) || (rawId>=369141028 && rawId<369141296) || (rawId>=369142084 && rawId<369142384) ||
00292             (rawId>=369157492 && rawId<369157840) || (rawId>=369158532 && rawId<369158896) || (rawId>=369173940 && rawId<369174352) || (rawId>=369174996 && rawId<369175440) ) whichHalfShell=2;
00293       treeMem.layer = tTopo->tibLayer(detId); 
00294       treeMem.side = tTopo->tibStringInfo(detId)[0];
00295       treeMem.half = whichHalfShell;
00296       treeMem.rod = tTopo->tibStringInfo(detId)[2]; 
00297       treeMem.outerInner = tTopo->tibStringInfo(detId)[1]; 
00298       treeMem.module = tTopo->tibModule(detId);
00299       treeMem.isStereo = tTopo->tibStereo(detId);
00300       treeMem.isDoubleSide = tTopo->tibIsDoubleSide(detId);
00301     } else if(treeMem.subDetId == StripSubdetector::TID){
00302        
00303       treeMem.layer = tTopo->tidWheel(detId); 
00304       treeMem.side = tTopo->tidSide(detId);
00305       treeMem.ring = tTopo->tidRing(detId); 
00306       treeMem.outerInner = tTopo->tidModuleInfo(detId)[0]; 
00307       treeMem.module = tTopo->tidModuleInfo(detId)[1];
00308       treeMem.isStereo = tTopo->tidStereo(detId);
00309       treeMem.isDoubleSide = tTopo->tidIsDoubleSide(detId);
00310     } else if(treeMem.subDetId == StripSubdetector::TOB){
00311        
00312       treeMem.layer = tTopo->tobLayer(detId); 
00313       treeMem.side = tTopo->tobRodInfo(detId)[0];
00314       treeMem.rod = tTopo->tobRodInfo(detId)[1]; 
00315       treeMem.module = tTopo->tobModule(detId);
00316       treeMem.isStereo = tTopo->tobStereo(detId);
00317       treeMem.isDoubleSide = tTopo->tobIsDoubleSide(detId);
00318     } else if(treeMem.subDetId == StripSubdetector::TEC) {
00319        
00320       treeMem.layer = tTopo->tecWheel(detId); 
00321       treeMem.side  = tTopo->tecSide(detId);
00322       treeMem.ring  = tTopo->tecRing(detId); 
00323       treeMem.petal = tTopo->tecPetalInfo(detId)[1]; 
00324       treeMem.outerInner = tTopo->tecPetalInfo(detId)[0];
00325       treeMem.module = tTopo->tecModule(detId);
00326       treeMem.isStereo = tTopo->tecStereo(detId);
00327       treeMem.isDoubleSide = tTopo->tecIsDoubleSide(detId);
00328     }
00329     
00330     //variables concerning the tracker geometry
00331     
00332     const Surface::PositionType &gPModule = tkgeom.idToDet(detId)->position();
00333     treeMem.posPhi = gPModule.phi();
00334     treeMem.posEta = gPModule.eta();
00335     treeMem.posR   = gPModule.perp();
00336     treeMem.posX   = gPModule.x();
00337     treeMem.posY   = gPModule.y();
00338     treeMem.posZ   = gPModule.z();
00339  
00340     const Surface& surface =  tkgeom.idToDet(detId)->surface();
00341     
00342     //global Orientation of local coordinate system of dets/detUnits   
00343     LocalPoint  lUDirection(1.,0.,0.), lVDirection(0.,1.,0.), lWDirection(0.,0.,1.);
00344     GlobalPoint gUDirection = surface.toGlobal(lUDirection),
00345                 gVDirection = surface.toGlobal(lVDirection),
00346                 gWDirection = surface.toGlobal(lWDirection);
00347     double dR(999.), dPhi(999.), dZ(999.);
00348     if(treeMem.subDetId==PixelSubdetector::PixelBarrel || treeMem.subDetId==StripSubdetector::TIB || treeMem.subDetId==StripSubdetector::TOB){
00349       dR = gWDirection.perp() - gPModule.perp();
00350       dPhi = deltaPhi(gUDirection.phi(),gPModule.phi());
00351       dZ = gVDirection.z() - gPModule.z();
00352       if(dZ>=0.)treeMem.rOrZDirection = 1; else treeMem.rOrZDirection = -1;
00353     }else if(treeMem.subDetId==PixelSubdetector::PixelEndcap){
00354       dR = gUDirection.perp() - gPModule.perp();
00355       dPhi = deltaPhi(gVDirection.phi(),gPModule.phi());
00356       dZ = gWDirection.z() - gPModule.z();
00357       if(dR>=0.)treeMem.rOrZDirection = 1; else treeMem.rOrZDirection = -1;
00358     }else if(treeMem.subDetId==StripSubdetector::TID || treeMem.subDetId==StripSubdetector::TEC){
00359       dR = gVDirection.perp() - gPModule.perp();
00360       dPhi = deltaPhi(gUDirection.phi(),gPModule.phi());
00361       dZ = gWDirection.z() - gPModule.z();
00362       if(dR>=0.)treeMem.rOrZDirection = 1; else treeMem.rOrZDirection = -1;
00363     }
00364     if(dR>=0.)treeMem.rDirection = 1; else treeMem.rDirection = -1;
00365     if(dPhi>=0.)treeMem.phiDirection = 1; else treeMem.phiDirection = -1;
00366     if(dZ>=0.)treeMem.zDirection = 1; else treeMem.zDirection = -1;
00367     
00368     
00369     // Assign histos from first step (TrackerOfflineValidation) to the module's entry in the TTree for retrieving mean, rms, median ...
00370     const std::string histDir = associateModuleHistsWithTree(treeMem, it->second, substructureName);
00371     
00372     
00373     //mean and RMS values (extracted from histograms Xprime on module level)
00374     treeMem.entries = static_cast<UInt_t>(it->second.ResXprimeHisto->GetEntries());
00375     treeMem.meanX = it->second.ResXprimeHisto->GetMean();
00376     treeMem.rmsX  = it->second.ResXprimeHisto->GetRMS();
00377     //treeMem.sigmaX = Fwhm(it->second.ResXprimeHisto)/2.355;
00378     if (useFit_) {
00379       //call fit function which returns mean and sigma from the fit
00380       //for absolute residuals
00381       std::pair<float,float> fitResult1 = this->fitResiduals(it->second.ResXprimeHisto);
00382       treeMem.fitMeanX = fitResult1.first;
00383       treeMem.fitSigmaX = fitResult1.second;
00384       //for normalized residuals
00385       std::pair<float,float> fitResult2 = this->fitResiduals(it->second.NormResXprimeHisto);
00386       treeMem.fitMeanNormX = fitResult2.first;
00387       treeMem.fitSigmaNormX = fitResult2.second;
00388     }
00389     
00390     //get median for absolute residuals
00391     treeMem.medianX = this->getMedian(it->second.ResXprimeHisto);
00392 
00393     int numberOfBins=it->second.ResXprimeHisto->GetNbinsX();
00394     treeMem.numberOfUnderflows = it->second.ResXprimeHisto->GetBinContent(0);
00395     treeMem.numberOfOverflows = it->second.ResXprimeHisto->GetBinContent(numberOfBins+1);
00396     treeMem.numberOfOutliers =  it->second.ResXprimeHisto->GetBinContent(0)+it->second.ResXprimeHisto->GetBinContent(numberOfBins+1);
00397     //mean and RMS values (extracted from histograms(normalized Xprime on module level)
00398     treeMem.meanNormX = it->second.NormResXprimeHisto->GetMean();
00399     treeMem.rmsNormX = it->second.NormResXprimeHisto->GetRMS();
00400 
00401     double stats[20];
00402     it->second.NormResXprimeHisto->GetStats(stats);
00403     // GF  treeMem.chi2PerDofX = stats[3]/(stats[0]-1);
00404     if (stats[0]) treeMem.chi2PerDofX = stats[3]/stats[0];
00405     
00406     //treeMem.sigmaNormX = Fwhm(it->second.NormResXprimeHisto)/2.355;
00407     treeMem.histNameX = it->second.ResXprimeHisto->GetName();
00408     treeMem.histNameNormX = it->second.NormResXprimeHisto->GetName();
00409     
00410 
00411     // fill tree variables in local coordinates if set in cfg of TrackerOfllineValidation
00412     if(it->second.ResHisto && it->second.NormResHisto){ // if(lCoorHistOn_) {
00413       treeMem.meanLocalX = it->second.ResHisto->GetMean();
00414       treeMem.rmsLocalX = it->second.ResHisto->GetRMS();
00415       treeMem.meanNormLocalX = it->second.NormResHisto->GetMean();
00416       treeMem.rmsNormLocalX = it->second.NormResHisto->GetRMS();
00417       treeMem.histNameLocalX = it->second.ResHisto->GetName();
00418       treeMem.histNameNormLocalX = it->second.NormResHisto->GetName();
00419     }
00420 
00421     // mean and RMS values in local y (extracted from histograms Yprime on module level)
00422     // might exist in pixel only
00423     if (it->second.ResYprimeHisto) { //(stripYResiduals_){
00424       TH1 *h = it->second.ResYprimeHisto;
00425       treeMem.meanY = h->GetMean();
00426       treeMem.rmsY  = h->GetRMS();
00427       
00428       if (useFit_) { // fit function which returns mean and sigma from the fit
00429         std::pair<float,float> fitMeanSigma = this->fitResiduals(h);
00430         treeMem.fitMeanY  = fitMeanSigma.first;
00431         treeMem.fitSigmaY = fitMeanSigma.second;
00432       }
00433       
00434       //get median for absolute residuals
00435       treeMem.medianY = this->getMedian(h);
00436 
00437       treeMem.histNameY = h->GetName();
00438     }
00439     
00440     if (it->second.NormResYprimeHisto) {
00441       TH1 *h = it->second.NormResYprimeHisto;
00442       treeMem.meanNormY = h->GetMean();
00443       treeMem.rmsNormY  = h->GetRMS();
00444       h->GetStats(stats); // stats buffer defined above
00445       if (stats[0]) treeMem.chi2PerDofY = stats[3]/stats[0];
00446 
00447       if (useFit_) { // fit function which returns mean and sigma from the fit
00448         std::pair<float,float> fitMeanSigma = this->fitResiduals(h);
00449         treeMem.fitMeanNormY  = fitMeanSigma.first;
00450         treeMem.fitSigmaNormY = fitMeanSigma.second;
00451       }
00452       treeMem.histNameNormY = h->GetName();
00453     }
00454     
00455     // Delete module level hists if set in cfg
00456     const bool removeModuleLevelHists(parSet_.getParameter<bool>("removeModuleLevelHists"));
00457     if(removeModuleLevelHists){
00458       dbe_->setCurrentFolder("");
00459       if(it->second.ResHisto)          dbe_->removeElement(histDir + "/" + it->second.ResHisto->GetName());
00460       if(it->second.NormResHisto)      dbe_->removeElement(histDir + "/" + it->second.NormResHisto->GetName());
00461       if(it->second.ResXprimeHisto)    dbe_->removeElement(histDir + "/" + it->second.ResXprimeHisto->GetName());
00462       if(it->second.NormResXprimeHisto)dbe_->removeElement(histDir + "/" + it->second.NormResXprimeHisto->GetName());
00463       if(it->second.ResYprimeHisto)    dbe_->removeElement(histDir + "/" + it->second.ResYprimeHisto->GetName());
00464       if(it->second.NormResYprimeHisto)dbe_->removeElement(histDir + "/" + it->second.NormResYprimeHisto->GetName());
00465     }
00466     
00467     tree.Fill();
00468   }
00469 }
00470 
00471 
00472 const std::string
00473 TrackerOfflineValidationSummary::associateModuleHistsWithTree(const TkOffTreeVariables& treeMem, TrackerOfflineValidationSummary::ModuleHistos& moduleHists, std::map<std::string,std::string>& substructureName){
00474    std::stringstream histDir, sSubdetName;
00475    std::string componentName;
00476    if(moduleDirectory_.length() != 0)histDir<<moduleDirectory_<<"/";
00477    std::string wheelOrLayer("_layer_");
00478    if(treeMem.subDetId == PixelSubdetector::PixelBarrel){
00479      unsigned int half(treeMem.half), layer(treeMem.layer), ladder(0);
00480      if(layer==1){
00481        if(half==2)ladder = treeMem.rod -5;
00482        else if(treeMem.rod>15)ladder = treeMem.rod -10;
00483        else ladder = treeMem.rod;
00484      }else if(layer==2){
00485        if(half==2)ladder = treeMem.rod -8;
00486        else if(treeMem.rod>24)ladder = treeMem.rod -16;
00487        else ladder = treeMem.rod;
00488      }else if(layer==3){
00489        if(half==2)ladder = treeMem.rod -11;
00490        else if(treeMem.rod>33)ladder = treeMem.rod -22;
00491        else ladder = treeMem.rod;
00492      }
00493      componentName = "Pixel";
00494      sSubdetName<<"TPBBarrel_1";
00495      histDir<<componentName<<"/"<<sSubdetName.str()<<"/TPBHalfBarrel_"<<treeMem.half<<"/TPBLayer_"<<treeMem.layer<<"/TPBLadder_"<<ladder;
00496    }else if(treeMem.subDetId == PixelSubdetector::PixelEndcap){
00497      unsigned int side(treeMem.side), half(treeMem.half), blade(0);
00498      if(side==1)side=3;
00499      if(half==2)blade = treeMem.blade -6;
00500      else if(treeMem.blade>18)blade = treeMem.blade -12;
00501      else blade = treeMem.blade;
00502      componentName = "Pixel";
00503      sSubdetName<<"TPEEndcap_"<<side;
00504      histDir<<componentName<<"/"<<sSubdetName.str()<<"/TPEHalfCylinder_"<<treeMem.half<<"/TPEHalfDisk_"<<treeMem.layer<<"/TPEBlade_"<<blade<<"/TPEPanel_"<<treeMem.panel;
00505      wheelOrLayer = "_wheel_";
00506    }else if(treeMem.subDetId == StripSubdetector::TIB){
00507      unsigned int half(treeMem.half), layer(treeMem.layer), surface(treeMem.outerInner), string(0);
00508      if(half==2){
00509        if(layer==1){
00510          if(surface==1)string = treeMem.rod -13;
00511          else if(surface==2)string = treeMem.rod -15;
00512        }
00513        if(layer==2){
00514          if(surface==1)string = treeMem.rod -17;
00515          else if(surface==2)string = treeMem.rod -19;
00516        }
00517        if(layer==3){
00518          if(surface==1)string = treeMem.rod -22;
00519          else if(surface==2)string = treeMem.rod -23;
00520        }
00521        if(layer==4){
00522          if(surface==1)string = treeMem.rod -26;
00523          else if(surface==2)string = treeMem.rod -28;
00524        }
00525      }
00526      else string = treeMem.rod;
00527      std::stringstream detString;
00528      if(treeMem.layer<3 && !treeMem.isDoubleSide)detString<<"/Det_"<<treeMem.module;
00529      else detString<<"";
00530      componentName = "Strip";
00531      sSubdetName<<"TIBBarrel_1";
00532      histDir<<componentName<<"/"<<sSubdetName.str()<<"/TIBHalfBarrel_"<<treeMem.side<<"/TIBLayer_"<<treeMem.layer<<"/TIBHalfShell_"<<treeMem.half<<"/TIBSurface_"<<treeMem.outerInner<<"/TIBString_"<<string<<detString.str();
00533    }else if(treeMem.subDetId == StripSubdetector::TID){
00534      unsigned int side(treeMem.side), outerInner(0);
00535      if(side==1)side=3;
00536      if(treeMem.outerInner==1)outerInner=2;
00537      else if(treeMem.outerInner==2)outerInner=1;
00538      std::stringstream detString;
00539      if(treeMem.ring<3 && !treeMem.isDoubleSide)detString<<"/Det_"<<treeMem.module;
00540      else detString<<"";
00541      componentName = "Strip";
00542      sSubdetName<<"TIDEndcap_"<<side;
00543      histDir<<componentName<<"/"<<sSubdetName.str()<<"/TIDDisk_"<<treeMem.layer<<"/TIDRing_"<<treeMem.ring<<"/TIDSide_"<<outerInner<<detString.str();
00544      wheelOrLayer = "_wheel_";
00545    }else if(treeMem.subDetId == StripSubdetector::TOB){
00546      std::stringstream detString;
00547      if(treeMem.layer<3 && !treeMem.isDoubleSide)detString<<"/Det_"<<treeMem.module;
00548      else detString<<"";
00549      componentName = "Strip";
00550      sSubdetName<<"TOBBarrel_4";
00551      histDir<<componentName<<"/"<<sSubdetName.str()<<"/TOBHalfBarrel_"<<treeMem.side<<"/TOBLayer_"<<treeMem.layer<<"/TOBRod_"<<treeMem.rod<<detString.str();
00552    }else if(treeMem.subDetId == StripSubdetector::TEC) {
00553      unsigned int side(0), outerInner(0), ring(0);
00554      if(treeMem.side==1)side=6;
00555      else if(treeMem.side==2)side=5;
00556      if(treeMem.outerInner==1)outerInner = 2;
00557      else if(treeMem.outerInner==2)outerInner=1;
00558      if(treeMem.layer>3 && treeMem.layer<7)ring = treeMem.ring -1;
00559      else if(treeMem.layer==7 || treeMem.layer==8)ring = treeMem.ring -2;
00560      else if(treeMem.layer==9)ring = treeMem.ring -3;
00561      else ring = treeMem.ring;
00562      std::stringstream detString;
00563      if((treeMem.ring<3 || treeMem.ring==5) && !treeMem.isDoubleSide)detString<<"/Det_"<<treeMem.module;
00564      else detString<<"";
00565      componentName = "Strip";
00566      sSubdetName<<"TECEndcap_"<<side;
00567      histDir<<componentName<<"/"<<sSubdetName.str()<<"/TECDisk_"<<treeMem.layer<<"/TECSide_"<<outerInner<<"/TECPetal_"<<treeMem.petal<<"/TECRing_"<<ring<<detString.str();
00568      wheelOrLayer = "_wheel_";
00569    }
00570    
00571    substructureName["component"] = componentName;
00572    substructureName["subdet"] = sSubdetName.str();
00573    
00574    std::stringstream histName;
00575    histName<<"residuals_subdet_"<<treeMem.subDetId<<wheelOrLayer<<treeMem.layer<<"_module_"<<treeMem.moduleId;
00576    
00577    std::string fullPath;
00578    fullPath = histDir.str()+"/h_xprime_"+histName.str();
00579    if(dbe_->get(fullPath)) moduleHists.ResXprimeHisto = dbe_->get(fullPath)->getTH1();
00580    else{edm::LogError("TrackerOfflineValidationSummary")<<"Problem with names in input file produced in TrackerOfflineValidation ...\n"
00581                                                         <<"This histogram should exist in every configuration, "
00582                                                         <<"but no histogram with name "<<fullPath<<" is found!";
00583      return "";
00584    }
00585    fullPath = histDir.str()+"/h_normxprime"+histName.str();
00586    if(dbe_->get(fullPath)) moduleHists.NormResXprimeHisto = dbe_->get(fullPath)->getTH1();
00587    fullPath = histDir.str()+"/h_yprime_"+histName.str();
00588    if(dbe_->get(fullPath)) moduleHists.ResYprimeHisto = dbe_->get(fullPath)->getTH1();
00589    fullPath = histDir.str()+"/h_normyprime"+histName.str();
00590    if(dbe_->get(fullPath)) moduleHists.NormResYprimeHisto = dbe_->get(fullPath)->getTH1();
00591    fullPath = histDir.str()+"/h_"+histName.str();
00592    if(dbe_->get(fullPath)) moduleHists.ResHisto = dbe_->get(fullPath)->getTH1();
00593    fullPath = histDir.str()+"/h_norm"+histName.str();
00594    if(dbe_->get(fullPath)) moduleHists.NormResHisto = dbe_->get(fullPath)->getTH1();
00595    
00596    return histDir.str();
00597 }
00598 
00599 
00600 std::pair<float,float> 
00601 TrackerOfflineValidationSummary::fitResiduals(TH1* hist) const
00602 {
00603   std::pair<float,float> fitResult(9999., 9999.);
00604   if (!hist || hist->GetEntries() < 20) return fitResult;
00605 
00606   float mean  = hist->GetMean();
00607   float sigma = hist->GetRMS();
00608 
00609   try { // for < CMSSW_2_2_0 since ROOT warnings from fit are converted to exceptions
00610     // Remove the try/catch for more recent CMSSW!
00611     // first fit: two RMS around mean
00612     TF1 func("tmp", "gaus", mean - 2.*sigma, mean + 2.*sigma); 
00613     if (0 == hist->Fit(&func,"QNR")) { // N: do not blow up file by storing fit!
00614       mean  = func.GetParameter(1);
00615       sigma = func.GetParameter(2);
00616       // second fit: three sigma of first fit around mean of first fit
00617       func.SetRange(mean - 3.*sigma, mean + 3.*sigma);
00618       // I: integral gives more correct results if binning is too wide
00619       // L: Likelihood can treat empty bins correctly (if hist not weighted...)
00620       if (0 == hist->Fit(&func, "Q0LR")) {
00621         if (hist->GetFunction(func.GetName())) { // Take care that it is later on drawn:
00622           hist->GetFunction(func.GetName())->ResetBit(TF1::kNotDraw);
00623         }
00624         fitResult.first = func.GetParameter(1);
00625         fitResult.second = func.GetParameter(2);
00626       }
00627     }
00628   } catch (cms::Exception const & e) {
00629     edm::LogWarning("Alignment") << "@SUB=TrackerOfflineValidation::fitResiduals"
00630                                  << "Caught this exception during ROOT fit: "
00631                                  << e.what();
00632   }
00633   return fitResult;
00634 }
00635 
00636 
00637 float 
00638 TrackerOfflineValidationSummary::getMedian(const TH1 *histo) const
00639 {
00640   float median = 999;
00641   const int nbins = histo->GetNbinsX();
00642  
00643   //extract median from histogram
00644   double *x = new double[nbins];
00645   double *y = new double[nbins];
00646   for (int j = 0; j < nbins; j++) {
00647     x[j] = histo->GetBinCenter(j+1);
00648     y[j] = histo->GetBinContent(j+1);
00649   }
00650   median = TMath::Median(nbins, x, y);
00651   
00652   delete[] x; x = 0;
00653   delete [] y; y = 0;  
00654 
00655   return median;
00656 }
00657 
00658 
00659 void
00660 TrackerOfflineValidationSummary::collateHarvestingHists(TTree& tree)
00661 {
00662   this->applyHarvestingHierarchy(tree);
00663   this->fillHarvestingHists(tree);
00664 }
00665 
00666 
00667 void
00668 TrackerOfflineValidationSummary::applyHarvestingHierarchy(TTree& tree)
00669 {
00670   TkOffTreeVariables *treeMemPtr = 0;
00671   std::map<std::string,std::string> *substructureName = 0;
00672   tree.SetBranchAddress("TkOffTreeVariables", &treeMemPtr);
00673   tree.SetBranchAddress("SubstructureName", &substructureName);
00674   
00675   // Loop over modules to select accumulation criteria for harvesting plots
00676   for(unsigned int iSubdet = 1; iSubdet<7; ++iSubdet){
00677     std::string hierarchyName("");
00678     std::string componentName("");
00679     std::vector<unsigned int> treeEntries;
00680     for(unsigned int iSide = 1; iSide<3; ++iSide){
00681       // Set up only one collection for Barrels, not separated for side
00682       if(iSide==1 && (iSubdet==PixelSubdetector::PixelBarrel || iSubdet==StripSubdetector::TIB || iSubdet==StripSubdetector::TOB))continue;
00683       for(int iTree=0; iTree<tree.GetEntries(); ++iTree){
00684         tree.GetEntry(iTree);
00685         // Do not use glued Dets
00686         if(treeMemPtr->isDoubleSide)continue;
00687         if(treeMemPtr->subDetId == iSubdet){
00688           if(iSide!=treeMemPtr->side && (iSubdet==PixelSubdetector::PixelEndcap || iSubdet==StripSubdetector::TID || iSubdet==StripSubdetector::TEC))continue;
00689           treeEntries.push_back(iTree);
00690           if(hierarchyName.length() == 0){
00691             hierarchyName = (*substructureName)["subdet"];
00692             componentName = (*substructureName)["component"];
00693           }
00694         }
00695       }
00696       HarvestingHierarchy harvestingHierarchy(hierarchyName,componentName,treeEntries);
00697       vHarvestingHierarchy_.push_back(harvestingHierarchy);
00698       hierarchyName = ""; componentName = ""; treeEntries.clear();
00699     }
00700   }
00701   // Here could be a further separation of the HarvestingHierarchy.
00702   // E.g. separate the existing ones by layer and add them to the vector without deleting any element from the vector.
00703   // The existing hists will stay and the new ones are added
00704   
00705   // Now, book the corresponding histos
00706   this->bookHarvestingHists();
00707 }
00708 
00709 
00710 void
00711 TrackerOfflineValidationSummary::bookHarvestingHists()
00712 {
00713   edm::LogInfo("TrackerOfflineValidationSummary")<<"Harvesting histograms will be booked for "<<vHarvestingHierarchy_.size()<<" different hierarchy selections";
00714   for(std::vector<HarvestingHierarchy>::iterator iHier = vHarvestingHierarchy_.begin(); iHier != vHarvestingHierarchy_.end(); ++iHier){
00715     
00716     std::stringstream dmrXprimeHistoName, dmrYprimeHistoName, dmrXprimeHistoTitle, dmrYprimeHistoTitle;
00717     dmrXprimeHistoName << "h_DmrXprime_" << iHier->hierarchyName;
00718     dmrYprimeHistoName << "h_DmrYprime_" << iHier->hierarchyName;
00719     dmrXprimeHistoTitle<<  "DMR for " << iHier->hierarchyName <<";<#DeltaX> [cm];# modules";
00720     dmrYprimeHistoTitle<<  "DMR for " << iHier->hierarchyName <<";<#DeltaY> [cm];# modules";
00721     
00722     std::string directoryString(moduleDirectory_);
00723     if(directoryString.length()!=0)directoryString += "/";
00724     directoryString += iHier->componentName;
00725     dbe_->setCurrentFolder(directoryString);
00726     
00727     int nBinsX(0); double xMin(0.), xMax(0.);
00728     if(iHier->componentName == "Pixel"){
00729       this->getBinning("TH1DmrXprimePixelModules",nBinsX,xMin,xMax);
00730       iHier->harvestingHistos.DmrXprime = dbe_->book1D(dmrXprimeHistoName.str(),dmrXprimeHistoTitle.str(),nBinsX,xMin,xMax)->getTH1();
00731       this->getBinning("TH1DmrYprimePixelModules",nBinsX,xMin,xMax);
00732       iHier->harvestingHistos.DmrYprime = dbe_->book1D(dmrYprimeHistoName.str(),dmrYprimeHistoTitle.str(),nBinsX,xMin,xMax)->getTH1();
00733     }
00734     else if(iHier->componentName == "Strip"){
00735       this->getBinning("TH1DmrXprimeStripModules",nBinsX,xMin,xMax);
00736       iHier->harvestingHistos.DmrXprime = dbe_->book1D(dmrXprimeHistoName.str(),dmrXprimeHistoTitle.str(),nBinsX,xMin,xMax)->getTH1();
00737       if(!parSet_.getParameter<bool>("stripYDmrs"))continue;
00738       this->getBinning("TH1DmrYprimeStripModules",nBinsX,xMin,xMax);
00739       iHier->harvestingHistos.DmrYprime = dbe_->book1D(dmrYprimeHistoName.str(),dmrYprimeHistoTitle.str(),nBinsX,xMin,xMax)->getTH1();
00740     }
00741   }
00742 }
00743 
00744 
00745 void
00746 TrackerOfflineValidationSummary::getBinning(const std::string& binningPSetName, int& nBinsX, double& lowerBoundX, double& upperBoundX)const
00747 {
00748   const edm::ParameterSet& binningPSet = parSet_.getParameter<edm::ParameterSet>(binningPSetName);
00749   nBinsX      = binningPSet.getParameter<int>("Nbinx");                
00750   lowerBoundX = binningPSet.getParameter<double>("xmin");                      
00751   upperBoundX = binningPSet.getParameter<double>("xmax");
00752 }
00753 
00754 
00755 void
00756 TrackerOfflineValidationSummary::fillHarvestingHists(TTree& tree)
00757 {
00758   TkOffTreeVariables *treeMemPtr = 0;
00759   std::map<std::string,std::string> *substructureName = 0;
00760   tree.SetBranchAddress("TkOffTreeVariables", &treeMemPtr);
00761   tree.SetBranchAddress("SubstructureName", &substructureName);
00762   
00763   const unsigned int minEntriesPerModule(parSet_.getParameter<unsigned int>("minEntriesPerModuleForDmr"));
00764   edm::LogInfo("TrackerOfflineValidationSummary")<<"Median of a module is added to DMR plots if it contains at least "<<minEntriesPerModule<<" hits";
00765   
00766   for(std::vector<HarvestingHierarchy>::iterator iHier = vHarvestingHierarchy_.begin(); iHier != vHarvestingHierarchy_.end(); ++iHier){
00767     for(std::vector<unsigned int>::const_iterator iTreeEntries = iHier->treeEntries.begin(); iTreeEntries != iHier->treeEntries.end(); ++iTreeEntries){
00768       tree.GetEntry(*iTreeEntries);
00769       if(treeMemPtr->entries < minEntriesPerModule)continue;
00770       iHier->harvestingHistos.DmrXprime->Fill(treeMemPtr->medianX);
00771       if(iHier->harvestingHistos.DmrYprime)iHier->harvestingHistos.DmrYprime->Fill(treeMemPtr->medianY);
00772     }
00773   }
00774 }
00775 
00776 
00777 //define this as a plug-in
00778 DEFINE_FWK_MODULE(TrackerOfflineValidationSummary);