Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 10:39:29

0001 /**
0002  * @package   Alignment/MillePedeAlignmentAlgorithm
0003  * @file      MillePedeDQMModule.cc
0004  *
0005  * @author    Max Stark (max.stark@cern.ch)
0006  * @date      Feb 19, 2016
0007  */
0008 
0009 /*** header-file ***/
0010 #include "Alignment/MillePedeAlignmentAlgorithm/plugins/MillePedeDQMModule.h"
0011 
0012 /*** ROOT objects ***/
0013 #include "TH1F.h"
0014 
0015 /*** Core framework functionality ***/
0016 #include "FWCore/Framework/interface/EventSetup.h"
0017 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0018 
0019 /*** Alignment ***/
0020 #include "Alignment/MillePedeAlignmentAlgorithm/interface/PedeLabelerBase.h"
0021 #include "Alignment/MillePedeAlignmentAlgorithm/interface/PedeLabelerPluginFactory.h"
0022 #include "Alignment/TrackerAlignment/interface/AlignableTracker.h"
0023 
0024 /*** Necessary Framework infrastructure ***/
0025 #include "FWCore/Framework/interface/ProcessBlock.h"
0026 #include "DataFormats/Alignment/interface/AlignmentToken.h"
0027 
0028 MillePedeDQMModule ::MillePedeDQMModule(const edm::ParameterSet& config)
0029     : tTopoToken_(esConsumes<edm::Transition::BeginRun>()),
0030       gDetToken_(esConsumes<edm::Transition::BeginRun>()),
0031       ptpToken_(esConsumes<edm::Transition::BeginRun>()),
0032       aliThrToken_(esConsumes<edm::Transition::BeginRun>()),
0033       geomToken_(esConsumes<edm::Transition::BeginRun>()),
0034       mpReaderConfig_(config.getParameter<edm::ParameterSet>("MillePedeFileReader")),
0035       isHG_(mpReaderConfig_.getParameter<bool>("isHG")) {
0036   consumes<AlignmentToken, edm::InProcess>(config.getParameter<edm::InputTag>("alignmentTokenSrc"));
0037 }
0038 
0039 MillePedeDQMModule ::~MillePedeDQMModule() {}
0040 
0041 //=============================================================================
0042 //===   INTERFACE IMPLEMENTATION                                            ===
0043 //=============================================================================
0044 
0045 void MillePedeDQMModule ::bookHistograms(DQMStore::IBooker& booker) {
0046   edm::LogInfo("MillePedeDQMModule") << "Booking histograms";
0047 
0048   booker.cd();
0049   if (!isHG_) {
0050     booker.setCurrentFolder("AlCaReco/SiPixelAli/");
0051     h_xPos = booker.book1D("Xpos", "Alignment fit #DeltaX;;#mum", 36, 0., 36.);
0052     h_xRot = booker.book1D("Xrot", "Alignment fit #Delta#theta_{X};;#murad", 36, 0., 36.);
0053     h_yPos = booker.book1D("Ypos", "Alignment fit #DeltaY;;#mum", 36, 0., 36.);
0054     h_yRot = booker.book1D("Yrot", "Alignment fit #Delta#theta_{Y};;#murad", 36, 0., 36.);
0055     h_zPos = booker.book1D("Zpos", "Alignment fit #DeltaZ;;#mum", 36, 0., 36.);
0056     h_zRot = booker.book1D("Zrot", "Alignment fit #Delta#theta_{Z};;#murad", 36, 0., 36.);
0057     statusResults = booker.book2D("statusResults", "Status of SiPixelAli PCL workflow;;", 6, 0., 6., 1, 0., 1.);
0058   } else {
0059     booker.setCurrentFolder("AlCaReco/SiPixelAliHG/");
0060 
0061     layerVec = {{"Layer1", pixelTopologyMap_->getPXBLadders(1)},
0062                 {"Layer2", pixelTopologyMap_->getPXBLadders(2)},
0063                 {"Layer3", pixelTopologyMap_->getPXBLadders(3)},
0064                 {"Layer4", pixelTopologyMap_->getPXBLadders(4)},
0065                 {"Disk-3", pixelTopologyMap_->getPXFBlades(-3) * 2},
0066                 {"Disk-2", pixelTopologyMap_->getPXFBlades(-2) * 2},
0067                 {"Disk-1", pixelTopologyMap_->getPXFBlades(-1) * 2},
0068                 {"Disk1", pixelTopologyMap_->getPXFBlades(1) * 2},
0069                 {"Disk2", pixelTopologyMap_->getPXFBlades(2) * 2},
0070                 {"Disk3", pixelTopologyMap_->getPXFBlades(3) * 2}};
0071 
0072     for (const auto& layer : layerVec) {
0073       h_xPos_HG[layer.first] = booker.book1D("Xpos_HG_" + layer.first,
0074                                              "Alignment fit #DeltaX for " + layer.first + ";;#mum",
0075                                              layer.second + 5,
0076                                              0.,
0077                                              layer.second + 5);
0078       h_xRot_HG[layer.first] = booker.book1D("Xrot_HG_" + layer.first,
0079                                              "Alignment fit #Delta#theta_{X} for " + layer.first + ";;#murad",
0080                                              layer.second + 5,
0081                                              0.,
0082                                              layer.second + 5);
0083       h_yPos_HG[layer.first] = booker.book1D("Ypos_HG_" + layer.first,
0084                                              "Alignment fit #DeltaY for " + layer.first + ";;#mum",
0085                                              layer.second + 5,
0086                                              0.,
0087                                              layer.second + 5);
0088       h_yRot_HG[layer.first] = booker.book1D("Yrot_HG_" + layer.first,
0089                                              "Alignment fit #Delta#theta_{Y} for " + layer.first + ";;#murad",
0090                                              layer.second + 5,
0091                                              0.,
0092                                              layer.second + 5);
0093       h_zPos_HG[layer.first] = booker.book1D("Zpos_HG_" + layer.first,
0094                                              "Alignment fit #DeltaZ for " + layer.first + ";;#mum",
0095                                              layer.second + 5,
0096                                              0.,
0097                                              layer.second + 5);
0098       h_zRot_HG[layer.first] = booker.book1D("Zrot_HG_" + layer.first,
0099                                              "Alignment fit #Delta#theta_{Z} for " + layer.first + ";;#murad",
0100                                              layer.second + 5,
0101                                              0.,
0102                                              layer.second + 5);
0103     }
0104 
0105     statusResults =
0106         booker.book2D("statusResults", "Fraction threshold check for SiPixelAliHG PCL;;", 6, 0., 6., 10, 0., 10.);
0107   }
0108 
0109   binariesAvalaible = booker.bookInt("BinariesFound");
0110   exitCode = booker.bookString("PedeExitCode", "");
0111   isVetoed = booker.bookString("IsVetoed", "");
0112 
0113   booker.cd();
0114 }
0115 
0116 void MillePedeDQMModule ::dqmEndJob(DQMStore::IBooker& booker, DQMStore::IGetter&) {
0117   bookHistograms(booker);
0118   if (mpReader_) {
0119     mpReader_->read();
0120   } else {
0121     throw cms::Exception("LogicError") << "@SUB=MillePedeDQMModule::dqmEndJob\n"
0122                                        << "Try to read MillePede results before initializing MillePedeFileReader";
0123   }
0124   if (!isHG_) {
0125     fillExpertHistos();
0126     fillStatusHisto(statusResults);
0127   } else {
0128     fillExpertHistos_HG();
0129     fillStatusHistoHG(statusResults);
0130   }
0131   binariesAvalaible->Fill(mpReader_->binariesAmount());
0132   auto theResults = mpReader_->getResults();
0133   std::string exitCodeStr = theResults.getExitMessage();
0134 
0135   std::string vetoStr{};
0136   if (mpReader_->storeAlignments()) {
0137     vetoStr = "DB Updated!"; /* easy peasy, fait accompli an alignment is there */
0138   } else {
0139     if (theResults.isHighGranularity()) { /* HG case */
0140       if (theResults.getDBVetoed() && theResults.getDBUpdated()) {
0141         vetoStr = "DB Update Vetoed"; /* this can happen in the HG PCL case */
0142       } else {
0143         vetoStr = "N/A";
0144       }
0145     } else { /* LG case */
0146       if (theResults.exceedsCutoffs()) {
0147         vetoStr = "DB Update Vetoed"; /* this can happen in the LG PCL case */
0148       } else {
0149         vetoStr = "N/A";
0150       }  // if the alignment exceeds the cutoffs
0151     }    // LG case
0152   }      // if the alignment was not stored
0153 
0154   exitCode->Fill(exitCodeStr);
0155   isVetoed->Fill(vetoStr);
0156 }
0157 
0158 //=============================================================================
0159 //===   PRIVATE METHOD IMPLEMENTATION                                       ===
0160 //=============================================================================
0161 
0162 void MillePedeDQMModule ::beginRun(const edm::Run&, const edm::EventSetup& setup) {
0163   if (!setupChanged(setup))
0164     return;
0165 
0166   const TrackerTopology* const tTopo = &setup.getData(tTopoToken_);
0167   const GeometricDet* geometricDet = &setup.getData(gDetToken_);
0168   const PTrackerParameters* ptp = &setup.getData(ptpToken_);
0169   const TrackerGeometry* geom = &setup.getData(geomToken_);
0170 
0171   pixelTopologyMap_ = std::make_shared<PixelTopologyMap>(geom, tTopo);
0172 
0173   // take the thresholds from DB
0174   const auto& thresholds_ = &setup.getData(aliThrToken_);
0175 
0176   auto myThresholds = std::make_shared<AlignPCLThresholdsHG>();
0177   myThresholds->setAlignPCLThresholds(thresholds_->getNrecords(), thresholds_->getThreshold_Map());
0178   myThresholds->setFloatMap(thresholds_->getFloatMap());
0179 
0180   TrackerGeomBuilderFromGeometricDet builder;
0181 
0182   const auto trackerGeometry = builder.build(geometricDet, *ptp, tTopo);
0183   tracker_ = std::make_unique<AlignableTracker>(trackerGeometry, tTopo);
0184 
0185   const std::string labelerPlugin{"PedeLabeler"};
0186   edm::ParameterSet labelerConfig{};
0187   labelerConfig.addUntrackedParameter("plugin", labelerPlugin);
0188   labelerConfig.addUntrackedParameter("RunRangeSelection", edm::VParameterSet{});
0189 
0190   std::shared_ptr<PedeLabelerBase> pedeLabeler{PedeLabelerPluginFactory::get()->create(
0191       labelerPlugin, PedeLabelerBase::TopLevelAlignables(tracker_.get(), nullptr, nullptr), labelerConfig)};
0192 
0193   mpReader_ = std::make_unique<MillePedeFileReader>(
0194       mpReaderConfig_, pedeLabeler, std::shared_ptr<const AlignPCLThresholdsHG>(myThresholds), pixelTopologyMap_);
0195 }
0196 
0197 void MillePedeDQMModule ::fillStatusHisto(MonitorElement* statusHisto) {
0198   TH2F* histo_status = statusHisto->getTH2F();
0199   auto theResults = mpReader_->getResults();
0200   theResults.print();
0201   histo_status->SetBinContent(1, 1, theResults.getDBUpdated());
0202   histo_status->GetXaxis()->SetBinLabel(1, "DB updated");
0203   histo_status->SetBinContent(2, 1, theResults.exceedsCutoffs());
0204   histo_status->GetXaxis()->SetBinLabel(2, "significant movement");
0205   histo_status->SetBinContent(3, 1, theResults.getDBVetoed());
0206   histo_status->GetXaxis()->SetBinLabel(3, "DB update vetoed");
0207   histo_status->SetBinContent(4, 1, !theResults.exceedsThresholds());
0208   histo_status->GetXaxis()->SetBinLabel(4, "within max movement");
0209   histo_status->SetBinContent(5, 1, !theResults.exceedsMaxError());
0210   histo_status->GetXaxis()->SetBinLabel(5, "within max error");
0211   histo_status->SetBinContent(6, 1, !theResults.belowSignificance());
0212   histo_status->GetXaxis()->SetBinLabel(6, "above significance");
0213 }
0214 
0215 void MillePedeDQMModule ::fillStatusHistoHG(MonitorElement* statusHisto) {
0216   TH2F* histo_status = statusHisto->getTH2F();
0217   auto& theResults = mpReader_->getResultsHG();
0218   histo_status->GetXaxis()->SetBinLabel(1, "#DeltaX");
0219   histo_status->GetXaxis()->SetBinLabel(2, "#DeltaY");
0220   histo_status->GetXaxis()->SetBinLabel(3, "#DeltaZ");
0221   histo_status->GetXaxis()->SetBinLabel(4, "#Delta#theta_{X}");
0222   histo_status->GetXaxis()->SetBinLabel(5, "#Delta#theta_{Y}");
0223   histo_status->GetXaxis()->SetBinLabel(6, "#Delta#theta_{Z}");
0224 
0225   int i = 0;
0226   for (const auto& result : theResults) {
0227     histo_status->GetYaxis()->SetBinLabel(i + 1, result.first.data());
0228     for (std::size_t j = 0; j < result.second.size(); ++j) {
0229       histo_status->SetBinContent(j + 1, i + 1, result.second[j]);
0230     }
0231     i++;
0232   }
0233 }
0234 
0235 void MillePedeDQMModule ::fillExpertHistos() {
0236   std::array<double, SIZE_INDEX> Xcut_, sigXcut_, maxMoveXcut_, maxErrorXcut_;
0237   std::array<double, SIZE_INDEX> tXcut_, sigtXcut_, maxMovetXcut_, maxErrortXcut_;
0238 
0239   std::array<double, SIZE_INDEX> Ycut_, sigYcut_, maxMoveYcut_, maxErrorYcut_;
0240   std::array<double, SIZE_INDEX> tYcut_, sigtYcut_, maxMovetYcut_, maxErrortYcut_;
0241 
0242   std::array<double, SIZE_INDEX> Zcut_, sigZcut_, maxMoveZcut_, maxErrorZcut_;
0243   std::array<double, SIZE_INDEX> tZcut_, sigtZcut_, maxMovetZcut_, maxErrortZcut_;
0244 
0245   auto myMap = mpReader_->getThresholdMap();
0246 
0247   std::vector<std::string> alignablesList;
0248   for (auto it = myMap.begin(); it != myMap.end(); ++it) {
0249     alignablesList.push_back(it->first);
0250   }
0251 
0252   for (auto& alignable : alignablesList) {
0253     int detIndex = getIndexFromString(alignable);
0254 
0255     Xcut_[detIndex] = myMap[alignable].getXcut();
0256     sigXcut_[detIndex] = myMap[alignable].getSigXcut();
0257     maxMoveXcut_[detIndex] = myMap[alignable].getMaxMoveXcut();
0258     maxErrorXcut_[detIndex] = myMap[alignable].getErrorXcut();
0259 
0260     Ycut_[detIndex] = myMap[alignable].getYcut();
0261     sigYcut_[detIndex] = myMap[alignable].getSigYcut();
0262     maxMoveYcut_[detIndex] = myMap[alignable].getMaxMoveYcut();
0263     maxErrorYcut_[detIndex] = myMap[alignable].getErrorYcut();
0264 
0265     Zcut_[detIndex] = myMap[alignable].getZcut();
0266     sigZcut_[detIndex] = myMap[alignable].getSigZcut();
0267     maxMoveZcut_[detIndex] = myMap[alignable].getMaxMoveZcut();
0268     maxErrorZcut_[detIndex] = myMap[alignable].getErrorZcut();
0269 
0270     tXcut_[detIndex] = myMap[alignable].getThetaXcut();
0271     sigtXcut_[detIndex] = myMap[alignable].getSigThetaXcut();
0272     maxMovetXcut_[detIndex] = myMap[alignable].getMaxMoveThetaXcut();
0273     maxErrortXcut_[detIndex] = myMap[alignable].getErrorThetaXcut();
0274 
0275     tYcut_[detIndex] = myMap[alignable].getThetaYcut();
0276     sigtYcut_[detIndex] = myMap[alignable].getSigThetaYcut();
0277     maxMovetYcut_[detIndex] = myMap[alignable].getMaxMoveThetaYcut();
0278     maxErrortYcut_[detIndex] = myMap[alignable].getErrorThetaYcut();
0279 
0280     tZcut_[detIndex] = myMap[alignable].getThetaZcut();
0281     sigtZcut_[detIndex] = myMap[alignable].getSigThetaZcut();
0282     maxMovetZcut_[detIndex] = myMap[alignable].getMaxMoveThetaZcut();
0283     maxErrortZcut_[detIndex] = myMap[alignable].getErrorThetaZcut();
0284   }
0285 
0286   fillExpertHisto(h_xPos, Xcut_, sigXcut_, maxMoveXcut_, maxErrorXcut_, mpReader_->getXobs(), mpReader_->getXobsErr());
0287   fillExpertHisto(
0288       h_xRot, tXcut_, sigtXcut_, maxMovetXcut_, maxErrortXcut_, mpReader_->getTXobs(), mpReader_->getTXobsErr());
0289 
0290   fillExpertHisto(h_yPos, Ycut_, sigYcut_, maxMoveYcut_, maxErrorYcut_, mpReader_->getYobs(), mpReader_->getYobsErr());
0291   fillExpertHisto(
0292       h_yRot, tYcut_, sigtYcut_, maxMovetYcut_, maxErrortYcut_, mpReader_->getTYobs(), mpReader_->getTYobsErr());
0293 
0294   fillExpertHisto(h_zPos, Zcut_, sigZcut_, maxMoveZcut_, maxErrorZcut_, mpReader_->getZobs(), mpReader_->getZobsErr());
0295   fillExpertHisto(
0296       h_zRot, tZcut_, sigtZcut_, maxMovetZcut_, maxErrortZcut_, mpReader_->getTZobs(), mpReader_->getTZobsErr());
0297 }
0298 
0299 void MillePedeDQMModule ::fillExpertHisto(MonitorElement* histo,
0300                                           const std::array<double, SIZE_INDEX>& cut,
0301                                           const std::array<double, SIZE_INDEX>& sigCut,
0302                                           const std::array<double, SIZE_INDEX>& maxMoveCut,
0303                                           const std::array<double, SIZE_INDEX>& maxErrorCut,
0304                                           const std::array<double, SIZE_LG_STRUCTS>& obs,
0305                                           const std::array<double, SIZE_LG_STRUCTS>& obsErr) {
0306   TH1F* histo_0 = histo->getTH1F();
0307 
0308   double max_ = *std::max_element(maxMoveCut.begin(), maxMoveCut.end());
0309 
0310   histo_0->SetMinimum(-(max_));
0311   histo_0->SetMaximum(max_);
0312 
0313   //  Schematics of the bin contents
0314   //
0315   //  XX XX XX XX XX XX    OO OO OO OO    II II II II
0316   // |--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|
0317   // | 1| 2| 3| 4| 5| 6| 7| 8| 9|10|11|12|13|14|15|16|17|  ...
0318   //
0319   // |-----------------|  |-----------|  |-----------|
0320   // |observed movement|  |thresholds1|  |thresholds2|
0321 
0322   for (size_t i = 0; i < obs.size(); ++i) {
0323     // fist obs.size() bins for observed movements
0324     histo_0->SetBinContent(i + 1, obs[i]);
0325     histo_0->SetBinError(i + 1, obsErr[i]);
0326 
0327     // then at bin 8,8+5,8+10,... for cutoffs
0328     // 5 bins is the space allocated for the 4 other thresholds + 1 empty separation bin
0329     histo_0->SetBinContent(8 + i * 5, cut[i]);
0330 
0331     // then at bin 9,9+5,9+10,... for significances
0332     histo_0->SetBinContent(9 + i * 5, sigCut[i]);
0333 
0334     // then at bin 10,10+5,10+10,... for maximum movements
0335     histo_0->SetBinContent(10 + i * 5, maxMoveCut[i]);
0336 
0337     // then at bin 11,11+5,11+10,... for maximum errors
0338     histo_0->SetBinContent(11 + i * 5, maxErrorCut[i]);
0339   }
0340 }
0341 
0342 void MillePedeDQMModule ::fillExpertHistos_HG() {
0343   std::array<double, SIZE_INDEX> Xcut_, sigXcut_, maxMoveXcut_, maxErrorXcut_;
0344   std::array<double, SIZE_INDEX> tXcut_, sigtXcut_, maxMovetXcut_, maxErrortXcut_;
0345 
0346   std::array<double, SIZE_INDEX> Ycut_, sigYcut_, maxMoveYcut_, maxErrorYcut_;
0347   std::array<double, SIZE_INDEX> tYcut_, sigtYcut_, maxMovetYcut_, maxErrortYcut_;
0348 
0349   std::array<double, SIZE_INDEX> Zcut_, sigZcut_, maxMoveZcut_, maxErrorZcut_;
0350   std::array<double, SIZE_INDEX> tZcut_, sigtZcut_, maxMovetZcut_, maxErrortZcut_;
0351 
0352   auto myMap = mpReader_->getThresholdMap();
0353 
0354   std::vector<std::string> alignablesList;
0355   for (auto it = myMap.begin(); it != myMap.end(); ++it) {
0356     alignablesList.push_back(it->first);
0357   }
0358 
0359   for (auto& alignable : alignablesList) {
0360     int detIndex = getIndexFromString(alignable);
0361 
0362     Xcut_[detIndex] = myMap[alignable].getXcut();
0363     sigXcut_[detIndex] = myMap[alignable].getSigXcut();
0364     maxMoveXcut_[detIndex] = myMap[alignable].getMaxMoveXcut();
0365     maxErrorXcut_[detIndex] = myMap[alignable].getErrorXcut();
0366 
0367     Ycut_[detIndex] = myMap[alignable].getYcut();
0368     sigYcut_[detIndex] = myMap[alignable].getSigYcut();
0369     maxMoveYcut_[detIndex] = myMap[alignable].getMaxMoveYcut();
0370     maxErrorYcut_[detIndex] = myMap[alignable].getErrorYcut();
0371 
0372     Zcut_[detIndex] = myMap[alignable].getZcut();
0373     sigZcut_[detIndex] = myMap[alignable].getSigZcut();
0374     maxMoveZcut_[detIndex] = myMap[alignable].getMaxMoveZcut();
0375     maxErrorZcut_[detIndex] = myMap[alignable].getErrorZcut();
0376 
0377     tXcut_[detIndex] = myMap[alignable].getThetaXcut();
0378     sigtXcut_[detIndex] = myMap[alignable].getSigThetaXcut();
0379     maxMovetXcut_[detIndex] = myMap[alignable].getMaxMoveThetaXcut();
0380     maxErrortXcut_[detIndex] = myMap[alignable].getErrorThetaXcut();
0381 
0382     tYcut_[detIndex] = myMap[alignable].getThetaYcut();
0383     sigtYcut_[detIndex] = myMap[alignable].getSigThetaYcut();
0384     maxMovetYcut_[detIndex] = myMap[alignable].getMaxMoveThetaYcut();
0385     maxErrortYcut_[detIndex] = myMap[alignable].getErrorThetaYcut();
0386 
0387     tZcut_[detIndex] = myMap[alignable].getThetaZcut();
0388     sigtZcut_[detIndex] = myMap[alignable].getSigThetaZcut();
0389     maxMovetZcut_[detIndex] = myMap[alignable].getMaxMoveThetaZcut();
0390     maxErrortZcut_[detIndex] = myMap[alignable].getErrorThetaZcut();
0391   }
0392 
0393   fillExpertHisto_HG(
0394       h_xPos_HG, Xcut_, sigXcut_, maxMoveXcut_, maxErrorXcut_, mpReader_->getXobs_HG(), mpReader_->getXobsErr_HG());
0395   fillExpertHisto_HG(h_xRot_HG,
0396                      tXcut_,
0397                      sigtXcut_,
0398                      maxMovetXcut_,
0399                      maxErrortXcut_,
0400                      mpReader_->getTXobs_HG(),
0401                      mpReader_->getTXobsErr_HG());
0402 
0403   fillExpertHisto_HG(
0404       h_yPos_HG, Ycut_, sigYcut_, maxMoveYcut_, maxErrorYcut_, mpReader_->getYobs_HG(), mpReader_->getYobsErr_HG());
0405   fillExpertHisto_HG(h_yRot_HG,
0406                      tYcut_,
0407                      sigtYcut_,
0408                      maxMovetYcut_,
0409                      maxErrortYcut_,
0410                      mpReader_->getTYobs_HG(),
0411                      mpReader_->getTYobsErr_HG());
0412 
0413   fillExpertHisto_HG(
0414       h_zPos_HG, Zcut_, sigZcut_, maxMoveZcut_, maxErrorZcut_, mpReader_->getZobs_HG(), mpReader_->getZobsErr_HG());
0415   fillExpertHisto_HG(h_zRot_HG,
0416                      tZcut_,
0417                      sigtZcut_,
0418                      maxMovetZcut_,
0419                      maxErrortZcut_,
0420                      mpReader_->getTZobs_HG(),
0421                      mpReader_->getTZobsErr_HG());
0422 }
0423 
0424 void MillePedeDQMModule ::fillExpertHisto_HG(std::map<std::string, MonitorElement*>& histo_map,
0425                                              const std::array<double, SIZE_INDEX>& cut,
0426                                              const std::array<double, SIZE_INDEX>& sigCut,
0427                                              const std::array<double, SIZE_INDEX>& maxMoveCut,
0428                                              const std::array<double, SIZE_INDEX>& maxErrorCut,
0429                                              const std::array<double, SIZE_HG_STRUCTS>& obs,
0430                                              const std::array<double, SIZE_HG_STRUCTS>& obsErr) {
0431   int currentStart = 0;
0432   int bin = 0;
0433   double max_ = 0;
0434 
0435   for (const auto& layer : layerVec) {
0436     TH1F* histo_0 = histo_map[layer.first]->getTH1F();
0437 
0438     max_ = -1;
0439     for (int i = currentStart; i < (currentStart + layer.second); ++i) {
0440       // first obs.size() bins for observed movements
0441       bin = i - currentStart + 1;
0442 
0443       // fill observed values
0444       histo_0->SetBinContent(bin, obs[i]);
0445       histo_0->SetBinError(bin, obsErr[i]);
0446 
0447       if (std::abs(obs[i]) > max_) {
0448         max_ = std::abs(obs[i]);
0449       }
0450     }
0451 
0452     // five extra bins at the end, one empty, one with threshold, one with sigCut, one with maxMoveCut, one with MaxErrorCut
0453     histo_0->SetBinContent(bin + 1, 0);
0454     histo_0->SetBinError(bin + 1, 0);
0455 
0456     int detIndex;
0457     if (layer.first.find("Disk") != std::string::npos) {
0458       // 7 is the detId for panels, see getIndexFromString
0459       detIndex = 7;
0460       histo_0->GetXaxis()->SetTitle("Panel");
0461     } else {
0462       // 6 is the detId for ladders, see getIndexFromString
0463       detIndex = 6;
0464       histo_0->GetXaxis()->SetTitle("Ladder");
0465     }
0466 
0467     histo_0->SetBinContent(bin + 2, cut[detIndex]);
0468     histo_0->SetBinError(bin + 2, 0);
0469     histo_0->SetBinContent(bin + 3, sigCut[detIndex]);
0470     histo_0->SetBinError(bin + 3, 0);
0471     histo_0->SetBinContent(bin + 4, maxMoveCut[detIndex]);
0472     histo_0->SetBinError(bin + 4, 0);
0473     histo_0->SetBinContent(bin + 5, maxErrorCut[detIndex]);
0474     histo_0->SetBinError(bin + 5, 0);
0475 
0476     // always scale so the cutoff is visible
0477     max_ = std::max(cut[detIndex] * 1.2, max_);
0478 
0479     histo_0->SetMinimum(-(max_)*1.2);
0480     histo_0->SetMaximum(max_ * 1.2);
0481 
0482     currentStart += layer.second;
0483   }
0484 }
0485 
0486 bool MillePedeDQMModule ::setupChanged(const edm::EventSetup& setup) {
0487   bool changed{false};
0488 
0489   if (watchIdealGeometryRcd_.check(setup))
0490     changed = true;
0491   if (watchTrackerTopologyRcd_.check(setup))
0492     changed = true;
0493   if (watchPTrackerParametersRcd_.check(setup))
0494     changed = true;
0495 
0496   return changed;
0497 }
0498 
0499 int MillePedeDQMModule ::getIndexFromString(const std::string& alignableId) {
0500   if (alignableId == "TPBHalfBarrelXminus") {
0501     return 3;
0502   } else if (alignableId == "TPBHalfBarrelXplus") {
0503     return 2;
0504   } else if (alignableId == "TPEHalfCylinderXminusZminus") {
0505     return 1;
0506   } else if (alignableId == "TPEHalfCylinderXplusZminus") {
0507     return 0;
0508   } else if (alignableId == "TPEHalfCylinderXminusZplus") {
0509     return 5;
0510   } else if (alignableId == "TPEHalfCylinderXplusZplus") {
0511     return 4;
0512   } else if (alignableId.rfind("TPBLadder", 0) == 0) {
0513     return 6;
0514   } else if (alignableId.rfind("TPEPanel", 0) == 0) {
0515     return 7;
0516   } else {
0517     throw cms::Exception("LogicError") << "@SUB=MillePedeDQMModule::getIndexFromString\n"
0518                                        << "Retrieving conversion for not supported Alignable partition" << alignableId;
0519   }
0520 }