Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #ifndef CondCore_SiStripPlugins_SiStripCondObjectRepresent_h
0002 #define CondCore_SiStripPlugins_SiStripCondObjectRepresent_h
0003 
0004 // system includes
0005 #include <fstream>
0006 #include <iostream>
0007 #include <sstream>
0008 #include <string>
0009 #include <vector>
0010 #include <fmt/printf.h>
0011 
0012 // user includes
0013 #include "CalibTracker/StandaloneTrackerTopology/interface/StandaloneTrackerTopology.h"
0014 #include "CommonTools/TrackerMap/interface/TrackerMap.h"
0015 #include "CondCore/SiStripPlugins/interface/SiStripPayloadInspectorHelper.h"
0016 #include "DataFormats/DetId/interface/DetId.h"
0017 #include "FWCore/Utilities/interface/Exception.h"
0018 
0019 // ROOT includes
0020 #include "TCanvas.h"
0021 #include "TColor.h"
0022 #include "TGaxis.h"
0023 #include "TH1F.h"
0024 #include "TH2F.h"
0025 #include "TLatex.h"
0026 #include "TLegend.h"
0027 #include "TLine.h"
0028 #include "TPaveLabel.h"
0029 #include "TProfile.h"
0030 #include "TROOT.h"
0031 #include "TStyle.h"
0032 
0033 //functions for correct representation of data in summary and plot
0034 namespace SiStripCondObjectRepresent {
0035 
0036   static const std::map<std::string, int> k_colormap = {
0037       {"TIB", kRed}, {"TOB", kGreen}, {"TID", kBlack}, {"TEC", kBlue}};
0038   static const std::map<std::string, int> k_markermap = {
0039       {"TIB", kFullCircle}, {"TOB", kFullTriangleUp}, {"TID", kFullSquare}, {"TEC", kFullTriangleDown}};
0040 
0041   enum plotType { STANDARD, COMPARISON, DIFF, RATIO, MAP, END_OF_TYPES };
0042   enum granularity { PERSTRIP, PERAPV, PERMODULE };
0043 
0044   template <class type>
0045   class SiStripCondDataItem {
0046   public:
0047     SiStripCondDataItem() { init(); }
0048 
0049     virtual ~SiStripCondDataItem() = default;
0050 
0051     void fillAll(unsigned int detid, const std::vector<type> &store) {
0052       m_info[detid] = store;
0053       m_cached = true;
0054       return;
0055     }
0056 
0057     void fillByPushBack(unsigned int detid, const type &value) {
0058       m_info[detid].push_back(value);
0059       m_cached = true;
0060     }
0061 
0062     void divide(unsigned int detid, const std::vector<type> &denominator) {
0063       if (m_info[detid].size() != denominator.size()) {
0064         throw cms::Exception("Unaligned Conditions")
0065             << "data size of numerator mismatched the data size of denominator";
0066       }
0067 
0068       unsigned int counter = 0;
0069       for (const auto &den : denominator) {
0070         m_info[detid].at(counter) /= den;
0071         counter++;
0072       }
0073     }
0074 
0075     void subtract(unsigned int detid, const std::vector<type> &subtractor) {
0076       if (m_info[detid].size() != subtractor.size()) {
0077         throw cms::Exception("Unaligned Conditions")
0078             << "data size of numerator mismatched the data size of denominator";
0079       }
0080 
0081       unsigned int counter = 0;
0082       for (const auto &sub : subtractor) {
0083         m_info[detid].at(counter) -= sub;
0084         counter++;
0085       }
0086     }
0087 
0088     std::vector<type> data(unsigned int detid) { return m_info[detid]; }
0089 
0090     std::pair<std::vector<type>, std::vector<type> > demuxedData(unsigned int detid) {
0091       if (m_compared) {
0092         std::vector<type> v1(m_info[detid].begin(), m_info[detid].begin() + m_info[detid].size() / 2);
0093         std::vector<type> v2(m_info[detid].begin() + m_info[detid].size() / 2, m_info[detid].end());
0094         assert(v1.size() == v2.size());
0095         return std::make_pair(v1, v2);
0096       } else {
0097         throw cms::Exception("Logic error") << "not being in compared mode, data cannot be demultiplexed";
0098       }
0099     }
0100 
0101     void fillMonitor1D(const SiStripPI::OpMode &mymode,
0102                        SiStripPI::Monitor1D *&mon,
0103                        SiStripPI::Entry &entry,
0104                        std::vector<type> &values,
0105                        const unsigned int prev_det,
0106                        unsigned int &prev_apv,
0107                        const unsigned int detid) {
0108       unsigned int istrip = 0;
0109       for (const auto &value : values) {
0110         bool flush = false;
0111         switch (mymode) {
0112           case (SiStripPI::APV_BASED):
0113             flush = (prev_det != 0 && prev_apv != istrip / sistrip::STRIPS_PER_APV);
0114             break;
0115           case (SiStripPI::MODULE_BASED):
0116             flush = (prev_det != 0 && prev_det != detid);
0117             break;
0118           case (SiStripPI::STRIP_BASED):
0119             flush = (istrip != 0);
0120             break;
0121         }
0122 
0123         if (flush) {
0124           mon->Fill(prev_apv, prev_det, entry.mean());
0125           entry.reset();
0126         }
0127 
0128         entry.add(value);
0129 
0130         prev_apv = istrip / sistrip::STRIPS_PER_APV;
0131         istrip++;
0132       }
0133     }
0134 
0135     void setGranularity(bool isPerStrip, bool isPerAPV) {
0136       m_servedPerStrip = isPerStrip;
0137       m_servedPerAPV = isPerAPV;
0138     }
0139 
0140     bool isCached() { return m_cached; }
0141 
0142     void setComparedBit() { m_compared = true; }
0143 
0144     std::vector<unsigned int> detIds(bool verbose) {
0145       std::vector<unsigned int> v;
0146       for (const auto &element : m_info) {
0147         if (verbose) {
0148           std::cout << element.first << "\n";
0149         }
0150         v.push_back(element.first);
0151       }
0152 
0153       return v;
0154     }
0155 
0156   private:
0157     std::map<unsigned int, std::vector<type> > m_info;
0158     bool m_servedPerStrip;
0159     bool m_servedPerAPV;
0160     bool m_cached;
0161     bool m_compared;
0162 
0163     void init() {
0164       m_servedPerStrip = false;
0165       m_servedPerAPV = false;
0166       m_info.clear();
0167       m_cached = false;
0168       m_compared = false;
0169     }
0170   };
0171 
0172   //used to produce all display objects for payload inspector
0173   template <class Item, class type>
0174   class SiStripDataContainer {
0175   public:
0176     SiStripDataContainer(const std::shared_ptr<Item> &payload,
0177                          const SiStripPI::MetaData &metadata,
0178                          const std::string &tagname)
0179         : payload_(payload),
0180           run_(std::get<0>(metadata)),
0181           hash_(std::get<1>(metadata)),
0182           tagname_(tagname),
0183           m_trackerTopo(StandaloneTrackerTopology::fromTrackerParametersXMLFile(
0184               edm::FileInPath("Geometry/TrackerCommonData/data/trackerParameters.xml").fullPath())) {
0185       payloadType_ = std::string();
0186       granularity_ = PERSTRIP;
0187       plotMode_ = STANDARD;
0188       additionalIOV_ = std::make_tuple(-1, "", "");
0189     }
0190 
0191     virtual ~SiStripDataContainer() = default;
0192 
0193     ///////////////// public get functions  /////////////////
0194     const unsigned int run() const { return run_; }
0195     const unsigned int run2() const { return std::get<0>(additionalIOV_); }
0196     const std::string &hash() const { return hash_; }
0197     const std::string &hash2() const { return std::get<1>(additionalIOV_); }
0198     const SiStripPI::MetaData metaData() const { return std::make_tuple(run_, hash_); }
0199     const std::string &tagName() const { return tagname_; }
0200     const std::string &tagName2() const { return std::get<2>(additionalIOV_); }
0201     const std::string &topoMode() const { return TopoMode_; }
0202     const std::string &payloadName() const { return payloadType_; }
0203     const plotType &getPlotType() const { return plotMode_; }
0204     const bool isMultiTag() { return (tagname_ != this->tagName2() && !(this->tagName2()).empty()); }
0205 
0206     void setPlotType(plotType myType) { plotMode_ = myType; }
0207     void setPayloadType(std::string myPayloadType) { payloadType_ = myPayloadType; }
0208     void setGranularity(granularity myGranularity) {
0209       granularity_ = myGranularity;
0210 
0211       switch (myGranularity) {
0212         case PERSTRIP:
0213           SiStripCondData_.setGranularity(true, false);
0214           break;
0215         case PERAPV:
0216           SiStripCondData_.setGranularity(false, true);
0217           break;
0218         case PERMODULE:
0219           SiStripCondData_.setGranularity(false, false);
0220           break;
0221         default:
0222           edm::LogError("LogicError") << "Unknown granularity type: " << myGranularity;
0223       }
0224     }
0225 
0226     void setAdditionalIOV(const unsigned int run, const std::string &hash, const std::string &tagname) {
0227       std::get<0>(additionalIOV_) = run;
0228       std::get<1>(additionalIOV_) = hash;
0229       std::get<2>(additionalIOV_) = tagname;
0230     };
0231 
0232     ////NOTE to be implemented in PayloadInspector classes
0233     virtual void storeAllValues() {
0234       throw cms::Exception("Value definition not found")
0235           << "storeAllValues definition not found for " << payloadName() << "\n;";
0236     };
0237 
0238     SiStripCondDataItem<type> siStripCondData() { return SiStripCondData_; }
0239 
0240     /***********************************************************************/
0241     const char *plotDescriptor()
0242     /***********************************************************************/
0243     {
0244       const char *thePlotType = "";
0245       switch (plotMode_) {
0246         case STANDARD:
0247           thePlotType = Form("Display - IOV: %i", run_);
0248           break;
0249         case COMPARISON:
0250           thePlotType = "Display";
0251           break;
0252         case DIFF:
0253           thePlotType = Form("#Delta (%i-%i)", run_, std::get<0>(additionalIOV_));
0254           break;
0255         case RATIO:
0256           thePlotType = Form("Ratio (%i/%i)", run_, std::get<0>(additionalIOV_));
0257           break;
0258         case MAP:
0259           thePlotType = Form("TrackerMap - %s", hash_.c_str());
0260           break;
0261         case END_OF_TYPES:
0262           edm::LogError("LogicError") << "Unknown plot type: " << plotMode_;
0263           break;
0264         default:
0265           edm::LogError("LogicError") << "Unknown plot type: " << plotMode_;
0266           break;
0267       }
0268 
0269       return thePlotType;
0270     }
0271 
0272     // all methods needed for comparison of 2 IOVs
0273 
0274     /***********************************************************************/
0275     void compare(SiStripDataContainer *dataCont2)
0276     /***********************************************************************/
0277     {
0278       plotMode_ = COMPARISON;
0279       dataCont2->setPlotType(COMPARISON);
0280       SiStripCondData_.setComparedBit();
0281 
0282       setAdditionalIOV(dataCont2->run(), dataCont2->hash(), dataCont2->tagName());
0283 
0284       if (!SiStripCondData_.isCached())
0285         storeAllValues();
0286       dataCont2->storeAllValues();
0287       auto SiStripCondData2_ = dataCont2->siStripCondData();
0288 
0289       auto listOfDetIds = SiStripCondData_.detIds(false);
0290       for (const auto &detId : listOfDetIds) {
0291         auto entriesToAdd = SiStripCondData2_.data(detId);
0292         for (const auto &entry : entriesToAdd) {
0293           SiStripCondData_.fillByPushBack(detId, entry);
0294         }
0295       }
0296     }
0297 
0298     /***********************************************************************/
0299     void divide(SiStripDataContainer *dataCont2)
0300     /***********************************************************************/
0301     {
0302       plotMode_ = RATIO;
0303       dataCont2->setPlotType(RATIO);
0304 
0305       setAdditionalIOV(dataCont2->run(), dataCont2->hash(), dataCont2->tagName());
0306 
0307       if (!SiStripCondData_.isCached())
0308         storeAllValues();
0309       dataCont2->storeAllValues();
0310       auto SiStripCondData2_ = dataCont2->siStripCondData();
0311 
0312       auto listOfDetIds = SiStripCondData_.detIds(false);
0313       for (const auto &detId : listOfDetIds) {
0314         SiStripCondData_.divide(detId, SiStripCondData2_.data(detId));
0315       }
0316     }
0317 
0318     /***********************************************************************/
0319     void subtract(SiStripDataContainer *dataCont2)
0320     /***********************************************************************/
0321     {
0322       plotMode_ = DIFF;
0323       dataCont2->setPlotType(DIFF);
0324 
0325       setAdditionalIOV(dataCont2->run(), dataCont2->hash(), dataCont2->tagName());
0326 
0327       if (!SiStripCondData_.isCached())
0328         storeAllValues();
0329       dataCont2->storeAllValues();
0330       auto SiStripCondData2_ = dataCont2->siStripCondData();
0331 
0332       auto listOfDetIds = SiStripCondData_.detIds(false);
0333       for (const auto &detId : listOfDetIds) {
0334         SiStripCondData_.subtract(detId, SiStripCondData2_.data(detId));
0335       }
0336     }
0337 
0338     /***********************************************************************/
0339     void printAll()
0340     /***********************************************************************/
0341     {
0342       if (!SiStripCondData_.isCached())
0343         storeAllValues();
0344       auto listOfDetIds = SiStripCondData_.detIds(false);
0345       for (const auto &detId : listOfDetIds) {
0346         std::cout << detId << ": ";
0347         auto values = SiStripCondData_.data(detId);
0348         for (const auto &value : values) {
0349           std::cout << value << " ";
0350         }
0351         std::cout << "\n";
0352       }
0353     }
0354 
0355     /***********************************************************************/
0356     void fillTrackerMap(TrackerMap *&tmap,
0357                         std::pair<float, float> &range,
0358                         const SiStripPI::estimator &est,
0359                         const int nsigmas_of_saturation)
0360     /***********************************************************************/
0361     {
0362       std::string titleMap;
0363       if (plotMode_ != DIFF && plotMode_ != RATIO) {
0364         titleMap =
0365             "Tracker Map of " + payloadType_ + " " + estimatorType(est) + " per module (payload : " + hash_ + ")";
0366       } else {
0367         titleMap = "Tracker Map of " + payloadType_ + " " + Form("%s", plotDescriptor()) + " " + estimatorType(est) +
0368                    " per module";
0369       }
0370 
0371       tmap = new TrackerMap(payloadType_);
0372       tmap->setTitle(titleMap);
0373       tmap->setPalette(1);
0374 
0375       // storage of info
0376       std::map<unsigned int, float> info_per_detid;
0377 
0378       if (!SiStripCondData_.isCached())
0379         storeAllValues();
0380       auto listOfDetIds = SiStripCondData_.detIds(false);
0381       for (const auto &detId : listOfDetIds) {
0382         auto values = SiStripCondData_.data(detId);
0383 
0384         unsigned int nElements = values.size();
0385         double mean(0.), rms(0.), min(10000.), max(0.);
0386 
0387         for (const auto &value : values) {
0388           mean += value;
0389           rms += value * value;
0390           if (value < min)
0391             min = value;
0392           if (value > max)
0393             max = value;
0394         }
0395 
0396         mean /= nElements;
0397         if ((rms / nElements - mean * mean) > 0.) {
0398           rms = sqrt(rms / nElements - mean * mean);
0399         } else {
0400           rms = 0.;
0401         }
0402 
0403         switch (est) {
0404           case SiStripPI::min:
0405             info_per_detid[detId] = min;
0406             break;
0407           case SiStripPI::max:
0408             info_per_detid[detId] = max;
0409             break;
0410           case SiStripPI::mean:
0411             info_per_detid[detId] = mean;
0412             break;
0413           case SiStripPI::rms:
0414             info_per_detid[detId] = rms;
0415             break;
0416           default:
0417             edm::LogWarning("LogicError") << "Unknown estimator: " << est;
0418             break;
0419         }
0420       }
0421 
0422       // loop on the map
0423       for (const auto &item : info_per_detid) {
0424         tmap->fill(item.first, item.second);
0425       }
0426 
0427       range = SiStripPI::getTheRange(info_per_detid, nsigmas_of_saturation);
0428     }
0429 
0430     /***********************************************************************/
0431     void fillValuePlot(TCanvas &canvas, const SiStripPI::OpMode &op_mode_, int nbins, float min, float max)
0432     /***********************************************************************/
0433     {
0434       auto myMode = op_mode_;
0435       // check the consistency first
0436 
0437       if (granularity_ == PERAPV) {
0438         switch (op_mode_) {
0439           case SiStripPI::STRIP_BASED:
0440             edm::LogError("LogicError") << " Cannot display average per " << opType(op_mode_).c_str()
0441                                         << " in a conditions served per APV";
0442             return;
0443           case SiStripPI::APV_BASED:
0444             myMode = SiStripPI::STRIP_BASED;
0445             break;
0446           default:
0447             break;
0448         }
0449       } else if (granularity_ == PERMODULE) {
0450         if (op_mode_ == SiStripPI::STRIP_BASED || op_mode_ == SiStripPI::APV_BASED) {
0451           edm::LogError("LogicError") << " Cannot display average per " << opType(op_mode_).c_str()
0452                                       << " in a conditions served per module";
0453           return;
0454         }
0455       }
0456 
0457       SiStripPI::Monitor1D *f_mon = nullptr;
0458       SiStripPI::Monitor1D *l_mon = nullptr;
0459 
0460       f_mon = new SiStripPI::Monitor1D(myMode,
0461                                        "first",
0462                                        Form("#LT %s #GT per %s;#LT%s per %s#GT %s;n. %ss",
0463                                             payloadType_.c_str(),
0464                                             opType(op_mode_).c_str(),
0465                                             payloadType_.c_str(),
0466                                             opType(op_mode_).c_str(),
0467                                             (units_[payloadType_]).c_str(),
0468                                             opType(op_mode_).c_str()),
0469                                        nbins,
0470                                        min,
0471                                        max);
0472 
0473       if (plotMode_ == COMPARISON) {
0474         l_mon = new SiStripPI::Monitor1D(myMode,
0475                                          "last",
0476                                          Form("#LT %s #GT per %s;#LT%s per %s#GT %s;n. %ss",
0477                                               payloadType_.c_str(),
0478                                               opType(op_mode_).c_str(),
0479                                               payloadType_.c_str(),
0480                                               opType(op_mode_).c_str(),
0481                                               (units_[payloadType_]).c_str(),
0482                                               opType(op_mode_).c_str()),
0483                                          nbins,
0484                                          min,
0485                                          max);
0486       }
0487 
0488       // retrieve the data
0489       if (!SiStripCondData_.isCached())
0490         storeAllValues();
0491       auto listOfDetIds = SiStripCondData_.detIds(false);
0492 
0493       unsigned int prev_det = 0;
0494       unsigned int prev_apv = 0;
0495       SiStripPI::Entry f_entryContainer;
0496       SiStripPI::Entry l_entryContainer;
0497 
0498       std::cout << "mode:" << opType(myMode) << " granularity: " << granularity_
0499                 << " listOfDetIds.size(): " << listOfDetIds.size() << std::endl;
0500 
0501       for (const auto &detId : listOfDetIds) {
0502         if (plotMode_ == COMPARISON) {
0503           auto values = SiStripCondData_.demuxedData(detId);
0504           SiStripCondData_.fillMonitor1D(myMode, f_mon, f_entryContainer, values.first, prev_det, prev_apv, detId);
0505           SiStripCondData_.fillMonitor1D(myMode, l_mon, l_entryContainer, values.second, prev_det, prev_apv, detId);
0506         } else {
0507           auto values = SiStripCondData_.data(detId);
0508           SiStripCondData_.fillMonitor1D(myMode, f_mon, l_entryContainer, values, prev_det, prev_apv, detId);
0509         }
0510         prev_det = detId;
0511       }
0512 
0513       TH1F *h_first = (TH1F *)(f_mon->getHist()).Clone("h_first");
0514       h_first->SetStats(kFALSE);
0515       SiStripPI::makeNicePlotStyle(h_first);
0516       h_first->GetYaxis()->CenterTitle(true);
0517       h_first->GetXaxis()->CenterTitle(true);
0518       h_first->SetLineWidth(2);
0519       h_first->SetLineColor(kBlack);
0520 
0521       //=========================
0522       canvas.cd();
0523       canvas.SetBottomMargin(0.11);
0524       canvas.SetLeftMargin(0.13);
0525       canvas.SetRightMargin(0.05);
0526       //canvas.Modified();
0527 
0528       TLegend *legend = new TLegend(0.52, 0.82, 0.95, 0.9);
0529       legend->SetTextSize(0.025);
0530 
0531       if (plotMode_ != COMPARISON) {
0532         float theMax = h_first->GetMaximum();
0533         h_first->SetMaximum(theMax * 1.30);
0534         h_first->Draw();
0535 
0536         legend->AddEntry(h_first, Form("IOV: %i", run_), "L");
0537 
0538       } else {
0539         TH1F *h_last = (TH1F *)(l_mon->getHist()).Clone("h_last");
0540         h_last->SetStats(kFALSE);
0541         SiStripPI::makeNicePlotStyle(h_last);
0542         h_last->GetYaxis()->CenterTitle(true);
0543         h_last->GetXaxis()->CenterTitle(true);
0544         h_last->SetLineWidth(2);
0545         h_last->SetLineColor(kBlue);
0546 
0547         std::cout << h_first->GetEntries() << " ---- " << h_last->GetEntries() << std::endl;
0548 
0549         float theMax = (h_first->GetMaximum() > h_last->GetMaximum()) ? h_first->GetMaximum() : h_last->GetMaximum();
0550 
0551         h_first->SetMaximum(theMax * 1.30);
0552         h_last->SetMaximum(theMax * 1.30);
0553 
0554         h_first->Draw();
0555         h_last->Draw("same");
0556 
0557         legend->SetHeader(Form("%s comparison", payloadType_.c_str()), "C");  // option "C" allows to center the header
0558         legend->AddEntry(h_first, Form("IOV: %i", run_), "F");
0559         legend->AddEntry(h_last, Form("IOV: %i", (std::get<0>(additionalIOV_))), "F");
0560       }
0561 
0562       legend->Draw("same");
0563     }
0564 
0565     /***********************************************************************/
0566     void fillSummary(TCanvas &canvas)
0567     /***********************************************************************/
0568     {
0569       std::map<unsigned int, SiStripDetSummary::Values> f_map;
0570       std::map<unsigned int, SiStripDetSummary::Values> l_map;
0571 
0572       if (!SiStripCondData_.isCached())
0573         storeAllValues();
0574       auto listOfDetIds = SiStripCondData_.detIds(false);
0575 
0576       if (plotMode_ == COMPARISON) {
0577         for (const auto &detId : listOfDetIds) {
0578           auto values = SiStripCondData_.demuxedData(detId);
0579           for (const auto &value : values.first) {
0580             summary.add(detId, value);
0581           }
0582         }
0583 
0584         f_map = summary.getCounts();
0585         summary.clear();
0586 
0587         for (const auto &detId : listOfDetIds) {
0588           auto values = SiStripCondData_.demuxedData(detId);
0589           for (const auto &value : values.second) {
0590             summary.add(detId, value);
0591           }
0592         }
0593 
0594         l_map = summary.getCounts();
0595 
0596       } else {
0597         for (const auto &detId : listOfDetIds) {
0598           auto values = SiStripCondData_.data(detId);
0599           for (const auto &value : values) {
0600             summary.add(detId, value);
0601           }
0602         }
0603         f_map = summary.getCounts();
0604       }
0605 
0606       if (plotMode_ == COMPARISON) {
0607         std::cout << "f map size: " << f_map.size() << " l map size:" << l_map.size() << std::endl;
0608         assert(f_map.size() == l_map.size());
0609       }
0610       //=========================
0611 
0612       canvas.cd();
0613       auto h1 = new TH1F(
0614           "byRegion1",
0615           Form("SiStrip %s average by region;; average SiStrip %s", payloadType_.c_str(), payloadType_.c_str()),
0616           f_map.size(),
0617           0.,
0618           f_map.size());
0619       h1->SetStats(false);
0620 
0621       auto h2 = new TH1F(
0622           "byRegion2",
0623           Form("SiStrip %s average by region;; average SiStrip %s", payloadType_.c_str(), payloadType_.c_str()),
0624           f_map.size(),
0625           0.,
0626           f_map.size());
0627       h2->SetStats(false);
0628 
0629       canvas.SetBottomMargin(0.18);
0630       canvas.SetLeftMargin(0.17);
0631       canvas.SetRightMargin(0.05);
0632       canvas.Modified();
0633 
0634       std::vector<int> boundaries;
0635       unsigned int iBin = 0;
0636 
0637       std::string detector;
0638       std::string currentDetector;
0639 
0640       for (const auto &element : f_map) {
0641         iBin++;
0642         int count = element.second.count;
0643         double mean = (element.second.mean) / count;
0644 
0645         if (currentDetector.empty())
0646           currentDetector = "TIB";
0647 
0648         switch ((element.first) / 1000) {
0649           case 1:
0650             detector = "TIB";
0651             break;
0652           case 2:
0653             detector = "TOB";
0654             break;
0655           case 3:
0656             detector = "TEC";
0657             break;
0658           case 4:
0659             detector = "TID";
0660             break;
0661         }
0662 
0663         h1->SetBinContent(iBin, mean);
0664         h1->GetXaxis()->SetBinLabel(iBin, SiStripPI::regionType(element.first).second);
0665         h1->GetXaxis()->LabelsOption("v");
0666 
0667         if (detector != currentDetector) {
0668           boundaries.push_back(iBin);
0669           currentDetector = detector;
0670         }
0671       }
0672 
0673       iBin = 0;
0674       if (plotMode_ == COMPARISON) {
0675         for (const auto &element : l_map) {
0676           iBin++;
0677           int count = element.second.count;
0678           double mean = (element.second.mean) / count;
0679 
0680           h2->SetBinContent(iBin, mean);
0681           h2->GetXaxis()->SetBinLabel(iBin, SiStripPI::regionType(element.first).second);
0682           h2->GetXaxis()->LabelsOption("v");
0683         }
0684       }
0685 
0686       h1->GetYaxis()->SetRangeUser(0., h1->GetMaximum() * 1.30);
0687       h1->SetMarkerStyle(20);
0688       h1->SetMarkerSize(1.5);
0689       h1->Draw("HIST");
0690       h1->Draw("Psame");
0691 
0692       if (plotMode_ == COMPARISON) {
0693         h2->GetYaxis()->SetRangeUser(0., h2->GetMaximum() * 1.30);
0694         h2->SetMarkerStyle(25);
0695         h2->SetMarkerColor(kBlue);
0696         h2->SetLineColor(kBlue);
0697         h2->SetMarkerSize(1.5);
0698         h2->Draw("HISTsame");
0699         h2->Draw("Psame");
0700       }
0701 
0702       canvas.Update();
0703 
0704       TLine *l[boundaries.size()];
0705       unsigned int i = 0;
0706       for (const auto &line : boundaries) {
0707         l[i] = new TLine(h1->GetBinLowEdge(line), canvas.GetUymin(), h1->GetBinLowEdge(line), canvas.GetUymax());
0708         l[i]->SetLineWidth(1);
0709         l[i]->SetLineStyle(9);
0710         l[i]->SetLineColor(2);
0711         l[i]->Draw("same");
0712         i++;
0713       }
0714 
0715       TLegend *legend = new TLegend(0.52, 0.82, 0.95, 0.9);
0716       legend->SetHeader(hash_.c_str(), "C");  // option "C" allows to center the header
0717       legend->AddEntry(h1, Form("IOV: %i", run_), "PL");
0718       if (plotMode_ == COMPARISON) {
0719         legend->AddEntry(h2, Form("IOV: %i", std::get<0>(additionalIOV_)), "PL");
0720       }
0721       legend->SetTextSize(0.025);
0722       legend->Draw("same");
0723     }
0724 
0725     /***********************************************************************/
0726     void fillByPartition(TCanvas &canvas, int nbins, float min, float max)
0727     /***********************************************************************/
0728     {
0729       std::map<std::string, TH1F *> h_parts;
0730       std::map<std::string, TH1F *> h_parts2;
0731       std::vector<std::string> parts = {"TEC", "TOB", "TIB", "TID"};
0732 
0733       const char *device;
0734       switch (granularity_) {
0735         case PERSTRIP:
0736           device = "strips";
0737           break;
0738         case PERAPV:
0739           device = "APVs";
0740           break;
0741         case PERMODULE:
0742           device = "modules";
0743           break;
0744         default:
0745           device = "unrecognized device";
0746           break;
0747       }
0748 
0749       for (const auto &part : parts) {
0750         TString globalTitle = Form("%s - %s %s;%s %s;n. %s",
0751                                    plotDescriptor(),
0752                                    payloadType_.c_str(),
0753                                    part.c_str(),
0754                                    payloadType_.c_str(),
0755                                    (units_[payloadType_]).c_str(),
0756                                    device);
0757 
0758         h_parts[part] = new TH1F(Form("h_%s", part.c_str()), globalTitle, nbins, min, max);
0759         h_parts[part]->SetTitle(""); /* remove the title from display */
0760         if (plotMode_ == COMPARISON) {
0761           h_parts2[part] = new TH1F(Form("h2_%s", part.c_str()), globalTitle, nbins, min, max);
0762           h_parts2[part]->SetTitle(""); /* remove the title from display */
0763         }
0764       }
0765 
0766       if (!SiStripCondData_.isCached())
0767         storeAllValues();
0768       auto listOfDetIds = SiStripCondData_.detIds(false);
0769       for (const auto &detId : listOfDetIds) {
0770         auto values = SiStripCondData_.data(detId);
0771         int subid = DetId(detId).subdetId();
0772         unsigned int counter{0};
0773         for (const auto &value : values) {
0774           counter++;
0775           switch (subid) {
0776             case StripSubdetector::TIB:
0777               if ((plotMode_ == COMPARISON) && (counter > (values.size() / 2))) {
0778                 h_parts2["TIB"]->Fill(value);
0779               } else {
0780                 h_parts["TIB"]->Fill(value);
0781               }
0782               break;
0783             case StripSubdetector::TID:
0784               if ((plotMode_ == COMPARISON) && (counter > (values.size() / 2))) {
0785                 h_parts2["TID"]->Fill(value);
0786               } else {
0787                 h_parts["TID"]->Fill(value);
0788               }
0789               break;
0790             case StripSubdetector::TOB:
0791               if ((plotMode_ == COMPARISON) && (counter > (values.size() / 2))) {
0792                 h_parts2["TOB"]->Fill(value);
0793               } else {
0794                 h_parts["TOB"]->Fill(value);
0795               }
0796               break;
0797             case StripSubdetector::TEC:
0798               if ((plotMode_ == COMPARISON) && (counter > (values.size() / 2))) {
0799                 h_parts2["TEC"]->Fill(value);
0800               } else {
0801                 h_parts["TEC"]->Fill(value);
0802               }
0803               break;
0804             default:
0805               edm::LogError("LogicError") << "Unknown partition: " << subid;
0806               break;
0807           }
0808         }
0809       }
0810 
0811       canvas.Divide(2, 2);
0812 
0813       auto ltx = TLatex();
0814       ltx.SetTextFont(62);
0815       ltx.SetTextSize(0.05);
0816       ltx.SetTextAlign(31);
0817 
0818       int index = 0;
0819       for (const auto &part : parts) {
0820         index++;
0821         canvas.cd(index)->SetTopMargin(0.07);
0822         canvas.cd(index)->SetLeftMargin(0.13);
0823         canvas.cd(index)->SetRightMargin(0.08);
0824 
0825         SiStripPI::makeNicePlotStyle(h_parts[part]);
0826         h_parts[part]->SetMinimum(1.);
0827         h_parts[part]->SetStats(false);
0828         h_parts[part]->SetLineWidth(2);
0829 
0830         if (plotMode_ != COMPARISON) {
0831           h_parts[part]->SetLineColor(k_colormap.at(part));
0832           h_parts[part]->SetFillColorAlpha(k_colormap.at(part), 0.15);
0833           float theMax = h_parts[part]->GetMaximum();
0834           h_parts[part]->SetMaximum(theMax * 1.30);
0835         } else {
0836           h_parts[part]->SetLineColor(kBlack);
0837 
0838           SiStripPI::makeNicePlotStyle(h_parts2[part]);
0839           h_parts2[part]->SetMinimum(1.);
0840           h_parts2[part]->SetStats(false);
0841           h_parts2[part]->SetLineWidth(2);
0842           h_parts2[part]->SetLineColor(kBlue);
0843           h_parts2[part]->SetFillColorAlpha(kBlue, 0.15);
0844 
0845           float theMax = (h_parts[part]->GetMaximum() > h_parts2[part]->GetMaximum()) ? h_parts[part]->GetMaximum()
0846                                                                                       : h_parts2[part]->GetMaximum();
0847 
0848           h_parts[part]->SetMaximum(theMax * 1.30);
0849           h_parts2[part]->SetMaximum(theMax * 1.30);
0850         }
0851 
0852         h_parts[part]->Draw();
0853         if (plotMode_ == COMPARISON) {
0854           h_parts2[part]->Draw("same");
0855         }
0856 
0857         TLegend *leg = new TLegend(.13, 0.81, 0.92, 0.93);
0858         if (plotMode_ != COMPARISON) {
0859           // it means it's a difference
0860           if (this->isMultiTag()) {
0861             leg->SetHeader("#bf{Two Tags Difference}", "C");  // option "C" allows to center the header
0862             leg->AddEntry(h_parts[part],
0863                           (fmt::sprintf("#splitline{%s : %i}{%s : %i}", tagName(), run(), tagName2(), run2())).c_str(),
0864                           "F");
0865           } else {
0866             leg->SetHeader(("tag: #bf{" + tagName() + "}").c_str(), "C");  // option "C" allows to center the header
0867             leg->AddEntry(h_parts[part], (fmt::sprintf("%s", plotDescriptor())).c_str(), "F");
0868           }
0869           leg->SetTextSize(0.04);
0870           leg->Draw("same");
0871           ltx.DrawLatexNDC(
0872               0.35,
0873               0.7,
0874               (fmt::sprintf("#splitline{#mu = %.2f}{r.m.s. = %.2f}", h_parts[part]->GetMean(), h_parts[part]->GetRMS()))
0875                   .c_str());
0876           ltx.DrawLatexNDC(1 - gPad->GetRightMargin(),
0877                            1 - gPad->GetTopMargin() + 0.01,
0878                            (fmt::sprintf("#color[2]{%s} %s Values %s", part, payloadType_, plotDescriptor())).c_str());
0879         } else {
0880           if (this->isMultiTag()) {
0881             leg->SetHeader("#bf{Two Tags Comparison}", "C");  // option "C" allows to center the header
0882             leg->AddEntry(h_parts[part], (fmt::sprintf("%s : %i", tagName(), run())).c_str(), "F");
0883             leg->AddEntry(h_parts2[part], (fmt::sprintf("%s : %i", tagName2(), run2())).c_str(), "F");
0884           } else {
0885             leg->SetHeader(("tag: #bf{" + tagName() + "}").c_str(), "C");  // option "C" allows to center the header
0886             leg->AddEntry(h_parts[part], (fmt::sprintf("IOV since: %i", this->run())).c_str(), "F");
0887             leg->AddEntry(h_parts2[part], (fmt::sprintf("IOV since: %i", this->run2())).c_str(), "F");
0888           }
0889           leg->SetTextSize(0.035);
0890           leg->Draw("same");
0891           ltx.DrawLatexNDC(1 - gPad->GetRightMargin(),
0892                            1 - gPad->GetTopMargin() + 0.01,
0893                            (fmt::sprintf("#color[2]{%s} %s Values Comparison", part, payloadType_)).c_str());
0894         }
0895       }
0896     }
0897 
0898     /***********************************************************************/
0899     void fillCorrelationByPartition(TCanvas &canvas, int nbins, float min, float max)
0900     /***********************************************************************/
0901     {
0902       SiStripPI::setPaletteStyle(SiStripPI::DEFAULT); /* better looking palette ;)*/
0903 
0904       if (plotMode_ != COMPARISON) {
0905         throw cms::Exception("Logic error") << "not being in compared mode, cannot plot correlations";
0906       }
0907 
0908       std::map<std::string, TH2F *> h2_parts;
0909       std::vector<std::string> parts = {"TEC", "TOB", "TIB", "TID"};
0910 
0911       const char *device;
0912       switch (granularity_) {
0913         case PERSTRIP:
0914           device = "strips";
0915           break;
0916         case PERAPV:
0917           device = "APVs";
0918           break;
0919         case PERMODULE:
0920           device = "modules";
0921           break;
0922         default:
0923           device = "unrecognized device";
0924           break;
0925       }
0926 
0927       for (const auto &part : parts) {
0928         TString globalTitle = Form("%s - %s %s;%s %s (#color[4]{%s});%s %s (#color[4]{%s});n. %s",
0929                                    "Correlation",  // FIXME: can use the plotDescriptor()
0930                                    payloadType_.c_str(),
0931                                    part.c_str(),
0932                                    payloadType_.c_str(),
0933                                    (units_[payloadType_]).c_str(),
0934                                    std::to_string(run_).c_str(),
0935                                    payloadType_.c_str(),
0936                                    (units_[payloadType_]).c_str(),
0937                                    std::to_string(std::get<0>(additionalIOV_)).c_str(),
0938                                    device);
0939 
0940         h2_parts[part] = new TH2F(Form("h2_%s", part.c_str()), globalTitle, nbins, min, max, nbins, min, max);
0941       }
0942 
0943       if (!SiStripCondData_.isCached())
0944         storeAllValues();
0945       auto listOfDetIds = SiStripCondData_.detIds(false);
0946       for (const auto &detId : listOfDetIds) {
0947         auto values = SiStripCondData_.demuxedData(detId);
0948         int subid = DetId(detId).subdetId();
0949         unsigned int counter{0};
0950         for (const auto &value : values.first) {
0951           switch (subid) {
0952             case StripSubdetector::TIB:
0953               h2_parts["TIB"]->Fill(value, (values.second)[counter]);
0954               break;
0955             case StripSubdetector::TID:
0956               h2_parts["TID"]->Fill(value, (values.second)[counter]);
0957               break;
0958             case StripSubdetector::TOB:
0959               h2_parts["TOB"]->Fill(value, (values.second)[counter]);
0960               break;
0961             case StripSubdetector::TEC:
0962               h2_parts["TEC"]->Fill(value, (values.second)[counter]);
0963               break;
0964             default:
0965               edm::LogError("LogicError") << "Unknown partition: " << subid;
0966               break;
0967           }
0968           counter++;
0969         }
0970       }
0971 
0972       canvas.Divide(2, 2);
0973 
0974       int index = 0;
0975       for (const auto &part : parts) {
0976         index++;
0977         canvas.cd(index)->SetTopMargin(0.07);
0978         canvas.cd(index)->SetLeftMargin(0.13);
0979         canvas.cd(index)->SetRightMargin(0.17);
0980 
0981         SiStripPI::makeNicePlotStyle(h2_parts[part]);
0982         h2_parts[part]->GetZaxis()->SetTitleOffset(1.6);
0983         h2_parts[part]->GetZaxis()->SetTitleSize(0.04);
0984         h2_parts[part]->GetZaxis()->CenterTitle();
0985         h2_parts[part]->GetZaxis()->SetMaxDigits(2); /* exponentiate z-axis */
0986 
0987         //h2_parts[part]->SetMarkerColor(k_colormap.at(part));
0988         //h2_parts[part]->SetMarkerStyle(k_markermap.at(part));
0989         //h2_parts[part]->SetStats(false);
0990         //h2_parts[part]->Draw("P");
0991         h2_parts[part]->Draw("colz");
0992 
0993         TLegend *leg = new TLegend(.13, 0.87, 0.27, 0.93);
0994         leg->SetTextSize(0.045);
0995         leg->SetHeader(Form("#bf{%s}", part.c_str()), "C");  // option "C" allows to center the header
0996         //leg->AddEntry(h2_parts[part], Form("#DeltaIOV: #splitline{%i}{%i}", run_, std::get<0>(additionalIOV_)),"P");
0997         leg->Draw("same");
0998       }
0999     }
1000 
1001   protected:
1002     std::shared_ptr<Item> payload_;
1003     std::string payloadType_;
1004     SiStripCondDataItem<type> SiStripCondData_;
1005 
1006   private:
1007     unsigned int run_;
1008     std::string hash_;
1009     std::string tagname_;
1010     granularity granularity_;
1011     std::string TopoMode_;
1012     TrackerTopology m_trackerTopo;
1013     SiStripDetSummary summary{&m_trackerTopo};
1014     // "Map", "Ratio", or "Diff"
1015     plotType plotMode_;
1016     std::tuple<int, std::string, std::string> additionalIOV_;
1017 
1018     std::map<std::string, std::string> units_ = {{"SiStripPedestals", "[ADC counts]"},
1019                                                  {"SiStripApvGain", ""},  //dimensionless TODO: verify
1020                                                  {"SiStripNoises", "[ADC counts]"},
1021                                                  {"SiStripLorentzAngle", "[1/T}]"},
1022                                                  {"SiStripBackPlaneCorrection", ""},
1023                                                  {"SiStripBadStrip", ""},  // dimensionless
1024                                                  {"SiStripDetVOff", ""}};  // dimensionless
1025 
1026     std::string opType(SiStripPI::OpMode mode) {
1027       std::string types[3] = {"Strip", "APV", "Module"};
1028       return types[mode];
1029     }
1030   };
1031 
1032 }  // namespace SiStripCondObjectRepresent
1033 
1034 #endif