Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-04-12 07:44:06

0001 /*!
0002   \file SiStripNoises_PayloadInspector
0003   \Payload Inspector Plugin for SiStrip Noises
0004   \author M. Musich
0005   \version $Revision: 1.0 $
0006   \date $Date: 2017/09/21 13: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/SiStripNoises.h"
0015 #include "DataFormats/DetId/interface/DetId.h"
0016 #include "DataFormats/SiStripDetId/interface/StripSubdetector.h"
0017 #include "CondFormats/SiStripObjects/interface/SiStripDetSummary.h"
0018 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0019 
0020 // needed for the tracker map
0021 #include "CommonTools/TrackerMap/interface/TrackerMap.h"
0022 
0023 // auxilliary functions
0024 #include "CondCore/SiStripPlugins/interface/SiStripPayloadInspectorHelper.h"
0025 #include "CalibTracker/StandaloneTrackerTopology/interface/StandaloneTrackerTopology.h"
0026 #include "CalibTracker/SiStripCommon/interface/SiStripDetInfoFileReader.h"
0027 #include "FWCore/ParameterSet/interface/FileInPath.h"
0028 #include "SiStripCondObjectRepresent.h"
0029 
0030 #include <memory>
0031 #include <sstream>
0032 #include <iostream>
0033 #include <boost/tokenizer.hpp>
0034 
0035 // include ROOT
0036 #include "TH2F.h"
0037 #include "TF1.h"
0038 #include "TGraphErrors.h"
0039 #include "TLegend.h"
0040 #include "TCanvas.h"
0041 #include "TLine.h"
0042 #include "TStyle.h"
0043 #include "TLatex.h"
0044 #include "TPave.h"
0045 #include "TPaveStats.h"
0046 #include "TGaxis.h"
0047 
0048 namespace {
0049 
0050   using namespace cond::payloadInspector;
0051 
0052   class SiStripNoiseContainer : public SiStripCondObjectRepresent::SiStripDataContainer<SiStripNoises, float> {
0053   public:
0054     SiStripNoiseContainer(const std::shared_ptr<SiStripNoises>& payload,
0055                           const SiStripPI::MetaData& metadata,
0056                           const std::string& tagName)
0057         : SiStripCondObjectRepresent::SiStripDataContainer<SiStripNoises, float>(payload, metadata, tagName) {
0058       payloadType_ = "SiStripNoises";
0059       setGranularity(SiStripCondObjectRepresent::PERSTRIP);
0060     }
0061 
0062     void storeAllValues() override {
0063       std::vector<uint32_t> detid;
0064       payload_->getDetIds(detid);
0065 
0066       for (const auto& d : detid) {
0067         SiStripNoises::Range range = payload_->getRange(d);
0068         for (int it = 0; it < (range.second - range.first) * 8 / 9; ++it) {
0069           // to be used to fill the histogram
0070           SiStripCondData_.fillByPushBack(d, payload_->getNoise(it, range));
0071         }
0072       }
0073     }
0074   };
0075 
0076   class SiStripNoiseCompareByPartition : public PlotImage<SiStripNoises, MULTI_IOV, 2> {
0077   public:
0078     SiStripNoiseCompareByPartition() : PlotImage<SiStripNoises, MULTI_IOV, 2>("SiStrip Compare Noises By Partition") {}
0079 
0080     bool fill() override {
0081       // trick to deal with the multi-ioved tag and two tag case at the same time
0082       auto theIOVs = PlotBase::getTag<0>().iovs;
0083       auto tagname1 = PlotBase::getTag<0>().name;
0084       auto tag2iovs = PlotBase::getTag<1>().iovs;
0085       auto tagname2 = PlotBase::getTag<1>().name;
0086       SiStripPI::MetaData firstiov = theIOVs.front();
0087       SiStripPI::MetaData lastiov = tag2iovs.front();
0088 
0089       std::shared_ptr<SiStripNoises> last_payload = fetchPayload(std::get<1>(lastiov));
0090       std::shared_ptr<SiStripNoises> first_payload = fetchPayload(std::get<1>(firstiov));
0091 
0092       SiStripNoiseContainer* l_objContainer = new SiStripNoiseContainer(last_payload, lastiov, tagname1);
0093       SiStripNoiseContainer* f_objContainer = new SiStripNoiseContainer(first_payload, firstiov, tagname2);
0094 
0095       l_objContainer->compare(f_objContainer);
0096 
0097       //l_objContainer->printAll();
0098 
0099       TCanvas canvas("Partition summary", "partition summary", 1400, 1000);
0100       l_objContainer->fillByPartition(canvas, 100, 0.1, 10.);
0101 
0102       std::string fileName(m_imageFileName);
0103       canvas.SaveAs(fileName.c_str());
0104 
0105       return true;
0106     }  // fill
0107   };
0108 
0109   class SiStripNoiseDiffByPartition : public PlotImage<SiStripNoises, MULTI_IOV, 2> {
0110   public:
0111     SiStripNoiseDiffByPartition() : PlotImage<SiStripNoises, MULTI_IOV, 2>("SiStrip Diff Noises By Partition") {}
0112 
0113     bool fill() override {
0114       // trick to deal with the multi-ioved tag and two tag case at the same time
0115       auto theIOVs = PlotBase::getTag<0>().iovs;
0116       auto tagname1 = PlotBase::getTag<0>().name;
0117       auto tag2iovs = PlotBase::getTag<1>().iovs;
0118       auto tagname2 = PlotBase::getTag<1>().name;
0119       SiStripPI::MetaData firstiov = theIOVs.front();
0120       SiStripPI::MetaData lastiov = tag2iovs.front();
0121 
0122       std::shared_ptr<SiStripNoises> last_payload = fetchPayload(std::get<1>(lastiov));
0123       std::shared_ptr<SiStripNoises> first_payload = fetchPayload(std::get<1>(firstiov));
0124 
0125       SiStripNoiseContainer* l_objContainer = new SiStripNoiseContainer(last_payload, lastiov, tagname1);
0126       SiStripNoiseContainer* f_objContainer = new SiStripNoiseContainer(first_payload, firstiov, tagname2);
0127 
0128       l_objContainer->subtract(f_objContainer);
0129 
0130       //l_objContainer->printAll();
0131 
0132       TCanvas canvas("Partition summary", "partition summary", 1400, 1000);
0133       l_objContainer->fillByPartition(canvas, 100, -1., 1.);
0134 
0135       std::string fileName(m_imageFileName);
0136       canvas.SaveAs(fileName.c_str());
0137 
0138       return true;
0139     }  // fill
0140   };
0141 
0142   class SiStripNoiseCorrelationByPartition : public PlotImage<SiStripNoises> {
0143   public:
0144     SiStripNoiseCorrelationByPartition() : PlotImage<SiStripNoises>("SiStrip Noises Correlation By Partition") {
0145       setSingleIov(false);
0146     }
0147 
0148     bool fill(const std::vector<SiStripPI::MetaData>& iovs) override {
0149       std::vector<SiStripPI::MetaData> sorted_iovs = iovs;
0150 
0151       // make absolute sure the IOVs are sortd by since
0152       std::sort(begin(sorted_iovs), end(sorted_iovs), [](auto const& t1, auto const& t2) {
0153         return std::get<0>(t1) < std::get<0>(t2);
0154       });
0155 
0156       auto firstiov = sorted_iovs.front();
0157       auto lastiov = sorted_iovs.back();
0158 
0159       std::shared_ptr<SiStripNoises> last_payload = fetchPayload(std::get<1>(lastiov));
0160       std::shared_ptr<SiStripNoises> first_payload = fetchPayload(std::get<1>(firstiov));
0161 
0162       SiStripNoiseContainer* l_objContainer = new SiStripNoiseContainer(last_payload, lastiov, "");
0163       SiStripNoiseContainer* f_objContainer = new SiStripNoiseContainer(first_payload, firstiov, "");
0164 
0165       l_objContainer->compare(f_objContainer);
0166 
0167       TCanvas canvas("Partition summary", "partition summary", 1200, 1200);
0168       l_objContainer->fillCorrelationByPartition(canvas, 100, 0.1, 10.);
0169 
0170       std::string fileName(m_imageFileName);
0171       canvas.SaveAs(fileName.c_str());
0172 
0173       return true;
0174     }  // fill
0175   };
0176 
0177   class SiStripNoiseConsistencyCheck : public PlotImage<SiStripNoises> {
0178   public:
0179     SiStripNoiseConsistencyCheck() : PlotImage<SiStripNoises>("SiStrip Noise Consistency Check") {
0180       setSingleIov(false);
0181     }
0182 
0183     bool fill(const std::vector<SiStripPI::MetaData>& iovs) override {
0184       std::vector<SiStripPI::MetaData> sorted_iovs = iovs;
0185 
0186       // make absolute sure the IOVs are sortd by since
0187       std::sort(begin(sorted_iovs), end(sorted_iovs), [](auto const& t1, auto const& t2) {
0188         return std::get<0>(t1) < std::get<0>(t2);
0189       });
0190 
0191       auto firstiov = sorted_iovs.front();
0192       auto lastiov = sorted_iovs.back();
0193 
0194       std::shared_ptr<SiStripNoises> last_payload = fetchPayload(std::get<1>(lastiov));
0195       std::shared_ptr<SiStripNoises> first_payload = fetchPayload(std::get<1>(firstiov));
0196 
0197       SiStripNoiseContainer* f_objContainer = new SiStripNoiseContainer(first_payload, firstiov, "");
0198       SiStripNoiseContainer* l_objContainer = new SiStripNoiseContainer(last_payload, lastiov, "");
0199 
0200       f_objContainer->compare(l_objContainer);
0201 
0202       //l_objContainer->printAll();
0203 
0204       TCanvas canvas("Partition summary", "partition summary", 1200, 1000);
0205       //f_objContainer->fillValuePlot(canvas,SiStripPI::STRIP_BASED,100,0.1,10);
0206       f_objContainer->fillValuePlot(canvas, SiStripPI::APV_BASED, 100, 0.1, 10);
0207       //f_objContainer->fillValuePlot(canvas,SiStripPI::MODULE_BASED,100,0.1,10);
0208 
0209       std::string fileName(m_imageFileName);
0210       canvas.SaveAs(fileName.c_str());
0211 
0212       return true;
0213     }  // fill
0214   };
0215 
0216   /************************************************
0217     test class
0218   *************************************************/
0219 
0220   class SiStripNoisesTest : public Histogram1D<SiStripNoises, SINGLE_IOV> {
0221   public:
0222     SiStripNoisesTest()
0223         : Histogram1D<SiStripNoises, SINGLE_IOV>("SiStrip Noise test", "SiStrip Noise test", 10, 0.0, 10.0),
0224           m_trackerTopo{StandaloneTrackerTopology::fromTrackerParametersXMLFile(
0225               edm::FileInPath("Geometry/TrackerCommonData/data/trackerParameters.xml").fullPath())} {}
0226 
0227     bool fill() override {
0228       auto tag = PlotBase::getTag<0>();
0229       for (auto const& iov : tag.iovs) {
0230         std::shared_ptr<SiStripNoises> payload = Base::fetchPayload(std::get<1>(iov));
0231         if (payload.get()) {
0232           fillWithValue(1.);
0233 
0234           std::stringstream ss;
0235           ss << "Summary of strips noises:" << std::endl;
0236 
0237           //payload->printDebug(ss);
0238           payload->printSummary(ss, &m_trackerTopo);
0239 
0240           std::vector<uint32_t> detid;
0241           payload->getDetIds(detid);
0242 
0243           // for (const auto & d : detid) {
0244           //   int nstrip=0;
0245           //   SiStripNoises::Range range=payload->getRange(d);
0246           //   for( int it=0; it < (range.second-range.first)*8/9; ++it ){
0247           //     auto noise = payload->getNoise(it,range);
0248           //     nstrip++;
0249           //     ss << "DetId="<< d << " Strip=" << nstrip <<": "<< noise << std::endl;
0250           //   } // end of loop on strips
0251           // } // end of loop on detIds
0252 
0253           std::cout << ss.str() << std::endl;
0254 
0255         }  // payload
0256       }    // iovs
0257       return true;
0258     }  // fill
0259   private:
0260     TrackerTopology m_trackerTopo;
0261   };
0262 
0263   /************************************************
0264     SiStrip Noise Profile of 1 IOV for one selected DetId
0265   *************************************************/
0266 
0267   class SiStripNoisePerDetId : public PlotImage<SiStripNoises, SINGLE_IOV> {
0268   public:
0269     SiStripNoisePerDetId() : PlotImage<SiStripNoises, SINGLE_IOV>("SiStrip Noise values Per DetId") {
0270       PlotBase::addInputParam("DetIds");
0271     }
0272 
0273     bool fill() override {
0274       auto tag = PlotBase::getTag<0>();
0275       auto iov = tag.iovs.front();
0276       auto tagname = tag.name;
0277       std::shared_ptr<SiStripNoises> payload = fetchPayload(std::get<1>(iov));
0278 
0279       std::vector<uint32_t> the_detids = {};
0280 
0281       auto paramValues = PlotBase::inputParamValues();
0282       auto ip = paramValues.find("DetIds");
0283       if (ip != paramValues.end()) {
0284         auto input = ip->second;
0285         typedef boost::tokenizer<boost::char_separator<char>> tokenizer;
0286         boost::char_separator<char> sep{","};
0287         tokenizer tok{input, sep};
0288         for (const auto& t : tok) {
0289           the_detids.push_back(atoi(t.c_str()));
0290         }
0291       } else {
0292         edm::LogWarning("SiStripNoisePerDetId")
0293             << "\n WARNING!!!! \n The needed parameter DetIds has not been passed. Will use all Strip DetIds! \n\n";
0294         the_detids.push_back(0xFFFFFFFF);
0295       }
0296 
0297       size_t ndets = the_detids.size();
0298       std::vector<std::shared_ptr<TH1F>> hnoise;
0299       std::vector<std::shared_ptr<TLegend>> legends;
0300       std::vector<unsigned int> v_nAPVs;
0301       std::vector<std::vector<std::shared_ptr<TLine>>> lines;
0302       hnoise.reserve(ndets);
0303       legends.reserve(ndets);
0304 
0305       // determine how the plot will be paginated
0306       auto sides = getClosestFactors(the_detids.size());
0307       edm::LogPrint("SiStripNoisePerDetId") << "Aspect ratio: " << sides.first << ":" << sides.second << std::endl;
0308 
0309       if (payload.get()) {
0310         //=========================
0311         TCanvas canvas("ByDetId", "ByDetId", sides.second * 800, sides.first * 600);
0312         canvas.Divide(sides.second, sides.first);
0313         const auto detInfo =
0314             SiStripDetInfoFileReader::read(edm::FileInPath(SiStripDetInfoFileReader::kDefaultFile).fullPath());
0315         for (const auto& the_detid : the_detids) {
0316           edm::LogPrint("SiStripNoisePerDetId") << "DetId:" << the_detid << std::endl;
0317 
0318           unsigned int nAPVs = detInfo.getNumberOfApvsAndStripLength(the_detid).first;
0319           if (nAPVs == 0)
0320             nAPVs = 6;
0321           v_nAPVs.push_back(nAPVs);
0322 
0323           auto histo =
0324               std::make_shared<TH1F>(Form("Noise profile_%s", std::to_string(the_detid).c_str()),
0325                                      Form("SiStrip Noise profile for DetId: %s;Strip number;SiStrip Noise [ADC counts]",
0326                                           std::to_string(the_detid).c_str()),
0327                                      sistrip::STRIPS_PER_APV * nAPVs,
0328                                      -0.5,
0329                                      (sistrip::STRIPS_PER_APV * nAPVs) - 0.5);
0330 
0331           histo->SetStats(false);
0332           histo->SetTitle("");
0333 
0334           if (the_detid != 0xFFFFFFFF) {
0335             fillHisto(payload, histo, the_detid);
0336           } else {
0337             auto allDetIds = detInfo.getAllDetIds();
0338             for (const auto& id : allDetIds) {
0339               fillHisto(payload, histo, id);
0340             }
0341           }
0342 
0343           SiStripPI::makeNicePlotStyle(histo.get());
0344           histo->GetYaxis()->SetTitleOffset(1.0);
0345           hnoise.push_back(histo);
0346         }  // loop on the detids
0347 
0348         for (size_t index = 0; index < ndets; index++) {
0349           canvas.cd(index + 1);
0350           canvas.cd(index + 1)->SetBottomMargin(0.11);
0351           canvas.cd(index + 1)->SetTopMargin(0.06);
0352           canvas.cd(index + 1)->SetLeftMargin(0.10);
0353           canvas.cd(index + 1)->SetRightMargin(0.02);
0354           hnoise.at(index)->Draw();
0355           hnoise.at(index)->GetYaxis()->SetRangeUser(0, hnoise.at(index)->GetMaximum() * 1.2);
0356           canvas.cd(index)->Update();
0357 
0358           std::vector<int> boundaries;
0359           for (size_t b = 0; b < v_nAPVs.at(index); b++) {
0360             boundaries.push_back(b * sistrip::STRIPS_PER_APV);
0361           }
0362 
0363           std::vector<std::shared_ptr<TLine>> linesVec;
0364           for (const auto& bound : boundaries) {
0365             auto line = std::make_shared<TLine>(hnoise.at(index)->GetBinLowEdge(bound),
0366                                                 canvas.cd(index + 1)->GetUymin(),
0367                                                 hnoise.at(index)->GetBinLowEdge(bound),
0368                                                 canvas.cd(index + 1)->GetUymax());
0369             line->SetLineWidth(1);
0370             line->SetLineStyle(9);
0371             line->SetLineColor(2);
0372             linesVec.push_back(line);
0373           }
0374           lines.push_back(linesVec);
0375 
0376           for (const auto& line : lines.at(index)) {
0377             line->Draw("same");
0378           }
0379 
0380           canvas.cd(index + 1);
0381 
0382           auto ltx = TLatex();
0383           ltx.SetTextFont(62);
0384           ltx.SetTextSize(0.05);
0385           ltx.SetTextAlign(11);
0386           ltx.DrawLatexNDC(gPad->GetLeftMargin(),
0387                            1 - gPad->GetTopMargin() + 0.01,
0388                            Form("SiStrip Noise profile for DetId %s", std::to_string(the_detids[index]).c_str()));
0389 
0390           legends.push_back(std::make_shared<TLegend>(0.55, 0.83, 0.95, 0.93));
0391           legends.at(index)->SetHeader(tagname.c_str(), "C");  // option "C" allows to center the header
0392           legends.at(index)->AddEntry(
0393               hnoise.at(index).get(), ("IOV: " + std::to_string(std::get<0>(iov))).c_str(), "PL");
0394           legends.at(index)->SetTextSize(0.045);
0395           legends.at(index)->Draw("same");
0396         }
0397 
0398         std::string fileName(m_imageFileName);
0399         canvas.SaveAs(fileName.c_str());
0400       }  // payload
0401       return true;
0402     }  // fill
0403 
0404   private:
0405     int nextPerfectSquare(int N) { return std::floor(sqrt(N)) + 1; }
0406 
0407     std::pair<int, int> getClosestFactors(int input) {
0408       if ((input % 2 != 0) && input > 1) {
0409         input += 1;
0410       }
0411 
0412       int testNum = (int)sqrt(input);
0413       while (input % testNum != 0) {
0414         testNum--;
0415       }
0416       return std::make_pair(testNum, input / testNum);
0417     }
0418 
0419     void fillHisto(const std::shared_ptr<SiStripNoises> payload, std::shared_ptr<TH1F>& histo, uint32_t the_detid) {
0420       int nstrip = 0;
0421       SiStripNoises::Range range = payload->getRange(the_detid);
0422       for (int it = 0; it < (range.second - range.first) * 8 / 9; ++it) {
0423         auto noise = payload->getNoise(it, range);
0424         nstrip++;
0425         histo->AddBinContent(nstrip, noise);
0426       }  // end of loop on strips
0427     }
0428   };
0429 
0430   /************************************************
0431     1d histogram of SiStripNoises of 1 IOV 
0432   *************************************************/
0433 
0434   // inherit from one of the predefined plot class: Histogram1D
0435   class SiStripNoiseValue : public Histogram1D<SiStripNoises, SINGLE_IOV> {
0436   public:
0437     SiStripNoiseValue()
0438         : Histogram1D<SiStripNoises, SINGLE_IOV>("SiStrip Noise values", "SiStrip Noise values", 100, 0.0, 10.0) {}
0439 
0440     bool fill() override {
0441       auto tag = PlotBase::getTag<0>();
0442       for (auto const& iov : tag.iovs) {
0443         std::shared_ptr<SiStripNoises> payload = Base::fetchPayload(std::get<1>(iov));
0444         if (payload.get()) {
0445           std::vector<uint32_t> detid;
0446           payload->getDetIds(detid);
0447 
0448           for (const auto& d : detid) {
0449             SiStripNoises::Range range = payload->getRange(d);
0450             for (int it = 0; it < (range.second - range.first) * 8 / 9; ++it) {
0451               auto noise = payload->getNoise(it, range);
0452               //to be used to fill the histogram
0453               fillWithValue(noise);
0454             }  // loop over APVs
0455           }    // loop over detIds
0456         }      // payload
0457       }        // iovs
0458       return true;
0459     }  // fill
0460   };
0461 
0462   /************************************************
0463     1d histogram of SiStripNoises of 1 IOV per Detid
0464   *************************************************/
0465 
0466   // inherit from one of the predefined plot class: Histogram1D
0467   class SiStripNoiseValuePerDetId : public Histogram1D<SiStripNoises, SINGLE_IOV> {
0468   public:
0469     SiStripNoiseValuePerDetId()
0470         : Histogram1D<SiStripNoises, SINGLE_IOV>(
0471               "SiStrip Noise values per DetId", "SiStrip Noise values per DetId", 100, 0.0, 10.0) {
0472       PlotBase::addInputParam("DetId");
0473     }
0474 
0475     bool fill() override {
0476       auto tag = PlotBase::getTag<0>();
0477       for (auto const& iov : tag.iovs) {
0478         std::shared_ptr<SiStripNoises> payload = Base::fetchPayload(std::get<1>(iov));
0479         unsigned int the_detid(0xFFFFFFFF);
0480         auto paramValues = PlotBase::inputParamValues();
0481         auto ip = paramValues.find("DetId");
0482         if (ip != paramValues.end()) {
0483           the_detid = std::stoul(ip->second);
0484         }
0485 
0486         if (payload.get()) {
0487           SiStripNoises::Range range = payload->getRange(the_detid);
0488           for (int it = 0; it < (range.second - range.first) * 8 / 9; ++it) {
0489             auto noise = payload->getNoise(it, range);
0490             //to be used to fill the histogram
0491             fillWithValue(noise);
0492           }  // loop over APVs
0493         }    // payload
0494       }      // iovs
0495       return true;
0496     }  // fill
0497   };
0498 
0499   /************************************************
0500     templated 1d histogram of SiStripNoises of 1 IOV
0501   *************************************************/
0502 
0503   // inherit from one of the predefined plot class: PlotImage
0504   template <SiStripPI::OpMode op_mode_>
0505   class SiStripNoiseDistribution : public PlotImage<SiStripNoises, SINGLE_IOV> {
0506   public:
0507     SiStripNoiseDistribution() : PlotImage<SiStripNoises, SINGLE_IOV>("SiStrip Noise values") {}
0508 
0509     bool fill() override {
0510       auto tag = PlotBase::getTag<0>();
0511       auto iov = tag.iovs.front();
0512 
0513       TGaxis::SetMaxDigits(3);
0514       gStyle->SetOptStat("emr");
0515 
0516       std::shared_ptr<SiStripNoises> payload = fetchPayload(std::get<1>(iov));
0517 
0518       auto mon1D = std::unique_ptr<SiStripPI::Monitor1D>(new SiStripPI::Monitor1D(
0519           op_mode_,
0520           "Noise",
0521           Form("#LT Strip Noise #GT per %s for IOV [%s];#LTStrip Noise per %s#GT [ADC counts];n. %ss",
0522                opType(op_mode_).c_str(),
0523                std::to_string(std::get<0>(iov)).c_str(),
0524                opType(op_mode_).c_str(),
0525                opType(op_mode_).c_str()),
0526           100,
0527           0.1,
0528           10.));
0529 
0530       unsigned int prev_det = 0, prev_apv = 0;
0531       SiStripPI::Entry enoise;
0532 
0533       std::vector<uint32_t> detids;
0534       payload->getDetIds(detids);
0535 
0536       // loop on payload
0537 
0538       for (const auto& d : detids) {
0539         SiStripNoises::Range range = payload->getRange(d);
0540 
0541         unsigned int istrip = 0;
0542 
0543         for (int it = 0; it < (range.second - range.first) * 8 / 9; ++it) {
0544           auto noise = payload->getNoise(it, range);
0545           bool flush = false;
0546           switch (op_mode_) {
0547             case (SiStripPI::APV_BASED):
0548               flush = (prev_det != 0 && prev_apv != istrip / sistrip::STRIPS_PER_APV);
0549               break;
0550             case (SiStripPI::MODULE_BASED):
0551               flush = (prev_det != 0 && prev_det != d);
0552               break;
0553             case (SiStripPI::STRIP_BASED):
0554               flush = (istrip != 0);
0555               break;
0556           }
0557 
0558           if (flush) {
0559             mon1D->Fill(prev_apv, prev_det, enoise.mean());
0560             enoise.reset();
0561           }
0562 
0563           enoise.add(std::min<float>(noise, 30.5));
0564           prev_apv = istrip / sistrip::STRIPS_PER_APV;
0565           istrip++;
0566         }
0567         prev_det = d;
0568       }
0569 
0570       //=========================
0571       TCanvas canvas("Partition summary", "partition summary", 1200, 1000);
0572       canvas.cd();
0573       canvas.SetBottomMargin(0.11);
0574       canvas.SetTopMargin(0.07);
0575       canvas.SetLeftMargin(0.13);
0576       canvas.SetRightMargin(0.05);
0577       canvas.Modified();
0578 
0579       auto hist = mon1D->getHist();
0580       SiStripPI::makeNicePlotStyle(&hist);
0581       hist.SetStats(kTRUE);
0582       hist.SetFillColorAlpha(kRed, 0.35);
0583       hist.Draw();
0584 
0585       canvas.Update();
0586 
0587       TPaveStats* st = (TPaveStats*)hist.GetListOfFunctions()->FindObject("stats");
0588       st->SetLineColor(kRed);
0589       st->SetTextColor(kRed);
0590       st->SetX1NDC(.75);
0591       st->SetX2NDC(.95);
0592       st->SetY1NDC(.83);
0593       st->SetY2NDC(.93);
0594 
0595       TLegend legend = TLegend(0.13, 0.83, 0.43, 0.93);
0596       legend.SetHeader(Form("SiStrip Noise values per %s", opType(op_mode_).c_str()),
0597                        "C");  // option "C" allows to center the header
0598       legend.AddEntry(&hist, ("IOV: " + std::to_string(std::get<0>(iov))).c_str(), "F");
0599       legend.SetTextSize(0.025);
0600       legend.Draw("same");
0601 
0602       std::string fileName(m_imageFileName);
0603       canvas.SaveAs(fileName.c_str());
0604 
0605       return true;
0606     }
0607 
0608     std::string opType(SiStripPI::OpMode mode) {
0609       std::string types[3] = {"Strip", "APV", "Module"};
0610       return types[mode];
0611     }
0612   };
0613 
0614   typedef SiStripNoiseDistribution<SiStripPI::STRIP_BASED> SiStripNoiseValuePerStrip;
0615   typedef SiStripNoiseDistribution<SiStripPI::APV_BASED> SiStripNoiseValuePerAPV;
0616   typedef SiStripNoiseDistribution<SiStripPI::MODULE_BASED> SiStripNoiseValuePerModule;
0617 
0618   /************************************************
0619   template 1d histogram comparison of SiStripNoises of 1 IOV
0620   *************************************************/
0621 
0622   // inherit from one of the predefined plot class: PlotImage
0623   template <SiStripPI::OpMode op_mode_, int ntags, IOVMultiplicity nIOVs>
0624   class SiStripNoiseDistributionComparisonBase : public PlotImage<SiStripNoises, nIOVs, ntags> {
0625   public:
0626     SiStripNoiseDistributionComparisonBase()
0627         : PlotImage<SiStripNoises, nIOVs, ntags>("SiStrip Noise values comparison") {}
0628 
0629     bool fill() override {
0630       TGaxis::SetExponentOffset(-0.1, 0.01, "y");  // X and Y offset for Y axis
0631 
0632       // trick to deal with the multi-ioved tag and two tag case at the same time
0633       auto theIOVs = PlotBase::getTag<0>().iovs;
0634       auto tagname1 = PlotBase::getTag<0>().name;
0635       std::string tagname2 = "";
0636       auto firstiov = theIOVs.front();
0637       SiStripPI::MetaData lastiov;
0638 
0639       // we don't support (yet) comparison with more than 2 tags
0640       assert(this->m_plotAnnotations.ntags < 3);
0641 
0642       if (this->m_plotAnnotations.ntags == 2) {
0643         auto tag2iovs = PlotBase::getTag<1>().iovs;
0644         tagname2 = PlotBase::getTag<1>().name;
0645         lastiov = tag2iovs.front();
0646       } else {
0647         lastiov = theIOVs.back();
0648       }
0649 
0650       std::shared_ptr<SiStripNoises> f_payload = this->fetchPayload(std::get<1>(firstiov));
0651       std::shared_ptr<SiStripNoises> l_payload = this->fetchPayload(std::get<1>(lastiov));
0652 
0653       auto f_mon = std::unique_ptr<SiStripPI::Monitor1D>(new SiStripPI::Monitor1D(
0654           op_mode_,
0655           "f_Noise",
0656           Form(";#LTStrip Noise per %s#GT [ADC counts];n. %ss", opType(op_mode_).c_str(), opType(op_mode_).c_str()),
0657           100,
0658           0.1,
0659           10.));
0660 
0661       auto l_mon = std::unique_ptr<SiStripPI::Monitor1D>(new SiStripPI::Monitor1D(
0662           op_mode_,
0663           "l_Noise",
0664           Form(";#LTStrip Noise per %s#GT [ADC counts];n. %ss", opType(op_mode_).c_str(), opType(op_mode_).c_str()),
0665           100,
0666           0.1,
0667           10.));
0668 
0669       unsigned int prev_det = 0, prev_apv = 0;
0670       SiStripPI::Entry enoise;
0671 
0672       std::vector<uint32_t> f_detid;
0673       f_payload->getDetIds(f_detid);
0674 
0675       // loop on first payload
0676       for (const auto& d : f_detid) {
0677         SiStripNoises::Range range = f_payload->getRange(d);
0678 
0679         unsigned int istrip = 0;
0680         for (int it = 0; it < (range.second - range.first) * 8 / 9; ++it) {
0681           float noise = f_payload->getNoise(it, range);
0682           //to be used to fill the histogram
0683 
0684           bool flush = false;
0685           switch (op_mode_) {
0686             case (SiStripPI::APV_BASED):
0687               flush = (prev_det != 0 && prev_apv != istrip / sistrip::STRIPS_PER_APV);
0688               break;
0689             case (SiStripPI::MODULE_BASED):
0690               flush = (prev_det != 0 && prev_det != d);
0691               break;
0692             case (SiStripPI::STRIP_BASED):
0693               flush = (istrip != 0);
0694               break;
0695           }
0696 
0697           if (flush) {
0698             f_mon->Fill(prev_apv, prev_det, enoise.mean());
0699             enoise.reset();
0700           }
0701           enoise.add(std::min<float>(noise, 30.5));
0702           prev_apv = istrip / sistrip::STRIPS_PER_APV;
0703           istrip++;
0704         }
0705         prev_det = d;
0706       }
0707 
0708       prev_det = 0, prev_apv = 0;
0709       enoise.reset();
0710 
0711       std::vector<uint32_t> l_detid;
0712       l_payload->getDetIds(l_detid);
0713 
0714       // loop on first payload
0715 
0716       for (const auto& d : l_detid) {
0717         SiStripNoises::Range range = l_payload->getRange(d);
0718 
0719         unsigned int istrip = 0;
0720         for (int it = 0; it < (range.second - range.first) * 8 / 9; ++it) {
0721           float noise = l_payload->getNoise(it, range);
0722 
0723           bool flush = false;
0724           switch (op_mode_) {
0725             case (SiStripPI::APV_BASED):
0726               flush = (prev_det != 0 && prev_apv != istrip / sistrip::STRIPS_PER_APV);
0727               break;
0728             case (SiStripPI::MODULE_BASED):
0729               flush = (prev_det != 0 && prev_det != d);
0730               break;
0731             case (SiStripPI::STRIP_BASED):
0732               flush = (istrip != 0);
0733               break;
0734           }
0735 
0736           if (flush) {
0737             l_mon->Fill(prev_apv, prev_det, enoise.mean());
0738             enoise.reset();
0739           }
0740 
0741           enoise.add(std::min<float>(noise, 30.5));
0742           prev_apv = istrip / sistrip::STRIPS_PER_APV;
0743           istrip++;
0744         }
0745         prev_det = d;
0746       }
0747 
0748       auto h_first = f_mon->getHist();
0749       h_first.SetStats(kFALSE);
0750       auto h_last = l_mon->getHist();
0751       h_last.SetStats(kFALSE);
0752 
0753       SiStripPI::makeNicePlotStyle(&h_first);
0754       SiStripPI::makeNicePlotStyle(&h_last);
0755 
0756       h_first.GetYaxis()->CenterTitle(true);
0757       h_last.GetYaxis()->CenterTitle(true);
0758 
0759       h_first.GetXaxis()->CenterTitle(true);
0760       h_last.GetXaxis()->CenterTitle(true);
0761 
0762       h_first.SetLineWidth(2);
0763       h_last.SetLineWidth(2);
0764 
0765       h_first.SetLineColor(kBlack);
0766       h_last.SetLineColor(kBlue);
0767 
0768       //=========================
0769       TCanvas canvas("Partition summary", "partition summary", 1200, 1000);
0770       canvas.cd();
0771       canvas.SetTopMargin(0.06);
0772       canvas.SetBottomMargin(0.10);
0773       canvas.SetLeftMargin(0.13);
0774       canvas.SetRightMargin(0.05);
0775       canvas.Modified();
0776 
0777       float theMax = (h_first.GetMaximum() > h_last.GetMaximum()) ? h_first.GetMaximum() : h_last.GetMaximum();
0778 
0779       h_first.SetMaximum(theMax * 1.20);
0780       h_last.SetMaximum(theMax * 1.20);
0781 
0782       h_first.Draw();
0783       h_last.SetFillColorAlpha(kBlue, 0.15);
0784       h_last.Draw("same");
0785 
0786       TLegend legend = TLegend(0.13, 0.83, 0.95, 0.94);
0787       if (this->m_plotAnnotations.ntags == 2) {
0788         legend.SetHeader("#bf{Two Tags Comparison}", "C");  // option "C" allows to center the header
0789         legend.AddEntry(&h_first, (tagname1 + " : " + std::to_string(std::get<0>(firstiov))).c_str(), "F");
0790         legend.AddEntry(&h_last, (tagname2 + " : " + std::to_string(std::get<0>(lastiov))).c_str(), "F");
0791       } else {
0792         legend.SetHeader(("tag: #bf{" + tagname1 + "}").c_str(), "C");  // option "C" allows to center the header
0793         legend.AddEntry(&h_first, ("IOV since: " + std::to_string(std::get<0>(firstiov))).c_str(), "F");
0794         legend.AddEntry(&h_last, ("IOV since: " + std::to_string(std::get<0>(lastiov))).c_str(), "F");
0795       }
0796       legend.SetTextSize(0.025);
0797       legend.Draw("same");
0798 
0799       auto ltx = TLatex();
0800       ltx.SetTextFont(62);
0801       ltx.SetTextSize(0.05);
0802       ltx.SetTextAlign(11);
0803       ltx.DrawLatexNDC(gPad->GetLeftMargin(),
0804                        1 - gPad->GetTopMargin() + 0.01,
0805                        Form("#LTSiStrip Noise#GT Comparison per %s", opType(op_mode_).c_str()));
0806 
0807       std::string fileName(this->m_imageFileName);
0808       canvas.SaveAs(fileName.c_str());
0809 
0810       return true;
0811     }
0812 
0813     std::string opType(SiStripPI::OpMode mode) {
0814       std::string types[3] = {"Strip", "APV", "Module"};
0815       return types[mode];
0816     }
0817   };
0818 
0819   template <SiStripPI::OpMode op_mode_>
0820   using SiStripNoiseDistributionComparisonSingleTag = SiStripNoiseDistributionComparisonBase<op_mode_, 1, MULTI_IOV>;
0821 
0822   template <SiStripPI::OpMode op_mode_>
0823   using SiStripNoiseDistributionComparisonTwoTags = SiStripNoiseDistributionComparisonBase<op_mode_, 2, SINGLE_IOV>;
0824 
0825   typedef SiStripNoiseDistributionComparisonSingleTag<SiStripPI::STRIP_BASED>
0826       SiStripNoiseValueComparisonPerStripSingleTag;
0827   typedef SiStripNoiseDistributionComparisonSingleTag<SiStripPI::APV_BASED> SiStripNoiseValueComparisonPerAPVSingleTag;
0828   typedef SiStripNoiseDistributionComparisonSingleTag<SiStripPI::MODULE_BASED>
0829       SiStripNoiseValueComparisonPerModuleSingleTag;
0830 
0831   typedef SiStripNoiseDistributionComparisonTwoTags<SiStripPI::STRIP_BASED> SiStripNoiseValueComparisonPerStripTwoTags;
0832   typedef SiStripNoiseDistributionComparisonTwoTags<SiStripPI::APV_BASED> SiStripNoiseValueComparisonPerAPVTwoTags;
0833   typedef SiStripNoiseDistributionComparisonTwoTags<SiStripPI::MODULE_BASED> SiStripNoiseValueComparisonPerModuleTwoTags;
0834 
0835   /************************************************
0836     1d histogram comparison of SiStripNoises of 1 IOV 
0837   *************************************************/
0838 
0839   // inherit from one of the predefined plot class: PlotImage
0840 
0841   template <int ntags, IOVMultiplicity nIOVs>
0842   class SiStripNoiseValueComparisonBase : public PlotImage<SiStripNoises, nIOVs, ntags> {
0843   public:
0844     SiStripNoiseValueComparisonBase() : PlotImage<SiStripNoises, nIOVs, ntags>("SiStrip Noise values comparison") {}
0845 
0846     bool fill() override {
0847       TGaxis::SetExponentOffset(-0.1, 0.01, "y");  // X and Y offset for Y axis
0848 
0849       // trick to deal with the multi-ioved tag and two tag case at the same time
0850       auto theIOVs = PlotBase::getTag<0>().iovs;
0851       auto tagname1 = PlotBase::getTag<0>().name;
0852       std::string tagname2 = "";
0853       auto firstiov = theIOVs.front();
0854       SiStripPI::MetaData lastiov;
0855 
0856       // we don't support (yet) comparison with more than 2 tags
0857       assert(this->m_plotAnnotations.ntags < 3);
0858 
0859       if (this->m_plotAnnotations.ntags == 2) {
0860         auto tag2iovs = PlotBase::getTag<1>().iovs;
0861         tagname2 = PlotBase::getTag<1>().name;
0862         lastiov = tag2iovs.front();
0863       } else {
0864         lastiov = theIOVs.back();
0865       }
0866 
0867       std::shared_ptr<SiStripNoises> f_payload = this->fetchPayload(std::get<1>(firstiov));
0868       std::shared_ptr<SiStripNoises> l_payload = this->fetchPayload(std::get<1>(lastiov));
0869 
0870       auto h_first = std::make_unique<TH1F>("f_Noise", ";Strip Noise [ADC counts];n. strips", 100, 0.1, 10.);
0871       h_first->SetStats(false);
0872 
0873       auto h_last = std::make_unique<TH1F>("l_Noise", ";Strip Noise [ADC counts];n. strips", 100, 0.1, 10.);
0874       h_last->SetStats(false);
0875 
0876       std::vector<uint32_t> f_detid;
0877       f_payload->getDetIds(f_detid);
0878 
0879       // loop on first payload
0880       for (const auto& d : f_detid) {
0881         SiStripNoises::Range range = f_payload->getRange(d);
0882         for (int it = 0; it < (range.second - range.first) * 8 / 9; ++it) {
0883           float noise = f_payload->getNoise(it, range);
0884           //to be used to fill the histogram
0885           h_first->Fill(noise);
0886         }  // loop over strips
0887       }
0888 
0889       std::vector<uint32_t> l_detid;
0890       l_payload->getDetIds(l_detid);
0891 
0892       // loop on first payload
0893       for (const auto& d : l_detid) {
0894         SiStripNoises::Range range = l_payload->getRange(d);
0895         for (int it = 0; it < (range.second - range.first) * 8 / 9; ++it) {
0896           float noise = l_payload->getNoise(it, range);
0897           //to be used to fill the histogram
0898           h_last->Fill(noise);
0899         }  // loop over strips
0900       }
0901 
0902       SiStripPI::makeNicePlotStyle(h_first.get());
0903       SiStripPI::makeNicePlotStyle(h_last.get());
0904 
0905       h_first->GetYaxis()->CenterTitle(true);
0906       h_last->GetYaxis()->CenterTitle(true);
0907 
0908       h_first->GetXaxis()->CenterTitle(true);
0909       h_last->GetXaxis()->CenterTitle(true);
0910 
0911       h_first->SetLineWidth(2);
0912       h_last->SetLineWidth(2);
0913 
0914       h_first->SetLineColor(kBlack);
0915       h_last->SetLineColor(kBlue);
0916 
0917       //=========================
0918       TCanvas canvas("Partition summary", "partition summary", 1200, 1000);
0919       canvas.cd();
0920       canvas.SetTopMargin(0.06);
0921       canvas.SetBottomMargin(0.10);
0922       canvas.SetLeftMargin(0.13);
0923       canvas.SetRightMargin(0.05);
0924       canvas.Modified();
0925 
0926       float theMax = (h_first->GetMaximum() > h_last->GetMaximum()) ? h_first->GetMaximum() : h_last->GetMaximum();
0927 
0928       h_first->SetMaximum(theMax * 1.20);
0929       h_last->SetMaximum(theMax * 1.20);
0930 
0931       h_first->Draw();
0932       h_last->SetFillColorAlpha(kBlue, 0.15);
0933       h_last->Draw("same");
0934 
0935       TLegend legend = TLegend(0.13, 0.83, 0.95, 0.94);
0936       if (this->m_plotAnnotations.ntags == 2) {
0937         legend.SetHeader("#bf{Two Tags Comparison}", "C");  // option "C" allows to center the header
0938         legend.AddEntry(h_first.get(), (tagname1 + " : " + std::to_string(std::get<0>(firstiov))).c_str(), "F");
0939         legend.AddEntry(h_last.get(), (tagname2 + " : " + std::to_string(std::get<0>(lastiov))).c_str(), "F");
0940       } else {
0941         legend.SetHeader(("tag: #bf{" + tagname1 + "}").c_str(), "C");  // option "C" allows to center the header
0942         legend.AddEntry(h_first.get(), ("IOV since: " + std::to_string(std::get<0>(firstiov))).c_str(), "F");
0943         legend.AddEntry(h_last.get(), ("IOV since: " + std::to_string(std::get<0>(lastiov))).c_str(), "F");
0944       }
0945       legend.SetTextSize(0.025);
0946       legend.Draw("same");
0947 
0948       auto ltx = TLatex();
0949       ltx.SetTextFont(62);
0950       ltx.SetTextSize(0.05);
0951       ltx.SetTextAlign(11);
0952       ltx.DrawLatexNDC(gPad->GetLeftMargin(), 1 - gPad->GetTopMargin() + 0.01, "SiStrip Noise Values Comparison");
0953 
0954       std::string fileName(this->m_imageFileName);
0955       canvas.SaveAs(fileName.c_str());
0956 
0957       return true;
0958     }
0959   };
0960 
0961   using SiStripNoiseValueComparisonSingleTag = SiStripNoiseValueComparisonBase<1, MULTI_IOV>;
0962   using SiStripNoiseValueComparisonTwoTags = SiStripNoiseValueComparisonBase<2, SINGLE_IOV>;
0963 
0964   /************************************************
0965     SiStrip Noise Tracker Map 
0966   *************************************************/
0967 
0968   template <SiStripPI::estimator est>
0969   class SiStripNoiseTrackerMap : public PlotImage<SiStripNoises, SINGLE_IOV> {
0970   public:
0971     SiStripNoiseTrackerMap()
0972         : PlotImage<SiStripNoises, SINGLE_IOV>("Tracker Map of SiStripNoise " + estimatorType(est) + " per module") {}
0973 
0974     bool fill() override {
0975       auto tag = PlotBase::getTag<0>();
0976       auto iov = tag.iovs.front();
0977       std::shared_ptr<SiStripNoises> payload = fetchPayload(std::get<1>(iov));
0978 
0979       std::string titleMap =
0980           "Tracker Map of Noise " + estimatorType(est) + " per module (payload : " + std::get<1>(iov) + ")";
0981 
0982       std::unique_ptr<TrackerMap> tmap = std::make_unique<TrackerMap>("SiStripNoises");
0983       tmap->setTitle(titleMap);
0984       tmap->setPalette(1);
0985 
0986       // storage of info
0987       std::map<unsigned int, float> info_per_detid;
0988 
0989       SiStripNoises::RegistryIterator rit = payload->getRegistryVectorBegin(), erit = payload->getRegistryVectorEnd();
0990       uint16_t Nstrips;
0991       std::vector<float> vstripnoise;
0992       double mean, rms, min, max;
0993       for (; rit != erit; ++rit) {
0994         Nstrips =
0995             (rit->iend - rit->ibegin) * 8 / 9;  //number of strips = number of chars * char size / strip noise size
0996         vstripnoise.resize(Nstrips);
0997         payload->allNoises(
0998             vstripnoise,
0999             make_pair(payload->getDataVectorBegin() + rit->ibegin, payload->getDataVectorBegin() + rit->iend));
1000         mean = 0;
1001         rms = 0;
1002         min = 10000;
1003         max = 0;
1004 
1005         DetId detId(rit->detid);
1006 
1007         for (size_t i = 0; i < Nstrips; ++i) {
1008           mean += vstripnoise[i];
1009           rms += vstripnoise[i] * vstripnoise[i];
1010           if (vstripnoise[i] < min)
1011             min = vstripnoise[i];
1012           if (vstripnoise[i] > max)
1013             max = vstripnoise[i];
1014         }
1015 
1016         mean /= Nstrips;
1017         if ((rms / Nstrips - mean * mean) > 0.) {
1018           rms = sqrt(rms / Nstrips - mean * mean);
1019         } else {
1020           rms = 0.;
1021         }
1022 
1023         switch (est) {
1024           case SiStripPI::min:
1025             info_per_detid[rit->detid] = min;
1026             break;
1027           case SiStripPI::max:
1028             info_per_detid[rit->detid] = max;
1029             break;
1030           case SiStripPI::mean:
1031             info_per_detid[rit->detid] = mean;
1032             break;
1033           case SiStripPI::rms:
1034             info_per_detid[rit->detid] = rms;
1035             break;
1036           default:
1037             edm::LogWarning("LogicError") << "Unknown estimator: " << est;
1038             break;
1039         }
1040       }
1041 
1042       // loop on the map
1043       for (const auto& item : info_per_detid) {
1044         tmap->fill(item.first, item.second);
1045       }
1046 
1047       auto range = SiStripPI::getTheRange(info_per_detid, 2);
1048 
1049       //=========================
1050 
1051       std::string fileName(m_imageFileName);
1052       if (est == SiStripPI::rms && (range.first < 0.)) {
1053         tmap->save(true, 0., range.second, fileName);
1054       } else {
1055         tmap->save(true, range.first, range.second, fileName);
1056       }
1057 
1058       return true;
1059     }
1060   };
1061 
1062   typedef SiStripNoiseTrackerMap<SiStripPI::min> SiStripNoiseMin_TrackerMap;
1063   typedef SiStripNoiseTrackerMap<SiStripPI::max> SiStripNoiseMax_TrackerMap;
1064   typedef SiStripNoiseTrackerMap<SiStripPI::mean> SiStripNoiseMean_TrackerMap;
1065   typedef SiStripNoiseTrackerMap<SiStripPI::rms> SiStripNoiseRMS_TrackerMap;
1066 
1067   /************************************************
1068     SiStrip Noise Tracker Map  (ratio with previous gain per detid)
1069   *************************************************/
1070 
1071   template <SiStripPI::estimator est, int ntags, IOVMultiplicity nIOVs>
1072   class SiStripNoiseRatioWithPreviousIOVTrackerMapBase : public PlotImage<SiStripNoises, nIOVs, ntags> {
1073   public:
1074     SiStripNoiseRatioWithPreviousIOVTrackerMapBase()
1075         : PlotImage<SiStripNoises, nIOVs, ntags>("Tracker Map of ratio of SiStripNoises " + estimatorType(est) +
1076                                                  "with previous IOV") {
1077       PlotBase::addInputParam("nsigma");
1078     }
1079 
1080     std::map<unsigned int, float> computeEstimator(std::shared_ptr<SiStripNoises> payload) {
1081       std::map<unsigned int, float> info_per_detid;
1082       SiStripNoises::RegistryIterator rit = payload->getRegistryVectorBegin(), erit = payload->getRegistryVectorEnd();
1083       uint16_t Nstrips;
1084       std::vector<float> vstripnoise;
1085       double mean, rms, min, max;
1086       for (; rit != erit; ++rit) {
1087         Nstrips =
1088             (rit->iend - rit->ibegin) * 8 / 9;  //number of strips = number of chars * char size / strip noise size
1089         vstripnoise.resize(Nstrips);
1090         payload->allNoises(
1091             vstripnoise,
1092             make_pair(payload->getDataVectorBegin() + rit->ibegin, payload->getDataVectorBegin() + rit->iend));
1093         mean = 0;
1094         rms = 0;
1095         min = 10000;
1096         max = 0;
1097 
1098         DetId detId(rit->detid);
1099 
1100         for (size_t i = 0; i < Nstrips; ++i) {
1101           mean += vstripnoise[i];
1102           rms += vstripnoise[i] * vstripnoise[i];
1103           if (vstripnoise[i] < min)
1104             min = vstripnoise[i];
1105           if (vstripnoise[i] > max)
1106             max = vstripnoise[i];
1107         }
1108 
1109         mean /= Nstrips;
1110         if ((rms / Nstrips - mean * mean) > 0.) {
1111           rms = sqrt(rms / Nstrips - mean * mean);
1112         } else {
1113           rms = 0.;
1114         }
1115         switch (est) {
1116           case SiStripPI::min:
1117             info_per_detid[rit->detid] = min;
1118             break;
1119           case SiStripPI::max:
1120             info_per_detid[rit->detid] = max;
1121             break;
1122           case SiStripPI::mean:
1123             info_per_detid[rit->detid] = mean;
1124             break;
1125           case SiStripPI::rms:
1126             info_per_detid[rit->detid] = rms;
1127             break;
1128           default:
1129             edm::LogWarning("LogicError") << "Unknown estimator: " << est;
1130             break;
1131         }
1132       }
1133       return info_per_detid;
1134     }
1135 
1136     bool fill() override {
1137       unsigned int nsigma(1);
1138 
1139       auto paramValues = PlotBase::inputParamValues();
1140       auto ip = paramValues.find("nsigma");
1141       if (ip != paramValues.end()) {
1142         nsigma = std::stoul(ip->second);
1143       }
1144 
1145       // trick to deal with the multi-ioved tag and two tag case at the same time
1146       auto theIOVs = PlotBase::getTag<0>().iovs;
1147       auto tagname1 = PlotBase::getTag<0>().name;
1148       std::string tagname2 = "";
1149       auto firstiov = theIOVs.front();
1150       SiStripPI::MetaData lastiov;
1151 
1152       // we don't support (yet) comparison with more than 2 tags
1153       assert(this->m_plotAnnotations.ntags < 3);
1154 
1155       if (this->m_plotAnnotations.ntags == 2) {
1156         auto tag2iovs = PlotBase::getTag<1>().iovs;
1157         tagname2 = PlotBase::getTag<1>().name;
1158         lastiov = tag2iovs.front();
1159       } else {
1160         lastiov = theIOVs.back();
1161       }
1162 
1163       std::shared_ptr<SiStripNoises> last_payload = this->fetchPayload(std::get<1>(lastiov));
1164       std::shared_ptr<SiStripNoises> first_payload = this->fetchPayload(std::get<1>(firstiov));
1165 
1166       std::string titleMap = "SiStripNoise " + estimatorType(est) + " ratio per module average (IOV: ";
1167 
1168       titleMap += std::to_string(std::get<0>(firstiov));
1169       titleMap += "/ IOV:";
1170       titleMap += std::to_string(std::get<0>(lastiov));
1171       titleMap += ")";
1172       titleMap += +" " + std::to_string(nsigma) + " std. dev. saturation";
1173 
1174       std::unique_ptr<TrackerMap> tmap = std::make_unique<TrackerMap>("SiStripNoises");
1175       tmap->setTitle(titleMap);
1176       tmap->setPalette(1);
1177 
1178       std::map<unsigned int, float> map_first, map_second;
1179 
1180       map_first = computeEstimator(first_payload);
1181       map_second = computeEstimator(last_payload);
1182       std::map<unsigned int, float> cachedRatio;
1183 
1184       for (auto entry : map_first) {
1185         auto it2 = map_second.find(entry.first);
1186         if (it2 == map_second.end() || it2->second == 0)
1187           continue;
1188         tmap->fill(entry.first, entry.second / it2->second);
1189         cachedRatio[entry.first] = (entry.second / it2->second);
1190       }
1191 
1192       auto range = SiStripPI::getTheRange(cachedRatio, nsigma);
1193       std::string fileName(this->m_imageFileName);
1194       if (est == SiStripPI::rms && (range.first < 0.)) {
1195         tmap->save(true, 0., range.second, fileName);
1196       } else {
1197         tmap->save(true, range.first, range.second, fileName);
1198       }
1199 
1200       return true;
1201     }
1202   };
1203 
1204   template <SiStripPI::estimator est>
1205   using SiStripNoiseRatioWithPreviousIOVTrackerMapSingleTag =
1206       SiStripNoiseRatioWithPreviousIOVTrackerMapBase<est, 1, MULTI_IOV>;
1207 
1208   template <SiStripPI::estimator est>
1209   using SiStripNoiseRatioWithPreviousIOVTrackerMapTwoTags =
1210       SiStripNoiseRatioWithPreviousIOVTrackerMapBase<est, 2, SINGLE_IOV>;
1211 
1212   typedef SiStripNoiseRatioWithPreviousIOVTrackerMapSingleTag<SiStripPI::min>
1213       SiStripNoiseMin_RatioWithPreviousIOVTrackerMapSingleTag;
1214   typedef SiStripNoiseRatioWithPreviousIOVTrackerMapSingleTag<SiStripPI::max>
1215       SiStripNoiseMax_RatioWithPreviousIOVTrackerMapSingleTag;
1216   typedef SiStripNoiseRatioWithPreviousIOVTrackerMapSingleTag<SiStripPI::mean>
1217       SiStripNoiseMean_RatioWithPreviousIOVTrackerMapSingleTag;
1218   typedef SiStripNoiseRatioWithPreviousIOVTrackerMapSingleTag<SiStripPI::rms>
1219       SiStripNoiseRms_RatioWithPreviousIOVTrackerMapSingleTag;
1220 
1221   typedef SiStripNoiseRatioWithPreviousIOVTrackerMapTwoTags<SiStripPI::min>
1222       SiStripNoiseMin_RatioWithPreviousIOVTrackerMapTwoTags;
1223   typedef SiStripNoiseRatioWithPreviousIOVTrackerMapTwoTags<SiStripPI::max>
1224       SiStripNoiseMax_RatioWithPreviousIOVTrackerMapTwoTags;
1225   typedef SiStripNoiseRatioWithPreviousIOVTrackerMapTwoTags<SiStripPI::mean>
1226       SiStripNoiseMean_RatioWithPreviousIOVTrackerMapTwoTags;
1227   typedef SiStripNoiseRatioWithPreviousIOVTrackerMapTwoTags<SiStripPI::rms>
1228       SiStripNoiseRms_RatioWithPreviousIOVTrackerMapTwoTags;
1229 
1230   /************************************************
1231   SiStrip Noise Tracker Summaries 
1232   *************************************************/
1233 
1234   template <SiStripPI::estimator est>
1235   class SiStripNoiseByRegion : public PlotImage<SiStripNoises, SINGLE_IOV> {
1236   public:
1237     SiStripNoiseByRegion()
1238         : PlotImage<SiStripNoises, SINGLE_IOV>("SiStrip Noise " + estimatorType(est) + " by Region"),
1239           m_trackerTopo{StandaloneTrackerTopology::fromTrackerParametersXMLFile(
1240               edm::FileInPath("Geometry/TrackerCommonData/data/trackerParameters.xml").fullPath())} {}
1241 
1242     bool fill() override {
1243       auto tag = PlotBase::getTag<0>();
1244       auto iov = tag.iovs.front();
1245       std::shared_ptr<SiStripNoises> payload = fetchPayload(std::get<1>(iov));
1246 
1247       SiStripDetSummary summaryNoise{&m_trackerTopo};
1248 
1249       SiStripPI::fillNoiseDetSummary(summaryNoise, payload, est);
1250 
1251       std::map<unsigned int, SiStripDetSummary::Values> map = summaryNoise.getCounts();
1252       //=========================
1253 
1254       TCanvas canvas("Partition summary", "partition summary", 1200, 1000);
1255       canvas.cd();
1256       auto h1 = std::unique_ptr<TH1F>(
1257           new TH1F("byRegion",
1258                    Form("Average by partition of %s SiStrip Noise per module;;average SiStrip Noise %s [ADC counts]",
1259                         estimatorType(est).c_str(),
1260                         estimatorType(est).c_str()),
1261                    map.size(),
1262                    0.,
1263                    map.size()));
1264       h1->SetStats(false);
1265       canvas.SetBottomMargin(0.18);
1266       canvas.SetLeftMargin(0.17);
1267       canvas.SetRightMargin(0.05);
1268       canvas.Modified();
1269 
1270       std::vector<int> boundaries;
1271       unsigned int iBin = 0;
1272 
1273       std::string detector;
1274       std::string currentDetector;
1275 
1276       for (const auto& element : map) {
1277         iBin++;
1278         int count = element.second.count;
1279         double mean = (element.second.mean) / count;
1280         double rms = (element.second.rms) / count - mean * mean;
1281 
1282         if (rms <= 0)
1283           rms = 0;
1284         else
1285           rms = sqrt(rms);
1286 
1287         if (currentDetector.empty())
1288           currentDetector = "TIB";
1289 
1290         switch ((element.first) / 1000) {
1291           case 1:
1292             detector = "TIB";
1293             break;
1294           case 2:
1295             detector = "TOB";
1296             break;
1297           case 3:
1298             detector = "TEC";
1299             break;
1300           case 4:
1301             detector = "TID";
1302             break;
1303         }
1304 
1305         h1->SetBinContent(iBin, mean);
1306         h1->GetXaxis()->SetBinLabel(iBin, SiStripPI::regionType(element.first).second);
1307         h1->GetXaxis()->LabelsOption("v");
1308 
1309         if (detector != currentDetector) {
1310           boundaries.push_back(iBin);
1311           currentDetector = detector;
1312         }
1313       }
1314 
1315       h1->SetMarkerStyle(20);
1316       h1->SetMarkerSize(1);
1317       h1->SetMaximum(h1->GetMaximum() * 1.1);
1318       h1->Draw("HIST");
1319       h1->Draw("Psame");
1320 
1321       canvas.Update();
1322 
1323       TLine l[boundaries.size()];
1324       unsigned int i = 0;
1325 
1326       for (const auto& line : boundaries) {
1327         l[i] = TLine(h1->GetBinLowEdge(line), canvas.GetUymin(), h1->GetBinLowEdge(line), canvas.GetUymax());
1328         l[i].SetLineWidth(1);
1329         l[i].SetLineStyle(9);
1330         l[i].SetLineColor(2);
1331         l[i].Draw("same");
1332         i++;
1333       }
1334 
1335       TLegend legend = TLegend(0.52, 0.82, 0.95, 0.9);
1336       legend.SetHeader((std::get<1>(iov)).c_str(), "C");  // option "C" allows to center the header
1337       legend.AddEntry(h1.get(), ("IOV: " + std::to_string(std::get<0>(iov))).c_str(), "PL");
1338       legend.SetTextSize(0.025);
1339       legend.Draw("same");
1340 
1341       std::string fileName(m_imageFileName);
1342       canvas.SaveAs(fileName.c_str());
1343 
1344       return true;
1345     }
1346 
1347   private:
1348     TrackerTopology m_trackerTopo;
1349   };
1350 
1351   typedef SiStripNoiseByRegion<SiStripPI::mean> SiStripNoiseMeanByRegion;
1352   typedef SiStripNoiseByRegion<SiStripPI::min> SiStripNoiseMinByRegion;
1353   typedef SiStripNoiseByRegion<SiStripPI::max> SiStripNoiseMaxByRegion;
1354   typedef SiStripNoiseByRegion<SiStripPI::rms> SiStripNoiseRMSByRegion;
1355 
1356   /************************************************
1357   SiStrip Noise Comparator
1358   *************************************************/
1359 
1360   template <SiStripPI::estimator est, int ntags, IOVMultiplicity nIOVs>
1361   class SiStripNoiseComparatorByRegionBase : public PlotImage<SiStripNoises, nIOVs, ntags> {
1362   public:
1363     SiStripNoiseComparatorByRegionBase()
1364         : PlotImage<SiStripNoises, nIOVs, ntags>("SiStrip Noise " + estimatorType(est) + " comparator by Region"),
1365           m_trackerTopo{StandaloneTrackerTopology::fromTrackerParametersXMLFile(
1366               edm::FileInPath("Geometry/TrackerCommonData/data/trackerParameters.xml").fullPath())} {}
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<SiStripNoises> f_payload = this->fetchPayload(std::get<1>(firstiov));
1388       std::shared_ptr<SiStripNoises> l_payload = this->fetchPayload(std::get<1>(lastiov));
1389 
1390       SiStripDetSummary f_summaryNoise{&m_trackerTopo};
1391       SiStripDetSummary l_summaryNoise{&m_trackerTopo};
1392 
1393       SiStripPI::fillNoiseDetSummary(f_summaryNoise, f_payload, est);
1394       SiStripPI::fillNoiseDetSummary(l_summaryNoise, l_payload, est);
1395 
1396       std::map<unsigned int, SiStripDetSummary::Values> f_map = f_summaryNoise.getCounts();
1397       std::map<unsigned int, SiStripDetSummary::Values> l_map = l_summaryNoise.getCounts();
1398 
1399       //=========================
1400       TCanvas canvas("Partition summary", "partition summary", 1200, 1000);
1401       canvas.cd();
1402 
1403       auto hfirst = std::unique_ptr<TH1F>(
1404           new TH1F("f_byRegion",
1405                    Form("Average by partition of %s SiStrip Noise per module;;average SiStrip Noise %s [ADC counts]",
1406                         estimatorType(est).c_str(),
1407                         estimatorType(est).c_str()),
1408                    f_map.size(),
1409                    0.,
1410                    f_map.size()));
1411       hfirst->SetStats(false);
1412 
1413       auto hlast = std::unique_ptr<TH1F>(
1414           new TH1F("l_byRegion",
1415                    Form("Average by partition of %s SiStrip Noise per module;;average SiStrip Noise %s [ADC counts]",
1416                         estimatorType(est).c_str(),
1417                         estimatorType(est).c_str()),
1418                    l_map.size(),
1419                    0.,
1420                    l_map.size()));
1421       hlast->SetStats(false);
1422 
1423       canvas.SetBottomMargin(0.18);
1424       canvas.SetLeftMargin(0.17);
1425       canvas.SetRightMargin(0.05);
1426       canvas.Modified();
1427 
1428       std::vector<int> boundaries;
1429       unsigned int iBin = 0;
1430 
1431       std::string detector;
1432       std::string currentDetector;
1433 
1434       for (const auto& element : f_map) {
1435         iBin++;
1436         int count = element.second.count;
1437         double mean = (element.second.mean) / count;
1438         double rms = (element.second.rms) / count - mean * mean;
1439 
1440         if (rms <= 0)
1441           rms = 0;
1442         else
1443           rms = sqrt(rms);
1444 
1445         if (currentDetector.empty())
1446           currentDetector = "TIB";
1447 
1448         switch ((element.first) / 1000) {
1449           case 1:
1450             detector = "TIB";
1451             break;
1452           case 2:
1453             detector = "TOB";
1454             break;
1455           case 3:
1456             detector = "TEC";
1457             break;
1458           case 4:
1459             detector = "TID";
1460             break;
1461         }
1462 
1463         hfirst->SetBinContent(iBin, mean);
1464         //hfirst->SetBinError(iBin,rms);
1465         hfirst->GetXaxis()->SetBinLabel(iBin, SiStripPI::regionType(element.first).second);
1466         hfirst->GetXaxis()->LabelsOption("v");
1467 
1468         if (detector != currentDetector) {
1469           boundaries.push_back(iBin);
1470           currentDetector = detector;
1471         }
1472       }
1473 
1474       // second payload
1475       // reset the counter
1476       iBin = 0;
1477 
1478       for (const auto& element : l_map) {
1479         iBin++;
1480         int count = element.second.count;
1481         double mean = (element.second.mean) / count;
1482         double rms = (element.second.rms) / count - mean * mean;
1483 
1484         if (rms <= 0)
1485           rms = 0;
1486         else
1487           rms = sqrt(rms);
1488 
1489         hlast->SetBinContent(iBin, mean);
1490         //hlast->SetBinError(iBin,rms);
1491         hlast->GetXaxis()->SetBinLabel(iBin, SiStripPI::regionType(element.first).second);
1492         hlast->GetXaxis()->LabelsOption("v");
1493       }
1494 
1495       float theMax = (hfirst->GetMaximum() > hlast->GetMaximum()) ? hfirst->GetMaximum() : hlast->GetMaximum();
1496       float theMin = (hfirst->GetMinimum() < hlast->GetMinimum()) ? hfirst->GetMinimum() : hlast->GetMinimum();
1497 
1498       hfirst->SetMarkerStyle(20);
1499       hfirst->SetMarkerSize(1);
1500       hfirst->GetYaxis()->SetTitleOffset(1.3);
1501       hfirst->GetYaxis()->SetRangeUser(theMin * 0.9, theMax * 1.1);
1502       hfirst->Draw("HIST");
1503       hfirst->Draw("Psame");
1504 
1505       hlast->SetMarkerStyle(21);
1506       hlast->SetMarkerSize(1);
1507       hlast->SetMarkerColor(kBlue);
1508       hlast->SetLineColor(kBlue);
1509       hlast->GetYaxis()->SetTitleOffset(1.3);
1510       hlast->GetYaxis()->SetRangeUser(theMin * 0.9, theMax * 1.1);
1511       hlast->Draw("HISTsame");
1512       hlast->Draw("Psame");
1513 
1514       canvas.Update();
1515 
1516       TLine l[boundaries.size()];
1517       unsigned int i = 0;
1518 
1519       for (const auto& line : boundaries) {
1520         l[i] = TLine(hfirst->GetBinLowEdge(line), canvas.GetUymin(), hfirst->GetBinLowEdge(line), canvas.GetUymax());
1521         l[i].SetLineWidth(1);
1522         l[i].SetLineStyle(9);
1523         l[i].SetLineColor(2);
1524         l[i].Draw("same");
1525         i++;
1526       }
1527 
1528       TLegend legend = TLegend(0.52, 0.82, 0.95, 0.9);
1529       legend.SetHeader(("SiStrip Noise " + estimatorType(est) + " by region").c_str(),
1530                        "C");  // option "C" allows to center the header
1531       legend.AddEntry(hfirst.get(), ("IOV: " + std::to_string(std::get<0>(firstiov))).c_str(), "PL");
1532       legend.AddEntry(hlast.get(), ("IOV: " + std::to_string(std::get<0>(lastiov))).c_str(), "PL");
1533       legend.SetTextSize(0.025);
1534       legend.Draw("same");
1535 
1536       std::string fileName(this->m_imageFileName);
1537       canvas.SaveAs(fileName.c_str());
1538 
1539       return true;
1540     }
1541 
1542   private:
1543     TrackerTopology m_trackerTopo;
1544   };
1545 
1546   template <SiStripPI::estimator est>
1547   using SiStripNoiseComparatorByRegionSingleTag = SiStripNoiseComparatorByRegionBase<est, 1, MULTI_IOV>;
1548 
1549   template <SiStripPI::estimator est>
1550   using SiStripNoiseComparatorByRegionTwoTags = SiStripNoiseComparatorByRegionBase<est, 2, SINGLE_IOV>;
1551 
1552   typedef SiStripNoiseComparatorByRegionSingleTag<SiStripPI::mean> SiStripNoiseComparatorMeanByRegionSingleTag;
1553   typedef SiStripNoiseComparatorByRegionSingleTag<SiStripPI::min> SiStripNoiseComparatorMinByRegionSingleTag;
1554   typedef SiStripNoiseComparatorByRegionSingleTag<SiStripPI::max> SiStripNoiseComparatorMaxByRegionSingleTag;
1555   typedef SiStripNoiseComparatorByRegionSingleTag<SiStripPI::rms> SiStripNoiseComparatorRMSByRegionSingleTag;
1556 
1557   typedef SiStripNoiseComparatorByRegionTwoTags<SiStripPI::mean> SiStripNoiseComparatorMeanByRegionTwoTags;
1558   typedef SiStripNoiseComparatorByRegionTwoTags<SiStripPI::min> SiStripNoiseComparatorMinByRegionTwoTags;
1559   typedef SiStripNoiseComparatorByRegionTwoTags<SiStripPI::max> SiStripNoiseComparatorMaxByRegionTwoTags;
1560   typedef SiStripNoiseComparatorByRegionTwoTags<SiStripPI::rms> SiStripNoiseComparatorRMSByRegionTwoTags;
1561 
1562   /************************************************
1563     Noise linearity
1564   *************************************************/
1565   class SiStripNoiseLinearity : public PlotImage<SiStripNoises, SINGLE_IOV> {
1566   public:
1567     SiStripNoiseLinearity()
1568         : PlotImage<SiStripNoises, SINGLE_IOV>("Linearity of Strip Noise as a fuction of strip length") {}
1569 
1570     bool fill() override {
1571       auto tag = PlotBase::getTag<0>();
1572       auto iov = tag.iovs.front();
1573       std::shared_ptr<SiStripNoises> payload = fetchPayload(std::get<1>(iov));
1574 
1575       const auto detInfo =
1576           SiStripDetInfoFileReader::read(edm::FileInPath(SiStripDetInfoFileReader::kDefaultFile).fullPath());
1577 
1578       std::vector<uint32_t> detid;
1579       payload->getDetIds(detid);
1580 
1581       std::map<float, std::tuple<int, float, float>> noisePerStripLength;
1582 
1583       for (const auto& d : detid) {
1584         SiStripNoises::Range range = payload->getRange(d);
1585         for (int it = 0; it < (range.second - range.first) * 8 / 9; ++it) {
1586           auto noise = payload->getNoise(it, range);
1587           //to be used to fill the histogram
1588           float stripL = detInfo.getNumberOfApvsAndStripLength(d).second;
1589           std::get<0>(noisePerStripLength[stripL]) += 1;
1590           std::get<1>(noisePerStripLength[stripL]) += noise;
1591           std::get<2>(noisePerStripLength[stripL]) += (noise * noise);
1592         }  // loop over strips
1593       }    // loop over detIds
1594 
1595       TCanvas canvas("Noise linearity", "noise linearity", 1200, 1000);
1596       canvas.cd();
1597 
1598       std::vector<float> x;
1599       x.reserve(noisePerStripLength.size());
1600       std::vector<float> y;
1601       y.reserve(noisePerStripLength.size());
1602       std::vector<float> ex;
1603       ex.reserve(noisePerStripLength.size());
1604       std::vector<float> ey;
1605       ey.reserve(noisePerStripLength.size());
1606 
1607       for (const auto& element : noisePerStripLength) {
1608         x.push_back(element.first);
1609         ex.push_back(0.);
1610         float sum = std::get<1>(element.second);
1611         float sum2 = std::get<2>(element.second);
1612         float nstrips = std::get<0>(element.second);
1613         float mean = sum / nstrips;
1614         float rms = (sum2 / nstrips - mean * mean) > 0. ? sqrt(sum2 / nstrips - mean * mean) : 0.;
1615         y.push_back(mean);
1616         ey.push_back(rms);
1617         //std::cout<<" strip lenght: " << element.first << " avg noise=" << mean <<" +/-" << rms << std::endl;
1618       }
1619 
1620       auto graph = std::make_unique<TGraphErrors>(noisePerStripLength.size(), &x[0], &y[0], &ex[0], &ey[0]);
1621       graph->SetTitle("SiStrip Noise Linearity");
1622       graph->GetXaxis()->SetTitle("Strip length [cm]");
1623       graph->GetYaxis()->SetTitle("Average Strip Noise [ADC counts]");
1624       graph->SetMarkerColor(kBlue);
1625       graph->SetMarkerStyle(20);
1626       graph->SetMarkerSize(1.5);
1627       canvas.SetBottomMargin(0.13);
1628       canvas.SetLeftMargin(0.17);
1629       canvas.SetTopMargin(0.08);
1630       canvas.SetRightMargin(0.05);
1631       canvas.Modified();
1632       canvas.cd();
1633 
1634       graph->GetXaxis()->CenterTitle(true);
1635       graph->GetYaxis()->CenterTitle(true);
1636       graph->GetXaxis()->SetTitleFont(42);
1637       graph->GetYaxis()->SetTitleFont(42);
1638       graph->GetXaxis()->SetTitleSize(0.05);
1639       graph->GetYaxis()->SetTitleSize(0.05);
1640       graph->GetXaxis()->SetTitleOffset(1.1);
1641       graph->GetYaxis()->SetTitleOffset(1.3);
1642       graph->GetXaxis()->SetLabelFont(42);
1643       graph->GetYaxis()->SetLabelFont(42);
1644       graph->GetYaxis()->SetLabelSize(.05);
1645       graph->GetXaxis()->SetLabelSize(.05);
1646 
1647       graph->Draw("AP");
1648       graph->Fit("pol1");
1649       //Access the fit resuts
1650       TF1* f1 = graph->GetFunction("pol1");
1651       f1->SetLineWidth(2);
1652       f1->SetLineColor(kBlue);
1653       f1->Draw("same");
1654 
1655       auto fits = std::make_unique<TPaveText>(0.2, 0.72, 0.6, 0.9, "NDC");
1656       char buffer[255];
1657       sprintf(buffer, "fit function: p_{0} + p_{1} * l_{strip}");
1658       fits->AddText(buffer);
1659       sprintf(buffer, "p_{0} : %5.2f [ADC counts]", f1->GetParameter(0));
1660       fits->AddText(buffer);
1661       sprintf(buffer, "p_{1} : %5.2f [ADC counts/cm]", f1->GetParameter(1));
1662       fits->AddText(buffer);
1663       sprintf(buffer, "#chi^{2}/ndf = %5.2f / %i ", f1->GetChisquare(), f1->GetNDF());
1664       fits->AddText(buffer);
1665       fits->SetTextFont(42);
1666       fits->SetTextColor(kBlue);
1667       fits->SetFillColor(0);
1668       fits->SetTextSize(0.03);
1669       fits->SetBorderSize(1);
1670       fits->SetLineColor(kBlue);
1671       fits->SetMargin(0.05);
1672       fits->SetTextAlign(12);
1673       fits->Draw();
1674 
1675       std::string fileName(m_imageFileName);
1676       canvas.SaveAs(fileName.c_str());
1677 
1678       delete f1;
1679       return true;
1680     }
1681   };
1682 
1683   /************************************************
1684    template Noise history per subdetector
1685   *************************************************/
1686 
1687   template <StripSubdetector::SubDetector sub>
1688   class NoiseHistory : public HistoryPlot<SiStripNoises, std::pair<double, double>> {
1689   public:
1690     NoiseHistory()
1691         : HistoryPlot<SiStripNoises, std::pair<double, double>>(
1692               "Average " + SiStripPI::getStringFromSubdet(sub) + " noise vs run number",
1693               "average " + SiStripPI::getStringFromSubdet(sub) + " Noise") {}
1694 
1695     std::pair<double, double> getFromPayload(SiStripNoises& payload) override {
1696       std::vector<uint32_t> detid;
1697       payload.getDetIds(detid);
1698 
1699       int nStrips = 0;
1700       float sum = 0., sum2 = 0.;
1701 
1702       for (const auto& d : detid) {
1703         int subid = DetId(d).subdetId();
1704         if (subid != sub)
1705           continue;
1706         SiStripNoises::Range range = payload.getRange(d);
1707         for (int it = 0; it < (range.second - range.first) * 8 / 9; ++it) {
1708           nStrips++;
1709           auto noise = payload.getNoise(it, range);
1710           sum += noise;
1711           sum2 += (noise * noise);
1712         }  // loop on strips
1713       }    // loop on detIds
1714 
1715       float mean = sum / nStrips;
1716       float rms = (sum2 / nStrips - mean * mean) > 0. ? sqrt(sum2 / nStrips - mean * mean) : 0.;
1717 
1718       return std::make_pair(mean, rms);
1719 
1720     }  // close getFromPayload
1721   };
1722 
1723   typedef NoiseHistory<StripSubdetector::TIB> TIBNoiseHistory;
1724   typedef NoiseHistory<StripSubdetector::TOB> TOBNoiseHistory;
1725   typedef NoiseHistory<StripSubdetector::TID> TIDNoiseHistory;
1726   typedef NoiseHistory<StripSubdetector::TEC> TECNoiseHistory;
1727 
1728   /************************************************
1729    template Noise run history  per subdetector
1730   *************************************************/
1731 
1732   template <StripSubdetector::SubDetector sub>
1733   class NoiseRunHistory : public RunHistoryPlot<SiStripNoises, std::pair<double, double>> {
1734   public:
1735     NoiseRunHistory()
1736         : RunHistoryPlot<SiStripNoises, std::pair<double, double>>(
1737               "Average " + SiStripPI::getStringFromSubdet(sub) + " noise vs run number",
1738               "average " + SiStripPI::getStringFromSubdet(sub) + " Noise") {}
1739 
1740     std::pair<double, double> getFromPayload(SiStripNoises& payload) override {
1741       std::vector<uint32_t> detid;
1742       payload.getDetIds(detid);
1743 
1744       int nStrips = 0;
1745       float sum = 0., sum2 = 0.;
1746 
1747       for (const auto& d : detid) {
1748         int subid = DetId(d).subdetId();
1749         if (subid != sub)
1750           continue;
1751         SiStripNoises::Range range = payload.getRange(d);
1752         for (int it = 0; it < (range.second - range.first) * 8 / 9; ++it) {
1753           nStrips++;
1754           auto noise = payload.getNoise(it, range);
1755           sum += noise;
1756           sum2 += (noise * noise);
1757         }  // loop on strips
1758       }    // loop on detIds
1759 
1760       float mean = sum / nStrips;
1761       float rms = (sum2 / nStrips - mean * mean) > 0. ? sqrt(sum2 / nStrips - mean * mean) : 0.;
1762 
1763       return std::make_pair(mean, rms);
1764 
1765     }  // close getFromPayload
1766   };
1767 
1768   typedef NoiseRunHistory<StripSubdetector::TIB> TIBNoiseRunHistory;
1769   typedef NoiseRunHistory<StripSubdetector::TOB> TOBNoiseRunHistory;
1770   typedef NoiseRunHistory<StripSubdetector::TID> TIDNoiseRunHistory;
1771   typedef NoiseRunHistory<StripSubdetector::TEC> TECNoiseRunHistory;
1772 
1773   /************************************************
1774    template Noise Time history per subdetector
1775   *************************************************/
1776 
1777   template <StripSubdetector::SubDetector sub>
1778   class NoiseTimeHistory : public TimeHistoryPlot<SiStripNoises, std::pair<double, double>> {
1779   public:
1780     NoiseTimeHistory()
1781         : TimeHistoryPlot<SiStripNoises, std::pair<double, double>>(
1782               "Average " + SiStripPI::getStringFromSubdet(sub) + " noise vs run number",
1783               "average " + SiStripPI::getStringFromSubdet(sub) + " Noise") {}
1784 
1785     std::pair<double, double> getFromPayload(SiStripNoises& payload) override {
1786       std::vector<uint32_t> detid;
1787       payload.getDetIds(detid);
1788 
1789       int nStrips = 0;
1790       float sum = 0., sum2 = 0.;
1791 
1792       for (const auto& d : detid) {
1793         int subid = DetId(d).subdetId();
1794         if (subid != sub)
1795           continue;
1796         SiStripNoises::Range range = payload.getRange(d);
1797         for (int it = 0; it < (range.second - range.first) * 8 / 9; ++it) {
1798           nStrips++;
1799           auto noise = payload.getNoise(it, range);
1800           sum += noise;
1801           sum2 += (noise * noise);
1802         }  // loop on strips
1803       }    // loop on detIds
1804 
1805       float mean = sum / nStrips;
1806       float rms = (sum2 / nStrips - mean * mean) > 0. ? sqrt(sum2 / nStrips - mean * mean) : 0.;
1807 
1808       return std::make_pair(mean, rms);
1809 
1810     }  // close getFromPayload
1811   };
1812 
1813   typedef NoiseTimeHistory<StripSubdetector::TIB> TIBNoiseTimeHistory;
1814   typedef NoiseTimeHistory<StripSubdetector::TOB> TOBNoiseTimeHistory;
1815   typedef NoiseTimeHistory<StripSubdetector::TID> TIDNoiseTimeHistory;
1816   typedef NoiseTimeHistory<StripSubdetector::TEC> TECNoiseTimeHistory;
1817 
1818   /************************************************
1819    template Noise run history  per layer
1820   *************************************************/
1821   template <StripSubdetector::SubDetector sub>
1822   class NoiseLayerRunHistory : public PlotImage<SiStripNoises, MULTI_IOV> {
1823   public:
1824     NoiseLayerRunHistory()
1825         : PlotImage<SiStripNoises, MULTI_IOV>("SiStrip Noise values comparison"),
1826           m_trackerTopo{StandaloneTrackerTopology::fromTrackerParametersXMLFile(
1827               edm::FileInPath("Geometry/TrackerCommonData/data/trackerParameters.xml").fullPath())} {}
1828 
1829     bool fill() override {
1830       auto tag = PlotBase::getTag<0>();
1831       auto sorted_iovs = tag.iovs;
1832 
1833       // make absolute sure the IOVs are sortd by since
1834       std::sort(begin(sorted_iovs), end(sorted_iovs), [](auto const& t1, auto const& t2) {
1835         return std::get<0>(t1) < std::get<0>(t2);
1836       });
1837 
1838       std::unordered_map<int, std::vector<float>> noises_avg;
1839       std::unordered_map<int, std::vector<float>> noises_err;
1840       std::vector<float> runs;
1841       std::vector<float> runs_err;
1842 
1843       for (auto const& iov : sorted_iovs) {
1844         std::unordered_map<int, std::vector<float>> noises;  //map with noises per layer
1845 
1846         std::shared_ptr<SiStripNoises> payload = fetchPayload(std::get<1>(iov));
1847         unsigned int run = std::get<0>(iov);
1848         runs.push_back(run);
1849         runs_err.push_back(0);
1850 
1851         if (payload.get()) {
1852           std::vector<uint32_t> detid;
1853           payload->getDetIds(detid);
1854 
1855           for (const auto& d : detid) {
1856             int subid = DetId(d).subdetId();
1857             int layer = -1;
1858             if (subid != sub)
1859               continue;
1860             if (subid == StripSubdetector::TIB) {
1861               layer = m_trackerTopo.tibLayer(d);
1862             } else if (subid == StripSubdetector::TOB) {
1863               layer = m_trackerTopo.tobLayer(d);
1864             } else if (subid == StripSubdetector::TID) {
1865               layer = m_trackerTopo.tidWheel(d);
1866             } else if (subid == StripSubdetector::TEC) {
1867               layer = m_trackerTopo.tecWheel(d);
1868             }
1869 
1870             SiStripNoises::Range range = payload->getRange(d);
1871             for (int it = 0; it < (range.second - range.first) * 8 / 9; ++it) {
1872               auto noise = payload->getNoise(it, range);
1873               if (noises.find(layer) == noises.end())
1874                 noises.emplace(layer, std::vector<float>{});
1875               noises[layer].push_back(noise);
1876             }  // loop on strips
1877           }    // loop on detIds
1878 
1879           for (auto& entry : noises) {
1880             double sum = std::accumulate(entry.second.begin(), entry.second.end(), 0.0);
1881             double mean = sum / entry.second.size();
1882 
1883             //double sq_sum = std::inner_product(entry.second.begin(), entry.second.end(), entry.second.begin(), 0.0);
1884             //double stdev = std::sqrt(sq_sum / entry.second.size() - mean * mean);
1885 
1886             if (noises_avg.find(entry.first) == noises_avg.end())
1887               noises_avg.emplace(entry.first, std::vector<float>{});
1888             noises_avg[entry.first].push_back(mean);
1889 
1890             if (noises_err.find(entry.first) == noises_err.end())
1891               noises_err.emplace(entry.first, std::vector<float>{});
1892             noises_err[entry.first].push_back(0);
1893           }  //get
1894         }    //run on iov
1895       }
1896       TCanvas canvas("Partition summary", "partition summary", 2000, 1000);
1897       canvas.cd();
1898       canvas.SetBottomMargin(0.11);
1899       canvas.SetLeftMargin(0.13);
1900       canvas.SetRightMargin(0.05);
1901       canvas.Modified();
1902 
1903       TLegend legend = TLegend(0.73, 0.13, 0.89, 0.43);
1904       //legend.SetHeader("Layers","C"); // option "C" allows to center the header
1905       legend.SetTextSize(0.03);
1906 
1907       std::unique_ptr<TGraphErrors> graph[noises_avg.size()];
1908 
1909       int colors[18] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 20, 30, 40, 42, 46, 48, 32, 36, 38};
1910 
1911       int el = 0;
1912 
1913       for (auto& entry : noises_avg) {
1914         graph[el] = std::make_unique<TGraphErrors>(
1915             runs.size(), &runs[0], &(entry.second[0]), &runs_err[0], &(noises_err[entry.first][0]));
1916         char title[100];
1917         char name[100];
1918         snprintf(name, sizeof(name), "gr%d", entry.first);
1919         graph[el]->SetName(name);
1920 
1921         if (sub == StripSubdetector::TIB) {
1922           snprintf(title, sizeof(title), "SiStrip avg noise per layer -- TIB");
1923           graph[el]->GetYaxis()->SetTitle("Average Noise per Layer [ADC counts]");
1924         } else if (sub == StripSubdetector::TOB) {
1925           snprintf(title, sizeof(title), "SiStrip avg noise per layer -- TOB");
1926           graph[el]->GetYaxis()->SetTitle("Average Noise per Layer [ADC counts]");
1927         } else if (sub == StripSubdetector::TID) {
1928           snprintf(title, sizeof(title), "SiStrip avg noise per disk -- TID");
1929           graph[el]->GetYaxis()->SetTitle("Average Noise per Disk [ADC counts]");
1930         } else if (sub == StripSubdetector::TEC) {
1931           snprintf(title, sizeof(title), "SiStrip avg noise per disk -- TEC");
1932           graph[el]->GetYaxis()->SetTitle("Average Noise per Disk [ADC counts]");
1933         }
1934 
1935         graph[el]->SetTitle(title);
1936         graph[el]->GetXaxis()->SetTitle("run");
1937         graph[el]->SetMarkerColor(colors[el]);
1938         graph[el]->SetMarkerStyle(20);
1939         graph[el]->SetMarkerSize(1.5);
1940         graph[el]->GetXaxis()->CenterTitle(true);
1941         graph[el]->GetYaxis()->CenterTitle(true);
1942         graph[el]->GetXaxis()->SetTitleFont(42);
1943         graph[el]->GetYaxis()->SetTitleFont(42);
1944         graph[el]->GetXaxis()->SetTitleSize(0.05);
1945         graph[el]->GetYaxis()->SetTitleSize(0.05);
1946         graph[el]->GetXaxis()->SetTitleOffset(1.1);
1947         graph[el]->GetYaxis()->SetTitleOffset(1.3);
1948         graph[el]->GetXaxis()->SetLabelFont(42);
1949         graph[el]->GetYaxis()->SetLabelFont(42);
1950         graph[el]->GetYaxis()->SetLabelSize(.05);
1951         graph[el]->GetXaxis()->SetLabelSize(.05);
1952         graph[el]->SetMinimum(3);
1953         graph[el]->SetMaximum(7.5);
1954 
1955         if (el == 0)
1956           graph[el]->Draw("AP");
1957         else
1958           graph[el]->Draw("P");
1959 
1960         if (sub == StripSubdetector::TIB) {
1961           legend.AddEntry(name, ("layer " + std::to_string(entry.first)).c_str(), "lep");
1962         } else if (sub == StripSubdetector::TOB) {
1963           legend.AddEntry(name, ("layer " + std::to_string(entry.first)).c_str(), "lep");
1964         } else if (sub == StripSubdetector::TID) {
1965           legend.AddEntry(name, ("disk " + std::to_string(entry.first)).c_str(), "lep");
1966         } else if (sub == StripSubdetector::TEC) {
1967           legend.AddEntry(name, ("disk " + std::to_string(entry.first)).c_str(), "lep");
1968         }
1969 
1970         if (el == 0)
1971           legend.Draw();
1972         else
1973           legend.Draw("same");
1974         el++;
1975       }
1976       //canvas.BuildLegend();
1977       std::string fileName(m_imageFileName);
1978       canvas.SaveAs(fileName.c_str());
1979       return true;
1980     }
1981 
1982   private:
1983     TrackerTopology m_trackerTopo;
1984   };
1985 
1986   typedef NoiseLayerRunHistory<StripSubdetector::TIB> TIBNoiseLayerRunHistory;
1987   typedef NoiseLayerRunHistory<StripSubdetector::TOB> TOBNoiseLayerRunHistory;
1988   typedef NoiseLayerRunHistory<StripSubdetector::TID> TIDNoiseLayerRunHistory;
1989   typedef NoiseLayerRunHistory<StripSubdetector::TEC> TECNoiseLayerRunHistory;
1990 
1991 }  // namespace
1992 
1993 PAYLOAD_INSPECTOR_MODULE(SiStripNoises) {
1994   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseConsistencyCheck);
1995   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseCompareByPartition);
1996   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseDiffByPartition);
1997   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseCorrelationByPartition);
1998   PAYLOAD_INSPECTOR_CLASS(SiStripNoisesTest);
1999   PAYLOAD_INSPECTOR_CLASS(SiStripNoisePerDetId);
2000   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseValue);
2001   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseValuePerDetId);
2002   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseValuePerStrip);
2003   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseValuePerAPV);
2004   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseValuePerModule);
2005   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseValueComparisonSingleTag);
2006   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseValueComparisonTwoTags);
2007   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseValueComparisonPerStripSingleTag);
2008   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseValueComparisonPerAPVSingleTag);
2009   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseValueComparisonPerModuleSingleTag);
2010   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseValueComparisonPerStripTwoTags);
2011   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseValueComparisonPerAPVTwoTags);
2012   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseValueComparisonPerModuleTwoTags);
2013   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseMin_TrackerMap);
2014   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseMax_TrackerMap);
2015   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseMean_TrackerMap);
2016   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseRMS_TrackerMap);
2017   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseMeanByRegion);
2018   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseMinByRegion);
2019   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseMaxByRegion);
2020   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseRMSByRegion);
2021   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseComparatorMeanByRegionSingleTag);
2022   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseComparatorMinByRegionSingleTag);
2023   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseComparatorMaxByRegionSingleTag);
2024   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseComparatorRMSByRegionSingleTag);
2025   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseComparatorMeanByRegionTwoTags);
2026   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseComparatorMinByRegionTwoTags);
2027   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseComparatorMaxByRegionTwoTags);
2028   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseComparatorRMSByRegionTwoTags);
2029   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseMin_RatioWithPreviousIOVTrackerMapSingleTag);
2030   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseMax_RatioWithPreviousIOVTrackerMapSingleTag);
2031   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseMean_RatioWithPreviousIOVTrackerMapSingleTag);
2032   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseRms_RatioWithPreviousIOVTrackerMapSingleTag);
2033   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseMin_RatioWithPreviousIOVTrackerMapTwoTags);
2034   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseMax_RatioWithPreviousIOVTrackerMapTwoTags);
2035   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseMean_RatioWithPreviousIOVTrackerMapTwoTags);
2036   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseRms_RatioWithPreviousIOVTrackerMapTwoTags);
2037   PAYLOAD_INSPECTOR_CLASS(SiStripNoiseLinearity);
2038   PAYLOAD_INSPECTOR_CLASS(TIBNoiseHistory);
2039   PAYLOAD_INSPECTOR_CLASS(TOBNoiseHistory);
2040   PAYLOAD_INSPECTOR_CLASS(TIDNoiseHistory);
2041   PAYLOAD_INSPECTOR_CLASS(TECNoiseHistory);
2042   PAYLOAD_INSPECTOR_CLASS(TIBNoiseRunHistory);
2043   PAYLOAD_INSPECTOR_CLASS(TOBNoiseRunHistory);
2044   PAYLOAD_INSPECTOR_CLASS(TIDNoiseRunHistory);
2045   PAYLOAD_INSPECTOR_CLASS(TECNoiseRunHistory);
2046   PAYLOAD_INSPECTOR_CLASS(TIBNoiseLayerRunHistory);
2047   PAYLOAD_INSPECTOR_CLASS(TOBNoiseLayerRunHistory);
2048   PAYLOAD_INSPECTOR_CLASS(TIDNoiseLayerRunHistory);
2049   PAYLOAD_INSPECTOR_CLASS(TECNoiseLayerRunHistory);
2050   PAYLOAD_INSPECTOR_CLASS(TIBNoiseTimeHistory);
2051   PAYLOAD_INSPECTOR_CLASS(TOBNoiseTimeHistory);
2052   PAYLOAD_INSPECTOR_CLASS(TIDNoiseTimeHistory);
2053   PAYLOAD_INSPECTOR_CLASS(TECNoiseTimeHistory);
2054 }