Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 10:54:25

0001 #include "DQM/EcalCommon/interface/MESetEcal.h"
0002 
0003 #include "DQM/EcalCommon/interface/EcalDQMCommonUtils.h"
0004 #include "DQM/EcalCommon/interface/MESetUtils.h"
0005 
0006 #include <limits>
0007 #include <sstream>
0008 
0009 namespace ecaldqm {
0010   MESetEcal::MESetEcal(std::string const &_fullPath,
0011                        binning::ObjectType _otype,
0012                        binning::BinningType _btype,
0013                        MonitorElement::Kind _kind,
0014                        unsigned _logicalDimensions,
0015                        binning::AxisSpecs const *_xaxis /* = 0*/,
0016                        binning::AxisSpecs const *_yaxis /* = 0*/,
0017                        binning::AxisSpecs const *_zaxis /* = 0*/)
0018       : MESet(_fullPath, _otype, _btype, _kind),
0019         logicalDimensions_(_logicalDimensions),
0020         xaxis_(_xaxis ? new binning::AxisSpecs(*_xaxis) : nullptr),
0021         yaxis_(_yaxis ? new binning::AxisSpecs(*_yaxis) : nullptr),
0022         zaxis_(_zaxis ? new binning::AxisSpecs(*_zaxis) : nullptr) {
0023     if (btype_ == binning::kUser && ((logicalDimensions_ > 0 && !xaxis_) || (logicalDimensions_ > 1 && !yaxis_)))
0024       throw_("Need axis specifications");
0025   }
0026 
0027   MESetEcal::MESetEcal(MESetEcal const &_orig)
0028       : MESet(_orig),
0029         logicalDimensions_(_orig.logicalDimensions_),
0030         xaxis_(_orig.xaxis_ ? new binning::AxisSpecs(*_orig.xaxis_) : nullptr),
0031         yaxis_(_orig.yaxis_ ? new binning::AxisSpecs(*_orig.yaxis_) : nullptr),
0032         zaxis_(_orig.zaxis_ ? new binning::AxisSpecs(*_orig.zaxis_) : nullptr) {}
0033 
0034   MESetEcal::~MESetEcal() {
0035     delete xaxis_;
0036     delete yaxis_;
0037     delete zaxis_;
0038   }
0039 
0040   MESet &MESetEcal::operator=(MESet const &_rhs) {
0041     delete xaxis_;
0042     delete yaxis_;
0043     delete zaxis_;
0044     xaxis_ = nullptr;
0045     yaxis_ = nullptr;
0046     zaxis_ = nullptr;
0047 
0048     MESetEcal const *pRhs(dynamic_cast<MESetEcal const *>(&_rhs));
0049     if (pRhs) {
0050       logicalDimensions_ = pRhs->logicalDimensions_;
0051       if (pRhs->xaxis_)
0052         xaxis_ = new binning::AxisSpecs(*pRhs->xaxis_);
0053       if (pRhs->yaxis_)
0054         yaxis_ = new binning::AxisSpecs(*pRhs->yaxis_);
0055       if (pRhs->zaxis_)
0056         zaxis_ = new binning::AxisSpecs(*pRhs->zaxis_);
0057     }
0058     return MESet::operator=(_rhs);
0059   }
0060 
0061   MESet *MESetEcal::clone(std::string const &_path /* = ""*/) const {
0062     std::string path(path_);
0063     if (!_path.empty())
0064       path_ = _path;
0065     MESet *copy(new MESetEcal(*this));
0066     path_ = path;
0067     return copy;
0068   }
0069 
0070   void MESetEcal::book(DQMStore::IBooker &_ibooker, EcalElectronicsMapping const *electronicsMap) {
0071     using namespace std;
0072 
0073     auto oldscope = MonitorElementData::Scope::RUN;
0074     if (lumiFlag_)
0075       oldscope = _ibooker.setScope(MonitorElementData::Scope::LUMI);
0076 
0077     clear();
0078 
0079     vector<string> mePaths(generatePaths(electronicsMap));
0080 
0081     for (unsigned iME(0); iME < mePaths.size(); iME++) {
0082       string &path(mePaths[iME]);
0083       if (path.find('%') != string::npos)
0084         throw_("book() called with incompletely formed path [" + path + "]");
0085 
0086       binning::ObjectType actualObject(binning::getObject(otype_, iME));
0087 
0088       binning::AxisSpecs xaxis, yaxis, zaxis;
0089 
0090       bool isHistogram(logicalDimensions_ > 0);
0091       bool isMap(logicalDimensions_ > 1);
0092 
0093       if (isHistogram) {
0094         if (xaxis_)
0095           xaxis = *xaxis_;
0096         if (yaxis_)
0097           yaxis = *yaxis_;
0098         if (zaxis_)
0099           zaxis = *zaxis_;
0100 
0101         if (xaxis.nbins == 0) {  // uses preset
0102           binning::AxisSpecs xdef(binning::getBinning(electronicsMap, actualObject, btype_, isMap, 1, iME));
0103           if (xaxis.labels || !xaxis.title.empty()) {  // PSet specifies title / label only
0104             std::string *labels(xaxis.labels);
0105             std::string title(xaxis.title);
0106             xaxis = xdef;
0107             delete[] xaxis.labels;
0108             xaxis.labels = labels;
0109             xaxis.title = title;
0110           } else
0111             xaxis = xdef;
0112         }
0113 
0114         if (isMap && yaxis.nbins == 0) {
0115           binning::AxisSpecs ydef(binning::getBinning(electronicsMap, actualObject, btype_, isMap, 2, iME));
0116           if (yaxis.labels || !yaxis.title.empty()) {  // PSet specifies title / label only
0117             std::string *labels(yaxis.labels);
0118             std::string title(yaxis.title);
0119             yaxis = ydef;
0120             delete[] yaxis.labels;
0121             yaxis.labels = labels;
0122             yaxis.title = title;
0123           } else
0124             yaxis = ydef;
0125         }
0126 
0127         if (yaxis.high - yaxis.low < 1.e-10) {
0128           yaxis.low = -numeric_limits<double>::max();
0129           yaxis.high = numeric_limits<double>::max();
0130         }
0131 
0132         if (zaxis.high - zaxis.low < 1.e-10) {
0133           zaxis.low = -numeric_limits<double>::max();
0134           zaxis.high = numeric_limits<double>::max();
0135         }
0136       }
0137 
0138       size_t slashPos(path.find_last_of('/'));
0139       string name(path.substr(slashPos + 1));
0140       _ibooker.cd();
0141       _ibooker.setCurrentFolder(path.substr(0, slashPos));
0142 
0143       MonitorElement *me(nullptr);
0144 
0145       switch (kind_) {
0146         case MonitorElement::Kind::REAL:
0147           me = _ibooker.bookFloat(name);
0148 
0149           break;
0150 
0151         case MonitorElement::Kind::TH1F:
0152           if (xaxis.edges)
0153             me = _ibooker.book1D(name, name, xaxis.nbins, xaxis.edges);
0154           else
0155             me = _ibooker.book1D(name, name, xaxis.nbins, xaxis.low, xaxis.high);
0156 
0157           break;
0158 
0159         case MonitorElement::Kind::TPROFILE:
0160           if (xaxis.edges) {
0161             // DQMStore bookProfile interface uses double* for bin edges
0162             double *edges(new double[xaxis.nbins + 1]);
0163             std::copy(xaxis.edges, xaxis.edges + xaxis.nbins + 1, edges);
0164             me = _ibooker.bookProfile(name, name, xaxis.nbins, edges, yaxis.low, yaxis.high, "");
0165             delete[] edges;
0166           } else
0167             me = _ibooker.bookProfile(name, name, xaxis.nbins, xaxis.low, xaxis.high, yaxis.low, yaxis.high, "");
0168 
0169           break;
0170 
0171         case MonitorElement::Kind::TH2F:
0172           if (xaxis.edges || yaxis.edges) {
0173             binning::AxisSpecs *specs[] = {&xaxis, &yaxis};
0174             for (int iSpec(0); iSpec < 2; iSpec++) {
0175               if (!specs[iSpec]->edges) {
0176                 specs[iSpec]->edges = new float[specs[iSpec]->nbins + 1];
0177                 int nbins(specs[iSpec]->nbins);
0178                 double low(specs[iSpec]->low), high(specs[iSpec]->high);
0179                 for (int i(0); i < nbins + 1; i++)
0180                   specs[iSpec]->edges[i] = low + (high - low) / nbins * i;
0181               }
0182             }
0183             me = _ibooker.book2D(name, name, xaxis.nbins, xaxis.edges, yaxis.nbins, yaxis.edges);
0184           } else
0185             me = _ibooker.book2D(name, name, xaxis.nbins, xaxis.low, xaxis.high, yaxis.nbins, yaxis.low, yaxis.high);
0186 
0187           break;
0188 
0189         case MonitorElement::Kind::TPROFILE2D:
0190           if (zaxis.edges) {
0191             zaxis.low = zaxis.edges[0];
0192             zaxis.high = zaxis.edges[zaxis.nbins];
0193           }
0194           if (xaxis.edges || yaxis.edges)
0195             throw_("Variable bin size for 2D profile not implemented");
0196           me = _ibooker.bookProfile2D(name,
0197                                       name,
0198                                       xaxis.nbins,
0199                                       xaxis.low,
0200                                       xaxis.high,
0201                                       yaxis.nbins,
0202                                       yaxis.low,
0203                                       yaxis.high,
0204                                       zaxis.low,
0205                                       zaxis.high,
0206                                       "");
0207 
0208           break;
0209 
0210         default:
0211           break;
0212       }
0213 
0214       if (!me)
0215         throw_("ME could not be booked");
0216 
0217       if (isHistogram) {
0218         me->setAxisTitle(xaxis.title, 1);
0219         me->setAxisTitle(yaxis.title, 2);
0220         if (isMap)
0221           me->setAxisTitle(zaxis.title, 3);
0222 
0223         if (xaxis.labels) {
0224           for (int iBin(1); iBin <= xaxis.nbins; ++iBin)
0225             me->setBinLabel(iBin, xaxis.labels[iBin - 1], 1);
0226         }
0227         if (yaxis.labels) {
0228           for (int iBin(1); iBin <= yaxis.nbins; ++iBin)
0229             me->setBinLabel(iBin, yaxis.labels[iBin - 1], 2);
0230         }
0231         if (zaxis.labels) {
0232           for (int iBin(1); iBin <= zaxis.nbins; ++iBin)
0233             me->setBinLabel(iBin, zaxis.labels[iBin - 1], 3);
0234         }
0235 
0236         /* FIX: In ROOT 6.0.12 bit 20 is used by ROOT (bit 19 was already in use
0237       in 6.0.x). Talking with the ROOT team, users should never use SetBit for
0238       their own purpose since those bits are reserved for ROOT internally. See
0239       https://github.com/cms-sw/cmssw/issues/21423 for some alternative ways of
0240       attaching additional information to a TH1
0241 
0242       // For plot tagging in RenderPlugin; default values are 1 for both
0243       // bits 19 - 23 are free in TH1::fBits
0244       // can only pack object + logical dimensions into 5 bits (4 bits for
0245       object, 1 bit for dim (1 -> dim >= 2))
0246       me->getTH1()->SetBit(uint32_t(actualObject + 1) << 20);
0247       if(isMap) me->getTH1()->SetBit(0x1 << 19);
0248       */
0249 
0250         // The render plugin requires some metadata in order to set the correct
0251         // rendering for each plot. The original solution was to use bits number
0252         // 19 to 23 in TH1::fBits, but these were meant for ROOT's internal usage
0253         // and eventually started breaking things, see:
0254         // https://github.com/cms-sw/cmssw/issues/21423 The current solution is to
0255         // use the UniqueID field in the parent TObject, which is expected to work
0256         // if there is no TRef pointing to the TObject.
0257 
0258         // To check that indeed there is no such TRef, one can use
0259         // TestBit(kIsReferenced), e.g. std::cout << "Need to set unique ID at
0260         // path = " << path << "; for this path, TestBit(kIsReferenced) is: " <<
0261         // (me->getTH1()->TestBit(kIsReferenced)? "true": "false") << std::endl;
0262         // // should always output false for the solution to work
0263 
0264         // Originally, bit 19 in TH1::fBits was set to isMap, while bits 20-23
0265         // contained (actualObject+1). The idea is to make sure that both these
0266         // variables are easily recoverable in the render plugin, as in this
0267         // solution, where isMap is the last bit.
0268         me->getTH1()->SetUniqueID(uint32_t(2 * (actualObject + 1) + (isMap ? 1 : 0)));
0269       }
0270 
0271       mes_.push_back(me);
0272     }
0273 
0274     if (lumiFlag_)
0275       _ibooker.setScope(oldscope);
0276 
0277     active_ = true;
0278   }
0279 
0280   bool MESetEcal::retrieve(EcalElectronicsMapping const *electronicsMap,
0281                            DQMStore::IGetter &_igetter,
0282                            std::string *_failedPath /* = 0*/) const {
0283     clear();
0284 
0285     std::vector<std::string> mePaths(generatePaths(electronicsMap));
0286     if (mePaths.empty()) {
0287       if (_failedPath)
0288         _failedPath->clear();
0289       return false;
0290     }
0291 
0292     for (unsigned iME(0); iME < mePaths.size(); iME++) {
0293       std::string &path(mePaths[iME]);
0294       if (path.find('%') != std::string::npos)
0295         throw_("retrieve() called with incompletely formed path [" + path + "]");
0296 
0297       MonitorElement *me(_igetter.get(path));
0298       if (me)
0299         mes_.push_back(me);
0300       else {
0301         clear();
0302         if (_failedPath)
0303           *_failedPath = path;
0304         return false;
0305       }
0306     }
0307 
0308     active_ = true;
0309     return true;
0310   }
0311 
0312   void MESetEcal::fill(EcalDQMSetupObjects const edso,
0313                        DetId const &_id,
0314                        double _x /* = 1.*/,
0315                        double _wy /* = 1.*/,
0316                        double _w /* = 1.*/) {
0317     if (!active_)
0318       return;
0319 
0320     unsigned iME(binning::findPlotIndex(edso.electronicsMap, otype_, _id));
0321     checkME_(iME);
0322 
0323     fill_(iME, _x, _wy, _w);
0324   }
0325 
0326   void MESetEcal::fill(EcalDQMSetupObjects const edso,
0327                        EcalElectronicsId const &_id,
0328                        double _x /* = 1.*/,
0329                        double _wy /* = 1.*/,
0330                        double _w /* = 1.*/) {
0331     if (!active_)
0332       return;
0333 
0334     unsigned iME(binning::findPlotIndex(edso.electronicsMap, otype_, _id));
0335     checkME_(iME);
0336 
0337     fill_(iME, _x, _wy, _w);
0338   }
0339 
0340   void MESetEcal::fill(
0341       EcalDQMSetupObjects const edso, int _dcctccid, double _x /* = 1.*/, double _wy /* = 1.*/, double _w /* = 1.*/) {
0342     if (!active_)
0343       return;
0344 
0345     unsigned iME(binning::findPlotIndex(edso.electronicsMap, otype_, _dcctccid, btype_));
0346     checkME_(iME);
0347 
0348     fill_(iME, _x, _wy, _w);
0349   }
0350 
0351   void MESetEcal::fill(EcalDQMSetupObjects const edso, double _x, double _wy /* = 1.*/, double _w /* = 1.*/) {
0352     if (!active_)
0353       return;
0354 
0355     if (mes_.size() != 1)
0356       return;
0357 
0358     fill_(0, _x, _wy, _w);
0359   }
0360 
0361   void MESetEcal::setBinContent(EcalDQMSetupObjects const edso, DetId const &_id, int _bin, double _content) {
0362     if (!active_)
0363       return;
0364 
0365     unsigned iME(binning::findPlotIndex(edso.electronicsMap, otype_, _id));
0366     checkME_(iME);
0367 
0368     mes_[iME]->setBinContent(_bin, _content);
0369   }
0370 
0371   void MESetEcal::setBinContent(EcalDQMSetupObjects const edso,
0372                                 EcalElectronicsId const &_id,
0373                                 int _bin,
0374                                 double _content) {
0375     if (!active_)
0376       return;
0377 
0378     unsigned iME(binning::findPlotIndex(edso.electronicsMap, otype_, _id));
0379     checkME_(iME);
0380 
0381     mes_[iME]->setBinContent(_bin, _content);
0382   }
0383 
0384   void MESetEcal::setBinContent(EcalDQMSetupObjects const edso, int _dcctccid, int _bin, double _content) {
0385     if (!active_)
0386       return;
0387 
0388     unsigned iME(binning::findPlotIndex(edso.electronicsMap, otype_, _dcctccid, btype_));
0389     checkME_(iME);
0390 
0391     mes_[iME]->setBinContent(_bin, _content);
0392   }
0393 
0394   void MESetEcal::setBinError(EcalDQMSetupObjects const edso, DetId const &_id, int _bin, double _error) {
0395     if (!active_)
0396       return;
0397 
0398     unsigned iME(binning::findPlotIndex(edso.electronicsMap, otype_, _id));
0399     checkME_(iME);
0400 
0401     mes_[iME]->setBinError(_bin, _error);
0402   }
0403 
0404   void MESetEcal::setBinError(EcalDQMSetupObjects const edso, EcalElectronicsId const &_id, int _bin, double _error) {
0405     if (!active_)
0406       return;
0407 
0408     unsigned iME(binning::findPlotIndex(edso.electronicsMap, otype_, _id));
0409     checkME_(iME);
0410 
0411     mes_[iME]->setBinError(_bin, _error);
0412   }
0413 
0414   void MESetEcal::setBinError(EcalDQMSetupObjects const edso, int _dcctccid, int _bin, double _error) {
0415     if (!active_)
0416       return;
0417 
0418     unsigned iME(binning::findPlotIndex(edso.electronicsMap, otype_, _dcctccid, btype_));
0419     checkME_(iME);
0420 
0421     mes_[iME]->setBinError(_bin, _error);
0422   }
0423 
0424   void MESetEcal::setBinEntries(EcalDQMSetupObjects const edso, DetId const &_id, int _bin, double _entries) {
0425     if (!active_)
0426       return;
0427     if (kind_ != MonitorElement::Kind::TPROFILE && kind_ != MonitorElement::Kind::TPROFILE2D)
0428       return;
0429 
0430     unsigned iME(binning::findPlotIndex(edso.electronicsMap, otype_, _id));
0431     checkME_(iME);
0432 
0433     mes_[iME]->setBinEntries(_bin, _entries);
0434   }
0435 
0436   void MESetEcal::setBinEntries(EcalDQMSetupObjects const edso,
0437                                 EcalElectronicsId const &_id,
0438                                 int _bin,
0439                                 double _entries) {
0440     if (!active_)
0441       return;
0442     if (kind_ != MonitorElement::Kind::TPROFILE && kind_ != MonitorElement::Kind::TPROFILE2D)
0443       return;
0444 
0445     unsigned iME(binning::findPlotIndex(edso.electronicsMap, otype_, _id));
0446     checkME_(iME);
0447 
0448     mes_[iME]->setBinEntries(_bin, _entries);
0449   }
0450 
0451   void MESetEcal::setBinEntries(EcalDQMSetupObjects const edso, int _dcctccid, int _bin, double _entries) {
0452     if (!active_)
0453       return;
0454     if (kind_ != MonitorElement::Kind::TPROFILE && kind_ != MonitorElement::Kind::TPROFILE2D)
0455       return;
0456 
0457     unsigned iME(binning::findPlotIndex(edso.electronicsMap, otype_, _dcctccid, btype_));
0458     checkME_(iME);
0459 
0460     mes_[iME]->setBinEntries(_bin, _entries);
0461   }
0462 
0463   double MESetEcal::getBinContent(EcalDQMSetupObjects const edso, DetId const &_id, int _bin) const {
0464     if (!active_)
0465       return 0.;
0466 
0467     unsigned iME(binning::findPlotIndex(edso.electronicsMap, otype_, _id));
0468     checkME_(iME);
0469 
0470     return mes_[iME]->getBinContent(_bin);
0471   }
0472 
0473   double MESetEcal::getBinContent(EcalDQMSetupObjects const edso, EcalElectronicsId const &_id, int _bin) const {
0474     if (!active_)
0475       return 0.;
0476 
0477     unsigned iME(binning::findPlotIndex(edso.electronicsMap, otype_, _id));
0478     checkME_(iME);
0479 
0480     return mes_[iME]->getBinContent(_bin);
0481   }
0482 
0483   double MESetEcal::getBinContent(EcalDQMSetupObjects const edso, int _dcctccid, int _bin) const {
0484     if (!active_)
0485       return 0.;
0486 
0487     unsigned iME(binning::findPlotIndex(edso.electronicsMap, otype_, _dcctccid, btype_));
0488     checkME_(iME);
0489 
0490     return mes_[iME]->getBinContent(_bin);
0491   }
0492 
0493   double MESetEcal::getBinError(EcalDQMSetupObjects const edso, DetId const &_id, int _bin) const {
0494     if (!active_)
0495       return 0.;
0496 
0497     unsigned iME(binning::findPlotIndex(edso.electronicsMap, otype_, _id));
0498     checkME_(iME);
0499 
0500     return mes_[iME]->getBinError(_bin);
0501   }
0502 
0503   double MESetEcal::getBinError(EcalDQMSetupObjects const edso, EcalElectronicsId const &_id, int _bin) const {
0504     if (!active_)
0505       return 0.;
0506 
0507     unsigned iME(binning::findPlotIndex(edso.electronicsMap, otype_, _id));
0508     checkME_(iME);
0509 
0510     return mes_[iME]->getBinError(_bin);
0511   }
0512 
0513   double MESetEcal::getBinError(EcalDQMSetupObjects const edso, int _dcctccid, int _bin) const {
0514     if (!active_)
0515       return 0.;
0516 
0517     unsigned iME(binning::findPlotIndex(edso.electronicsMap, otype_, _dcctccid, btype_));
0518     checkME_(iME);
0519 
0520     return mes_[iME]->getBinError(_bin);
0521   }
0522 
0523   double MESetEcal::getBinEntries(EcalDQMSetupObjects const edso, DetId const &_id, int _bin) const {
0524     if (!active_)
0525       return 0.;
0526     if (kind_ != MonitorElement::Kind::TPROFILE && kind_ != MonitorElement::Kind::TPROFILE2D)
0527       return 0.;
0528 
0529     unsigned iME(binning::findPlotIndex(edso.electronicsMap, otype_, _id));
0530     checkME_(iME);
0531 
0532     return mes_[iME]->getBinEntries(_bin);
0533   }
0534 
0535   double MESetEcal::getBinEntries(EcalDQMSetupObjects const edso, EcalElectronicsId const &_id, int _bin) const {
0536     if (!active_)
0537       return 0.;
0538     if (kind_ != MonitorElement::Kind::TPROFILE && kind_ != MonitorElement::Kind::TPROFILE2D)
0539       return 0.;
0540 
0541     unsigned iME(binning::findPlotIndex(edso.electronicsMap, otype_, _id));
0542     checkME_(iME);
0543 
0544     return mes_[iME]->getBinEntries(_bin);
0545   }
0546 
0547   double MESetEcal::getBinEntries(EcalDQMSetupObjects const edso, int _dcctccid, int _bin) const {
0548     if (!active_)
0549       return 0.;
0550     if (kind_ != MonitorElement::Kind::TPROFILE && kind_ != MonitorElement::Kind::TPROFILE2D)
0551       return 0.;
0552 
0553     unsigned iME(binning::findPlotIndex(edso.electronicsMap, otype_, _dcctccid, btype_));
0554     checkME_(iME);
0555 
0556     return mes_[iME]->getBinEntries(_bin);
0557   }
0558 
0559   int MESetEcal::findBin(EcalDQMSetupObjects const edso, DetId const &_id, double _x, double _y /* = 0.*/) const {
0560     if (!active_)
0561       return -1;
0562 
0563     unsigned iME(binning::findPlotIndex(edso.electronicsMap, otype_, _id));
0564     checkME_(iME);
0565 
0566     return mes_[iME]->getTH1()->FindBin(_x, _y);
0567   }
0568 
0569   int MESetEcal::findBin(EcalDQMSetupObjects const edso,
0570                          EcalElectronicsId const &_id,
0571                          double _x,
0572                          double _y /* = 0.*/) const {
0573     if (!active_)
0574       return -1;
0575 
0576     unsigned iME(binning::findPlotIndex(edso.electronicsMap, otype_, _id));
0577     checkME_(iME);
0578 
0579     return mes_[iME]->getTH1()->FindBin(_x, _y);
0580   }
0581 
0582   int MESetEcal::findBin(EcalDQMSetupObjects const edso, int _dcctccid, double _x, double _y /* = 0.*/) const {
0583     if (!active_)
0584       return -1;
0585 
0586     unsigned iME(binning::findPlotIndex(edso.electronicsMap, otype_, _dcctccid, btype_));
0587     checkME_(iME);
0588 
0589     return mes_[iME]->getTH1()->FindBin(_x, _y);
0590   }
0591 
0592   bool MESetEcal::isVariableBinning() const {
0593     return (xaxis_ && xaxis_->edges) || (yaxis_ && yaxis_->edges) || (zaxis_ && zaxis_->edges);
0594   }
0595 
0596   std::vector<std::string> MESetEcal::generatePaths(EcalElectronicsMapping const *electronicsMap) const {
0597     using namespace std;
0598 
0599     vector<string> paths(0);
0600 
0601     unsigned nME(binning::getNObjects(otype_));
0602 
0603     for (unsigned iME(0); iME < nME; iME++) {
0604       binning::ObjectType obj(binning::getObject(otype_, iME));
0605 
0606       string path(path_);
0607       map<string, string> replacements;
0608 
0609       switch (obj) {
0610         case binning::kEB:
0611         case binning::kEBMEM:
0612           replacements["subdet"] = "EcalBarrel";
0613           replacements["prefix"] = "EB";
0614           replacements["suffix"] = "";
0615           replacements["subdetshort"] = "EB";
0616           replacements["subdetshortsig"] = "EB";
0617           replacements["supercrystal"] = "trigger tower";
0618           break;
0619         case binning::kEE:
0620         case binning::kEEMEM:
0621           replacements["subdet"] = "EcalEndcap";
0622           replacements["prefix"] = "EE";
0623           replacements["subdetshort"] = "EE";
0624           replacements["subdetshortsig"] = "EE";
0625           replacements["supercrystal"] = "super crystal";
0626           break;
0627         case binning::kEEm:
0628           replacements["subdet"] = "EcalEndcap";
0629           replacements["prefix"] = "EE";
0630           replacements["suffix"] = " EE -";
0631           replacements["subdetshort"] = "EE";
0632           replacements["subdetshortsig"] = "EEM";
0633           replacements["supercrystal"] = "super crystal";
0634           break;
0635         case binning::kEEp:
0636           replacements["subdet"] = "EcalEndcap";
0637           replacements["prefix"] = "EE";
0638           replacements["suffix"] = " EE +";
0639           replacements["subdetshort"] = "EE";
0640           replacements["subdetshortsig"] = "EEP";
0641           replacements["supercrystal"] = "super crystal";
0642           break;
0643         case binning::kSM:
0644           if (iME <= kEEmHigh || iME >= kEEpLow) {
0645             replacements["subdet"] = "EcalEndcap";
0646             replacements["prefix"] = "EE";
0647             replacements["supercrystal"] = "super crystal";
0648           } else {
0649             replacements["subdet"] = "EcalBarrel";
0650             replacements["prefix"] = "EB";
0651             replacements["supercrystal"] = "trigger tower";
0652           }
0653           replacements["sm"] = binning::channelName(electronicsMap, iME + 1);
0654           break;
0655         case binning::kEBSM:
0656           replacements["subdet"] = "EcalBarrel";
0657           replacements["prefix"] = "EB";
0658           replacements["sm"] = binning::channelName(electronicsMap, iME + kEBmLow + 1);
0659           replacements["supercrystal"] = "trigger tower";
0660           break;
0661         case binning::kEESM:
0662           replacements["subdet"] = "EcalEndcap";
0663           replacements["prefix"] = "EE";
0664           replacements["sm"] = binning::channelName(electronicsMap, iME <= kEEmHigh ? iME + 1 : iME + 37);
0665           replacements["supercrystal"] = "super crystal";
0666           break;
0667         case binning::kSMMEM: {
0668           unsigned iDCC(memDCCId(iME) - 1);
0669           // dccId(unsigned) skips DCCs without MEM
0670           if (iDCC <= kEEmHigh || iDCC >= kEEpLow) {
0671             replacements["subdet"] = "EcalEndcap";
0672             replacements["prefix"] = "EE";
0673           } else {
0674             replacements["subdet"] = "EcalBarrel";
0675             replacements["prefix"] = "EB";
0676           }
0677           replacements["sm"] = binning::channelName(electronicsMap, iDCC + 1);
0678         } break;
0679         case binning::kEBSMMEM: {
0680           unsigned iDCC(memDCCId(iME + 4) - 1);
0681           replacements["subdet"] = "EcalBarrel";
0682           replacements["prefix"] = "EB";
0683           replacements["sm"] = binning::channelName(electronicsMap, iDCC + 1);
0684         } break;
0685         case binning::kEESMMEM: {
0686           unsigned iDCC(memDCCId(iME < 4 ? iME : iME + 36) - 1);
0687           replacements["subdet"] = "EcalEndcap";
0688           replacements["prefix"] = "EE";
0689           replacements["sm"] = binning::channelName(electronicsMap, iDCC + 1);
0690         }
0691         default:
0692           break;
0693       }
0694 
0695       paths.push_back(formPath(replacements));
0696     }
0697 
0698     return paths;
0699   }
0700 }  // namespace ecaldqm