Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:50:19

0001 /*!
0002   \file TrackerAlignmentErrorExtended_PayloadInspector
0003   \Payload Inspector Plugin for Tracker Alignment Errors (APE)
0004   \author M. Musich
0005   \version $Revision: 1.0 $
0006   \date $Date: 2017/07/10 10:59:24 $
0007 */
0008 
0009 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0010 
0011 #include "CondCore/Utilities/interface/PayloadInspectorModule.h"
0012 #include "CondCore/Utilities/interface/PayloadInspector.h"
0013 #include "CondCore/CondDB/interface/Time.h"
0014 
0015 // the data format of the condition to be inspected
0016 #include "CondFormats/Alignment/interface/AlignmentErrorsExtended.h"
0017 #include "DataFormats/DetId/interface/DetId.h"
0018 #include "DataFormats/SiStripDetId/interface/StripSubdetector.h"
0019 #include "DataFormats/DetId/interface/DetId.h"
0020 
0021 // needed for the tracker map
0022 #include "CommonTools/TrackerMap/interface/TrackerMap.h"
0023 
0024 // needed for mapping
0025 #include "CondCore/AlignmentPlugins/interface/AlignmentPayloadInspectorHelper.h"
0026 #include "CalibTracker/StandaloneTrackerTopology/interface/StandaloneTrackerTopology.h"
0027 
0028 #include <memory>
0029 #include <sstream>
0030 #include <iostream>
0031 
0032 // include ROOT
0033 #include "TH2F.h"
0034 #include "TLegend.h"
0035 #include "TCanvas.h"
0036 #include "TLine.h"
0037 #include "TStyle.h"
0038 #include "TLatex.h"
0039 #include "TPave.h"
0040 #include "TPaveStats.h"
0041 
0042 namespace {
0043 
0044   using namespace cond::payloadInspector;
0045 
0046   const std::map<AlignmentPI::partitions, std::pair<AlignmentPI::regions, AlignmentPI::regions> > partLimits = {
0047       {AlignmentPI::BPix, std::make_pair(AlignmentPI::BPixL1o, AlignmentPI::BPixL4i)},
0048       {AlignmentPI::FPix, std::make_pair(AlignmentPI::FPixmL1, AlignmentPI::FPixpL3)},
0049       {AlignmentPI::TIB, std::make_pair(AlignmentPI::TIBL1Ro, AlignmentPI::TIBL4i)},
0050       {AlignmentPI::TOB, std::make_pair(AlignmentPI::TOBL1Ro, AlignmentPI::TOBL6i)},
0051       {AlignmentPI::TID, std::make_pair(AlignmentPI::TIDmR1R, AlignmentPI::TIDpR3)},
0052       {AlignmentPI::TEC, std::make_pair(AlignmentPI::TECmR1R, AlignmentPI::TECpR7)}};
0053 
0054   /************************************************
0055     1d histogram of sqrt(d_ii) of 1 IOV 
0056   *************************************************/
0057 
0058   // inherit from one of the predefined plot class: Histogram1D
0059   template <AlignmentPI::index i>
0060   class TrackerAlignmentErrorExtendedValue : public Histogram1D<AlignmentErrorsExtended, SINGLE_IOV> {
0061   public:
0062     TrackerAlignmentErrorExtendedValue()
0063         : Histogram1D<AlignmentErrorsExtended, SINGLE_IOV>(
0064               "TrackerAlignmentErrorExtendedValue",
0065               "TrackerAlignmentErrorExtendedValue sqrt(d_{" + getStringFromIndex(i) + "})",
0066               500,
0067               0.0,
0068               500.0) {}
0069 
0070     bool fill() override {
0071       auto tag = PlotBase::getTag<0>();
0072       for (auto const& iov : tag.iovs) {
0073         std::shared_ptr<AlignmentErrorsExtended> payload = Base::fetchPayload(std::get<1>(iov));
0074         if (payload.get()) {
0075           std::vector<AlignTransformErrorExtended> alignErrors = payload->m_alignError;
0076           auto indices = AlignmentPI::getIndices(i);
0077 
0078           for (const auto& it : alignErrors) {
0079             CLHEP::HepSymMatrix errMatrix = it.matrix();
0080 
0081             if (DetId(it.rawId()).det() != DetId::Tracker) {
0082               edm::LogWarning("TrackerAlignmentErrorExtended_PayloadInspector")
0083                   << "Encountered invalid Tracker DetId:" << it.rawId() << " - terminating ";
0084               return false;
0085             }
0086 
0087             // to be used to fill the histogram
0088             fillWithValue(sqrt(errMatrix[indices.first][indices.second]) * AlignmentPI::cmToUm);
0089           }  // loop on the vector of modules
0090         }    // payload
0091       }      // iovs
0092       return true;
0093     }  // fill
0094   };
0095 
0096   // diagonal elements
0097   typedef TrackerAlignmentErrorExtendedValue<AlignmentPI::XX> TrackerAlignmentErrorExtendedXXValue;
0098   typedef TrackerAlignmentErrorExtendedValue<AlignmentPI::YY> TrackerAlignmentErrorExtendedYYValue;
0099   typedef TrackerAlignmentErrorExtendedValue<AlignmentPI::ZZ> TrackerAlignmentErrorExtendedZZValue;
0100 
0101   // off-diagonal elements
0102   typedef TrackerAlignmentErrorExtendedValue<AlignmentPI::XY> TrackerAlignmentErrorExtendedXYValue;
0103   typedef TrackerAlignmentErrorExtendedValue<AlignmentPI::XZ> TrackerAlignmentErrorExtendedXZValue;
0104   typedef TrackerAlignmentErrorExtendedValue<AlignmentPI::YZ> TrackerAlignmentErrorExtendedYZValue;
0105 
0106   // /************************************************
0107   //   Summary spectra of sqrt(d_ii) of 1 IOV
0108   // *************************************************/
0109 
0110   template <AlignmentPI::index i>
0111   class TrackerAlignmentErrorExtendedSummary : public PlotImage<AlignmentErrorsExtended, SINGLE_IOV> {
0112   public:
0113     TrackerAlignmentErrorExtendedSummary()
0114         : PlotImage<AlignmentErrorsExtended, SINGLE_IOV>("Summary per Tracker Partition of sqrt(d_{" +
0115                                                          getStringFromIndex(i) + "}) of APE matrix") {}
0116 
0117     bool fill() override {
0118       auto tag = PlotBase::getTag<0>();
0119       auto iov = tag.iovs.front();
0120       std::shared_ptr<AlignmentErrorsExtended> payload = fetchPayload(std::get<1>(iov));
0121       std::vector<AlignTransformErrorExtended> alignErrors = payload->m_alignError;
0122 
0123       const char* path_toTopologyXML = (alignErrors.size() == AlignmentPI::phase0size)
0124                                            ? "Geometry/TrackerCommonData/data/trackerParameters.xml"
0125                                            : "Geometry/TrackerCommonData/data/PhaseI/trackerParameters.xml";
0126       TrackerTopology tTopo =
0127           StandaloneTrackerTopology::fromTrackerParametersXMLFile(edm::FileInPath(path_toTopologyXML).fullPath());
0128 
0129       auto indices = AlignmentPI::getIndices(i);
0130 
0131       TCanvas canvas("Partion summary", "partition summary", 1200, 1000);
0132       canvas.Divide(3, 2);
0133       std::map<AlignmentPI::partitions, int> colormap;
0134       colormap[AlignmentPI::BPix] = kBlue;
0135       colormap[AlignmentPI::FPix] = kBlue + 2;
0136       colormap[AlignmentPI::TIB] = kRed;
0137       colormap[AlignmentPI::TOB] = kRed + 2;
0138       colormap[AlignmentPI::TID] = kRed + 4;
0139       colormap[AlignmentPI::TEC] = kRed + 6;
0140 
0141       std::map<AlignmentPI::partitions, std::shared_ptr<TH1F> > APE_spectra;
0142       std::vector<AlignmentPI::partitions> parts = {
0143           AlignmentPI::BPix, AlignmentPI::FPix, AlignmentPI::TIB, AlignmentPI::TID, AlignmentPI::TOB, AlignmentPI::TEC};
0144 
0145       auto s_index = getStringFromIndex(i);
0146 
0147       for (const auto& part : parts) {
0148         std::string s_part = AlignmentPI::getStringFromPart(part);
0149 
0150         APE_spectra[part] =
0151             std::make_shared<TH1F>(Form("hAPE_%s", s_part.c_str()),
0152                                    Form(";%s APE #sqrt{d_{%s}} [#mum];n. of modules", s_part.c_str(), s_index.c_str()),
0153                                    200,
0154                                    -10.,
0155                                    200.);
0156       }
0157 
0158       for (const auto& it : alignErrors) {
0159         CLHEP::HepSymMatrix errMatrix = it.matrix();
0160         int subid = DetId(it.rawId()).subdetId();
0161         double matrixElement = sqrt(errMatrix[indices.first][indices.second]);
0162 
0163         if (DetId(it.rawId()).det() != DetId::Tracker) {
0164           edm::LogWarning("TrackerAlignmentErrorExtended_PayloadInspector")
0165               << "Encountered invalid Tracker DetId:" << it.rawId() << " - terminating ";
0166           return false;
0167         }
0168 
0169         switch (subid) {
0170           case 1:
0171             APE_spectra[AlignmentPI::BPix]->Fill(std::min(200., matrixElement) * AlignmentPI::cmToUm);
0172             break;
0173           case 2:
0174             APE_spectra[AlignmentPI::FPix]->Fill(std::min(200., matrixElement) * AlignmentPI::cmToUm);
0175             break;
0176           case 3:
0177             if (!tTopo.tibIsDoubleSide(it.rawId())) {  // no glued DetIds
0178               APE_spectra[AlignmentPI::TIB]->Fill(std::min(200., matrixElement) * AlignmentPI::cmToUm);
0179             }
0180             break;
0181           case 4:
0182             if (!tTopo.tidIsDoubleSide(it.rawId())) {  // no glued DetIds
0183               APE_spectra[AlignmentPI::TID]->Fill(std::min(200., matrixElement) * AlignmentPI::cmToUm);
0184             }
0185             break;
0186           case 5:
0187             if (!tTopo.tobIsDoubleSide(it.rawId())) {  // no glued DetIds
0188               APE_spectra[AlignmentPI::TOB]->Fill(std::min(200., matrixElement) * AlignmentPI::cmToUm);
0189             }
0190             break;
0191           case 6:
0192             if (!tTopo.tecIsDoubleSide(it.rawId())) {  // no glued DetIds
0193               APE_spectra[AlignmentPI::TEC]->Fill(std::min(200., matrixElement) * AlignmentPI::cmToUm);
0194             }
0195             break;
0196           default:
0197             COUT << "will do nothing" << std::endl;
0198             break;
0199         }
0200       }
0201 
0202       TLatex t1;
0203       t1.SetTextAlign(21);
0204       t1.SetTextSize(0.07);
0205       t1.SetTextColor(kBlue);
0206 
0207       int c_index = 1;
0208       for (const auto& part : parts) {
0209         canvas.cd(c_index)->SetLogy();
0210         canvas.cd(c_index)->SetTopMargin(0.02);
0211         canvas.cd(c_index)->SetBottomMargin(0.15);
0212         canvas.cd(c_index)->SetLeftMargin(0.14);
0213         canvas.cd(c_index)->SetRightMargin(0.04);
0214         APE_spectra[part]->SetLineWidth(2);
0215         AlignmentPI::makeNicePlotStyle(APE_spectra[part].get(), colormap[part]);
0216         APE_spectra[part]->Draw("HIST");
0217         AlignmentPI::makeNiceStats(APE_spectra[part].get(), part, colormap[part]);
0218 
0219         t1.DrawLatexNDC(0.35, 0.92, ("IOV: " + std::to_string(std::get<0>(iov))).c_str());
0220 
0221         c_index++;
0222       }
0223 
0224       std::string fileName(m_imageFileName);
0225       canvas.SaveAs(fileName.c_str());
0226 
0227       return true;
0228     }
0229   };
0230 
0231   // diagonal elements
0232   typedef TrackerAlignmentErrorExtendedSummary<AlignmentPI::XX> TrackerAlignmentErrorExtendedXXSummary;
0233   typedef TrackerAlignmentErrorExtendedSummary<AlignmentPI::YY> TrackerAlignmentErrorExtendedYYSummary;
0234   typedef TrackerAlignmentErrorExtendedSummary<AlignmentPI::ZZ> TrackerAlignmentErrorExtendedZZSummary;
0235 
0236   // off-diagonal elements
0237   typedef TrackerAlignmentErrorExtendedSummary<AlignmentPI::XY> TrackerAlignmentErrorExtendedXYSummary;
0238   typedef TrackerAlignmentErrorExtendedSummary<AlignmentPI::XZ> TrackerAlignmentErrorExtendedXZSummary;
0239   typedef TrackerAlignmentErrorExtendedSummary<AlignmentPI::YZ> TrackerAlignmentErrorExtendedYZSummary;
0240 
0241   // /************************************************
0242   //   TrackerMap of sqrt(d_ii) of 1 IOV
0243   // *************************************************/
0244   template <AlignmentPI::index i>
0245   class TrackerAlignmentErrorExtendedTrackerMap : public PlotImage<AlignmentErrorsExtended, SINGLE_IOV> {
0246   public:
0247     TrackerAlignmentErrorExtendedTrackerMap()
0248         : PlotImage<AlignmentErrorsExtended, SINGLE_IOV>("Tracker Map of sqrt(d_{" + getStringFromIndex(i) +
0249                                                          "}) of APE matrix") {}
0250 
0251     bool fill() override {
0252       auto tag = PlotBase::getTag<0>();
0253       auto iov = tag.iovs.front();
0254       std::shared_ptr<AlignmentErrorsExtended> payload = fetchPayload(std::get<1>(iov));
0255 
0256       std::string titleMap = "APE #sqrt{d_{" + getStringFromIndex(i) + "}} value (payload : " + std::get<1>(iov) + ")";
0257 
0258       std::unique_ptr<TrackerMap> tmap = std::make_unique<TrackerMap>("APE_dii");
0259       tmap->setTitle(titleMap);
0260       tmap->setPalette(1);
0261 
0262       std::vector<AlignTransformErrorExtended> alignErrors = payload->m_alignError;
0263 
0264       auto indices = AlignmentPI::getIndices(i);
0265 
0266       bool isPhase0(false);
0267       if (alignErrors.size() == AlignmentPI::phase0size)
0268         isPhase0 = true;
0269 
0270       for (const auto& it : alignErrors) {
0271         CLHEP::HepSymMatrix errMatrix = it.matrix();
0272 
0273         // fill the tracker map
0274 
0275         int subid = DetId(it.rawId()).subdetId();
0276 
0277         if (DetId(it.rawId()).det() != DetId::Tracker) {
0278           edm::LogWarning("TrackerAlignmentErrorExtended_PayloadInspector")
0279               << "Encountered invalid Tracker DetId:" << it.rawId() << " - terminating ";
0280           return false;
0281         }
0282 
0283         if (isPhase0) {
0284           tmap->addPixel(true);
0285           tmap->fill(it.rawId(), sqrt(errMatrix[indices.first][indices.second]) * AlignmentPI::cmToUm);
0286         } else {
0287           if (subid != 1 && subid != 2) {
0288             tmap->fill(it.rawId(), sqrt(errMatrix[indices.first][indices.second]) * AlignmentPI::cmToUm);
0289           }
0290         }
0291       }  // loop over detIds
0292 
0293       //=========================
0294 
0295       auto autoRange = tmap->getAutomaticRange();
0296 
0297       std::string fileName(m_imageFileName);
0298       // protect against uniform values (APE are defined positive)
0299       if (autoRange.first != autoRange.second) {
0300         tmap->save(true, 0., autoRange.second, fileName);
0301       } else {
0302         if (autoRange.first != 0.)
0303           tmap->save(true, 0., autoRange.first * 1.05, fileName);
0304         else
0305           tmap->save(true, 0., 1., fileName);
0306       }
0307 
0308       return true;
0309     }
0310   };
0311 
0312   // diagonal elements
0313   typedef TrackerAlignmentErrorExtendedTrackerMap<AlignmentPI::XX> TrackerAlignmentErrorExtendedXXTrackerMap;
0314   typedef TrackerAlignmentErrorExtendedTrackerMap<AlignmentPI::YY> TrackerAlignmentErrorExtendedYYTrackerMap;
0315   typedef TrackerAlignmentErrorExtendedTrackerMap<AlignmentPI::ZZ> TrackerAlignmentErrorExtendedZZTrackerMap;
0316 
0317   // off-diagonal elements
0318   typedef TrackerAlignmentErrorExtendedTrackerMap<AlignmentPI::XY> TrackerAlignmentErrorExtendedXYTrackerMap;
0319   typedef TrackerAlignmentErrorExtendedTrackerMap<AlignmentPI::XZ> TrackerAlignmentErrorExtendedXZTrackerMap;
0320   typedef TrackerAlignmentErrorExtendedTrackerMap<AlignmentPI::YZ> TrackerAlignmentErrorExtendedYZTrackerMap;
0321 
0322   // /************************************************
0323   //  Partition details of 1 IOV
0324   // *************************************************/
0325   template <AlignmentPI::partitions q>
0326   class TrackerAlignmentErrorExtendedDetail : public PlotImage<AlignmentErrorsExtended, SINGLE_IOV> {
0327   public:
0328     TrackerAlignmentErrorExtendedDetail()
0329         : PlotImage<AlignmentErrorsExtended, SINGLE_IOV>("Details for " + AlignmentPI::getStringFromPart(q)) {}
0330 
0331     bool fill() override {
0332       auto tag = PlotBase::getTag<0>();
0333       auto iov = tag.iovs.front();
0334 
0335       gStyle->SetPaintTextFormat(".1f");
0336       std::shared_ptr<AlignmentErrorsExtended> payload = fetchPayload(std::get<1>(iov));
0337 
0338       std::vector<AlignTransformErrorExtended> alignErrors = payload->m_alignError;
0339 
0340       const char* path_toTopologyXML = (alignErrors.size() == AlignmentPI::phase0size)
0341                                            ? "Geometry/TrackerCommonData/data/trackerParameters.xml"
0342                                            : "Geometry/TrackerCommonData/data/PhaseI/trackerParameters.xml";
0343       TrackerTopology tTopo =
0344           StandaloneTrackerTopology::fromTrackerParametersXMLFile(edm::FileInPath(path_toTopologyXML).fullPath());
0345 
0346       bool isPhase0(false);
0347       if (alignErrors.size() == AlignmentPI::phase0size)
0348         isPhase0 = true;
0349 
0350       TCanvas canvas("Summary", "Summary", 1600, 1200);
0351       canvas.Divide(3, 2);
0352 
0353       // define the paritions range to act upon
0354       auto begin = partLimits.at(q).first;
0355       auto end = partLimits.at(q).second;
0356       // dinamically defined range
0357       auto range = (end - begin) + 1;
0358 
0359       std::map<std::pair<AlignmentPI::index, AlignmentPI::regions>, std::shared_ptr<TH1F> > APE_spectraByRegion;
0360       std::map<AlignmentPI::index, std::shared_ptr<TH1F> > summaries;
0361 
0362       for (int k = AlignmentPI::XX; k <= AlignmentPI::ZZ; k++) {
0363         AlignmentPI::index coord = (AlignmentPI::index)k;
0364         std::string s_coord = AlignmentPI::getStringFromIndex(coord);
0365 
0366         summaries[coord] = std::make_shared<TH1F>(
0367             Form("Summary_%s", s_coord.c_str()),
0368             Form("Summary for #LT #sqrt{d_{%s}} #GT APE;;average APE #LT #sqrt{d_{%s}} #GT [#mum]",
0369                  s_coord.c_str(),
0370                  s_coord.c_str()),
0371             range,
0372             0,
0373             range);
0374 
0375         //COUT<<"begin ( "<< begin << "): " << AlignmentPI::getStringFromRegionEnum(begin) << " end ( " << end << "): " <<  AlignmentPI::getStringFromRegionEnum(end) <<" | range = "<< range << std::endl;
0376 
0377         for (int j = begin; j <= end; j++) {
0378           AlignmentPI::regions part = (AlignmentPI::regions)j;
0379 
0380           // dont' book region that don't exist
0381           if (isPhase0 && (part == AlignmentPI::BPixL4o || part == AlignmentPI::BPixL4i ||
0382                            part == AlignmentPI::FPixmL3 || part == AlignmentPI::FPixpL3))
0383             continue;
0384 
0385           std::string s_part = AlignmentPI::getStringFromRegionEnum(part);
0386 
0387           auto hash = std::make_pair(coord, part);
0388 
0389           APE_spectraByRegion[hash] = std::make_shared<TH1F>(
0390               Form("hAPE_%s_%s", s_coord.c_str(), s_part.c_str()),
0391               Form(";%s APE #sqrt{d_{%s}} [#mum];n. of modules", s_part.c_str(), s_coord.c_str()),
0392               1000,
0393               0.,
0394               1000.);
0395         }
0396       }
0397 
0398       // loop on the vector of errors
0399       for (const auto& it : alignErrors) {
0400         CLHEP::HepSymMatrix errMatrix = it.matrix();
0401 
0402         if (DetId(it.rawId()).det() != DetId::Tracker) {
0403           edm::LogWarning("TrackerAlignmentErrorExtended_PayloadInspector")
0404               << "Encountered invalid Tracker DetId:" << it.rawId() << " - terminating ";
0405           return false;
0406         }
0407 
0408         int subid = DetId(it.rawId()).subdetId();
0409         if (subid != q)
0410           continue;
0411 
0412         // fill the struct
0413         AlignmentPI::topolInfo t_info_fromXML;
0414         t_info_fromXML.init();
0415         DetId detid(it.rawId());
0416         t_info_fromXML.fillGeometryInfo(detid, tTopo, isPhase0);
0417         //t_info_fromXML.printAll();
0418 
0419         AlignmentPI::regions thePart = t_info_fromXML.filterThePartition();
0420 
0421         // skip the glued detector detIds
0422         if (thePart == AlignmentPI::StripDoubleSide)
0423           continue;
0424 
0425         for (int k = AlignmentPI::XX; k <= AlignmentPI::ZZ; k++) {
0426           AlignmentPI::index coord = (AlignmentPI::index)k;
0427           auto indices = AlignmentPI::getIndices(coord);
0428           auto hash = std::make_pair(coord, thePart);
0429 
0430           APE_spectraByRegion[hash]->Fill(sqrt(errMatrix[indices.first][indices.second]) * AlignmentPI::cmToUm);
0431 
0432         }  // loop on the coordinate indices
0433       }    // loop over detIds
0434 
0435       // plotting section
0436 
0437       TLegend legend = TLegend(0.15, 0.85, 0.99, 0.92);
0438       legend.AddEntry(summaries[AlignmentPI::XX].get(),
0439                       ("#splitline{IOV: " + std::to_string(std::get<0>(iov)) + "}{" + std::get<1>(iov) + "}").c_str(),
0440                       "F");
0441       legend.SetTextSize(0.030);
0442 
0443       for (int k = AlignmentPI::XX; k <= AlignmentPI::ZZ; k++) {
0444         AlignmentPI::index coord = (AlignmentPI::index)k;
0445 
0446         for (int j = begin; j <= end; j++) {
0447           AlignmentPI::regions part = (AlignmentPI::regions)j;
0448 
0449           // don't fill regions that do not exist
0450           if (isPhase0 && (part == AlignmentPI::BPixL4o || part == AlignmentPI::BPixL4i ||
0451                            part == AlignmentPI::FPixmL3 || part == AlignmentPI::FPixpL3))
0452             continue;
0453 
0454           auto hash = std::make_pair(coord, part);
0455           summaries[coord]->GetXaxis()->SetBinLabel((j - begin) + 1,
0456                                                     AlignmentPI::getStringFromRegionEnum(part).c_str());
0457 
0458           // avoid filling the histogram with numerical noise
0459           float mean = APE_spectraByRegion[hash]->GetMean() > 10.e-6 ? APE_spectraByRegion[hash]->GetMean() : 10.e-6;
0460           summaries[coord]->SetBinContent((j - begin) + 1, mean);
0461           //summaries[coord]->SetBinError((j-begin)+1,APE_spectraByRegion[hash]->GetRMS());
0462           AlignmentPI::makeNicePlotStyle(summaries[coord].get(), kBlue);
0463           summaries[coord]->GetXaxis()->LabelsOption("v");
0464           summaries[coord]->GetXaxis()->SetLabelSize(0.06);
0465 
0466         }  // loop over the detector regions
0467 
0468         canvas.cd(k);
0469         canvas.cd(k)->SetTopMargin(0.08);
0470         canvas.cd(k)->SetBottomMargin(0.15);
0471         canvas.cd(k)->SetLeftMargin(0.15);
0472         canvas.cd(k)->SetRightMargin(0.01);
0473         //summaries[coord]->SetTitleOffset(0.06);
0474         summaries[coord]->SetFillColorAlpha(kRed, 0.35);
0475         summaries[coord]->SetMarkerSize(2.5);
0476         summaries[coord]->SetMarkerColor(kRed);
0477 
0478         // to ensure 0. is actually displayed as 0.
0479         summaries[coord]->GetYaxis()->SetRangeUser(0., std::max(1., summaries[coord]->GetMaximum() * 1.50));
0480         summaries[coord]->Draw("text90");
0481         summaries[coord]->Draw("HISTsame");
0482 
0483         legend.Draw("same");
0484 
0485       }  // loop over the matrix elements
0486 
0487       std::string fileName(m_imageFileName);
0488       canvas.SaveAs(fileName.c_str());
0489 
0490       return true;
0491     }
0492   };
0493 
0494   typedef TrackerAlignmentErrorExtendedDetail<AlignmentPI::BPix> TrackerAlignmentErrorExtendedBPixDetail;
0495   typedef TrackerAlignmentErrorExtendedDetail<AlignmentPI::FPix> TrackerAlignmentErrorExtendedFPixDetail;
0496   typedef TrackerAlignmentErrorExtendedDetail<AlignmentPI::TIB> TrackerAlignmentErrorExtendedTIBDetail;
0497   typedef TrackerAlignmentErrorExtendedDetail<AlignmentPI::TOB> TrackerAlignmentErrorExtendedTOBDetail;
0498   typedef TrackerAlignmentErrorExtendedDetail<AlignmentPI::TID> TrackerAlignmentErrorExtendedTIDDetail;
0499   typedef TrackerAlignmentErrorExtendedDetail<AlignmentPI::TEC> TrackerAlignmentErrorExtendedTECDetail;
0500 
0501   // /************************************************
0502   //  Tracker Aligment Extended Errors grand summary comparison of 2 IOVs
0503   // *************************************************/
0504 
0505   template <AlignmentPI::index i, int ntags, IOVMultiplicity nIOVs>
0506   class TrackerAlignmentErrorExtendedComparatorBase : public PlotImage<AlignmentErrorsExtended, nIOVs, ntags> {
0507   public:
0508     TrackerAlignmentErrorExtendedComparatorBase()
0509         : PlotImage<AlignmentErrorsExtended, nIOVs, ntags>("Summary per Tracker region of sqrt(d_{" +
0510                                                            getStringFromIndex(i) + "}) of APE matrix") {}
0511 
0512     bool fill() override {
0513       // trick to deal with the multi-ioved tag and two tag case at the same time
0514       auto theIOVs = PlotBase::getTag<0>().iovs;
0515       auto tagname1 = PlotBase::getTag<0>().name;
0516       std::string tagname2 = "";
0517       auto firstiov = theIOVs.front();
0518       std::tuple<cond::Time_t, cond::Hash> lastiov;
0519 
0520       // we don't support (yet) comparison with more than 2 tags
0521       assert(this->m_plotAnnotations.ntags < 3);
0522 
0523       if (this->m_plotAnnotations.ntags == 2) {
0524         auto tag2iovs = PlotBase::getTag<1>().iovs;
0525         tagname2 = PlotBase::getTag<1>().name;
0526         lastiov = tag2iovs.front();
0527       } else {
0528         lastiov = theIOVs.back();
0529       }
0530 
0531       gStyle->SetPaintTextFormat(".1f");
0532 
0533       std::shared_ptr<AlignmentErrorsExtended> last_payload = this->fetchPayload(std::get<1>(lastiov));
0534       std::shared_ptr<AlignmentErrorsExtended> first_payload = this->fetchPayload(std::get<1>(firstiov));
0535 
0536       std::vector<AlignTransformErrorExtended> f_alignErrors = first_payload->m_alignError;
0537       std::vector<AlignTransformErrorExtended> l_alignErrors = last_payload->m_alignError;
0538 
0539       std::string lastIOVsince = std::to_string(std::get<0>(lastiov));
0540       std::string firstIOVsince = std::to_string(std::get<0>(firstiov));
0541 
0542       TCanvas canvas("Comparison", "Comparison", 1600, 800);
0543 
0544       std::map<AlignmentPI::regions, std::shared_ptr<TH1F> > FirstAPE_spectraByRegion;
0545       std::map<AlignmentPI::regions, std::shared_ptr<TH1F> > LastAPE_spectraByRegion;
0546       std::shared_ptr<TH1F> summaryFirst;
0547       std::shared_ptr<TH1F> summaryLast;
0548 
0549       // get the name of the index
0550       std::string s_coord = AlignmentPI::getStringFromIndex(i);
0551 
0552       // book the intermediate histograms
0553       for (int r = AlignmentPI::BPixL1o; r != AlignmentPI::StripDoubleSide; r++) {
0554         AlignmentPI::regions part = static_cast<AlignmentPI::regions>(r);
0555         std::string s_part = AlignmentPI::getStringFromRegionEnum(part);
0556 
0557         FirstAPE_spectraByRegion[part] =
0558             std::make_shared<TH1F>(Form("hfirstAPE_%s_%s", s_coord.c_str(), s_part.c_str()),
0559                                    Form(";%s APE #sqrt{d_{%s}} [#mum];n. of modules", s_part.c_str(), s_coord.c_str()),
0560                                    1000,
0561                                    0.,
0562                                    1000.);
0563         LastAPE_spectraByRegion[part] =
0564             std::make_shared<TH1F>(Form("hlastAPE_%s_%s", s_coord.c_str(), s_part.c_str()),
0565                                    Form(";%s APE #sqrt{d_{%s}} [#mum];n. of modules", s_part.c_str(), s_coord.c_str()),
0566                                    1000,
0567                                    0.,
0568                                    1000.);
0569       }
0570 
0571       summaryFirst =
0572           std::make_shared<TH1F>(Form("first Summary_%s", s_coord.c_str()),
0573                                  Form("Summary for #LT #sqrt{d_{%s}} #GT APE;;average APE #LT #sqrt{d_{%s}} #GT [#mum]",
0574                                       s_coord.c_str(),
0575                                       s_coord.c_str()),
0576                                  FirstAPE_spectraByRegion.size(),
0577                                  0,
0578                                  FirstAPE_spectraByRegion.size());
0579       summaryLast =
0580           std::make_shared<TH1F>(Form("last Summary_%s", s_coord.c_str()),
0581                                  Form("Summary for #LT #sqrt{d_{%s}} #GT APE;;average APE #LT #sqrt{d_{%s}} #GT [#mum]",
0582                                       s_coord.c_str(),
0583                                       s_coord.c_str()),
0584                                  LastAPE_spectraByRegion.size(),
0585                                  0,
0586                                  LastAPE_spectraByRegion.size());
0587 
0588       const char* path_toTopologyXML = (f_alignErrors.size() == AlignmentPI::phase0size)
0589                                            ? "Geometry/TrackerCommonData/data/trackerParameters.xml"
0590                                            : "Geometry/TrackerCommonData/data/PhaseI/trackerParameters.xml";
0591       TrackerTopology f_tTopo =
0592           StandaloneTrackerTopology::fromTrackerParametersXMLFile(edm::FileInPath(path_toTopologyXML).fullPath());
0593 
0594       bool isPhase0(false);
0595       if (f_alignErrors.size() == AlignmentPI::phase0size)
0596         isPhase0 = true;
0597 
0598       // -------------------------------------------------------------------
0599       // loop on the first vector of errors
0600       // -------------------------------------------------------------------
0601       for (const auto& it : f_alignErrors) {
0602         CLHEP::HepSymMatrix errMatrix = it.matrix();
0603 
0604         if (DetId(it.rawId()).det() != DetId::Tracker) {
0605           edm::LogWarning("TrackerAlignmentErrorExtended_PayloadInspector")
0606               << "Encountered invalid Tracker DetId:" << it.rawId() << " - terminating ";
0607           return false;
0608         }
0609 
0610         AlignmentPI::topolInfo t_info_fromXML;
0611         t_info_fromXML.init();
0612         DetId detid(it.rawId());
0613         t_info_fromXML.fillGeometryInfo(detid, f_tTopo, isPhase0);
0614 
0615         AlignmentPI::regions thePart = t_info_fromXML.filterThePartition();
0616 
0617         // skip the glued detector detIds
0618         if (thePart == AlignmentPI::StripDoubleSide)
0619           continue;
0620 
0621         auto indices = AlignmentPI::getIndices(i);
0622         FirstAPE_spectraByRegion[thePart]->Fill(sqrt(errMatrix[indices.first][indices.second]) * AlignmentPI::cmToUm);
0623       }  // ends loop on the vector of error transforms
0624 
0625       path_toTopologyXML = (l_alignErrors.size() == AlignmentPI::phase0size)
0626                                ? "Geometry/TrackerCommonData/data/trackerParameters.xml"
0627                                : "Geometry/TrackerCommonData/data/PhaseI/trackerParameters.xml";
0628       TrackerTopology l_tTopo =
0629           StandaloneTrackerTopology::fromTrackerParametersXMLFile(edm::FileInPath(path_toTopologyXML).fullPath());
0630 
0631       if (l_alignErrors.size() == AlignmentPI::phase0size)
0632         isPhase0 = true;
0633 
0634       // -------------------------------------------------------------------
0635       // loop on the second vector of errors
0636       // -------------------------------------------------------------------
0637       for (const auto& it : l_alignErrors) {
0638         CLHEP::HepSymMatrix errMatrix = it.matrix();
0639 
0640         if (DetId(it.rawId()).det() != DetId::Tracker) {
0641           edm::LogWarning("TrackerAlignmentErrorExtended_PayloadInspector")
0642               << "Encountered invalid Tracker DetId:" << it.rawId() << " - terminating ";
0643           return false;
0644         }
0645 
0646         AlignmentPI::topolInfo t_info_fromXML;
0647         t_info_fromXML.init();
0648         DetId detid(it.rawId());
0649         t_info_fromXML.fillGeometryInfo(detid, l_tTopo, isPhase0);
0650 
0651         AlignmentPI::regions thePart = t_info_fromXML.filterThePartition();
0652 
0653         // skip the glued detector detIds
0654         if (thePart == AlignmentPI::StripDoubleSide)
0655           continue;
0656 
0657         auto indices = AlignmentPI::getIndices(i);
0658         LastAPE_spectraByRegion[thePart]->Fill(sqrt(errMatrix[indices.first][indices.second]) * AlignmentPI::cmToUm);
0659       }  // ends loop on the vector of error transforms
0660 
0661       // fill the summary plots
0662       int bin = 1;
0663       for (int r = AlignmentPI::BPixL1o; r != AlignmentPI::StripDoubleSide; r++) {
0664         AlignmentPI::regions part = static_cast<AlignmentPI::regions>(r);
0665 
0666         summaryFirst->GetXaxis()->SetBinLabel(bin, AlignmentPI::getStringFromRegionEnum(part).c_str());
0667         // avoid filling the histogram with numerical noise
0668         float f_mean =
0669             FirstAPE_spectraByRegion[part]->GetMean() > 10.e-6 ? FirstAPE_spectraByRegion[part]->GetMean() : 10.e-6;
0670         summaryFirst->SetBinContent(bin, f_mean);
0671         //summaryFirst->SetBinError(bin,APE_spectraByRegion[hash]->GetRMS());
0672 
0673         summaryLast->GetXaxis()->SetBinLabel(bin, AlignmentPI::getStringFromRegionEnum(part).c_str());
0674         // avoid filling the histogram with numerical noise
0675         float l_mean =
0676             LastAPE_spectraByRegion[part]->GetMean() > 10.e-6 ? LastAPE_spectraByRegion[part]->GetMean() : 10.e-6;
0677         summaryLast->SetBinContent(bin, l_mean);
0678         //summaryLast->SetBinError(bin,APE_spectraByRegion[hash]->GetRMS());
0679         bin++;
0680       }
0681 
0682       AlignmentPI::makeNicePlotStyle(summaryFirst.get(), kBlue);
0683       summaryFirst->SetMarkerColor(kBlue);
0684       summaryFirst->GetXaxis()->LabelsOption("v");
0685       summaryFirst->GetXaxis()->SetLabelSize(0.05);
0686       summaryFirst->GetYaxis()->SetTitleOffset(0.9);
0687 
0688       AlignmentPI::makeNicePlotStyle(summaryLast.get(), kRed);
0689       summaryLast->SetMarkerColor(kRed);
0690       summaryLast->GetYaxis()->SetTitleOffset(0.9);
0691       summaryLast->GetXaxis()->LabelsOption("v");
0692       summaryLast->GetXaxis()->SetLabelSize(0.05);
0693 
0694       canvas.cd()->SetGridy();
0695 
0696       canvas.SetBottomMargin(0.18);
0697       canvas.SetLeftMargin(0.11);
0698       canvas.SetRightMargin(0.02);
0699       canvas.Modified();
0700 
0701       summaryFirst->SetFillColor(kBlue);
0702       summaryLast->SetFillColor(kRed);
0703 
0704       summaryFirst->SetBarWidth(0.45);
0705       summaryFirst->SetBarOffset(0.1);
0706 
0707       summaryLast->SetBarWidth(0.4);
0708       summaryLast->SetBarOffset(0.55);
0709 
0710       float max = (summaryFirst->GetMaximum() > summaryLast->GetMaximum()) ? summaryFirst->GetMaximum()
0711                                                                            : summaryLast->GetMaximum();
0712 
0713       summaryFirst->GetYaxis()->SetRangeUser(0., std::max(0., max * 1.20));
0714 
0715       summaryFirst->Draw("bar2");
0716       //summaryFirst->Draw("text90same");
0717       summaryLast->Draw("bar2,same");
0718       //summaryLast->Draw("text180same");
0719 
0720       TLegend legend = TLegend(0.52, 0.82, 0.98, 0.9);
0721       legend.SetHeader((getStringFromIndex(i) + " APE value comparison").c_str(),
0722                        "C");  // option "C" allows to center the header
0723       legend.AddEntry(
0724           summaryLast.get(),
0725           ("IOV: #scale[1.2]{" + std::to_string(std::get<0>(lastiov)) + "} | #color[2]{" + std::get<1>(lastiov) + "}")
0726               .c_str(),
0727           "F");
0728       legend.AddEntry(
0729           summaryFirst.get(),
0730           ("IOV: #scale[1.2]{" + std::to_string(std::get<0>(firstiov)) + "} | #color[4]{" + std::get<1>(firstiov) + "}")
0731               .c_str(),
0732           "F");
0733       legend.SetTextSize(0.025);
0734       legend.Draw("same");
0735 
0736       std::string fileName(this->m_imageFileName);
0737       canvas.SaveAs(fileName.c_str());
0738 
0739       return true;
0740 
0741     }  // ends fill method
0742   };
0743 
0744   template <AlignmentPI::index i>
0745   using TrackerAlignmentErrorExtendedComparator = TrackerAlignmentErrorExtendedComparatorBase<i, 1, MULTI_IOV>;
0746 
0747   template <AlignmentPI::index i>
0748   using TrackerAlignmentErrorExtendedComparatorTwoTags = TrackerAlignmentErrorExtendedComparatorBase<i, 2, SINGLE_IOV>;
0749 
0750   // diagonal elements
0751   typedef TrackerAlignmentErrorExtendedComparator<AlignmentPI::XX> TrackerAlignmentErrorExtendedXXComparator;
0752   typedef TrackerAlignmentErrorExtendedComparator<AlignmentPI::YY> TrackerAlignmentErrorExtendedYYComparator;
0753   typedef TrackerAlignmentErrorExtendedComparator<AlignmentPI::ZZ> TrackerAlignmentErrorExtendedZZComparator;
0754 
0755   // off-diagonal elements
0756   typedef TrackerAlignmentErrorExtendedComparator<AlignmentPI::XY> TrackerAlignmentErrorExtendedXYComparator;
0757   typedef TrackerAlignmentErrorExtendedComparator<AlignmentPI::XZ> TrackerAlignmentErrorExtendedXZComparator;
0758   typedef TrackerAlignmentErrorExtendedComparator<AlignmentPI::YZ> TrackerAlignmentErrorExtendedYZComparator;
0759 
0760   // diagonal elements
0761   typedef TrackerAlignmentErrorExtendedComparatorTwoTags<AlignmentPI::XX>
0762       TrackerAlignmentErrorExtendedXXComparatorTwoTags;
0763   typedef TrackerAlignmentErrorExtendedComparatorTwoTags<AlignmentPI::YY>
0764       TrackerAlignmentErrorExtendedYYComparatorTwoTags;
0765   typedef TrackerAlignmentErrorExtendedComparatorTwoTags<AlignmentPI::ZZ>
0766       TrackerAlignmentErrorExtendedZZComparatorTwoTags;
0767 
0768   // off-diagonal elements
0769   typedef TrackerAlignmentErrorExtendedComparatorTwoTags<AlignmentPI::XY>
0770       TrackerAlignmentErrorExtendedXYComparatorTwoTags;
0771   typedef TrackerAlignmentErrorExtendedComparatorTwoTags<AlignmentPI::XZ>
0772       TrackerAlignmentErrorExtendedXZComparatorTwoTags;
0773   typedef TrackerAlignmentErrorExtendedComparatorTwoTags<AlignmentPI::YZ>
0774       TrackerAlignmentErrorExtendedYZComparatorTwoTags;
0775 
0776 }  // namespace
0777 
0778 // Register the classes as boost python plugin
0779 PAYLOAD_INSPECTOR_MODULE(TrackerAlignmentErrorExtended) {
0780   PAYLOAD_INSPECTOR_CLASS(TrackerAlignmentErrorExtendedXXValue);
0781   PAYLOAD_INSPECTOR_CLASS(TrackerAlignmentErrorExtendedYYValue);
0782   PAYLOAD_INSPECTOR_CLASS(TrackerAlignmentErrorExtendedZZValue);
0783   PAYLOAD_INSPECTOR_CLASS(TrackerAlignmentErrorExtendedXYValue);
0784   PAYLOAD_INSPECTOR_CLASS(TrackerAlignmentErrorExtendedXZValue);
0785   PAYLOAD_INSPECTOR_CLASS(TrackerAlignmentErrorExtendedYZValue);
0786   PAYLOAD_INSPECTOR_CLASS(TrackerAlignmentErrorExtendedXXSummary);
0787   PAYLOAD_INSPECTOR_CLASS(TrackerAlignmentErrorExtendedYYSummary);
0788   PAYLOAD_INSPECTOR_CLASS(TrackerAlignmentErrorExtendedZZSummary);
0789   PAYLOAD_INSPECTOR_CLASS(TrackerAlignmentErrorExtendedXYSummary);
0790   PAYLOAD_INSPECTOR_CLASS(TrackerAlignmentErrorExtendedXZSummary);
0791   PAYLOAD_INSPECTOR_CLASS(TrackerAlignmentErrorExtendedYZSummary);
0792   PAYLOAD_INSPECTOR_CLASS(TrackerAlignmentErrorExtendedXXTrackerMap);
0793   PAYLOAD_INSPECTOR_CLASS(TrackerAlignmentErrorExtendedYYTrackerMap);
0794   PAYLOAD_INSPECTOR_CLASS(TrackerAlignmentErrorExtendedZZTrackerMap);
0795   PAYLOAD_INSPECTOR_CLASS(TrackerAlignmentErrorExtendedXYTrackerMap);
0796   PAYLOAD_INSPECTOR_CLASS(TrackerAlignmentErrorExtendedXZTrackerMap);
0797   PAYLOAD_INSPECTOR_CLASS(TrackerAlignmentErrorExtendedYZTrackerMap);
0798   PAYLOAD_INSPECTOR_CLASS(TrackerAlignmentErrorExtendedBPixDetail);
0799   PAYLOAD_INSPECTOR_CLASS(TrackerAlignmentErrorExtendedFPixDetail);
0800   PAYLOAD_INSPECTOR_CLASS(TrackerAlignmentErrorExtendedTIBDetail);
0801   PAYLOAD_INSPECTOR_CLASS(TrackerAlignmentErrorExtendedTOBDetail);
0802   PAYLOAD_INSPECTOR_CLASS(TrackerAlignmentErrorExtendedTIDDetail);
0803   PAYLOAD_INSPECTOR_CLASS(TrackerAlignmentErrorExtendedTECDetail);
0804   PAYLOAD_INSPECTOR_CLASS(TrackerAlignmentErrorExtendedXXComparator);
0805   PAYLOAD_INSPECTOR_CLASS(TrackerAlignmentErrorExtendedYYComparator);
0806   PAYLOAD_INSPECTOR_CLASS(TrackerAlignmentErrorExtendedZZComparator);
0807   PAYLOAD_INSPECTOR_CLASS(TrackerAlignmentErrorExtendedXYComparator);
0808   PAYLOAD_INSPECTOR_CLASS(TrackerAlignmentErrorExtendedXZComparator);
0809   PAYLOAD_INSPECTOR_CLASS(TrackerAlignmentErrorExtendedYZComparator);
0810   PAYLOAD_INSPECTOR_CLASS(TrackerAlignmentErrorExtendedXXComparatorTwoTags);
0811   PAYLOAD_INSPECTOR_CLASS(TrackerAlignmentErrorExtendedYYComparatorTwoTags);
0812   PAYLOAD_INSPECTOR_CLASS(TrackerAlignmentErrorExtendedZZComparatorTwoTags);
0813   PAYLOAD_INSPECTOR_CLASS(TrackerAlignmentErrorExtendedXYComparatorTwoTags);
0814   PAYLOAD_INSPECTOR_CLASS(TrackerAlignmentErrorExtendedXZComparatorTwoTags);
0815   PAYLOAD_INSPECTOR_CLASS(TrackerAlignmentErrorExtendedYZComparatorTwoTags);
0816 }