Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:01:48

0001 /*!
0002   \file SiStripApvGains_PayloadInspector
0003   \Payload Inspector Plugin for SiStrip Gain
0004   \author M. Musich
0005   \version $Revision: 1.0 $
0006   \date $Date: 2017/07/02 17:59:56 $
0007 */
0008 
0009 #include "CondCore/Utilities/interface/PayloadInspectorModule.h"
0010 #include "CondCore/Utilities/interface/PayloadInspector.h"
0011 #include "CondCore/CondDB/interface/Time.h"
0012 
0013 // the data format of the condition to be inspected
0014 #include "CondFormats/SiStripObjects/interface/SiStripApvGain.h"
0015 #include "DataFormats/DetId/interface/DetId.h"
0016 #include "DataFormats/SiStripDetId/interface/StripSubdetector.h"
0017 #include "CondFormats/SiStripObjects/interface/SiStripDetSummary.h"
0018 
0019 // needed for the tracker map
0020 #include "CommonTools/TrackerMap/interface/TrackerMap.h"
0021 
0022 // auxilliary functions
0023 #include "CondCore/SiStripPlugins/interface/SiStripPayloadInspectorHelper.h"
0024 #include "CalibTracker/StandaloneTrackerTopology/interface/StandaloneTrackerTopology.h"
0025 #include "SiStripCondObjectRepresent.h"
0026 
0027 #include <memory>
0028 #include <sstream>
0029 #include <iostream>
0030 
0031 // include ROOT
0032 #include "TProfile.h"
0033 #include "TH2F.h"
0034 #include "THStack.h"
0035 #include "TLegend.h"
0036 #include "TCanvas.h"
0037 #include "TLine.h"
0038 #include "TStyle.h"
0039 #include "TLatex.h"
0040 #include "TPave.h"
0041 #include "TPaveStats.h"
0042 
0043 namespace {
0044 
0045   using namespace cond::payloadInspector;
0046 
0047   class SiStripApvGainContainer : public SiStripCondObjectRepresent::SiStripDataContainer<SiStripApvGain, float> {
0048   public:
0049     SiStripApvGainContainer(const std::shared_ptr<SiStripApvGain>& payload,
0050                             const SiStripPI::MetaData& metadata,
0051                             const std::string& tagName)
0052         : SiStripCondObjectRepresent::SiStripDataContainer<SiStripApvGain, float>(payload, metadata, tagName) {
0053       payloadType_ = "SiStripApvGain";
0054       setGranularity(SiStripCondObjectRepresent::PERAPV);
0055     }
0056 
0057     void storeAllValues() override {
0058       std::vector<uint32_t> detid;
0059       payload_->getDetIds(detid);
0060 
0061       for (const auto& d : detid) {
0062         SiStripApvGain::Range range = payload_->getRange(d);
0063         for (int it = 0; it < range.second - range.first; it++) {
0064           // to be used to fill the histogram
0065           SiStripCondData_.fillByPushBack(d, payload_->getApvGain(it, range));
0066         }
0067       }
0068     }
0069   };
0070 
0071   /************************************************
0072     testing the machinery
0073   ************************************************/
0074   class SiStripApvGainTest : public Histogram1D<SiStripApvGain, SINGLE_IOV> {
0075   public:
0076     SiStripApvGainTest()
0077         : Histogram1D<SiStripApvGain, SINGLE_IOV>("SiStrip ApvGain values", "SiStrip ApvGain values", 1, 0.0, 1.) {}
0078 
0079     bool fill() override {
0080       auto tag = PlotBase::getTag<0>();
0081       auto tagname = tag.name;
0082       for (auto const& iov : tag.iovs) {
0083         std::shared_ptr<SiStripApvGain> payload = Base::fetchPayload(std::get<1>(iov));
0084         if (payload.get()) {
0085           SiStripApvGainContainer* objContainer = new SiStripApvGainContainer(payload, iov, tagname);
0086           objContainer->printAll();
0087 
0088         }  // payload
0089       }    // iovs
0090       return true;
0091     }  // fill
0092   };
0093 
0094   class SiStripApvGainByPartition : public PlotImage<SiStripApvGain, SINGLE_IOV> {
0095   public:
0096     SiStripApvGainByPartition() : PlotImage<SiStripApvGain, SINGLE_IOV>("SiStrip ApvGains By Partition") {}
0097 
0098     bool fill() override {
0099       auto tag = PlotBase::getTag<0>();
0100       auto iov = tag.iovs.front();
0101       auto tagname = tag.name;
0102       std::shared_ptr<SiStripApvGain> payload = fetchPayload(std::get<1>(iov));
0103       if (payload.get()) {
0104         SiStripApvGainContainer* objContainer = new SiStripApvGainContainer(payload, iov, tagname);
0105         //objContainer->printAll();
0106 
0107         TCanvas canvas("Partition summary", "partition summary", 1400, 1000);
0108         objContainer->fillByPartition(canvas, 100, 0., 2.);
0109 
0110         std::string fileName(m_imageFileName);
0111         canvas.SaveAs(fileName.c_str());
0112       }  // payload
0113       return true;
0114     }  // fill
0115   };
0116 
0117   class SiStripApvGainCompareByPartition : public PlotImage<SiStripApvGain, MULTI_IOV, 2> {
0118   public:
0119     SiStripApvGainCompareByPartition()
0120         : PlotImage<SiStripApvGain, MULTI_IOV, 2>("SiStrip Compare ApvGains By Partition") {}
0121 
0122     bool fill() override {
0123       // trick to deal with the multi-ioved tag and two tag case at the same time
0124       auto theIOVs = PlotBase::getTag<0>().iovs;
0125       auto tagname1 = PlotBase::getTag<0>().name;
0126       auto tag2iovs = PlotBase::getTag<1>().iovs;
0127       auto tagname2 = PlotBase::getTag<1>().name;
0128       SiStripPI::MetaData firstiov = theIOVs.front();
0129       SiStripPI::MetaData lastiov = tag2iovs.front();
0130 
0131       std::shared_ptr<SiStripApvGain> last_payload = fetchPayload(std::get<1>(lastiov));
0132       std::shared_ptr<SiStripApvGain> first_payload = fetchPayload(std::get<1>(firstiov));
0133 
0134       SiStripApvGainContainer* l_objContainer = new SiStripApvGainContainer(last_payload, lastiov, tagname1);
0135       SiStripApvGainContainer* f_objContainer = new SiStripApvGainContainer(first_payload, firstiov, tagname2);
0136 
0137       l_objContainer->compare(f_objContainer);
0138 
0139       //l_objContainer->printAll();
0140 
0141       TCanvas canvas("Partition summary", "partition summary", 1400, 1000);
0142       l_objContainer->fillByPartition(canvas, 100, 0.5, 1.5);
0143 
0144       std::string fileName(m_imageFileName);
0145       canvas.SaveAs(fileName.c_str());
0146 
0147       return true;
0148     }  // fill
0149   };
0150 
0151   class SiStripApvGainRatioByPartition : public PlotImage<SiStripApvGain, MULTI_IOV, 2> {
0152   public:
0153     SiStripApvGainRatioByPartition() : PlotImage<SiStripApvGain, MULTI_IOV, 2>("SiStrip Ratio ApvGains By Partition") {}
0154 
0155     bool fill() override {
0156       // trick to deal with the multi-ioved tag and two tag case at the same time
0157       auto theIOVs = PlotBase::getTag<0>().iovs;
0158       auto tagname1 = PlotBase::getTag<0>().name;
0159       auto tag2iovs = PlotBase::getTag<1>().iovs;
0160       auto tagname2 = PlotBase::getTag<1>().name;
0161       SiStripPI::MetaData firstiov = theIOVs.front();
0162       SiStripPI::MetaData lastiov = tag2iovs.front();
0163 
0164       std::shared_ptr<SiStripApvGain> last_payload = fetchPayload(std::get<1>(lastiov));
0165       std::shared_ptr<SiStripApvGain> first_payload = fetchPayload(std::get<1>(firstiov));
0166 
0167       SiStripApvGainContainer* l_objContainer = new SiStripApvGainContainer(last_payload, lastiov, tagname1);
0168       SiStripApvGainContainer* f_objContainer = new SiStripApvGainContainer(first_payload, firstiov, tagname2);
0169 
0170       l_objContainer->divide(f_objContainer);
0171 
0172       //l_objContainer->printAll();
0173 
0174       TCanvas canvas("Partition summary", "partition summary", 1400, 1000);
0175       l_objContainer->fillByPartition(canvas, 200, 0.5, 1.5);
0176       //for (int i = 1; i <= 4; i++)
0177       //  canvas.cd(i)->SetLogy();
0178 
0179       std::string fileName(m_imageFileName);
0180       canvas.SaveAs(fileName.c_str());
0181 
0182       return true;
0183     }  // fill
0184   };
0185 
0186   class SiStripApvGainDiffByPartition : public PlotImage<SiStripApvGain, MULTI_IOV, 2> {
0187   public:
0188     SiStripApvGainDiffByPartition() : PlotImage<SiStripApvGain, MULTI_IOV, 2>("SiStrip Diff ApvGains By Partition") {}
0189 
0190     bool fill() override {
0191       // trick to deal with the multi-ioved tag and two tag case at the same time
0192       auto theIOVs = PlotBase::getTag<0>().iovs;
0193       auto tagname1 = PlotBase::getTag<0>().name;
0194       auto tag2iovs = PlotBase::getTag<1>().iovs;
0195       auto tagname2 = PlotBase::getTag<1>().name;
0196       SiStripPI::MetaData firstiov = theIOVs.front();
0197       SiStripPI::MetaData lastiov = tag2iovs.front();
0198 
0199       std::shared_ptr<SiStripApvGain> last_payload = fetchPayload(std::get<1>(lastiov));
0200       std::shared_ptr<SiStripApvGain> first_payload = fetchPayload(std::get<1>(firstiov));
0201 
0202       SiStripApvGainContainer* l_objContainer = new SiStripApvGainContainer(last_payload, lastiov, tagname1);
0203       SiStripApvGainContainer* f_objContainer = new SiStripApvGainContainer(first_payload, firstiov, tagname2);
0204 
0205       l_objContainer->subtract(f_objContainer);
0206 
0207       //l_objContainer->printAll();
0208 
0209       TCanvas canvas("Partition summary", "partition summary", 1400, 1000);
0210       l_objContainer->fillByPartition(canvas, 100, -0.1, 0.1);
0211 
0212       std::string fileName(m_imageFileName);
0213       canvas.SaveAs(fileName.c_str());
0214 
0215       return true;
0216     }  // fill
0217   };
0218 
0219   /************************************************
0220     1d histogram of SiStripApvGains of 1 IOV 
0221   *************************************************/
0222 
0223   // inherit from one of the predefined plot class: Histogram1D
0224   class SiStripApvGainsValue : public Histogram1D<SiStripApvGain, SINGLE_IOV> {
0225   public:
0226     SiStripApvGainsValue()
0227         : Histogram1D<SiStripApvGain, SINGLE_IOV>("SiStripApv Gains values", "SiStripApv Gains values", 200, 0.0, 2.0) {
0228     }
0229 
0230     bool fill() override {
0231       auto tag = PlotBase::getTag<0>();
0232       for (auto const& iov : tag.iovs) {
0233         std::shared_ptr<SiStripApvGain> payload = Base::fetchPayload(std::get<1>(iov));
0234         if (payload.get()) {
0235           std::vector<uint32_t> detid;
0236           payload->getDetIds(detid);
0237 
0238           for (const auto& d : detid) {
0239             SiStripApvGain::Range range = payload->getRange(d);
0240             for (int it = 0; it < range.second - range.first; it++) {
0241               // to be used to fill the histogram
0242               fillWithValue(payload->getApvGain(it, range));
0243 
0244             }  // loop over APVs
0245           }    // loop over detIds
0246         }      // payload
0247       }        // iovs
0248       return true;
0249     }  // fill
0250   };
0251 
0252   /************************************************
0253     1d histogram of means of SiStripApvGains
0254     for Tracker Barrel of 1 IOV 
0255   *************************************************/
0256 
0257   // inherit from one of the predefined plot class: Histogram1D
0258   class SiStripApvBarrelGainsByLayer : public Histogram1D<SiStripApvGain, SINGLE_IOV> {
0259   public:
0260     SiStripApvBarrelGainsByLayer()
0261         : Histogram1D<SiStripApvGain, SINGLE_IOV>("SiStripApv Gains averages by Barrel layer",
0262                                                   "Barrel layer (0-3: TIB), (4-9: TOB)",
0263                                                   10,
0264                                                   0,
0265                                                   10,
0266                                                   "average SiStripApv Gain") {}
0267 
0268     bool fill() override {
0269       auto tag = PlotBase::getTag<0>();
0270       for (auto const& iov : tag.iovs) {
0271         std::shared_ptr<SiStripApvGain> payload = Base::fetchPayload(std::get<1>(iov));
0272         if (payload.get()) {
0273           TrackerTopology tTopo = StandaloneTrackerTopology::fromTrackerParametersXMLFile(
0274               edm::FileInPath("Geometry/TrackerCommonData/data/trackerParameters.xml").fullPath());
0275 
0276           std::vector<uint32_t> detid;
0277           payload->getDetIds(detid);
0278 
0279           std::map<int, std::pair<float, float>> sumOfGainsByLayer;
0280 
0281           for (const auto& d : detid) {
0282             int subid = DetId(d).subdetId();
0283             int layer(-1);
0284             if (subid != StripSubdetector::TIB && subid != StripSubdetector::TOB)
0285               continue;
0286             if (subid == StripSubdetector::TIB) {
0287               layer = tTopo.tibLayer(d);
0288             } else if (subid == StripSubdetector::TOB) {
0289               // layers of TOB start at 5th bin
0290               layer = tTopo.tobLayer(d);
0291               layer += 4;
0292             }
0293 
0294             SiStripApvGain::Range range = payload->getRange(d);
0295             for (int it = 0; it < range.second - range.first; it++) {
0296               sumOfGainsByLayer[layer].first += payload->getApvGain(it, range);
0297               sumOfGainsByLayer[layer].second += 1.;
0298             }  // loop over APVs
0299           }    // loop over detIds
0300 
0301           // loop on the map to fill the plot
0302           for (auto& data : sumOfGainsByLayer) {
0303             fillWithBinAndValue(data.first - 1, (data.second.first / data.second.second));
0304           }
0305 
0306         }  // payload
0307       }    // iovs
0308       return true;
0309     }  // fill
0310   };
0311 
0312   /************************************************
0313     2d histogram of absolute (i.e. not average)
0314     SiStripApvGains for Tracker Barrel of 1 IOV
0315   *************************************************/
0316 
0317   class SiStripApvAbsoluteBarrelGainsByLayer : public Histogram2D<SiStripApvGain, SINGLE_IOV> {
0318   public:
0319     SiStripApvAbsoluteBarrelGainsByLayer()
0320         : Histogram2D<SiStripApvGain, SINGLE_IOV>("SiStripApv Gains by Barrel layer",
0321                                                   "Barrel layer (0-3: TIB), (4-9: TOB)",
0322                                                   10,
0323                                                   0,
0324                                                   10,
0325                                                   "SiStripApv Gain",
0326                                                   200,
0327                                                   0.0,
0328                                                   2.0) {}
0329     bool fill() override {
0330       auto tag = PlotBase::getTag<0>();
0331       for (auto const& iov : tag.iovs) {
0332         std::shared_ptr<SiStripApvGain> payload = Base::fetchPayload(std::get<1>(iov));
0333         if (payload.get()) {
0334           TrackerTopology tTopo = StandaloneTrackerTopology::fromTrackerParametersXMLFile(
0335               edm::FileInPath("Geometry/TrackerCommonData/data/trackerParameters.xml").fullPath());
0336 
0337           std::vector<uint32_t> detid;
0338           payload->getDetIds(detid);
0339           for (const auto& d : detid) {
0340             int subid = DetId(d).subdetId();
0341             if (subid != 3 && subid != 5)
0342               continue;
0343 
0344             SiStripApvGain::Range range = payload->getRange(d);
0345             for (int it = 0; it < range.second - range.first; it++) {
0346               float gain = payload->getApvGain(it, range);
0347               fillWithValue(static_cast<float>((subid == 5) ? tTopo.tobLayer(d) + 3 : tTopo.tibLayer(d) - 1),
0348                             (gain > 2.0) ? 2.0 : gain);
0349             }
0350           }  //loop over detIds
0351         }    // loop over payloads
0352       }      // loop over iovs
0353       return true;
0354     }  // fill
0355   };
0356 
0357   /************************************************
0358     1d histogram of means of SiStripApvGains
0359     for Tracker Endcaps (minus side) of 1 IOV 
0360   *************************************************/
0361 
0362   // inherit from one of the predefined plot class: Histogram1D
0363   class SiStripApvEndcapMinusGainsByDisk : public Histogram1D<SiStripApvGain, SINGLE_IOV> {
0364   public:
0365     SiStripApvEndcapMinusGainsByDisk()
0366         : Histogram1D<SiStripApvGain, SINGLE_IOV>("SiStripApv Gains averages by Endcap (minus) disk",
0367                                                   "Endcap (minus) disk (0-2: TID), (3-11: TEC)",
0368                                                   12,
0369                                                   0,
0370                                                   12,
0371                                                   "average SiStripApv Gain") {}
0372 
0373     bool fill() override {
0374       auto tag = PlotBase::getTag<0>();
0375       for (auto const& iov : tag.iovs) {
0376         std::shared_ptr<SiStripApvGain> payload = Base::fetchPayload(std::get<1>(iov));
0377         if (payload.get()) {
0378           TrackerTopology tTopo = StandaloneTrackerTopology::fromTrackerParametersXMLFile(
0379               edm::FileInPath("Geometry/TrackerCommonData/data/trackerParameters.xml").fullPath());
0380 
0381           std::vector<uint32_t> detid;
0382           payload->getDetIds(detid);
0383 
0384           std::map<int, std::pair<float, float>> sumOfGainsByDisk;
0385 
0386           for (const auto& d : detid) {
0387             int disk = -1;
0388             int side = -1;
0389             int subid = DetId(d).subdetId();
0390             if (subid != StripSubdetector::TID && subid != StripSubdetector::TEC)
0391               continue;
0392 
0393             if (subid == StripSubdetector::TID) {
0394               side = tTopo.tidSide(d);
0395               disk = tTopo.tidWheel(d);
0396             } else {
0397               side = tTopo.tecSide(d);
0398               disk = tTopo.tecWheel(d);
0399               // disks of TEC start at 4th bin
0400               disk += 3;
0401             }
0402 
0403             // only negative side
0404             if (side != 1)
0405               continue;
0406 
0407             SiStripApvGain::Range range = payload->getRange(d);
0408             for (int it = 0; it < range.second - range.first; it++) {
0409               sumOfGainsByDisk[disk].first += payload->getApvGain(it, range);
0410               sumOfGainsByDisk[disk].second += 1.;
0411             }  // loop over APVs
0412           }    // loop over detIds
0413 
0414           // loop on the map to fill the plot
0415           for (auto& data : sumOfGainsByDisk) {
0416             fillWithBinAndValue(data.first - 1, (data.second.first / data.second.second));
0417           }
0418 
0419         }  // payload
0420       }    // iovs
0421       return true;
0422     }  // fill
0423   };
0424 
0425   /************************************************
0426     1d histogram of means of SiStripApvGains
0427     for Tracker Endcaps (plus side) of 1 IOV 
0428   *************************************************/
0429 
0430   // inherit from one of the predefined plot class: Histogram1D
0431   class SiStripApvEndcapPlusGainsByDisk : public Histogram1D<SiStripApvGain, SINGLE_IOV> {
0432   public:
0433     SiStripApvEndcapPlusGainsByDisk()
0434         : Histogram1D<SiStripApvGain, SINGLE_IOV>("SiStripApv Gains averages by Endcap (plus) disk",
0435                                                   "Endcap (plus) disk (0-2: TID), (3-11: TEC)",
0436                                                   12,
0437                                                   0,
0438                                                   12,
0439                                                   "average SiStripApv Gain") {}
0440 
0441     bool fill() override {
0442       auto tag = PlotBase::getTag<0>();
0443       for (auto const& iov : tag.iovs) {
0444         std::shared_ptr<SiStripApvGain> payload = Base::fetchPayload(std::get<1>(iov));
0445         if (payload.get()) {
0446           TrackerTopology tTopo = StandaloneTrackerTopology::fromTrackerParametersXMLFile(
0447               edm::FileInPath("Geometry/TrackerCommonData/data/trackerParameters.xml").fullPath());
0448 
0449           std::vector<uint32_t> detid;
0450           payload->getDetIds(detid);
0451 
0452           std::map<int, std::pair<float, float>> sumOfGainsByDisk;
0453 
0454           for (const auto& d : detid) {
0455             int disk = -1;
0456             int side = -1;
0457             int subid = DetId(d).subdetId();
0458             if (subid != StripSubdetector::TID && subid != StripSubdetector::TEC)
0459               continue;
0460 
0461             if (subid == StripSubdetector::TID) {
0462               side = tTopo.tidSide(d);
0463               disk = tTopo.tidWheel(d);
0464               ;
0465             } else {
0466               side = tTopo.tecSide(d);
0467               disk = tTopo.tecWheel(d);
0468               // disks of TEC start at 4th bin
0469               disk += 3;
0470             }
0471 
0472             // only positive side
0473             if (side != 2)
0474               continue;
0475 
0476             SiStripApvGain::Range range = payload->getRange(d);
0477             for (int it = 0; it < range.second - range.first; it++) {
0478               sumOfGainsByDisk[disk].first += payload->getApvGain(it, range);
0479               sumOfGainsByDisk[disk].second += 1.;
0480             }  // loop over APVs
0481           }    // loop over detIds
0482 
0483           // loop on the map to fill the plot
0484           for (auto& data : sumOfGainsByDisk) {
0485             fillWithBinAndValue(data.first - 1, (data.second.first / data.second.second));
0486           }
0487 
0488         }  // payload
0489       }    // iovs
0490       return true;
0491     }  // fill
0492   };
0493 
0494   /************************************************
0495     2D histogram of absolute (i.e. not average)
0496     SiStripApv Gains on the Endcap- for 1 IOV
0497    ************************************************/
0498   class SiStripApvAbsoluteEndcapMinusGainsByDisk : public Histogram2D<SiStripApvGain, SINGLE_IOV> {
0499   public:
0500     SiStripApvAbsoluteEndcapMinusGainsByDisk()
0501         : Histogram2D<SiStripApvGain, SINGLE_IOV>("SiStripApv Gains averages by Endcap (minus) disk",
0502                                                   "Endcap (minus) disk (0-2: TID), (3-11: TEC)",
0503                                                   12,
0504                                                   0,
0505                                                   12,
0506                                                   "SiStripApv Gain",
0507                                                   200,
0508                                                   0.0,
0509                                                   2.0) {}
0510 
0511     bool fill() override {
0512       auto tag = PlotBase::getTag<0>();
0513       for (auto const& iov : tag.iovs) {
0514         std::shared_ptr<SiStripApvGain> payload = Base::fetchPayload(std::get<1>(iov));
0515         if (payload.get()) {
0516           TrackerTopology tTopo = StandaloneTrackerTopology::fromTrackerParametersXMLFile(
0517               edm::FileInPath("Geometry/TrackerCommonData/data/trackerParameters.xml").fullPath());
0518 
0519           std::vector<uint32_t> detid;
0520           payload->getDetIds(detid);
0521 
0522           for (const auto& d : detid) {
0523             int subid = DetId(d).subdetId(), side = -1, disk = -1;
0524 
0525             switch (subid) {
0526               case 4:
0527                 side = tTopo.tidSide(d);
0528                 disk = tTopo.tidWheel(d);
0529                 break;
0530               case 6:
0531                 side = tTopo.tecSide(d);
0532                 disk = tTopo.tecWheel(d) + 4;
0533                 break;
0534               default:
0535                 continue;
0536             }
0537 
0538             if (side != 1)
0539               continue;
0540             SiStripApvGain::Range range = payload->getRange(d);
0541             for (int it = 0; it < range.second - range.first; it++) {
0542               float gain = payload->getApvGain(it, range);
0543               fillWithValue((float)disk - 1, (gain > 2.0) ? 2.0 : gain);
0544             }  // apvs
0545           }    // detids
0546         }
0547       }  // iovs
0548       return true;
0549     }  // fill
0550   };
0551 
0552   /************************************************
0553     2D histogram of absolute (i.e. not average)
0554     SiStripApv Gains on the Endcap+ for 1 IOV
0555    ************************************************/
0556   class SiStripApvAbsoluteEndcapPlusGainsByDisk : public Histogram2D<SiStripApvGain, SINGLE_IOV> {
0557   public:
0558     SiStripApvAbsoluteEndcapPlusGainsByDisk()
0559         : Histogram2D<SiStripApvGain, SINGLE_IOV>("SiStripApv Gains averages by Endcap (plus) disk",
0560                                                   "Endcap (plus) disk (0-2: TID), (3-11: TEC)",
0561                                                   12,
0562                                                   0,
0563                                                   12,
0564                                                   "SiStripApv Gain",
0565                                                   200,
0566                                                   0.0,
0567                                                   2.0) {}
0568     bool fill() override {
0569       auto tag = PlotBase::getTag<0>();
0570       for (auto const& iov : tag.iovs) {
0571         std::shared_ptr<SiStripApvGain> payload = Base::fetchPayload(std::get<1>(iov));
0572         if (payload.get()) {
0573           TrackerTopology tTopo = StandaloneTrackerTopology::fromTrackerParametersXMLFile(
0574               edm::FileInPath("Geometry/TrackerCommonData/data/trackerParameters.xml").fullPath());
0575 
0576           std::vector<uint32_t> detid;
0577           payload->getDetIds(detid);
0578 
0579           for (const auto& d : detid) {
0580             int subid = DetId(d).subdetId(), side = -1, disk = -1;
0581 
0582             switch (subid) {
0583               case 4:
0584                 side = tTopo.tidSide(d);
0585                 disk = tTopo.tidWheel(d);
0586                 break;
0587               case 6:
0588                 side = tTopo.tecSide(d);
0589                 disk = tTopo.tecWheel(d) + 4;
0590                 break;
0591               default:
0592                 continue;
0593             }
0594 
0595             if (side != 2)
0596               continue;
0597             SiStripApvGain::Range range = payload->getRange(d);
0598             for (int it = 0; it < range.second - range.first; it++) {
0599               float gain = payload->getApvGain(it, range);
0600               fillWithValue((float)disk - 1, (gain > 2.0) ? 2.0 : gain);
0601             }  //apvs
0602           }    //detids
0603         }
0604       }  // iovs
0605       return true;
0606     }  // fill
0607   };
0608 
0609   /************************************************
0610     TrackerMap of SiStripApvGains (average gain per detid)
0611   *************************************************/
0612   class SiStripApvGainsAverageTrackerMap : public PlotImage<SiStripApvGain, SINGLE_IOV> {
0613   public:
0614     SiStripApvGainsAverageTrackerMap() : PlotImage<SiStripApvGain, SINGLE_IOV>("Tracker Map of average SiStripGains") {}
0615 
0616     bool fill() override {
0617       auto tag = PlotBase::getTag<0>();
0618       auto iov = tag.iovs.front();
0619       std::shared_ptr<SiStripApvGain> payload = fetchPayload(std::get<1>(iov));
0620 
0621       std::string titleMap = "SiStrip APV Gain average per module (payload : " + std::get<1>(iov) + ")";
0622 
0623       std::unique_ptr<TrackerMap> tmap = std::make_unique<TrackerMap>("SiStripApvGains");
0624       tmap->setTitle(titleMap);
0625       tmap->setPalette(1);
0626 
0627       std::vector<uint32_t> detid;
0628       payload->getDetIds(detid);
0629 
0630       std::map<uint32_t, float> store;
0631 
0632       for (const auto& d : detid) {
0633         SiStripApvGain::Range range = payload->getRange(d);
0634         float sumOfGains = 0;
0635         float nAPVsPerModule = 0.;
0636         for (int it = 0; it < range.second - range.first; it++) {
0637           nAPVsPerModule += 1;
0638           sumOfGains += payload->getApvGain(it, range);
0639         }  // loop over APVs
0640         // fill the tracker map taking the average gain on a single DetId
0641         store[d] = (sumOfGains / nAPVsPerModule);
0642         tmap->fill(d, (sumOfGains / nAPVsPerModule));
0643       }  // loop over detIds
0644 
0645       //=========================
0646       // saturate at 2 std deviations
0647       auto range = SiStripPI::getTheRange(store, 2);
0648 
0649       std::string fileName(m_imageFileName);
0650       tmap->save(true, range.first, range.second, fileName);
0651 
0652       return true;
0653     }
0654   };
0655 
0656   /************************************************
0657     TrackerMap of SiStripApvGains (module with default)
0658   *************************************************/
0659   class SiStripApvGainsDefaultTrackerMap : public PlotImage<SiStripApvGain, SINGLE_IOV> {
0660   public:
0661     SiStripApvGainsDefaultTrackerMap()
0662         : PlotImage<SiStripApvGain, SINGLE_IOV>("Tracker Map of SiStripGains to default") {}
0663 
0664     bool fill() override {
0665       auto tag = PlotBase::getTag<0>();
0666       auto iov = tag.iovs.front();
0667       std::shared_ptr<SiStripApvGain> payload = fetchPayload(std::get<1>(iov));
0668 
0669       std::unique_ptr<TrackerMap> tmap = std::make_unique<TrackerMap>("SiStripApvGains");
0670 
0671       tmap->setPalette(1);
0672 
0673       std::vector<uint32_t> detid;
0674       payload->getDetIds(detid);
0675 
0676       /*
0677     the default G1 value comes from the ratio of DefaultTickHeight/GainNormalizationFactor
0678     as defined in the default of the O2O producer: OnlineDB/SiStripESSources/src/SiStripCondObjBuilderFromDb.cc
0679       */
0680 
0681       constexpr float G1default = 690. / 640.;
0682       constexpr float G2default = 1.f;
0683 
0684       int totalG1DefaultAPVs = 0;
0685       int totalG2DefaultAPVs = 0;
0686 
0687       for (const auto& d : detid) {
0688         SiStripApvGain::Range range = payload->getRange(d);
0689         float sumOfGains = 0;
0690         float nAPVsPerModule = 0.;
0691         int countDefaults = 0;
0692         for (int it = 0; it < range.second - range.first; it++) {
0693           nAPVsPerModule += 1;
0694           sumOfGains += payload->getApvGain(it, range);
0695           if ((payload->getApvGain(it, range)) == G1default || (payload->getApvGain(it, range)) == G2default)
0696             countDefaults++;
0697         }  // loop over APVs
0698         // fill the tracker map taking the average gain on a single DetId
0699         if (countDefaults > 0.) {
0700           tmap->fill(d, countDefaults);
0701           // check here if it exists at least a full module with all APVs defaulted
0702           if (countDefaults == nAPVsPerModule) {
0703             if (std::fmod((sumOfGains / countDefaults), G1default) == 0.) {
0704               totalG1DefaultAPVs += countDefaults;
0705             } else if (std::fmod((sumOfGains / countDefaults), G2default) == 0.) {
0706               totalG2DefaultAPVs += countDefaults;
0707             }
0708           }
0709         }
0710       }  // loop over detIds
0711 
0712       //=========================
0713       std::string gainType{""};
0714       if (totalG2DefaultAPVs == 0) {
0715         gainType = "G1 value (=690./640.)";
0716       } else if (totalG1DefaultAPVs == 0) {
0717         gainType = "G2 value (=1)";
0718       }
0719 
0720       std::string titleMap = "# of APVs/module w/ default " + gainType + " (payload : " + std::get<1>(iov) + ")";
0721       tmap->setTitle(titleMap);
0722 
0723       std::string fileName(m_imageFileName);
0724       tmap->save(true, 0, 0, fileName);
0725 
0726       return true;
0727     }
0728   };
0729 
0730   /************************************************
0731     TrackerMap of SiStripApvGains (ratio with previous gain per detid)
0732   *************************************************/
0733 
0734   template <int ntags, IOVMultiplicity nIOVs>
0735   class SiStripApvGainsRatioTrackerMapBase : public PlotImage<SiStripApvGain, nIOVs, ntags> {
0736   public:
0737     SiStripApvGainsRatioTrackerMapBase()
0738         : PlotImage<SiStripApvGain, nIOVs, ntags>("Tracker Map of ratio of SiStripGains with previous IOV") {
0739       PlotBase::addInputParam("nsigma");
0740     }
0741 
0742     bool fill() override {
0743       // determine n. sigmas
0744       unsigned int nsigma(1);
0745 
0746       auto paramValues = PlotBase::inputParamValues();
0747       auto ip = paramValues.find("nsigma");
0748       if (ip != paramValues.end()) {
0749         nsigma = std::stoul(ip->second);
0750       }
0751 
0752       // trick to deal with the multi-ioved tag and two tag case at the same time
0753       auto theIOVs = PlotBase::getTag<0>().iovs;
0754       auto tagname1 = PlotBase::getTag<0>().name;
0755       std::string tagname2 = "";
0756       auto firstiov = theIOVs.front();
0757       SiStripPI::MetaData lastiov;
0758 
0759       // we don't support (yet) comparison with more than 2 tags
0760       assert(this->m_plotAnnotations.ntags < 3);
0761 
0762       if (this->m_plotAnnotations.ntags == 2) {
0763         auto tag2iovs = PlotBase::getTag<1>().iovs;
0764         tagname2 = PlotBase::getTag<1>().name;
0765         lastiov = tag2iovs.front();
0766       } else {
0767         lastiov = theIOVs.back();
0768       }
0769 
0770       std::shared_ptr<SiStripApvGain> last_payload = this->fetchPayload(std::get<1>(lastiov));
0771       std::shared_ptr<SiStripApvGain> first_payload = this->fetchPayload(std::get<1>(firstiov));
0772 
0773       std::string titleMap = "SiStrip APV Gain ratio per module average (IOV: ";
0774 
0775       titleMap += std::to_string(std::get<0>(firstiov));
0776       titleMap += "/ IOV:";
0777       titleMap += std::to_string(std::get<0>(lastiov));
0778       titleMap += ")";
0779 
0780       titleMap += +" " + std::to_string(nsigma) + " std. dev. saturation";
0781 
0782       std::unique_ptr<TrackerMap> tmap = std::make_unique<TrackerMap>("SiStripApvGains");
0783       tmap->setTitle(titleMap);
0784       tmap->setPalette(1);
0785 
0786       std::map<uint32_t, float> lastmap, firstmap;
0787 
0788       std::vector<uint32_t> detid;
0789       last_payload->getDetIds(detid);
0790 
0791       // cache the last IOV
0792       for (const auto& d : detid) {
0793         SiStripApvGain::Range range = last_payload->getRange(d);
0794         float Gain = 0;
0795         float nAPV = 0;
0796         for (int it = 0; it < range.second - range.first; it++) {
0797           nAPV += 1;
0798           Gain += last_payload->getApvGain(it, range);
0799         }  // loop over APVs
0800         lastmap[d] = (Gain / nAPV);
0801       }  // loop over detIds
0802 
0803       detid.clear();
0804 
0805       first_payload->getDetIds(detid);
0806 
0807       // cache the first IOV
0808       for (const auto& d : detid) {
0809         SiStripApvGain::Range range = first_payload->getRange(d);
0810         float Gain = 0;
0811         float nAPV = 0;
0812         for (int it = 0; it < range.second - range.first; it++) {
0813           nAPV += 1;
0814           Gain += first_payload->getApvGain(it, range);
0815         }  // loop over APVs
0816         firstmap[d] = (Gain / nAPV);
0817       }  // loop over detIds
0818 
0819       std::map<uint32_t, float> cachedRatio;
0820       for (const auto& d : detid) {
0821         float ratio = firstmap[d] / lastmap[d];
0822         tmap->fill(d, ratio);
0823         cachedRatio[d] = ratio;
0824       }
0825 
0826       //=========================
0827       auto range = SiStripPI::getTheRange(cachedRatio, nsigma);
0828 
0829       std::string fileName(this->m_imageFileName);
0830       tmap->save(true, range.first, range.second, fileName);
0831 
0832       return true;
0833     }
0834   };
0835 
0836   using SiStripApvGainsAvgDeviationRatioWithPreviousIOVTrackerMap = SiStripApvGainsRatioTrackerMapBase<1, MULTI_IOV>;
0837   using SiStripApvGainsAvgDeviationRatioTrackerMapTwoTags = SiStripApvGainsRatioTrackerMapBase<2, SINGLE_IOV>;
0838 
0839   /************************************************
0840    TrackerMap of SiStripApvGains (ratio for largest deviation with previous gain per detid)
0841   *************************************************/
0842 
0843   template <int ntags, IOVMultiplicity nIOVs>
0844   class SiStripApvGainsRatioMaxDeviationTrackerMapBase : public PlotImage<SiStripApvGain, nIOVs, ntags> {
0845   public:
0846     SiStripApvGainsRatioMaxDeviationTrackerMapBase()
0847         : PlotImage<SiStripApvGain, nIOVs, ntags>(
0848               "Tracker Map of ratio (for largest deviation) of SiStripGains with previous IOV") {
0849       PlotBase::addInputParam("nsigma");
0850     }
0851 
0852     bool fill() override {
0853       unsigned int nsigma(1);
0854       auto paramValues = PlotBase::inputParamValues();
0855       auto ip = paramValues.find("nsigma");
0856       if (ip != paramValues.end()) {
0857         nsigma = std::stoul(ip->second);
0858         edm::LogPrint("SiStripApvGain_PayloadInspector")
0859             << "using custom z-axis saturation: " << nsigma << " sigmas" << std::endl;
0860       } else {
0861         edm::LogPrint("SiStripApvGain_PayloadInspector")
0862             << "using default saturation: " << nsigma << " sigmas" << std::endl;
0863       }
0864 
0865       // trick to deal with the multi-ioved tag and two tag case at the same time
0866       auto theIOVs = PlotBase::getTag<0>().iovs;
0867       auto tagname1 = PlotBase::getTag<0>().name;
0868       std::string tagname2 = "";
0869       auto firstiov = theIOVs.front();
0870       SiStripPI::MetaData lastiov;
0871 
0872       // we don't support (yet) comparison with more than 2 tags
0873       assert(this->m_plotAnnotations.ntags < 3);
0874 
0875       if (this->m_plotAnnotations.ntags == 2) {
0876         auto tag2iovs = PlotBase::getTag<1>().iovs;
0877         tagname2 = PlotBase::getTag<1>().name;
0878         lastiov = tag2iovs.front();
0879       } else {
0880         lastiov = theIOVs.back();
0881       }
0882 
0883       std::shared_ptr<SiStripApvGain> last_payload = this->fetchPayload(std::get<1>(lastiov));
0884       std::shared_ptr<SiStripApvGain> first_payload = this->fetchPayload(std::get<1>(firstiov));
0885 
0886       std::string titleMap = "SiStrip APV Gain ratio for largest deviation per module (IOV: ";
0887 
0888       titleMap += std::to_string(std::get<0>(firstiov));
0889       titleMap += "/ IOV:";
0890       titleMap += std::to_string(std::get<0>(lastiov));
0891       titleMap += ") ";
0892 
0893       titleMap += +" - " + std::to_string(nsigma) + " std. dev. saturation";
0894 
0895       std::unique_ptr<TrackerMap> tmap = std::make_unique<TrackerMap>("SiStripApvGains");
0896       tmap->setTitle(titleMap);
0897       tmap->setPalette(1);
0898 
0899       std::map<std::pair<uint32_t, int>, float> lastmap, firstmap;
0900 
0901       std::vector<uint32_t> detid;
0902       last_payload->getDetIds(detid);
0903 
0904       // cache the last IOV
0905       for (const auto& d : detid) {
0906         SiStripApvGain::Range range = last_payload->getRange(d);
0907         float nAPV = 0;
0908         for (int it = 0; it < range.second - range.first; it++) {
0909           nAPV += 1;
0910           float Gain = last_payload->getApvGain(it, range);
0911           std::pair<uint32_t, int> index = std::make_pair(d, nAPV);
0912           lastmap[index] = Gain;
0913         }  // loop over APVs
0914       }    // loop over detIds
0915 
0916       detid.clear();
0917 
0918       first_payload->getDetIds(detid);
0919 
0920       // cache the first IOV
0921       for (const auto& d : detid) {
0922         SiStripApvGain::Range range = first_payload->getRange(d);
0923         float nAPV = 0;
0924         for (int it = 0; it < range.second - range.first; it++) {
0925           nAPV += 1;
0926           float Gain = first_payload->getApvGain(it, range);
0927           std::pair<uint32_t, int> index = std::make_pair(d, nAPV);
0928           firstmap[index] = Gain;
0929         }  // loop over APVs
0930       }    // loop over detIds
0931 
0932       // find the largest deviation
0933       std::map<uint32_t, float> cachedRatio;
0934 
0935       for (const auto& item : firstmap) {
0936         // packed index (detid,APV)
0937         auto index = item.first;
0938         auto mod = item.first.first;
0939 
0940         float ratio = firstmap[index] / lastmap[index];
0941         // if we have already cached something
0942         if (cachedRatio[mod]) {
0943           // if the discrepancy with 1 of ratio is larger than the cached value
0944           if (std::abs(ratio - 1.) > std::abs(cachedRatio[mod] - 1.)) {
0945             cachedRatio[mod] = ratio;
0946           }
0947         } else {
0948           cachedRatio[mod] = ratio;
0949         }
0950       }
0951 
0952       for (const auto& element : cachedRatio) {
0953         tmap->fill(element.first, element.second);
0954       }
0955 
0956       // get the range of the TrackerMap (saturate at +/-n std deviations)
0957       auto range = SiStripPI::getTheRange(cachedRatio, nsigma);
0958 
0959       //=========================
0960 
0961       std::string fileName(this->m_imageFileName);
0962       tmap->save(true, range.first, range.second, fileName);
0963 
0964       return true;
0965     }
0966   };
0967 
0968   using SiStripApvGainsMaxDeviationRatioWithPreviousIOVTrackerMap =
0969       SiStripApvGainsRatioMaxDeviationTrackerMapBase<1, MULTI_IOV>;
0970 
0971   using SiStripApvGainsMaxDeviationRatioTrackerMapTwoTags =
0972       SiStripApvGainsRatioMaxDeviationTrackerMapBase<2, SINGLE_IOV>;
0973 
0974   /************************************************
0975     TrackerMap of SiStripApvGains (maximum gain per detid)
0976   *************************************************/
0977   class SiStripApvGainsMaximumTrackerMap : public PlotImage<SiStripApvGain, SINGLE_IOV> {
0978   public:
0979     SiStripApvGainsMaximumTrackerMap()
0980         : PlotImage<SiStripApvGain, SINGLE_IOV>("Tracker Map of SiStripAPVGains (maximum per DetId)") {}
0981 
0982     bool fill() override {
0983       auto tag = PlotBase::getTag<0>();
0984       auto iov = tag.iovs.front();
0985       std::shared_ptr<SiStripApvGain> payload = fetchPayload(std::get<1>(iov));
0986 
0987       std::string titleMap = "SiStrip APV Gain maximum per module (payload : " + std::get<1>(iov) + ")";
0988 
0989       std::unique_ptr<TrackerMap> tmap = std::make_unique<TrackerMap>("SiStripApvGains");
0990       tmap->setTitle(titleMap);
0991       tmap->setPalette(1);
0992 
0993       std::vector<uint32_t> detid;
0994       payload->getDetIds(detid);
0995 
0996       for (const auto& d : detid) {
0997         SiStripApvGain::Range range = payload->getRange(d);
0998         float theMaxGain = 0;
0999         for (int it = 0; it < range.second - range.first; it++) {
1000           float currentGain = payload->getApvGain(it, range);
1001           if (currentGain > theMaxGain) {
1002             theMaxGain = currentGain;
1003           }
1004         }  // loop over APVs
1005         // fill the tracker map taking the maximum gain on a single DetId
1006         tmap->fill(d, theMaxGain);
1007       }  // loop over detIds
1008 
1009       //=========================
1010 
1011       std::pair<float, float> extrema = tmap->getAutomaticRange();
1012 
1013       std::string fileName(m_imageFileName);
1014 
1015       // protect against uniform values (gains are defined positive)
1016       if (extrema.first != extrema.second) {
1017         tmap->save(true, 0, 0, fileName);
1018       } else {
1019         tmap->save(true, extrema.first * 0.95, extrema.first * 1.05, fileName);
1020       }
1021 
1022       return true;
1023     }
1024   };
1025 
1026   /************************************************
1027     TrackerMap of SiStripApvGains (minimum gain per detid)
1028   *************************************************/
1029   class SiStripApvGainsMinimumTrackerMap : public PlotImage<SiStripApvGain, SINGLE_IOV> {
1030   public:
1031     SiStripApvGainsMinimumTrackerMap()
1032         : PlotImage<SiStripApvGain, SINGLE_IOV>("Tracker Map of SiStripAPVGains (minimum per DetId)") {}
1033 
1034     bool fill() override {
1035       auto tag = PlotBase::getTag<0>();
1036       auto iov = tag.iovs.front();
1037 
1038       std::shared_ptr<SiStripApvGain> payload = fetchPayload(std::get<1>(iov));
1039 
1040       std::string titleMap = "SiStrip APV Gain minumum per module (payload : " + std::get<1>(iov) + ")";
1041 
1042       std::unique_ptr<TrackerMap> tmap = std::make_unique<TrackerMap>("SiStripApvGains");
1043       tmap->setTitle(titleMap);
1044       tmap->setPalette(1);
1045 
1046       std::vector<uint32_t> detid;
1047       payload->getDetIds(detid);
1048 
1049       for (const auto& d : detid) {
1050         SiStripApvGain::Range range = payload->getRange(d);
1051         float theMinGain = 999.;
1052         for (int it = 0; it < range.second - range.first; it++) {
1053           float currentGain = payload->getApvGain(it, range);
1054           if (currentGain < theMinGain) {
1055             theMinGain = currentGain;
1056           }
1057         }  // loop over APVs
1058         // fill the tracker map taking the minimum gain on a single DetId
1059         tmap->fill(d, theMinGain);
1060       }  // loop over detIds
1061 
1062       //=========================
1063 
1064       std::pair<float, float> extrema = tmap->getAutomaticRange();
1065 
1066       std::string fileName(m_imageFileName);
1067 
1068       // protect against uniform values (gains are defined positive)
1069       if (extrema.first != extrema.second) {
1070         tmap->save(true, 0, 0, fileName);
1071       } else {
1072         tmap->save(true, extrema.first * 0.95, extrema.first * 1.05, fileName);
1073       }
1074 
1075       return true;
1076     }
1077   };
1078 
1079   /************************************************
1080     time history histogram of SiStripApvGains 
1081   *************************************************/
1082 
1083   class SiStripApvGainByRunMeans : public HistoryPlot<SiStripApvGain, float> {
1084   public:
1085     SiStripApvGainByRunMeans()
1086         : HistoryPlot<SiStripApvGain, float>("SiStripApv Gains average", "average Strip APV gain value") {}
1087     ~SiStripApvGainByRunMeans() override = default;
1088 
1089     float getFromPayload(SiStripApvGain& payload) override {
1090       std::vector<uint32_t> detid;
1091       payload.getDetIds(detid);
1092 
1093       float nAPVs = 0;
1094       float sumOfGains = 0;
1095 
1096       for (const auto& d : detid) {
1097         SiStripApvGain::Range range = payload.getRange(d);
1098         for (int it = 0; it < range.second - range.first; it++) {
1099           nAPVs += 1;
1100           sumOfGains += payload.getApvGain(it, range);
1101         }  // loop over APVs
1102       }    // loop over detIds
1103 
1104       return sumOfGains / nAPVs;
1105     }  // payload
1106   };
1107 
1108   /************************************************
1109     time history of SiStripApvGains properties
1110   *************************************************/
1111 
1112   template <SiStripPI::estimator est>
1113   class SiStripApvGainProperties : public HistoryPlot<SiStripApvGain, float> {
1114   public:
1115     SiStripApvGainProperties()
1116         : HistoryPlot<SiStripApvGain, float>("SiStripApv Gains " + estimatorType(est),
1117                                              estimatorType(est) + " Strip APV gain value") {}
1118     ~SiStripApvGainProperties() override = default;
1119 
1120     float getFromPayload(SiStripApvGain& payload) override {
1121       std::vector<uint32_t> detid;
1122       payload.getDetIds(detid);
1123 
1124       float nAPVs = 0;
1125       float sumOfGains = 0;
1126       float meanOfGains = 0;
1127       float rmsOfGains = 0;
1128       float min(0.), max(0.);
1129 
1130       for (const auto& d : detid) {
1131         SiStripApvGain::Range range = payload.getRange(d);
1132         for (int it = 0; it < range.second - range.first; it++) {
1133           nAPVs += 1;
1134           float gain = payload.getApvGain(it, range);
1135           if (gain < min)
1136             min = gain;
1137           if (gain > max)
1138             max = gain;
1139           sumOfGains += gain;
1140           rmsOfGains += (gain * gain);
1141         }  // loop over APVs
1142       }    // loop over detIds
1143 
1144       meanOfGains = sumOfGains / nAPVs;
1145 
1146       switch (est) {
1147         case SiStripPI::min:
1148           return min;
1149           break;
1150         case SiStripPI::max:
1151           return max;
1152           break;
1153         case SiStripPI::mean:
1154           return meanOfGains;
1155           break;
1156         case SiStripPI::rms:
1157           if ((rmsOfGains / nAPVs - meanOfGains * meanOfGains) > 0.) {
1158             return sqrt(rmsOfGains / nAPVs - meanOfGains * meanOfGains);
1159           } else {
1160             return 0.;
1161           }
1162           break;
1163         default:
1164           edm::LogWarning("LogicError") << "Unknown estimator: " << est;
1165           break;
1166       }
1167       return 0.;
1168     }  // payload
1169   };
1170 
1171   typedef SiStripApvGainProperties<SiStripPI::min> SiStripApvGainMin_History;
1172   typedef SiStripApvGainProperties<SiStripPI::max> SiStripApvGainMax_History;
1173   typedef SiStripApvGainProperties<SiStripPI::mean> SiStripApvGainMean_History;
1174   typedef SiStripApvGainProperties<SiStripPI::rms> SiStripApvGainRMS_History;
1175 
1176   /************************************************
1177     time history histogram of TIB SiStripApvGains 
1178   *************************************************/
1179 
1180   class SiStripApvTIBGainByRunMeans : public HistoryPlot<SiStripApvGain, float> {
1181   public:
1182     SiStripApvTIBGainByRunMeans()
1183         : HistoryPlot<SiStripApvGain, float>("SiStripApv Gains average",
1184                                              "average Tracker Inner Barrel APV gain value") {}
1185     ~SiStripApvTIBGainByRunMeans() override = default;
1186 
1187     float getFromPayload(SiStripApvGain& payload) override {
1188       std::vector<uint32_t> detid;
1189       payload.getDetIds(detid);
1190 
1191       float nAPVs = 0;
1192       float sumOfGains = 0;
1193 
1194       for (const auto& d : detid) {
1195         int subid = DetId(d).subdetId();
1196         if (subid != StripSubdetector::TIB)
1197           continue;
1198 
1199         SiStripApvGain::Range range = payload.getRange(d);
1200         for (int it = 0; it < range.second - range.first; it++) {
1201           nAPVs += 1;
1202           sumOfGains += payload.getApvGain(it, range);
1203         }  // loop over APVs
1204       }    // loop over detIds
1205 
1206       return sumOfGains / nAPVs;
1207 
1208     }  // payload
1209   };
1210 
1211   /************************************************
1212     time history histogram of TOB SiStripApvGains 
1213   *************************************************/
1214 
1215   class SiStripApvTOBGainByRunMeans : public HistoryPlot<SiStripApvGain, float> {
1216   public:
1217     SiStripApvTOBGainByRunMeans()
1218         : HistoryPlot<SiStripApvGain, float>("SiStripApv Gains average", "average Tracker Outer Barrel gain value") {}
1219     ~SiStripApvTOBGainByRunMeans() override = default;
1220 
1221     float getFromPayload(SiStripApvGain& payload) override {
1222       std::vector<uint32_t> detid;
1223       payload.getDetIds(detid);
1224 
1225       float nAPVs = 0;
1226       float sumOfGains = 0;
1227 
1228       for (const auto& d : detid) {
1229         int subid = DetId(d).subdetId();
1230         if (subid != StripSubdetector::TOB)
1231           continue;
1232 
1233         SiStripApvGain::Range range = payload.getRange(d);
1234         for (int it = 0; it < range.second - range.first; it++) {
1235           nAPVs += 1;
1236           sumOfGains += payload.getApvGain(it, range);
1237         }  // loop over APVs
1238       }    // loop over detIds
1239 
1240       return sumOfGains / nAPVs;
1241 
1242     }  // payload
1243   };
1244 
1245   /************************************************
1246     time history histogram of TID SiStripApvGains 
1247   *************************************************/
1248 
1249   class SiStripApvTIDGainByRunMeans : public HistoryPlot<SiStripApvGain, float> {
1250   public:
1251     SiStripApvTIDGainByRunMeans()
1252         : HistoryPlot<SiStripApvGain, float>("SiStripApv Gains average", "average Tracker Inner Disks APV gain value") {
1253     }
1254     ~SiStripApvTIDGainByRunMeans() override = default;
1255 
1256     float getFromPayload(SiStripApvGain& payload) override {
1257       std::vector<uint32_t> detid;
1258       payload.getDetIds(detid);
1259 
1260       float nAPVs = 0;
1261       float sumOfGains = 0;
1262       for (const auto& d : detid) {
1263         int subid = DetId(d).subdetId();
1264         if (subid != StripSubdetector::TID)
1265           continue;
1266 
1267         SiStripApvGain::Range range = payload.getRange(d);
1268         for (int it = 0; it < range.second - range.first; it++) {
1269           nAPVs += 1;
1270           sumOfGains += payload.getApvGain(it, range);
1271         }  // loop over APVs
1272       }    // loop over detIds
1273 
1274       return sumOfGains / nAPVs;
1275 
1276     }  // payload
1277   };
1278 
1279   /************************************************
1280     time history histogram of TEC SiStripApvGains 
1281   *************************************************/
1282 
1283   class SiStripApvTECGainByRunMeans : public HistoryPlot<SiStripApvGain, float> {
1284   public:
1285     SiStripApvTECGainByRunMeans()
1286         : HistoryPlot<SiStripApvGain, float>("SiStripApv Gains average in TEC",
1287                                              "average Tracker Endcaps APV gain value") {}
1288     ~SiStripApvTECGainByRunMeans() override = default;
1289 
1290     float getFromPayload(SiStripApvGain& payload) override {
1291       std::vector<uint32_t> detid;
1292       payload.getDetIds(detid);
1293 
1294       float nAPVs = 0;
1295       float sumOfGains = 0;
1296 
1297       for (const auto& d : detid) {
1298         int subid = DetId(d).subdetId();
1299         if (subid != StripSubdetector::TEC)
1300           continue;
1301 
1302         SiStripApvGain::Range range = payload.getRange(d);
1303         for (int it = 0; it < range.second - range.first; it++) {
1304           nAPVs += 1;
1305           sumOfGains += payload.getApvGain(it, range);
1306         }  // loop over APVs
1307       }    // loop over detIds
1308 
1309       return sumOfGains / nAPVs;
1310 
1311     }  // payload
1312   };
1313 
1314   /************************************************
1315     test class
1316   *************************************************/
1317 
1318   class SiStripApvGainsTest : public Histogram1D<SiStripApvGain, SINGLE_IOV> {
1319   public:
1320     SiStripApvGainsTest()
1321         : Histogram1D<SiStripApvGain, SINGLE_IOV>("SiStripApv Gains test", "SiStripApv Gains test", 10, 0.0, 10.0),
1322           m_trackerTopo{StandaloneTrackerTopology::fromTrackerParametersXMLFile(
1323               edm::FileInPath("Geometry/TrackerCommonData/data/trackerParameters.xml").fullPath())} {}
1324 
1325     bool fill() override {
1326       auto tag = PlotBase::getTag<0>();
1327       for (auto const& iov : tag.iovs) {
1328         std::shared_ptr<SiStripApvGain> payload = Base::fetchPayload(std::get<1>(iov));
1329         if (payload.get()) {
1330           std::vector<uint32_t> detid;
1331           payload->getDetIds(detid);
1332 
1333           SiStripDetSummary summaryGain{&m_trackerTopo};
1334 
1335           for (const auto& d : detid) {
1336             SiStripApvGain::Range range = payload->getRange(d);
1337             for (int it = 0; it < range.second - range.first; ++it) {
1338               summaryGain.add(d, payload->getApvGain(it, range));
1339               fillWithValue(payload->getApvGain(it, range));
1340             }
1341           }
1342           std::map<unsigned int, SiStripDetSummary::Values> map = summaryGain.getCounts();
1343 
1344           //SiStripPI::printSummary(map);
1345 
1346           std::stringstream ss;
1347           ss << "Summary of gain values:" << std::endl;
1348           summaryGain.print(ss, true);
1349           std::cout << ss.str() << std::endl;
1350 
1351         }  // payload
1352       }    // iovs
1353       return true;
1354     }  // fill
1355   private:
1356     TrackerTopology m_trackerTopo;
1357   };
1358 
1359   /************************************************
1360     Compare Gains from 2 IOVs, 2 pads canvas, firsr for ratio, second for scatter plot
1361   *************************************************/
1362 
1363   template <int ntags, IOVMultiplicity nIOVs>
1364   class SiStripApvGainsComparatorBase : public PlotImage<SiStripApvGain, nIOVs, ntags> {
1365   public:
1366     SiStripApvGainsComparatorBase() : PlotImage<SiStripApvGain, nIOVs, ntags>("SiStripGains Comparison") {}
1367 
1368     bool fill() override {
1369       // trick to deal with the multi-ioved tag and two tag case at the same time
1370       auto theIOVs = PlotBase::getTag<0>().iovs;
1371       auto tagname1 = PlotBase::getTag<0>().name;
1372       std::string tagname2 = "";
1373       auto firstiov = theIOVs.front();
1374       SiStripPI::MetaData lastiov;
1375 
1376       // we don't support (yet) comparison with more than 2 tags
1377       assert(this->m_plotAnnotations.ntags < 3);
1378 
1379       if (this->m_plotAnnotations.ntags == 2) {
1380         auto tag2iovs = PlotBase::getTag<1>().iovs;
1381         tagname2 = PlotBase::getTag<1>().name;
1382         lastiov = tag2iovs.front();
1383       } else {
1384         lastiov = theIOVs.back();
1385       }
1386 
1387       std::shared_ptr<SiStripApvGain> last_payload = this->fetchPayload(std::get<1>(lastiov));
1388       std::shared_ptr<SiStripApvGain> first_payload = this->fetchPayload(std::get<1>(firstiov));
1389 
1390       std::string lastIOVsince = std::to_string(std::get<0>(lastiov));
1391       std::string firstIOVsince = std::to_string(std::get<0>(firstiov));
1392 
1393       std::vector<uint32_t> detid;
1394       last_payload->getDetIds(detid);
1395 
1396       std::map<std::pair<uint32_t, int>, float> lastmap, firstmap;
1397 
1398       // loop on the last payload
1399       for (const auto& d : detid) {
1400         SiStripApvGain::Range range = last_payload->getRange(d);
1401         float Gain = 0;
1402         float nAPV = 0;
1403         for (int it = 0; it < range.second - range.first; ++it) {
1404           nAPV += 1;
1405           Gain = last_payload->getApvGain(it, range);
1406           std::pair<uint32_t, int> index = std::make_pair(d, nAPV);
1407           lastmap[index] = Gain;
1408         }  // end loop on APVs
1409       }    // end loop on detids
1410 
1411       detid.clear();
1412       first_payload->getDetIds(detid);
1413 
1414       // loop on the first payload
1415       for (const auto& d : detid) {
1416         SiStripApvGain::Range range = first_payload->getRange(d);
1417         float Gain = 0;
1418         float nAPV = 0;
1419         for (int it = 0; it < range.second - range.first; ++it) {
1420           nAPV += 1;
1421           Gain = first_payload->getApvGain(it, range);
1422           std::pair<uint32_t, int> index = std::make_pair(d, nAPV);
1423           firstmap[index] = Gain;
1424         }  // end loop on APVs
1425       }    // end loop on detids
1426 
1427       TCanvas canvas("Payload comparison", "payload comparison", 1400, 1000);
1428       canvas.Divide(2, 1);
1429 
1430       std::map<std::string, std::shared_ptr<TH1F>> ratios;
1431       std::map<std::string, std::shared_ptr<TH2F>> scatters;
1432       std::map<std::string, int> colormap;
1433       std::map<std::string, int> markermap;
1434       colormap["TIB"] = kRed;
1435       markermap["TIB"] = kFullCircle;
1436       colormap["TOB"] = kGreen;
1437       markermap["TOB"] = kFullTriangleUp;
1438       colormap["TID"] = kBlack;
1439       markermap["TID"] = kFullSquare;
1440       colormap["TEC"] = kBlue;
1441       markermap["TEC"] = kFullTriangleDown;
1442 
1443       std::vector<std::string> parts = {"TEC", "TOB", "TIB", "TID"};
1444 
1445       for (const auto& part : parts) {
1446         ratios[part] = std::make_shared<TH1F>(
1447             Form("hRatio_%s", part.c_str()),
1448             Form("Gains ratio IOV: %s/ IOV: %s ;Previous Gain (%s) / New Gain (%s);Number of APV",
1449                  firstIOVsince.c_str(),
1450                  lastIOVsince.c_str(),
1451                  firstIOVsince.c_str(),
1452                  lastIOVsince.c_str()),
1453             200,
1454             0.,
1455             2.);
1456         scatters[part] =
1457             std::make_shared<TH2F>(Form("hScatter_%s", part.c_str()),
1458                                    Form("new Gain (%s) vs previous Gain (%s);Previous Gain (%s);New Gain (%s)",
1459                                         lastIOVsince.c_str(),
1460                                         firstIOVsince.c_str(),
1461                                         firstIOVsince.c_str(),
1462                                         lastIOVsince.c_str()),
1463                                    100,
1464                                    0.5,
1465                                    1.8,
1466                                    100,
1467                                    0.5,
1468                                    1.8);
1469       }
1470 
1471       // now loop on the cached maps
1472       for (const auto& item : firstmap) {
1473         // packed index (detid,APV)
1474         auto index = item.first;
1475         auto mod = item.first.first;
1476 
1477         int subid = DetId(mod).subdetId();
1478         float ratio = firstmap[index] / lastmap[index];
1479 
1480         if (subid == StripSubdetector::TIB) {
1481           ratios["TIB"]->Fill(ratio);
1482           scatters["TIB"]->Fill(firstmap[index], lastmap[index]);
1483         }
1484 
1485         if (subid == StripSubdetector::TOB) {
1486           ratios["TOB"]->Fill(ratio);
1487           scatters["TOB"]->Fill(firstmap[index], lastmap[index]);
1488         }
1489 
1490         if (subid == StripSubdetector::TID) {
1491           ratios["TID"]->Fill(ratio);
1492           scatters["TID"]->Fill(firstmap[index], lastmap[index]);
1493         }
1494 
1495         if (subid == StripSubdetector::TEC) {
1496           ratios["TEC"]->Fill(ratio);
1497           scatters["TEC"]->Fill(firstmap[index], lastmap[index]);
1498         }
1499       }
1500 
1501       auto legend = TLegend(0.60, 0.8, 0.92, 0.95);
1502       legend.SetTextSize(0.05);
1503       canvas.cd(1)->SetLogy();
1504       canvas.cd(1)->SetTopMargin(0.05);
1505       canvas.cd(1)->SetLeftMargin(0.13);
1506       canvas.cd(1)->SetRightMargin(0.08);
1507 
1508       for (const auto& part : parts) {
1509         SiStripPI::makeNicePlotStyle(ratios[part].get());
1510         ratios[part]->SetMinimum(1.);
1511         ratios[part]->SetStats(false);
1512         ratios[part]->SetLineWidth(2);
1513         ratios[part]->SetLineColor(colormap[part]);
1514         if (part == "TEC")
1515           ratios[part]->Draw();
1516         else
1517           ratios[part]->Draw("same");
1518         legend.AddEntry(ratios[part].get(), part.c_str(), "L");
1519       }
1520 
1521       legend.Draw("same");
1522       SiStripPI::drawStatBox(ratios, colormap, parts);
1523 
1524       auto legend2 = TLegend(0.60, 0.8, 0.92, 0.95);
1525       legend2.SetTextSize(0.05);
1526       canvas.cd(2);
1527       canvas.cd(2)->SetTopMargin(0.05);
1528       canvas.cd(2)->SetLeftMargin(0.13);
1529       canvas.cd(2)->SetRightMargin(0.08);
1530 
1531       for (const auto& part : parts) {
1532         SiStripPI::makeNicePlotStyle(scatters[part].get());
1533         scatters[part]->SetStats(false);
1534         scatters[part]->SetMarkerColor(colormap[part]);
1535         scatters[part]->SetMarkerStyle(markermap[part]);
1536         scatters[part]->SetMarkerSize(0.5);
1537 
1538         auto temp = (TH2F*)(scatters[part]->Clone());
1539         temp->SetMarkerSize(1.3);
1540 
1541         if (part == "TEC")
1542           scatters[part]->Draw("P");
1543         else
1544           scatters[part]->Draw("Psame");
1545 
1546         legend2.AddEntry(temp, part.c_str(), "P");
1547       }
1548 
1549       TLine diagonal(0.5, 0.5, 1.8, 1.8);
1550       diagonal.SetLineWidth(3);
1551       diagonal.SetLineStyle(2);
1552       diagonal.Draw("same");
1553 
1554       legend2.Draw("same");
1555 
1556       std::string fileName(this->m_imageFileName);
1557       canvas.SaveAs(fileName.c_str());
1558 
1559       return true;
1560     }
1561   };
1562 
1563   using SiStripApvGainsComparatorSingleTag = SiStripApvGainsComparatorBase<1, MULTI_IOV>;
1564   using SiStripApvGainsComparatorTwoTags = SiStripApvGainsComparatorBase<2, SINGLE_IOV>;
1565 
1566   /************************************************
1567     Plot stack of gain by region
1568   *************************************************/
1569 
1570   class SiStripApvGainsTHStack : public PlotImage<SiStripApvGain, SINGLE_IOV> {
1571   public:
1572     SiStripApvGainsTHStack()
1573         : PlotImage<SiStripApvGain, SINGLE_IOV>("Stack of SiStrip APV gains values"),
1574           m_trackerTopo{StandaloneTrackerTopology::fromTrackerParametersXMLFile(
1575               edm::FileInPath("Geometry/TrackerCommonData/data/trackerParameters.xml").fullPath())} {}
1576 
1577     bool fill() override {
1578       //TH1F::SetDefaultSumw2(true);
1579       auto tag = PlotBase::getTag<0>();
1580       auto iov = tag.iovs.front();
1581 
1582       std::shared_ptr<SiStripApvGain> payload = this->fetchPayload(std::get<1>(iov));
1583       std::string IOVsince = std::to_string(std::get<0>(iov));
1584 
1585       std::map<partition, std::shared_ptr<TH1F>> h_gains;
1586 
1587       //std::vector< SiStripPI::TrackerRegion > regions;
1588       std::vector<partition> regions;
1589 
1590       std::vector<uint32_t> detid;
1591       payload->getDetIds(detid);
1592 
1593       // fill the vector of regions
1594       for (const auto& d : detid) {
1595         //auto region = this->getTheRegion(d);
1596         auto region = this->getThePartition(d);
1597         if (std::find(regions.begin(), regions.end(), region) == regions.end()) {
1598           regions.push_back(region);
1599         }
1600       }
1601 
1602       LogDebug("SiStripApvGainsTHStack") << "regions.size()=" << regions.size() << std::endl;
1603 
1604       for (const auto& r : regions) {
1605         //auto part = std::string(SiStripPI::regionType(r).second);
1606 
1607         auto part = std::string(this->partitionName(r));
1608 
1609         h_gains[r] = std::make_shared<TH1F>(Form("hGains_%s", part.c_str()),
1610                                             Form("Gains values for IOV: %s ;Gain;Number of APV", IOVsince.c_str()),
1611                                             100,
1612                                             0.5,
1613                                             1.5);
1614       }
1615 
1616       // loop on the payload
1617       for (const auto& d : detid) {
1618         //auto region = this->getTheRegion(d);
1619         auto region = this->getThePartition(d);
1620         SiStripApvGain::Range range = payload->getRange(d);
1621         for (int it = 0; it < range.second - range.first; ++it) {
1622           float gain = payload->getApvGain(it, range);
1623           h_gains[region]->Fill(gain);
1624         }  // end loop on APVs
1625       }    // end loop on detids
1626 
1627       TCanvas canvas("Payload breakout", "payload breakout", 1200, 800);
1628       canvas.Divide(2, 1);
1629 
1630       std::array<int, 6> colors = {{kRed, kBlue, kGreen, kCyan, 8, kMagenta}};
1631 
1632       THStack* hs = new THStack("hs", Form("Gains values for IOV: %s;Gain;Number of APV", IOVsince.c_str()));
1633       int colorCounter = 0;
1634       for (const auto& r : regions) {
1635         hs->Add(h_gains[r].get());
1636         SiStripPI::makeNicePlotStyle(h_gains[r].get());
1637         h_gains[r]->SetFillColor(colors[colorCounter]);
1638         //h_gains[r]->SetLineColor(colorCounter);
1639         h_gains[r]->SetLineWidth(2);
1640         colorCounter++;
1641       }
1642 
1643       TLegend legend = TLegend(0.60, 0.65, 0.95, 0.93);
1644       legend.SetTextSize(0.05);
1645       legend.SetHeader("Gain break-out", "C");  // option "C" allows to center the header
1646       for (const auto& r : regions) {
1647         auto part = std::string(this->partitionName(r));
1648         legend.AddEntry(h_gains[r].get(), part.c_str(), "F");
1649       }
1650 
1651       canvas.cd(1)->SetLogy();
1652       canvas.cd(1)->SetTopMargin(0.07);
1653       canvas.cd(1)->SetBottomMargin(0.10);
1654       canvas.cd(1)->SetLeftMargin(0.15);
1655       canvas.cd(1)->SetRightMargin(0.05);
1656       //      hs->Draw("NOSTACKB");
1657 
1658       int count(0);
1659       auto stack = hs->GetHists();
1660       double maximum = hs->GetMaximum("nostack");  //SiStripPI::getMaximum(stack);
1661 
1662       TLegend legend2 = TLegend(0.70, 0.65, 0.95, 0.93);
1663       legend2.SetTextSize(0.05);
1664       legend2.SetHeader("Partition", "C");  // option "C" allows to center the header
1665 
1666       for (const auto&& elem : *stack) {
1667         auto clone = (TH1F*)(elem->Clone(Form("hclone_%s", elem->GetName())));
1668         SiStripPI::makeNicePlotStyle(clone);
1669         clone->SetFillColor(0);
1670         clone->SetMarkerStyle(20);
1671         clone->SetLineColor(colors[count]);
1672         clone->SetMarkerColor(colors[count]);
1673         clone->SetMaximum(maximum * 10);
1674         TString candName = clone->GetName();
1675         legend2.AddEntry(clone, candName.ReplaceAll("hclone_hGains_", ""), "L");
1676         if (count == 0) {
1677           clone->Draw("HIST");
1678         } else {
1679           clone->Draw("HISTsame");
1680         }
1681         count++;
1682       }
1683 
1684       legend2.Draw("same");
1685 
1686       canvas.cd(2);  //->SetLogy();
1687       canvas.cd(2)->SetTopMargin(0.07);
1688       canvas.cd(2)->SetBottomMargin(0.10);
1689       canvas.cd(2)->SetLeftMargin(0.12);
1690       canvas.cd(2)->SetRightMargin(0.05);
1691       hs->Draw();
1692       // all graphics manipulations *after* drawing the stack!
1693       hs->GetYaxis()->SetMaxDigits(2);
1694       SiStripPI::makeNiceStyle<THStack>(hs);
1695       legend.Draw("same");
1696 
1697       std::string fileName(this->m_imageFileName);
1698       canvas.SaveAs(fileName.c_str());
1699 
1700       return true;
1701     }
1702 
1703   private:
1704     TrackerTopology m_trackerTopo;
1705     enum partition { TIB = 30, TIDP = 41, TIDM = 42, TOB = 50, TECP = 61, TECM = 62, END_OF_PARTS };
1706 
1707     const char* partitionName(partition part) {
1708       std::map<partition, const char*> mapping = {{partition::TIB, "TIB"},
1709                                                   {partition::TIDP, "TIPp"},
1710                                                   {partition::TIDM, "TIDm"},
1711                                                   {partition::TOB, "TOB"},
1712                                                   {partition::TECP, "TECp"},
1713                                                   {partition::TECM, "TECm"}};
1714 
1715       if (mapping.find(part) == mapping.end()) {
1716         throw cms::Exception("Invalid Partition passed");
1717       } else {
1718         return mapping[part];
1719       }
1720     }
1721 
1722     partition getThePartition(DetId detid) {
1723       int detNum = 0;
1724       int side = 0;
1725       switch (detid.subdetId()) {
1726         case StripSubdetector::TIB:
1727           detNum = 30;
1728           break;
1729         case StripSubdetector::TOB:
1730           detNum = 50;
1731           break;
1732         case StripSubdetector::TEC:
1733           // is this module in TEC+ or TEC-?
1734           side = m_trackerTopo.tecSide(detid);
1735           detNum = 60;
1736           break;
1737         case StripSubdetector::TID:
1738           // is this module in TID+ or TID-?
1739           side = m_trackerTopo.tidSide(detid);
1740           detNum = 40;
1741           break;
1742       }
1743 
1744       detNum += side;
1745       return static_cast<partition>(detNum);
1746     }
1747 
1748     SiStripPI::TrackerRegion getTheRegion(DetId detid) {
1749       int layer = 0;
1750       int stereo = 0;
1751       int detNum = 0;
1752 
1753       switch (detid.subdetId()) {
1754         case StripSubdetector::TIB:
1755           layer = m_trackerTopo.tibLayer(detid);
1756           stereo = m_trackerTopo.tibStereo(detid);
1757           detNum = 1000;
1758           break;
1759         case StripSubdetector::TOB:
1760           layer = m_trackerTopo.tobLayer(detid);
1761           stereo = m_trackerTopo.tobStereo(detid);
1762           detNum = 2000;
1763           break;
1764         case StripSubdetector::TEC:
1765           // is this module in TEC+ or TEC-?
1766           layer = m_trackerTopo.tecWheel(detid);
1767           stereo = m_trackerTopo.tecStereo(detid);
1768           detNum = 3000;
1769           break;
1770         case StripSubdetector::TID:
1771           // is this module in TID+ or TID-?
1772           layer = m_trackerTopo.tidWheel(detid);
1773           stereo = m_trackerTopo.tidStereo(detid);
1774           detNum = 4000;
1775           break;
1776       }
1777 
1778       detNum += layer * 10 + stereo;
1779       return static_cast<SiStripPI::TrackerRegion>(detNum);
1780     }
1781   };
1782 
1783   //*******************************************//
1784   // Compare Gains from 2 IOVs
1785   //******************************************//
1786 
1787   template <int ntags, IOVMultiplicity nIOVs>
1788   class SiStripApvGainsValuesComparatorBase : public PlotImage<SiStripApvGain, nIOVs, ntags> {
1789   public:
1790     SiStripApvGainsValuesComparatorBase()
1791         : PlotImage<SiStripApvGain, nIOVs, ntags>("Comparison of SiStrip APV gains values") {}
1792 
1793     bool fill() override {
1794       TH1F::SetDefaultSumw2(true);
1795 
1796       // trick to deal with the multi-ioved tag and two tag case at the same time
1797       auto theIOVs = PlotBase::getTag<0>().iovs;
1798       auto tagname1 = PlotBase::getTag<0>().name;
1799       std::string tagname2 = "";
1800       auto firstiov = theIOVs.front();
1801       SiStripPI::MetaData lastiov;
1802 
1803       // we don't support (yet) comparison with more than 2 tags
1804       assert(this->m_plotAnnotations.ntags < 3);
1805 
1806       if (this->m_plotAnnotations.ntags == 2) {
1807         auto tag2iovs = PlotBase::getTag<1>().iovs;
1808         tagname2 = PlotBase::getTag<1>().name;
1809         lastiov = tag2iovs.front();
1810       } else {
1811         lastiov = theIOVs.back();
1812       }
1813 
1814       std::shared_ptr<SiStripApvGain> last_payload = this->fetchPayload(std::get<1>(lastiov));
1815       std::shared_ptr<SiStripApvGain> first_payload = this->fetchPayload(std::get<1>(firstiov));
1816 
1817       std::string lastIOVsince = std::to_string(std::get<0>(lastiov));
1818       std::string firstIOVsince = std::to_string(std::get<0>(firstiov));
1819 
1820       std::vector<uint32_t> detid;
1821       last_payload->getDetIds(detid);
1822 
1823       std::map<std::pair<uint32_t, int>, float> lastmap, firstmap;
1824 
1825       // loop on the last payload
1826       for (const auto& d : detid) {
1827         SiStripApvGain::Range range = last_payload->getRange(d);
1828         float nAPV = 0;
1829         for (int it = 0; it < range.second - range.first; ++it) {
1830           nAPV += 1;
1831           auto index = std::make_pair(d, nAPV);
1832           lastmap[index] = last_payload->getApvGain(it, range);
1833         }  // end loop on APVs
1834       }    // end loop on detids
1835 
1836       detid.clear();
1837       first_payload->getDetIds(detid);
1838 
1839       // loop on the first payload
1840       for (const auto& d : detid) {
1841         SiStripApvGain::Range range = first_payload->getRange(d);
1842         float nAPV = 0;
1843         for (int it = 0; it < range.second - range.first; ++it) {
1844           nAPV += 1;
1845           auto index = std::make_pair(d, nAPV);
1846           firstmap[index] = last_payload->getApvGain(it, range);
1847         }  // end loop on APVs
1848       }    // end loop on detids
1849 
1850       TCanvas canvas("Payload comparison", "payload comparison", 1000, 1000);
1851       canvas.cd();
1852 
1853       TPad pad1("pad1", "pad1", 0, 0.3, 1, 1.0);
1854       pad1.SetBottomMargin(0.02);  // Upper and lower plot are joined
1855       pad1.SetTopMargin(0.07);
1856       pad1.SetRightMargin(0.05);
1857       pad1.SetLeftMargin(0.15);
1858       pad1.Draw();  // Draw the upper pad: pad1
1859       pad1.cd();    // pad1 becomes the current pad
1860 
1861       auto h_firstGains =
1862           std::make_shared<TH1F>("hFirstGains", "SiStrip APV gains values; APV Gains;n. APVs", 200, 0.2, 1.8);
1863       auto h_lastGains =
1864           std::make_shared<TH1F>("hLastGains", "SiStrip APV gains values; APV Gains;n. APVs", 200, 0.2, 1.8);
1865 
1866       for (const auto& item : firstmap) {
1867         h_firstGains->Fill(item.second);
1868       }
1869 
1870       for (const auto& item : lastmap) {
1871         h_lastGains->Fill(item.second);
1872       }
1873 
1874       SiStripPI::makeNicePlotStyle(h_lastGains.get());
1875       SiStripPI::makeNicePlotStyle(h_firstGains.get());
1876 
1877       TH1F* hratio = (TH1F*)h_firstGains->Clone("hratio");
1878 
1879       h_firstGains->SetLineColor(kRed);
1880       h_lastGains->SetLineColor(kBlue);
1881 
1882       h_firstGains->SetMarkerColor(kRed);
1883       h_lastGains->SetMarkerColor(kBlue);
1884 
1885       h_firstGains->SetMarkerSize(1.);
1886       h_lastGains->SetMarkerSize(1.);
1887 
1888       h_firstGains->SetLineWidth(1);
1889       h_lastGains->SetLineWidth(1);
1890 
1891       h_firstGains->SetMarkerStyle(20);
1892       h_lastGains->SetMarkerStyle(21);
1893 
1894       h_firstGains->GetXaxis()->SetLabelOffset(2.);
1895       h_lastGains->GetXaxis()->SetLabelOffset(2.);
1896 
1897       h_firstGains->Draw("HIST");
1898       h_lastGains->Draw("HISTsame");
1899 
1900       TLegend legend = TLegend(0.70, 0.7, 0.95, 0.9);
1901       legend.SetHeader("Gain Comparison", "C");  // option "C" allows to center the header
1902       legend.AddEntry(h_firstGains.get(), ("IOV: " + std::to_string(std::get<0>(firstiov))).c_str(), "PL");
1903       legend.AddEntry(h_lastGains.get(), ("IOV: " + std::to_string(std::get<0>(lastiov))).c_str(), "PL");
1904       legend.Draw("same");
1905 
1906       // lower plot will be in pad
1907       canvas.cd();  // Go back to the main canvas before defining pad2
1908       TPad pad2("pad2", "pad2", 0, 0.005, 1, 0.3);
1909       pad2.SetTopMargin(0.01);
1910       pad2.SetBottomMargin(0.2);
1911       pad2.SetRightMargin(0.05);
1912       pad2.SetLeftMargin(0.15);
1913       pad2.SetGridy();  // horizontal grid
1914       pad2.Draw();
1915       pad2.cd();  // pad2 becomes the current pad
1916 
1917       // Define the ratio plot
1918       hratio->SetLineColor(kBlack);
1919       hratio->SetMarkerColor(kBlack);
1920       hratio->SetTitle("");
1921       hratio->SetMinimum(0.55);  // Define Y ..
1922       hratio->SetMaximum(1.55);  // .. range
1923       hratio->SetStats(false);   // No statistics on lower plot
1924       hratio->Divide(h_lastGains.get());
1925       hratio->SetMarkerStyle(20);
1926       hratio->Draw("ep");  // Draw the ratio plot
1927 
1928       // Y axis ratio plot settings
1929       hratio->GetYaxis()->SetTitle(
1930           ("ratio " + std::to_string(std::get<0>(firstiov)) + " / " + std::to_string(std::get<0>(lastiov))).c_str());
1931 
1932       hratio->GetYaxis()->SetNdivisions(505);
1933 
1934       SiStripPI::makeNicePlotStyle(hratio);
1935 
1936       hratio->GetYaxis()->SetTitleSize(25);
1937       hratio->GetXaxis()->SetLabelSize(25);
1938 
1939       hratio->GetYaxis()->SetTitleFont(43);
1940       hratio->GetYaxis()->SetTitleOffset(2.5);
1941       hratio->GetYaxis()->SetLabelFont(43);  // Absolute font size in pixel (precision 3)
1942       hratio->GetYaxis()->SetLabelSize(25);
1943 
1944       // X axis ratio plot settings
1945       hratio->GetXaxis()->SetTitleSize(30);
1946       hratio->GetXaxis()->SetTitleFont(43);
1947       hratio->GetXaxis()->SetTitle("SiStrip APV Gains");
1948       hratio->GetXaxis()->SetLabelFont(43);  // Absolute font size in pixel (precision 3)
1949       hratio->GetXaxis()->SetTitleOffset(3.);
1950 
1951       std::string fileName(this->m_imageFileName);
1952       canvas.SaveAs(fileName.c_str());
1953 
1954       return true;
1955     }
1956   };
1957 
1958   using SiStripApvGainsValuesComparatorSingleTag = SiStripApvGainsValuesComparatorBase<1, MULTI_IOV>;
1959   using SiStripApvGainsValuesComparatorTwoTags = SiStripApvGainsValuesComparatorBase<2, SINGLE_IOV>;
1960 
1961   //*******************************************//
1962   // Compare Gains ratio from 2 IOVs, region by region
1963   //******************************************//
1964 
1965   template <int ntags, IOVMultiplicity nIOVs>
1966   class SiStripApvGainsRatioComparatorByRegionBase : public PlotImage<SiStripApvGain, nIOVs, ntags> {
1967   public:
1968     SiStripApvGainsRatioComparatorByRegionBase()
1969         : PlotImage<SiStripApvGain, nIOVs, ntags>("Module by Module Comparison of SiStrip APV gains"),
1970           m_trackerTopo{StandaloneTrackerTopology::fromTrackerParametersXMLFile(
1971               edm::FileInPath("Geometry/TrackerCommonData/data/trackerParameters.xml").fullPath())} {}
1972 
1973     bool fill() override {
1974       //gStyle->SetPalette(5);
1975       SiStripPI::setPaletteStyle(SiStripPI::GRAY);
1976 
1977       // trick to deal with the multi-ioved tag and two tag case at the same time
1978       auto theIOVs = PlotBase::getTag<0>().iovs;
1979       auto tagname1 = PlotBase::getTag<0>().name;
1980       std::string tagname2 = "";
1981       auto firstiov = theIOVs.front();
1982       SiStripPI::MetaData lastiov;
1983 
1984       // we don't support (yet) comparison with more than 2 tags
1985       assert(this->m_plotAnnotations.ntags < 3);
1986 
1987       if (this->m_plotAnnotations.ntags == 2) {
1988         auto tag2iovs = PlotBase::getTag<1>().iovs;
1989         tagname2 = PlotBase::getTag<1>().name;
1990         lastiov = tag2iovs.front();
1991       } else {
1992         lastiov = theIOVs.back();
1993       }
1994 
1995       std::shared_ptr<SiStripApvGain> last_payload = this->fetchPayload(std::get<1>(lastiov));
1996       std::shared_ptr<SiStripApvGain> first_payload = this->fetchPayload(std::get<1>(firstiov));
1997 
1998       std::string lastIOVsince = std::to_string(std::get<0>(lastiov));
1999       std::string firstIOVsince = std::to_string(std::get<0>(firstiov));
2000 
2001       std::vector<uint32_t> detid;
2002       last_payload->getDetIds(detid);
2003 
2004       std::map<std::pair<uint32_t, int>, float> lastmap, firstmap;
2005 
2006       // loop on the last payload
2007       for (const auto& d : detid) {
2008         SiStripApvGain::Range range = last_payload->getRange(d);
2009         float Gain = 0;
2010         float nAPV = 0;
2011         for (int it = 0; it < range.second - range.first; ++it) {
2012           nAPV += 1;
2013           Gain = last_payload->getApvGain(it, range);
2014           std::pair<uint32_t, int> index = std::make_pair(d, nAPV);
2015           lastmap[index] = Gain;
2016         }  // end loop on APVs
2017       }    // end loop on detids
2018 
2019       detid.clear();
2020       first_payload->getDetIds(detid);
2021 
2022       // loop on the first payload
2023       for (const auto& d : detid) {
2024         SiStripApvGain::Range range = first_payload->getRange(d);
2025         float Gain = 0;
2026         float nAPV = 0;
2027         for (int it = 0; it < range.second - range.first; ++it) {
2028           nAPV += 1;
2029           Gain = first_payload->getApvGain(it, range);
2030           std::pair<uint32_t, int> index = std::make_pair(d, nAPV);
2031           firstmap[index] = Gain;
2032         }  // end loop on APVs
2033       }    // end loop on detids
2034 
2035       TCanvas canvas("Payload comparison by Tracker Region", "payload comparison by Tracker Region", 1800, 800);
2036       canvas.Divide(2, 1);
2037 
2038       auto h2first = std::make_unique<TH2F>(
2039           "byRegion1", "SiStrip APV Gain values by region;; average SiStrip Gain", 38, 1., 39., 100., 0., 2.);
2040       auto h2last = std::make_unique<TH2F>(
2041           "byRegion2", "SiStrip APV Gain values by region;; average SiStrip Gain", 38, 1., 39., 100., 0., 2.);
2042 
2043       auto h2ratio = std::make_unique<TH2F>("byRegionRatio",
2044                                             Form("SiStrip APV Gains ratio by region;; Gains ratio IOV: %s/ IOV %s",
2045                                                  lastIOVsince.c_str(),
2046                                                  firstIOVsince.c_str()),
2047                                             38,
2048                                             1.,
2049                                             39.,
2050                                             100.,
2051                                             0.85,
2052                                             1.15);
2053 
2054       h2first->SetStats(false);
2055       h2last->SetStats(false);
2056       h2ratio->SetStats(false);
2057 
2058       canvas.cd(1)->SetBottomMargin(0.18);
2059       canvas.cd(1)->SetLeftMargin(0.12);
2060       canvas.cd(1)->SetRightMargin(0.05);
2061       canvas.Modified();
2062 
2063       std::vector<int> boundaries;
2064       std::string detector;
2065       std::string currentDetector;
2066 
2067       for (const auto& element : lastmap) {
2068         auto region = this->getTheRegion(element.first.first);
2069         auto bin = SiStripPI::regionType(region).first;
2070         auto label = SiStripPI::regionType(region).second;
2071 
2072         h2last->Fill(bin, element.second);
2073         h2last->GetXaxis()->SetBinLabel(bin, label);
2074         h2ratio->Fill(bin, element.second / firstmap[element.first]);
2075         h2ratio->GetXaxis()->SetBinLabel(bin, label);
2076       }
2077 
2078       for (const auto& element : firstmap) {
2079         auto region = this->getTheRegion(element.first.first);
2080         auto bin = SiStripPI::regionType(region).first;
2081         auto label = SiStripPI::regionType(region).second;
2082 
2083         h2first->Fill(bin, element.second);
2084         h2first->GetXaxis()->SetBinLabel(bin, label);
2085       }
2086 
2087       h2first->GetXaxis()->LabelsOption("v");
2088       h2last->GetXaxis()->LabelsOption("v");
2089       h2ratio->GetXaxis()->LabelsOption("v");
2090 
2091       h2last->SetLineColor(kBlue);
2092       h2first->SetLineColor(kRed);
2093       h2first->SetFillColor(kRed);
2094 
2095       h2first->SetMarkerStyle(20);
2096       h2last->SetMarkerStyle(21);
2097 
2098       h2first->SetMarkerColor(kRed);
2099       h2last->SetMarkerColor(kBlue);
2100 
2101       canvas.cd(1);
2102       h2first->Draw("BOX");
2103       h2last->Draw("BOXsame");
2104 
2105       TLegend legend = TLegend(0.70, 0.8, 0.95, 0.9);
2106       legend.SetHeader("Gain Comparison", "C");  // option "C" allows to center the header
2107       legend.AddEntry(h2first.get(), ("IOV: " + std::to_string(std::get<0>(firstiov))).c_str(), "F");
2108       legend.AddEntry(h2last.get(), ("IOV: " + std::to_string(std::get<0>(lastiov))).c_str(), "F");
2109       legend.Draw("same");
2110 
2111       canvas.cd(2);
2112       canvas.cd(2)->SetBottomMargin(0.18);
2113       canvas.cd(2)->SetLeftMargin(0.12);
2114       canvas.cd(2)->SetRightMargin(0.12);
2115 
2116       h2ratio->Draw("COLZ");
2117       auto hpfx_tmp = (TProfile*)(h2ratio->ProfileX("_pfx", 1, -1, "o"));
2118       hpfx_tmp->SetStats(kFALSE);
2119       hpfx_tmp->SetMarkerColor(kRed);
2120       hpfx_tmp->SetLineColor(kRed);
2121       hpfx_tmp->SetMarkerSize(1.2);
2122       hpfx_tmp->SetMarkerStyle(20);
2123       hpfx_tmp->Draw("same");
2124 
2125       std::string fileName(this->m_imageFileName);
2126       canvas.SaveAs(fileName.c_str());
2127 
2128       delete hpfx_tmp;
2129       return true;
2130     }
2131 
2132   private:
2133     TrackerTopology m_trackerTopo;
2134 
2135     SiStripPI::TrackerRegion getTheRegion(DetId detid) {
2136       int layer = 0;
2137       int stereo = 0;
2138       int detNum = 0;
2139 
2140       switch (detid.subdetId()) {
2141         case StripSubdetector::TIB:
2142           layer = m_trackerTopo.tibLayer(detid);
2143           stereo = m_trackerTopo.tibStereo(detid);
2144           detNum = 1000;
2145           break;
2146         case StripSubdetector::TOB:
2147           layer = m_trackerTopo.tobLayer(detid);
2148           stereo = m_trackerTopo.tobStereo(detid);
2149           detNum = 2000;
2150           break;
2151         case StripSubdetector::TEC:
2152           // is this module in TEC+ or TEC-?
2153           layer = m_trackerTopo.tecWheel(detid);
2154           stereo = m_trackerTopo.tecStereo(detid);
2155           detNum = 3000;
2156           break;
2157         case StripSubdetector::TID:
2158           // is this module in TID+ or TID-?
2159           layer = m_trackerTopo.tidWheel(detid);
2160           stereo = m_trackerTopo.tidStereo(detid);
2161           detNum = 4000;
2162           break;
2163       }
2164 
2165       detNum += layer * 10 + stereo;
2166       return static_cast<SiStripPI::TrackerRegion>(detNum);
2167     }
2168   };
2169 
2170   using SiStripApvGainsRatioComparatorByRegionSingleTag = SiStripApvGainsRatioComparatorByRegionBase<1, MULTI_IOV>;
2171   using SiStripApvGainsRatioComparatorByRegionTwoTags = SiStripApvGainsRatioComparatorByRegionBase<2, SINGLE_IOV>;
2172 
2173   /************************************************
2174     Compare Gains for each tracker region
2175   *************************************************/
2176 
2177   template <int ntags, IOVMultiplicity nIOVs>
2178   class SiStripApvGainsComparatorByRegionBase : public PlotImage<SiStripApvGain, nIOVs, ntags> {
2179   public:
2180     SiStripApvGainsComparatorByRegionBase()
2181         : PlotImage<SiStripApvGain, nIOVs, ntags>("SiStripGains Comparison By Region"),
2182           m_trackerTopo{StandaloneTrackerTopology::fromTrackerParametersXMLFile(
2183               edm::FileInPath("Geometry/TrackerCommonData/data/trackerParameters.xml").fullPath())} {}
2184 
2185     bool fill() override {
2186       // trick to deal with the multi-ioved tag and two tag case at the same time
2187       auto theIOVs = PlotBase::getTag<0>().iovs;
2188       auto tagname1 = PlotBase::getTag<0>().name;
2189       std::string tagname2 = "";
2190       auto firstiov = theIOVs.front();
2191       SiStripPI::MetaData lastiov;
2192 
2193       // we don't support (yet) comparison with more than 2 tags
2194       assert(this->m_plotAnnotations.ntags < 3);
2195 
2196       if (this->m_plotAnnotations.ntags == 2) {
2197         auto tag2iovs = PlotBase::getTag<1>().iovs;
2198         tagname2 = PlotBase::getTag<1>().name;
2199         lastiov = tag2iovs.front();
2200       } else {
2201         lastiov = theIOVs.back();
2202       }
2203 
2204       std::shared_ptr<SiStripApvGain> last_payload = this->fetchPayload(std::get<1>(lastiov));
2205       std::shared_ptr<SiStripApvGain> first_payload = this->fetchPayload(std::get<1>(firstiov));
2206 
2207       std::vector<uint32_t> detid;
2208       last_payload->getDetIds(detid);
2209 
2210       SiStripDetSummary summaryLastGain{&m_trackerTopo};
2211 
2212       for (const auto& d : detid) {
2213         SiStripApvGain::Range range = last_payload->getRange(d);
2214         for (int it = 0; it < range.second - range.first; ++it) {
2215           summaryLastGain.add(d, last_payload->getApvGain(it, range));
2216         }
2217       }
2218 
2219       SiStripDetSummary summaryFirstGain{&m_trackerTopo};
2220 
2221       for (const auto& d : detid) {
2222         SiStripApvGain::Range range = first_payload->getRange(d);
2223         for (int it = 0; it < range.second - range.first; ++it) {
2224           summaryFirstGain.add(d, first_payload->getApvGain(it, range));
2225         }
2226       }
2227 
2228       std::map<unsigned int, SiStripDetSummary::Values> firstmap = summaryFirstGain.getCounts();
2229       std::map<unsigned int, SiStripDetSummary::Values> lastmap = summaryLastGain.getCounts();
2230       //=========================
2231 
2232       TCanvas canvas("Region summary", "region summary", 1200, 1000);
2233       canvas.cd();
2234 
2235       auto hfirst = std::make_unique<TH1F>("byRegion1",
2236                                            "SiStrip APV Gain average by region;; average SiStrip Gain",
2237                                            firstmap.size(),
2238                                            0.,
2239                                            firstmap.size());
2240       auto hlast = std::make_unique<TH1F>(
2241           "byRegion2", "SiStrip APV Gain average by region;; average SiStrip Gain", lastmap.size(), 0., lastmap.size());
2242 
2243       hfirst->SetStats(false);
2244       hlast->SetStats(false);
2245 
2246       canvas.SetBottomMargin(0.18);
2247       canvas.SetLeftMargin(0.12);
2248       canvas.SetRightMargin(0.05);
2249       canvas.Modified();
2250 
2251       std::vector<int> boundaries;
2252       unsigned int iBin = 0;
2253 
2254       std::string detector;
2255       std::string currentDetector;
2256 
2257       for (const auto& element : lastmap) {
2258         iBin++;
2259         int count = element.second.count;
2260         double mean = (element.second.mean) / count;
2261 
2262         if (currentDetector.empty())
2263           currentDetector = "TIB";
2264 
2265         switch ((element.first) / 1000) {
2266           case 1:
2267             detector = "TIB";
2268             break;
2269           case 2:
2270             detector = "TOB";
2271             break;
2272           case 3:
2273             detector = "TEC";
2274             break;
2275           case 4:
2276             detector = "TID";
2277             break;
2278         }
2279 
2280         hlast->SetBinContent(iBin, mean);
2281         hlast->SetBinError(iBin, mean / 10000.);
2282         hlast->GetXaxis()->SetBinLabel(iBin, SiStripPI::regionType(element.first).second);
2283         hlast->GetXaxis()->LabelsOption("v");
2284 
2285         if (detector != currentDetector) {
2286           boundaries.push_back(iBin);
2287           currentDetector = detector;
2288         }
2289       }
2290 
2291       // reset the count
2292       iBin = 0;
2293 
2294       for (const auto& element : firstmap) {
2295         iBin++;
2296         int count = element.second.count;
2297         double mean = (element.second.mean) / count;
2298 
2299         hfirst->SetBinContent(iBin, mean);
2300         hfirst->SetBinError(iBin, mean / 10000.);
2301         hfirst->GetXaxis()->SetBinLabel(iBin, SiStripPI::regionType(element.first).second);
2302         hfirst->GetXaxis()->LabelsOption("v");
2303       }
2304 
2305       auto extrema = SiStripPI::getExtrema(hfirst.get(), hlast.get());
2306       hlast->GetYaxis()->SetRangeUser(extrema.first, extrema.second);
2307 
2308       hlast->SetMarkerStyle(20);
2309       hlast->SetMarkerSize(1);
2310       hlast->Draw("E1");
2311       hlast->Draw("Psame");
2312 
2313       hfirst->SetMarkerStyle(18);
2314       hfirst->SetMarkerSize(1);
2315       hfirst->SetLineColor(kBlue);
2316       hfirst->SetMarkerColor(kBlue);
2317       hfirst->Draw("E1same");
2318       hfirst->Draw("Psame");
2319 
2320       canvas.Update();
2321       canvas.cd();
2322 
2323       TLine l[boundaries.size()];
2324       unsigned int i = 0;
2325       for (const auto& line : boundaries) {
2326         l[i] = TLine(
2327             hfirst->GetBinLowEdge(line), canvas.cd()->GetUymin(), hfirst->GetBinLowEdge(line), canvas.cd()->GetUymax());
2328         l[i].SetLineWidth(1);
2329         l[i].SetLineStyle(9);
2330         l[i].SetLineColor(2);
2331         l[i].Draw("same");
2332         i++;
2333       }
2334 
2335       TLegend legend = TLegend(0.70, 0.8, 0.95, 0.9);
2336       legend.SetHeader("Gain Comparison", "C");  // option "C" allows to center the header
2337       legend.AddEntry(hfirst.get(), ("IOV: " + std::to_string(std::get<0>(firstiov))).c_str(), "PL");
2338       legend.AddEntry(hlast.get(), ("IOV: " + std::to_string(std::get<0>(lastiov))).c_str(), "PL");
2339       legend.Draw("same");
2340 
2341       std::string fileName(this->m_imageFileName);
2342       canvas.SaveAs(fileName.c_str());
2343 
2344       return true;
2345     }
2346 
2347   private:
2348     TrackerTopology m_trackerTopo;
2349   };
2350 
2351   using SiStripApvGainsComparatorByRegionSingleTag = SiStripApvGainsComparatorByRegionBase<1, MULTI_IOV>;
2352   using SiStripApvGainsComparatorByRegionTwoTags = SiStripApvGainsComparatorByRegionBase<2, SINGLE_IOV>;
2353 
2354   /************************************************
2355     Plot gain averages by region 
2356   *************************************************/
2357 
2358   class SiStripApvGainsByRegion : public PlotImage<SiStripApvGain, SINGLE_IOV> {
2359   public:
2360     SiStripApvGainsByRegion()
2361         : PlotImage<SiStripApvGain, SINGLE_IOV>("SiStripGains By Region"),
2362           m_trackerTopo{StandaloneTrackerTopology::fromTrackerParametersXMLFile(
2363               edm::FileInPath("Geometry/TrackerCommonData/data/trackerParameters.xml").fullPath())} {}
2364 
2365     bool fill() override {
2366       auto tag = PlotBase::getTag<0>();
2367       auto iov = tag.iovs.front();
2368       std::shared_ptr<SiStripApvGain> payload = fetchPayload(std::get<1>(iov));
2369 
2370       std::vector<uint32_t> detid;
2371       payload->getDetIds(detid);
2372 
2373       SiStripDetSummary summaryGain{&m_trackerTopo};
2374 
2375       for (const auto& d : detid) {
2376         SiStripApvGain::Range range = payload->getRange(d);
2377         for (int it = 0; it < range.second - range.first; ++it) {
2378           summaryGain.add(d, payload->getApvGain(it, range));
2379         }
2380       }
2381 
2382       std::map<unsigned int, SiStripDetSummary::Values> map = summaryGain.getCounts();
2383       //=========================
2384 
2385       TCanvas canvas("Region summary", "region summary", 1200, 1000);
2386       canvas.cd();
2387       auto h1 = std::make_unique<TH1F>(
2388           "byRegion", "SiStrip Gain average by region;; average SiStrip Gain", map.size(), 0., map.size());
2389       h1->SetStats(false);
2390       canvas.SetBottomMargin(0.18);
2391       canvas.SetLeftMargin(0.12);
2392       canvas.SetRightMargin(0.05);
2393       canvas.Modified();
2394 
2395       std::vector<int> boundaries;
2396       unsigned int iBin = 0;
2397 
2398       std::string detector;
2399       std::string currentDetector;
2400 
2401       for (const auto& element : map) {
2402         iBin++;
2403         int count = element.second.count;
2404         double mean = (element.second.mean) / count;
2405 
2406         if (currentDetector.empty())
2407           currentDetector = "TIB";
2408 
2409         switch ((element.first) / 1000) {
2410           case 1:
2411             detector = "TIB";
2412             break;
2413           case 2:
2414             detector = "TOB";
2415             break;
2416           case 3:
2417             detector = "TEC";
2418             break;
2419           case 4:
2420             detector = "TID";
2421             break;
2422         }
2423 
2424         h1->SetBinContent(iBin, mean);
2425         h1->GetXaxis()->SetBinLabel(iBin, SiStripPI::regionType(element.first).second);
2426         h1->GetXaxis()->LabelsOption("v");
2427 
2428         if (detector != currentDetector) {
2429           boundaries.push_back(iBin);
2430           currentDetector = detector;
2431         }
2432       }
2433 
2434       h1->SetMarkerStyle(20);
2435       h1->SetMarkerSize(1);
2436       h1->Draw("HIST");
2437       h1->Draw("Psame");
2438 
2439       canvas.Update();
2440 
2441       TLine l[boundaries.size()];
2442       unsigned int i = 0;
2443       for (const auto& line : boundaries) {
2444         l[i] = TLine(h1->GetBinLowEdge(line), canvas.GetUymin(), h1->GetBinLowEdge(line), canvas.GetUymax());
2445         l[i].SetLineWidth(1);
2446         l[i].SetLineStyle(9);
2447         l[i].SetLineColor(2);
2448         l[i].Draw("same");
2449         i++;
2450       }
2451 
2452       TLegend legend = TLegend(0.52, 0.82, 0.95, 0.9);
2453       legend.SetHeader((std::get<1>(iov)).c_str(), "C");  // option "C" allows to center the header
2454       legend.AddEntry(h1.get(), ("IOV: " + std::to_string(std::get<0>(iov))).c_str(), "PL");
2455       legend.SetTextSize(0.025);
2456       legend.Draw("same");
2457 
2458       std::string fileName(m_imageFileName);
2459       canvas.SaveAs(fileName.c_str());
2460 
2461       return true;
2462     }
2463 
2464   private:
2465     TrackerTopology m_trackerTopo;
2466   };
2467 
2468 }  // namespace
2469 
2470 // Register the classes as boost python plugin
2471 PAYLOAD_INSPECTOR_MODULE(SiStripApvGain) {
2472   PAYLOAD_INSPECTOR_CLASS(SiStripApvGainsValue);
2473   PAYLOAD_INSPECTOR_CLASS(SiStripApvGainTest);
2474   PAYLOAD_INSPECTOR_CLASS(SiStripApvGainByPartition);
2475   PAYLOAD_INSPECTOR_CLASS(SiStripApvGainCompareByPartition);
2476   PAYLOAD_INSPECTOR_CLASS(SiStripApvGainRatioByPartition);
2477   PAYLOAD_INSPECTOR_CLASS(SiStripApvGainDiffByPartition);
2478   PAYLOAD_INSPECTOR_CLASS(SiStripApvGainsTest);
2479   PAYLOAD_INSPECTOR_CLASS(SiStripApvGainsByRegion);
2480   PAYLOAD_INSPECTOR_CLASS(SiStripApvGainsComparatorSingleTag);
2481   PAYLOAD_INSPECTOR_CLASS(SiStripApvGainsComparatorTwoTags);
2482   PAYLOAD_INSPECTOR_CLASS(SiStripApvGainsValuesComparatorSingleTag);
2483   PAYLOAD_INSPECTOR_CLASS(SiStripApvGainsValuesComparatorTwoTags);
2484   PAYLOAD_INSPECTOR_CLASS(SiStripApvGainsComparatorByRegionSingleTag);
2485   PAYLOAD_INSPECTOR_CLASS(SiStripApvGainsComparatorByRegionTwoTags);
2486   PAYLOAD_INSPECTOR_CLASS(SiStripApvGainsRatioComparatorByRegionSingleTag);
2487   PAYLOAD_INSPECTOR_CLASS(SiStripApvGainsRatioComparatorByRegionTwoTags);
2488   PAYLOAD_INSPECTOR_CLASS(SiStripApvGainsTHStack);
2489   PAYLOAD_INSPECTOR_CLASS(SiStripApvBarrelGainsByLayer);
2490   PAYLOAD_INSPECTOR_CLASS(SiStripApvAbsoluteBarrelGainsByLayer);
2491   PAYLOAD_INSPECTOR_CLASS(SiStripApvEndcapMinusGainsByDisk);
2492   PAYLOAD_INSPECTOR_CLASS(SiStripApvEndcapPlusGainsByDisk);
2493   PAYLOAD_INSPECTOR_CLASS(SiStripApvAbsoluteEndcapMinusGainsByDisk);
2494   PAYLOAD_INSPECTOR_CLASS(SiStripApvAbsoluteEndcapPlusGainsByDisk);
2495   PAYLOAD_INSPECTOR_CLASS(SiStripApvGainsAverageTrackerMap);
2496   PAYLOAD_INSPECTOR_CLASS(SiStripApvGainsDefaultTrackerMap);
2497   PAYLOAD_INSPECTOR_CLASS(SiStripApvGainsMaximumTrackerMap);
2498   PAYLOAD_INSPECTOR_CLASS(SiStripApvGainsMinimumTrackerMap);
2499   PAYLOAD_INSPECTOR_CLASS(SiStripApvGainsAvgDeviationRatioWithPreviousIOVTrackerMap);
2500   PAYLOAD_INSPECTOR_CLASS(SiStripApvGainsAvgDeviationRatioTrackerMapTwoTags);
2501   PAYLOAD_INSPECTOR_CLASS(SiStripApvGainsMaxDeviationRatioWithPreviousIOVTrackerMap);
2502   PAYLOAD_INSPECTOR_CLASS(SiStripApvGainsMaxDeviationRatioTrackerMapTwoTags);
2503   PAYLOAD_INSPECTOR_CLASS(SiStripApvGainByRunMeans);
2504   PAYLOAD_INSPECTOR_CLASS(SiStripApvGainMin_History);
2505   PAYLOAD_INSPECTOR_CLASS(SiStripApvGainMax_History);
2506   PAYLOAD_INSPECTOR_CLASS(SiStripApvGainMean_History);
2507   PAYLOAD_INSPECTOR_CLASS(SiStripApvGainRMS_History);
2508   PAYLOAD_INSPECTOR_CLASS(SiStripApvTIBGainByRunMeans);
2509   PAYLOAD_INSPECTOR_CLASS(SiStripApvTIDGainByRunMeans);
2510   PAYLOAD_INSPECTOR_CLASS(SiStripApvTOBGainByRunMeans);
2511   PAYLOAD_INSPECTOR_CLASS(SiStripApvTECGainByRunMeans);
2512 }