/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
Alignment/OfflineValidation/plugins/TrackerOfflineValidationSummary.cc
871 строка
37 KB
Shahzad Malik Muzaffar
[ALCA-DB] Drop Geometry/CommonDetUnit package
28 май 2026, 12:57
28 май 2026, 12:57
993d9d5
Код
Авторство
О чём код?
// -*- C++ -*- // // Package: TrackerOfflineValidationSummary // Class: TrackerOfflineValidationSummary // /**\class TrackerOfflineValidationSummary TrackerOfflineValidationSummary.cc Alignment/TrackerOfflineValidationSummary/src/TrackerOfflineValidationSummary.cc Description: <one line class summary> Implementation: <Notes on implementation> */ // // Original Author: Johannes Hauk // Created: Sat Aug 22 10:31:34 CEST 2009 // $Id: TrackerOfflineValidationSummary.cc,v 1.7 2012/06/30 09:09:47 eulisse Exp $ // // // system include files #include <memory> // user include files #include "FWCore/Framework/interface/Frameworkfwd.h" #include "FWCore/Framework/interface/one/EDAnalyzer.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/MakerMacros.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/Framework/interface/ESHandle.h" #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h" #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h" #include "Alignment/TrackerAlignment/interface/AlignableTracker.h" #include "TTree.h" //#include "Alignment/OfflineValidation/interface/TrackerValidationVariables.h" #include "Alignment/OfflineValidation/interface/TkOffTreeVariables.h" #include "DataFormats/SiPixelDetId/interface/PixelSubdetector.h" #include "DataFormats/SiStripDetId/interface/StripSubdetector.h" #include "DataFormats/TrackerCommon/interface/TrackerTopology.h" #include "Geometry/Records/interface/TrackerTopologyRcd.h" #include "DataFormats/GeometrySurface/interface/Surface.h" #include "Geometry/CommonTopologies/interface/GeomDet.h" #include "DataFormats/Math/interface/deltaPhi.h" #include "TH1.h" #include "TMath.h" #include "DQMServices/Core/interface/DQMStore.h" #include "FWCore/ServiceRegistry/interface/Service.h" // // class decleration // class TrackerOfflineValidationSummary : public edm::one::EDAnalyzer<edm::one::WatchRuns> { public: typedef dqm::legacy::DQMStore DQMStore; explicit TrackerOfflineValidationSummary(const edm::ParameterSet&); ~TrackerOfflineValidationSummary() override = default; static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); private: const edm::ESGetToken<TrackerGeometry, TrackerDigiGeometryRecord> geomToken_; const edm::ESGetToken<TrackerTopology, TrackerTopologyRcd> tTopoToken_; struct ModuleHistos { ModuleHistos() : ResHisto(), NormResHisto(), ResXprimeHisto(), NormResXprimeHisto(), ResYprimeHisto(), NormResYprimeHisto() {} TH1* ResHisto; TH1* NormResHisto; TH1* ResXprimeHisto; TH1* NormResXprimeHisto; TH1* ResYprimeHisto; TH1* NormResYprimeHisto; }; /// Put here the histograms created during harvesting struct HarvestingHistos { HarvestingHistos() : DmrXprime(), DmrYprime() {} TH1* DmrXprime; TH1* DmrYprime; }; struct HarvestingHierarchy { HarvestingHierarchy() {} HarvestingHierarchy(const std::string& name, const std::string& component, const std::vector<unsigned int>& entries) : hierarchyName(name), componentName(component), treeEntries(entries) {} // Needed for naming of histogram according to residual histograms std::string hierarchyName; // "Pixel" or "Strip" std::string componentName; // Modules belonging to selected hierarchy std::vector<unsigned int> treeEntries; HarvestingHistos harvestingHistos; }; void beginRun(const edm::Run&, const edm::EventSetup& iSetup) override {} void analyze(const edm::Event& evt, const edm::EventSetup&) override; void endRun(const edm::Run&, const edm::EventSetup& iSetup) override; void endJob() override; void fillTree(TTree& tree, std::map<int, TrackerOfflineValidationSummary::ModuleHistos>& moduleHist, TkOffTreeVariables& treeMem, const TrackerGeometry& tkgeom, std::map<std::string, std::string>& substructureName, const TrackerTopology* tTopo); std::pair<float, float> fitResiduals(TH1* hist) const; float getMedian(const TH1* hist) const; const std::string associateModuleHistsWithTree(const TkOffTreeVariables& treeMem, TrackerOfflineValidationSummary::ModuleHistos& moduleHists, std::map<std::string, std::string>& substructureName); void collateHarvestingHists(TTree& tree); void applyHarvestingHierarchy(TTree& treeMem); void bookHarvestingHists(); void getBinning(const std::string& binningPSetName, int& nBinsX, double& lowerBoundX, double& upperBoundX) const; void fillHarvestingHists(TTree& tree); // ----------member data --------------------------- const edm::ParameterSet parSet_; edm::ESHandle<TrackerGeometry> tkGeom_; std::unique_ptr<TrackerTopology> tTopo_; // parameters from cfg to steer const std::string moduleDirectory_; const bool useFit_; DQMStore* dbe_; bool moduleMapsInitialized; std::map<int, TrackerOfflineValidationSummary::ModuleHistos> mPxbResiduals_; std::map<int, TrackerOfflineValidationSummary::ModuleHistos> mPxeResiduals_; std::map<int, TrackerOfflineValidationSummary::ModuleHistos> mTibResiduals_; std::map<int, TrackerOfflineValidationSummary::ModuleHistos> mTidResiduals_; std::map<int, TrackerOfflineValidationSummary::ModuleHistos> mTobResiduals_; std::map<int, TrackerOfflineValidationSummary::ModuleHistos> mTecResiduals_; std::vector<HarvestingHierarchy> vHarvestingHierarchy_; }; // // constructors and destructor // TrackerOfflineValidationSummary::TrackerOfflineValidationSummary(const edm::ParameterSet& iConfig) : geomToken_(esConsumes()), tTopoToken_(esConsumes<edm::Transition::EndRun>()), parSet_(iConfig), tTopo_(nullptr), moduleDirectory_(parSet_.getParameter<std::string>("moduleDirectoryInOutput")), useFit_(parSet_.getParameter<bool>("useFit")), dbe_(nullptr), moduleMapsInitialized(false) { //now do what ever initialization is needed dbe_ = edm::Service<DQMStore>().operator->(); } void TrackerOfflineValidationSummary::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { edm::ParameterSetDescription desc; desc.setComment("Summary of alignment payloads validation by evaluating unbiased track-hit resisuals"); desc.add<std::string>("moduleDirectoryInOutput", "Alignment/Tracker"); desc.add<bool>("useFit", false); desc.add<bool>("stripYDmrs", false); desc.add<unsigned int>("minEntriesPerModuleForDmr", 100); // fill in the residuals details const std::vector<std::string> listOfDMRPSets = { "TH1DmrXprimeStripModules", "TH1DmrYprimeStripModules", "TH1DmrXprimePixelModules", "TH1DmrYprimePixelModules"}; for (const auto& myPSetName : listOfDMRPSets) { edm::ParameterSetDescription myPSet; myPSet.add<int>("Nbinx", 100); myPSet.add<double>("xmin", -5.f); myPSet.add<double>("xmax", 5.f); desc.add<edm::ParameterSetDescription>(myPSetName, myPSet); } descriptions.addWithDefaultLabel(desc); } // // member functions // // ------------ method called to for each event ------------ void TrackerOfflineValidationSummary::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { // Access of EventSetup is needed to get the list of silicon-modules and their IDs // Since they do not change, it is accessed only once if (moduleMapsInitialized) return; tkGeom_ = iSetup.getHandle(geomToken_); const TrackerGeometry* bareTkGeomPtr = &(*tkGeom_); const TrackingGeometry::DetIdContainer& detIdContainer = bareTkGeomPtr->detIds(); std::vector<DetId>::const_iterator iDet; for (iDet = detIdContainer.begin(); iDet != detIdContainer.end(); ++iDet) { const DetId& detId = *iDet; const uint32_t rawId = detId.rawId(); const unsigned int subdetId = detId.subdetId(); if (subdetId == PixelSubdetector::PixelBarrel) mPxbResiduals_[rawId]; else if (subdetId == PixelSubdetector::PixelEndcap) mPxeResiduals_[rawId]; else if (subdetId == StripSubdetector::TIB) mTibResiduals_[rawId]; else if (subdetId == StripSubdetector::TID) mTidResiduals_[rawId]; else if (subdetId == StripSubdetector::TOB) mTobResiduals_[rawId]; else if (subdetId == StripSubdetector::TEC) mTecResiduals_[rawId]; else { throw cms::Exception("Geometry Error") << "[TrackerOfflineValidationSummary] Error, tried to get reference for non-tracker subdet " << subdetId << " from detector " << detId.det(); } } moduleMapsInitialized = true; } // ------------ method called at each end of Run ------------ void TrackerOfflineValidationSummary::endRun(const edm::Run&, const edm::EventSetup& iSetup) { if (!tTopo_) { tTopo_ = std::make_unique<TrackerTopology>(iSetup.getData(tTopoToken_)); } } // ------------ method called once each job just after ending the event loop ------------ void TrackerOfflineValidationSummary::endJob() { AlignableTracker aliTracker(&(*tkGeom_), tTopo_.get()); TTree* tree = new TTree("TkOffVal", "TkOffVal"); TkOffTreeVariables* treeMemPtr = new TkOffTreeVariables; // We create branches for all members of 'TkOffTreeVariables' (even if not needed). // This works because we have a dictionary for 'TkOffTreeVariables' // (see src/classes_def.xml and src/classes.h): tree->Branch("TkOffTreeVariables", &treeMemPtr); // address of pointer! // second branch needed for assigning names and titles to harvesting histograms consistent to others std::map<std::string, std::string>* substructureName = new std::map<std::string, std::string>; tree->Branch("SubstructureName", &substructureName, 32000, 00); // SplitLevel must be set to zero this->fillTree(*tree, mPxbResiduals_, *treeMemPtr, *tkGeom_, *substructureName, tTopo_.get()); this->fillTree(*tree, mPxeResiduals_, *treeMemPtr, *tkGeom_, *substructureName, tTopo_.get()); this->fillTree(*tree, mTibResiduals_, *treeMemPtr, *tkGeom_, *substructureName, tTopo_.get()); this->fillTree(*tree, mTidResiduals_, *treeMemPtr, *tkGeom_, *substructureName, tTopo_.get()); this->fillTree(*tree, mTobResiduals_, *treeMemPtr, *tkGeom_, *substructureName, tTopo_.get()); this->fillTree(*tree, mTecResiduals_, *treeMemPtr, *tkGeom_, *substructureName, tTopo_.get()); //dbe_->save("dqmOut.root"); // Method for filling histograms which show summarized values (mean, rms, median ...) // of the module-based histograms from TrackerOfflineValidation this->collateHarvestingHists(*tree); delete tree; tree = nullptr; delete treeMemPtr; treeMemPtr = nullptr; delete substructureName; substructureName = nullptr; } void TrackerOfflineValidationSummary::fillTree(TTree& tree, std::map<int, TrackerOfflineValidationSummary::ModuleHistos>& moduleHist, TkOffTreeVariables& treeMem, const TrackerGeometry& tkgeom, std::map<std::string, std::string>& substructureName, const TrackerTopology* tTopo) { for (std::map<int, TrackerOfflineValidationSummary::ModuleHistos>::iterator it = moduleHist.begin(), itEnd = moduleHist.end(); it != itEnd; ++it) { treeMem.clear(); // make empty/default //variables concerning the tracker components/hierarchy levels const DetId detId = it->first; treeMem.moduleId = detId; treeMem.subDetId = detId.subdetId(); if (treeMem.subDetId == PixelSubdetector::PixelBarrel) { unsigned int whichHalfBarrel(1), rawId(detId.rawId()); //DetId does not know about halfBarrels is PXB ... if ((rawId >= 302056964 && rawId < 302059300) || (rawId >= 302123268 && rawId < 302127140) || (rawId >= 302189572 && rawId < 302194980)) whichHalfBarrel = 2; treeMem.layer = tTopo->pxbLayer(detId); treeMem.half = whichHalfBarrel; treeMem.rod = tTopo->pxbLadder( detId); // ... so, ladder is not per halfBarrel-Layer, but per barrel-layer! Needs complicated calculation in associateModuleHistsWithTree() treeMem.module = tTopo->pxbModule(detId); } else if (treeMem.subDetId == PixelSubdetector::PixelEndcap) { unsigned int whichHalfCylinder(1), rawId(detId.rawId()); //DetId does not kmow about halfCylinders in PXF if ((rawId >= 352394500 && rawId < 352406032) || (rawId >= 352460036 && rawId < 352471568) || (rawId >= 344005892 && rawId < 344017424) || (rawId >= 344071428 && rawId < 344082960)) whichHalfCylinder = 2; treeMem.layer = tTopo->pxfDisk(detId); treeMem.side = tTopo->pxfSide(detId); treeMem.half = whichHalfCylinder; treeMem.blade = tTopo->pxfBlade(detId); treeMem.panel = tTopo->pxfPanel(detId); treeMem.module = tTopo->pxfModule(detId); } else if (treeMem.subDetId == StripSubdetector::TIB) { unsigned int whichHalfShell(1), rawId(detId.rawId()); //DetId does not kmow about halfShells in TIB if ((rawId >= 369120484 && rawId < 369120688) || (rawId >= 369121540 && rawId < 369121776) || (rawId >= 369136932 && rawId < 369137200) || (rawId >= 369137988 && rawId < 369138288) || (rawId >= 369153396 && rawId < 369153744) || (rawId >= 369154436 && rawId < 369154800) || (rawId >= 369169844 && rawId < 369170256) || (rawId >= 369170900 && rawId < 369171344) || (rawId >= 369124580 && rawId < 369124784) || (rawId >= 369125636 && rawId < 369125872) || (rawId >= 369141028 && rawId < 369141296) || (rawId >= 369142084 && rawId < 369142384) || (rawId >= 369157492 && rawId < 369157840) || (rawId >= 369158532 && rawId < 369158896) || (rawId >= 369173940 && rawId < 369174352) || (rawId >= 369174996 && rawId < 369175440)) whichHalfShell = 2; treeMem.layer = tTopo->tibLayer(detId); treeMem.side = tTopo->tibStringInfo(detId)[0]; treeMem.half = whichHalfShell; treeMem.rod = tTopo->tibStringInfo(detId)[2]; treeMem.outerInner = tTopo->tibStringInfo(detId)[1]; treeMem.module = tTopo->tibModule(detId); treeMem.isStereo = tTopo->tibStereo(detId); treeMem.isDoubleSide = tTopo->tibIsDoubleSide(detId); } else if (treeMem.subDetId == StripSubdetector::TID) { treeMem.layer = tTopo->tidWheel(detId); treeMem.side = tTopo->tidSide(detId); treeMem.ring = tTopo->tidRing(detId); treeMem.outerInner = tTopo->tidModuleInfo(detId)[0]; treeMem.module = tTopo->tidModuleInfo(detId)[1]; treeMem.isStereo = tTopo->tidStereo(detId); treeMem.isDoubleSide = tTopo->tidIsDoubleSide(detId); } else if (treeMem.subDetId == StripSubdetector::TOB) { treeMem.layer = tTopo->tobLayer(detId); treeMem.side = tTopo->tobRodInfo(detId)[0]; treeMem.rod = tTopo->tobRodInfo(detId)[1]; treeMem.module = tTopo->tobModule(detId); treeMem.isStereo = tTopo->tobStereo(detId); treeMem.isDoubleSide = tTopo->tobIsDoubleSide(detId); } else if (treeMem.subDetId == StripSubdetector::TEC) { treeMem.layer = tTopo->tecWheel(detId); treeMem.side = tTopo->tecSide(detId); treeMem.ring = tTopo->tecRing(detId); treeMem.petal = tTopo->tecPetalInfo(detId)[1]; treeMem.outerInner = tTopo->tecPetalInfo(detId)[0]; treeMem.module = tTopo->tecModule(detId); treeMem.isStereo = tTopo->tecStereo(detId); treeMem.isDoubleSide = tTopo->tecIsDoubleSide(detId); } //variables concerning the tracker geometry const Surface::PositionType& gPModule = tkgeom.idToDet(detId)->position(); treeMem.posPhi = gPModule.phi(); treeMem.posEta = gPModule.eta(); treeMem.posR = gPModule.perp(); treeMem.posX = gPModule.x(); treeMem.posY = gPModule.y(); treeMem.posZ = gPModule.z(); const Surface& surface = tkgeom.idToDet(detId)->surface(); //global Orientation of local coordinate system of dets/detUnits LocalPoint lUDirection(1., 0., 0.), lVDirection(0., 1., 0.), lWDirection(0., 0., 1.); GlobalPoint gUDirection = surface.toGlobal(lUDirection), gVDirection = surface.toGlobal(lVDirection), gWDirection = surface.toGlobal(lWDirection); double dR(999.), dPhi(999.), dZ(999.); if (treeMem.subDetId == PixelSubdetector::PixelBarrel || treeMem.subDetId == StripSubdetector::TIB || treeMem.subDetId == StripSubdetector::TOB) { dR = gWDirection.perp() - gPModule.perp(); dPhi = deltaPhi(gUDirection.barePhi(), gPModule.barePhi()); dZ = gVDirection.z() - gPModule.z(); if (dZ >= 0.) treeMem.rOrZDirection = 1; else treeMem.rOrZDirection = -1; } else if (treeMem.subDetId == PixelSubdetector::PixelEndcap) { dR = gUDirection.perp() - gPModule.perp(); dPhi = deltaPhi(gVDirection.barePhi(), gPModule.barePhi()); dZ = gWDirection.z() - gPModule.z(); if (dR >= 0.) treeMem.rOrZDirection = 1; else treeMem.rOrZDirection = -1; } else if (treeMem.subDetId == StripSubdetector::TID || treeMem.subDetId == StripSubdetector::TEC) { dR = gVDirection.perp() - gPModule.perp(); dPhi = deltaPhi(gUDirection.barePhi(), gPModule.barePhi()); dZ = gWDirection.z() - gPModule.z(); if (dR >= 0.) treeMem.rOrZDirection = 1; else treeMem.rOrZDirection = -1; } if (dR >= 0.) treeMem.rDirection = 1; else treeMem.rDirection = -1; if (dPhi >= 0.) treeMem.phiDirection = 1; else treeMem.phiDirection = -1; if (dZ >= 0.) treeMem.zDirection = 1; else treeMem.zDirection = -1; // Assign histos from first step (TrackerOfflineValidation) to the module's entry in the TTree for retrieving mean, rms, median ... const std::string histDir = associateModuleHistsWithTree(treeMem, it->second, substructureName); //mean and RMS values (extracted from histograms Xprime on module level) treeMem.entries = static_cast<UInt_t>(it->second.ResXprimeHisto->GetEntries()); treeMem.meanX = it->second.ResXprimeHisto->GetMean(); treeMem.rmsX = it->second.ResXprimeHisto->GetRMS(); //treeMem.sigmaX = Fwhm(it->second.ResXprimeHisto)/2.355; if (useFit_) { //call fit function which returns mean and sigma from the fit //for absolute residuals std::pair<float, float> fitResult1 = this->fitResiduals(it->second.ResXprimeHisto); treeMem.fitMeanX = fitResult1.first; treeMem.fitSigmaX = fitResult1.second; //for normalized residuals std::pair<float, float> fitResult2 = this->fitResiduals(it->second.NormResXprimeHisto); treeMem.fitMeanNormX = fitResult2.first; treeMem.fitSigmaNormX = fitResult2.second; } //get median for absolute residuals treeMem.medianX = this->getMedian(it->second.ResXprimeHisto); int numberOfBins = it->second.ResXprimeHisto->GetNbinsX(); treeMem.numberOfUnderflows = it->second.ResXprimeHisto->GetBinContent(0); treeMem.numberOfOverflows = it->second.ResXprimeHisto->GetBinContent(numberOfBins + 1); treeMem.numberOfOutliers = it->second.ResXprimeHisto->GetBinContent(0) + it->second.ResXprimeHisto->GetBinContent(numberOfBins + 1); //mean and RMS values (extracted from histograms(normalized Xprime on module level) treeMem.meanNormX = it->second.NormResXprimeHisto->GetMean(); treeMem.rmsNormX = it->second.NormResXprimeHisto->GetRMS(); double stats[20]; it->second.NormResXprimeHisto->GetStats(stats); // GF treeMem.chi2PerDofX = stats[3]/(stats[0]-1); if (stats[0]) treeMem.chi2PerDofX = stats[3] / stats[0]; //treeMem.sigmaNormX = Fwhm(it->second.NormResXprimeHisto)/2.355; treeMem.histNameX = it->second.ResXprimeHisto->GetName(); treeMem.histNameNormX = it->second.NormResXprimeHisto->GetName(); // fill tree variables in local coordinates if set in cfg of TrackerOfllineValidation if (it->second.ResHisto && it->second.NormResHisto) { // if(lCoorHistOn_) { treeMem.meanLocalX = it->second.ResHisto->GetMean(); treeMem.rmsLocalX = it->second.ResHisto->GetRMS(); treeMem.meanNormLocalX = it->second.NormResHisto->GetMean(); treeMem.rmsNormLocalX = it->second.NormResHisto->GetRMS(); treeMem.histNameLocalX = it->second.ResHisto->GetName(); treeMem.histNameNormLocalX = it->second.NormResHisto->GetName(); } // mean and RMS values in local y (extracted from histograms Yprime on module level) // might exist in pixel only if (it->second.ResYprimeHisto) { //(stripYResiduals_){ TH1* h = it->second.ResYprimeHisto; treeMem.meanY = h->GetMean(); treeMem.rmsY = h->GetRMS(); if (useFit_) { // fit function which returns mean and sigma from the fit std::pair<float, float> fitMeanSigma = this->fitResiduals(h); treeMem.fitMeanY = fitMeanSigma.first; treeMem.fitSigmaY = fitMeanSigma.second; } //get median for absolute residuals treeMem.medianY = this->getMedian(h); treeMem.histNameY = h->GetName(); } if (it->second.NormResYprimeHisto) { TH1* h = it->second.NormResYprimeHisto; treeMem.meanNormY = h->GetMean(); treeMem.rmsNormY = h->GetRMS(); h->GetStats(stats); // stats buffer defined above if (stats[0]) treeMem.chi2PerDofY = stats[3] / stats[0]; if (useFit_) { // fit function which returns mean and sigma from the fit std::pair<float, float> fitMeanSigma = this->fitResiduals(h); treeMem.fitMeanNormY = fitMeanSigma.first; treeMem.fitSigmaNormY = fitMeanSigma.second; } treeMem.histNameNormY = h->GetName(); } tree.Fill(); } } const std::string TrackerOfflineValidationSummary::associateModuleHistsWithTree( const TkOffTreeVariables& treeMem, TrackerOfflineValidationSummary::ModuleHistos& moduleHists, std::map<std::string, std::string>& substructureName) { std::stringstream histDir, sSubdetName; std::string componentName; if (!moduleDirectory_.empty()) histDir << moduleDirectory_ << "/"; std::string wheelOrLayer("_layer_"); if (treeMem.subDetId == PixelSubdetector::PixelBarrel) { unsigned int half(treeMem.half), layer(treeMem.layer), ladder(0); if (layer == 1) { if (half == 2) ladder = treeMem.rod - 5; else if (treeMem.rod > 15) ladder = treeMem.rod - 10; else ladder = treeMem.rod; } else if (layer == 2) { if (half == 2) ladder = treeMem.rod - 8; else if (treeMem.rod > 24) ladder = treeMem.rod - 16; else ladder = treeMem.rod; } else if (layer == 3) { if (half == 2) ladder = treeMem.rod - 11; else if (treeMem.rod > 33) ladder = treeMem.rod - 22; else ladder = treeMem.rod; } componentName = "Pixel"; sSubdetName << "TPBBarrel_1"; histDir << componentName << "/" << sSubdetName.str() << "/TPBHalfBarrel_" << treeMem.half << "/TPBLayer_" << treeMem.layer << "/TPBLadder_" << ladder; } else if (treeMem.subDetId == PixelSubdetector::PixelEndcap) { unsigned int side(treeMem.side), half(treeMem.half), blade(0); if (side == 1) side = 3; if (half == 2) blade = treeMem.blade - 6; else if (treeMem.blade > 18) blade = treeMem.blade - 12; else blade = treeMem.blade; componentName = "Pixel"; sSubdetName << "TPEEndcap_" << side; histDir << componentName << "/" << sSubdetName.str() << "/TPEHalfCylinder_" << treeMem.half << "/TPEHalfDisk_" << treeMem.layer << "/TPEBlade_" << blade << "/TPEPanel_" << treeMem.panel; wheelOrLayer = "_wheel_"; } else if (treeMem.subDetId == StripSubdetector::TIB) { unsigned int half(treeMem.half), layer(treeMem.layer), surface(treeMem.outerInner), string(0); if (half == 2) { if (layer == 1) { if (surface == 1) string = treeMem.rod - 13; else if (surface == 2) string = treeMem.rod - 15; } if (layer == 2) { if (surface == 1) string = treeMem.rod - 17; else if (surface == 2) string = treeMem.rod - 19; } if (layer == 3) { if (surface == 1) string = treeMem.rod - 22; else if (surface == 2) string = treeMem.rod - 23; } if (layer == 4) { if (surface == 1) string = treeMem.rod - 26; else if (surface == 2) string = treeMem.rod - 28; } } else string = treeMem.rod; std::stringstream detString; if (treeMem.layer < 3 && !treeMem.isDoubleSide) detString << "/Det_" << treeMem.module; else detString << ""; componentName = "Strip"; sSubdetName << "TIBBarrel_1"; histDir << componentName << "/" << sSubdetName.str() << "/TIBHalfBarrel_" << treeMem.side << "/TIBLayer_" << treeMem.layer << "/TIBHalfShell_" << treeMem.half << "/TIBSurface_" << treeMem.outerInner << "/TIBString_" << string << detString.str(); } else if (treeMem.subDetId == StripSubdetector::TID) { unsigned int side(treeMem.side), outerInner(0); if (side == 1) side = 3; if (treeMem.outerInner == 1) outerInner = 2; else if (treeMem.outerInner == 2) outerInner = 1; std::stringstream detString; if (treeMem.ring < 3 && !treeMem.isDoubleSide) detString << "/Det_" << treeMem.module; else detString << ""; componentName = "Strip"; sSubdetName << "TIDEndcap_" << side; histDir << componentName << "/" << sSubdetName.str() << "/TIDDisk_" << treeMem.layer << "/TIDRing_" << treeMem.ring << "/TIDSide_" << outerInner << detString.str(); wheelOrLayer = "_wheel_"; } else if (treeMem.subDetId == StripSubdetector::TOB) { std::stringstream detString; if (treeMem.layer < 3 && !treeMem.isDoubleSide) detString << "/Det_" << treeMem.module; else detString << ""; componentName = "Strip"; sSubdetName << "TOBBarrel_4"; histDir << componentName << "/" << sSubdetName.str() << "/TOBHalfBarrel_" << treeMem.side << "/TOBLayer_" << treeMem.layer << "/TOBRod_" << treeMem.rod << detString.str(); } else if (treeMem.subDetId == StripSubdetector::TEC) { unsigned int side(0), outerInner(0), ring(0); if (treeMem.side == 1) side = 6; else if (treeMem.side == 2) side = 5; if (treeMem.outerInner == 1) outerInner = 2; else if (treeMem.outerInner == 2) outerInner = 1; if (treeMem.layer > 3 && treeMem.layer < 7) ring = treeMem.ring - 1; else if (treeMem.layer == 7 || treeMem.layer == 8) ring = treeMem.ring - 2; else if (treeMem.layer == 9) ring = treeMem.ring - 3; else ring = treeMem.ring; std::stringstream detString; if ((treeMem.ring < 3 || treeMem.ring == 5) && !treeMem.isDoubleSide) detString << "/Det_" << treeMem.module; else detString << ""; componentName = "Strip"; sSubdetName << "TECEndcap_" << side; histDir << componentName << "/" << sSubdetName.str() << "/TECDisk_" << treeMem.layer << "/TECSide_" << outerInner << "/TECPetal_" << treeMem.petal << "/TECRing_" << ring << detString.str(); wheelOrLayer = "_wheel_"; } substructureName["component"] = componentName; substructureName["subdet"] = sSubdetName.str(); std::stringstream histName; histName << "residuals_subdet_" << treeMem.subDetId << wheelOrLayer << treeMem.layer << "_module_" << treeMem.moduleId; std::string fullPath; fullPath = histDir.str() + "/h_xprime_" + histName.str(); if (dbe_->get(fullPath)) moduleHists.ResXprimeHisto = dbe_->get(fullPath)->getTH1(); else { edm::LogError("TrackerOfflineValidationSummary") << "Problem with names in input file produced in TrackerOfflineValidation ...\n" << "This histogram should exist in every configuration, " << "but no histogram with name " << fullPath << " is found!"; return ""; } fullPath = histDir.str() + "/h_normxprime" + histName.str(); if (dbe_->get(fullPath)) moduleHists.NormResXprimeHisto = dbe_->get(fullPath)->getTH1(); fullPath = histDir.str() + "/h_yprime_" + histName.str(); if (dbe_->get(fullPath)) moduleHists.ResYprimeHisto = dbe_->get(fullPath)->getTH1(); fullPath = histDir.str() + "/h_normyprime" + histName.str(); if (dbe_->get(fullPath)) moduleHists.NormResYprimeHisto = dbe_->get(fullPath)->getTH1(); fullPath = histDir.str() + "/h_" + histName.str(); if (dbe_->get(fullPath)) moduleHists.ResHisto = dbe_->get(fullPath)->getTH1(); fullPath = histDir.str() + "/h_norm" + histName.str(); if (dbe_->get(fullPath)) moduleHists.NormResHisto = dbe_->get(fullPath)->getTH1(); return histDir.str(); } std::pair<float, float> TrackerOfflineValidationSummary::fitResiduals(TH1* hist) const { std::pair<float, float> fitResult(9999., 9999.); if (!hist || hist->GetEntries() < 20) return fitResult; float mean = hist->GetMean(); float sigma = hist->GetRMS(); try { // for < CMSSW_2_2_0 since ROOT warnings from fit are converted to exceptions // Remove the try/catch for more recent CMSSW! // first fit: two RMS around mean TF1 func("tmp", "gaus", mean - 2. * sigma, mean + 2. * sigma); if (0 == hist->Fit(&func, "QNR")) { // N: do not blow up file by storing fit! mean = func.GetParameter(1); sigma = func.GetParameter(2); // second fit: three sigma of first fit around mean of first fit func.SetRange(mean - 3. * sigma, mean + 3. * sigma); // I: integral gives more correct results if binning is too wide // L: Likelihood can treat empty bins correctly (if hist not weighted...) if (0 == hist->Fit(&func, "Q0LR")) { if (hist->GetFunction(func.GetName())) { // Take care that it is later on drawn: hist->GetFunction(func.GetName())->ResetBit(TF1::kNotDraw); } fitResult.first = func.GetParameter(1); fitResult.second = func.GetParameter(2); } } } catch (cms::Exception const& e) { edm::LogWarning("Alignment") << "@SUB=TrackerOfflineValidation::fitResiduals" << "Caught this exception during ROOT fit: " << e.what(); } return fitResult; } float TrackerOfflineValidationSummary::getMedian(const TH1* histo) const { float median = 999; const int nbins = histo->GetNbinsX(); //extract median from histogram double* x = new double[nbins]; double* y = new double[nbins]; for (int j = 0; j < nbins; j++) { x[j] = histo->GetBinCenter(j + 1); y[j] = histo->GetBinContent(j + 1); } median = TMath::Median(nbins, x, y); delete[] x; x = nullptr; delete[] y; y = nullptr; return median; } void TrackerOfflineValidationSummary::collateHarvestingHists(TTree& tree) { this->applyHarvestingHierarchy(tree); this->fillHarvestingHists(tree); } void TrackerOfflineValidationSummary::applyHarvestingHierarchy(TTree& tree) { TkOffTreeVariables* treeMemPtr = nullptr; std::map<std::string, std::string>* substructureName = nullptr; tree.SetBranchAddress("TkOffTreeVariables", &treeMemPtr); tree.SetBranchAddress("SubstructureName", &substructureName); // Loop over modules to select accumulation criteria for harvesting plots for (unsigned int iSubdet = 1; iSubdet < 7; ++iSubdet) { std::string hierarchyName(""); std::string componentName(""); std::vector<unsigned int> treeEntries; for (unsigned int iSide = 1; iSide < 3; ++iSide) { // Set up only one collection for Barrels, not separated for side if (iSide == 1 && (iSubdet == PixelSubdetector::PixelBarrel || iSubdet == StripSubdetector::TIB || iSubdet == StripSubdetector::TOB)) continue; for (int iTree = 0; iTree < tree.GetEntries(); ++iTree) { tree.GetEntry(iTree); // Do not use glued Dets if (treeMemPtr->isDoubleSide) continue; if (treeMemPtr->subDetId == iSubdet) { if (iSide != treeMemPtr->side && (iSubdet == PixelSubdetector::PixelEndcap || iSubdet == StripSubdetector::TID || iSubdet == StripSubdetector::TEC)) continue; treeEntries.push_back(iTree); if (hierarchyName.empty()) { hierarchyName = (*substructureName)["subdet"]; componentName = (*substructureName)["component"]; } } } HarvestingHierarchy harvestingHierarchy(hierarchyName, componentName, treeEntries); vHarvestingHierarchy_.push_back(harvestingHierarchy); hierarchyName = ""; componentName = ""; treeEntries.clear(); } } // Here could be a further separation of the HarvestingHierarchy. // E.g. separate the existing ones by layer and add them to the vector without deleting any element from the vector. // The existing hists will stay and the new ones are added // Now, book the corresponding histos this->bookHarvestingHists(); } void TrackerOfflineValidationSummary::bookHarvestingHists() { edm::LogInfo("TrackerOfflineValidationSummary") << "Harvesting histograms will be booked for " << vHarvestingHierarchy_.size() << " different hierarchy selections"; for (std::vector<HarvestingHierarchy>::iterator iHier = vHarvestingHierarchy_.begin(); iHier != vHarvestingHierarchy_.end(); ++iHier) { std::stringstream dmrXprimeHistoName, dmrYprimeHistoName, dmrXprimeHistoTitle, dmrYprimeHistoTitle; dmrXprimeHistoName << "h_DmrXprime_" << iHier->hierarchyName; dmrYprimeHistoName << "h_DmrYprime_" << iHier->hierarchyName; dmrXprimeHistoTitle << "DMR for " << iHier->hierarchyName << ";<#DeltaX> [cm];# modules"; dmrYprimeHistoTitle << "DMR for " << iHier->hierarchyName << ";<#DeltaY> [cm];# modules"; std::string directoryString(moduleDirectory_); if (!directoryString.empty()) directoryString += "/"; directoryString += iHier->componentName; dbe_->setCurrentFolder(directoryString); int nBinsX(0); double xMin(0.), xMax(0.); if (iHier->componentName == "Pixel") { this->getBinning("TH1DmrXprimePixelModules", nBinsX, xMin, xMax); iHier->harvestingHistos.DmrXprime = dbe_->book1D(dmrXprimeHistoName.str(), dmrXprimeHistoTitle.str(), nBinsX, xMin, xMax)->getTH1(); this->getBinning("TH1DmrYprimePixelModules", nBinsX, xMin, xMax); iHier->harvestingHistos.DmrYprime = dbe_->book1D(dmrYprimeHistoName.str(), dmrYprimeHistoTitle.str(), nBinsX, xMin, xMax)->getTH1(); } else if (iHier->componentName == "Strip") { this->getBinning("TH1DmrXprimeStripModules", nBinsX, xMin, xMax); iHier->harvestingHistos.DmrXprime = dbe_->book1D(dmrXprimeHistoName.str(), dmrXprimeHistoTitle.str(), nBinsX, xMin, xMax)->getTH1(); if (!parSet_.getParameter<bool>("stripYDmrs")) continue; this->getBinning("TH1DmrYprimeStripModules", nBinsX, xMin, xMax); iHier->harvestingHistos.DmrYprime = dbe_->book1D(dmrYprimeHistoName.str(), dmrYprimeHistoTitle.str(), nBinsX, xMin, xMax)->getTH1(); } } } void TrackerOfflineValidationSummary::getBinning(const std::string& binningPSetName, int& nBinsX, double& lowerBoundX, double& upperBoundX) const { const edm::ParameterSet& binningPSet = parSet_.getParameter<edm::ParameterSet>(binningPSetName); nBinsX = binningPSet.getParameter<int>("Nbinx"); lowerBoundX = binningPSet.getParameter<double>("xmin"); upperBoundX = binningPSet.getParameter<double>("xmax"); } void TrackerOfflineValidationSummary::fillHarvestingHists(TTree& tree) { TkOffTreeVariables* treeMemPtr = nullptr; std::map<std::string, std::string>* substructureName = nullptr; tree.SetBranchAddress("TkOffTreeVariables", &treeMemPtr); tree.SetBranchAddress("SubstructureName", &substructureName); const unsigned int minEntriesPerModule(parSet_.getParameter<unsigned int>("minEntriesPerModuleForDmr")); edm::LogInfo("TrackerOfflineValidationSummary") << "Median of a module is added to DMR plots if it contains at least " << minEntriesPerModule << " hits"; for (std::vector<HarvestingHierarchy>::iterator iHier = vHarvestingHierarchy_.begin(); iHier != vHarvestingHierarchy_.end(); ++iHier) { for (std::vector<unsigned int>::const_iterator iTreeEntries = iHier->treeEntries.begin(); iTreeEntries != iHier->treeEntries.end(); ++iTreeEntries) { tree.GetEntry(*iTreeEntries); if (treeMemPtr->entries < minEntriesPerModule) continue; iHier->harvestingHistos.DmrXprime->Fill(treeMemPtr->medianX); if (iHier->harvestingHistos.DmrYprime) iHier->harvestingHistos.DmrYprime->Fill(treeMemPtr->medianY); } } } //define this as a plug-in DEFINE_FWK_MODULE(TrackerOfflineValidationSummary);