CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/DQM/EcalCommon/src/MESetEcal.cc

Go to the documentation of this file.
00001 #include "DQM/EcalCommon/interface/MESetEcal.h"
00002 
00003 #include "DQM/EcalCommon/interface/EcalDQMCommonUtils.h"
00004 
00005 #include "FWCore/Utilities/interface/Exception.h"
00006 
00007 #include <limits>
00008 
00009 namespace ecaldqm
00010 {
00011 
00012   MESetEcal::MESetEcal(std::string const& _fullpath, MEData const& _data, int _logicalDimensions, bool _readOnly/* = false*/) :
00013     MESet(_fullpath, _data, _readOnly),
00014     logicalDimensions_(_logicalDimensions),
00015     cacheId_(0),
00016     cache_(std::make_pair(-1, std::vector<int>(0)))
00017   {
00018     if(data_->btype == BinService::kUser && ((logicalDimensions_ > 0 && !data_->xaxis) || (logicalDimensions_ > 1 && !data_->yaxis)))
00019       throw cms::Exception("InvalidCall") << "Need axis specifications" << std::endl;
00020   }
00021 
00022   MESetEcal::~MESetEcal()
00023   {
00024   }
00025 
00026   void
00027   MESetEcal::book()
00028   {
00029     using namespace std;
00030 
00031     clear();
00032 
00033     dqmStore_->setCurrentFolder(dir_);
00034 
00035     if(data_->btype == BinService::kReport && name_ == "")
00036       name_ = dir_.substr(0, dir_.find_first_of('/'));
00037 
00038     std::vector<std::string> meNames(generateNames());
00039 
00040     for(unsigned iME(0); iME < meNames.size(); iME++){
00041       unsigned iObj(iME);
00042 
00043       BinService::ObjectType actualObject(binService_->objectFromOffset(data_->otype, iObj));
00044 
00045       BinService::AxisSpecs xaxis, yaxis, zaxis;
00046 
00047       if(logicalDimensions_ > 0){
00048         if(data_->xaxis){
00049           xaxis = *data_->xaxis;
00050         }
00051         else{ // uses preset
00052           bool isMap(logicalDimensions_ > 1);
00053           vector<BinService::AxisSpecs> presetAxes(binService_->getBinning(actualObject, data_->btype, isMap, iObj));
00054           if(presetAxes.size() != logicalDimensions_)
00055             throw cms::Exception("InvalidCall") << "Dimensionality mismatch " << data_->otype << " " << data_->btype << " " << iObj << std::endl;
00056 
00057           xaxis = presetAxes[0];
00058           if(isMap) yaxis = presetAxes[1];
00059         }
00060 
00061         if(data_->yaxis){
00062           yaxis = *data_->yaxis;
00063         }
00064         if(logicalDimensions_ == 1 && yaxis.high - yaxis.low < 0.0001){
00065           yaxis.low = -numeric_limits<double>::max();
00066           yaxis.high = numeric_limits<double>::max();
00067         }
00068 
00069         if(data_->zaxis){
00070           zaxis = *data_->zaxis;
00071         }
00072         if(logicalDimensions_ > 1 && zaxis.high - zaxis.low < 0.0001){
00073           zaxis.low = -numeric_limits<double>::max();
00074           zaxis.high = numeric_limits<double>::max();
00075         }
00076       }
00077 
00078       MonitorElement* me(0);
00079 
00080       switch(data_->kind) {
00081       case MonitorElement::DQM_KIND_REAL :
00082         me = dqmStore_->bookFloat(meNames[iME]);
00083 
00084         break;
00085 
00086       case MonitorElement::DQM_KIND_TH1F :
00087         if(xaxis.edges){
00088           float* edges(new float[xaxis.nbins + 1]);
00089           for(int i(0); i < xaxis.nbins + 1; i++)
00090             edges[i] = xaxis.edges[i];
00091           me = dqmStore_->book1D(meNames[iME], meNames[iME], xaxis.nbins, edges);
00092           delete [] edges;
00093         }
00094         else
00095           me = dqmStore_->book1D(meNames[iME], meNames[iME], xaxis.nbins, xaxis.low, xaxis.high);
00096 
00097         break;
00098 
00099       case MonitorElement::DQM_KIND_TPROFILE :
00100         if(xaxis.edges) {
00101           me = dqmStore_->bookProfile(meNames[iME], meNames[iME], xaxis.nbins, xaxis.edges, yaxis.low, yaxis.high, "");
00102         }
00103         else
00104           me = dqmStore_->bookProfile(meNames[iME], meNames[iME], xaxis.nbins, xaxis.low, xaxis.high, yaxis.low, yaxis.high, "");
00105 
00106         break;
00107 
00108       case MonitorElement::DQM_KIND_TH2F :
00109         if(xaxis.edges || yaxis.edges) {
00110           BinService::AxisSpecs* specs[] = {&xaxis, &yaxis};
00111           float* edges[] = {new float[xaxis.nbins + 1], new float[yaxis.nbins + 1]};
00112           for(int iSpec(0); iSpec < 2; iSpec++){
00113             if(specs[iSpec]->edges){
00114               for(int i(0); i < specs[iSpec]->nbins + 1; i++)
00115                 edges[iSpec][i] = specs[iSpec]->edges[i];
00116             }
00117             else{
00118               int nbins(specs[iSpec]->nbins);
00119               double low(specs[iSpec]->low), high(specs[iSpec]->high);
00120               for(int i(0); i < nbins + 1; i++)
00121                 edges[iSpec][i] = low + (high - low) / nbins * i;
00122             }
00123           }
00124           me = dqmStore_->book2D(meNames[iME], meNames[iME], xaxis.nbins, edges[0], yaxis.nbins, edges[1]);
00125           for(int iSpec(0); iSpec < 2; iSpec++)
00126             delete [] edges[iSpec];
00127         }
00128         else
00129           me = dqmStore_->book2D(meNames[iME], meNames[iME], xaxis.nbins, xaxis.low, xaxis.high, yaxis.nbins, yaxis.low, yaxis.high);
00130 
00131         break;
00132 
00133       case MonitorElement::DQM_KIND_TPROFILE2D :
00134         if(zaxis.edges) {
00135           zaxis.low = zaxis.edges[0];
00136           zaxis.high = zaxis.edges[zaxis.nbins];
00137         }
00138         if(xaxis.edges || yaxis.edges)
00139           throw cms::Exception("InvalidCall") << "Variable bin size for 2D profile not implemented" << std::endl;
00140         me = dqmStore_->bookProfile2D(meNames[iME], meNames[iME], xaxis.nbins, xaxis.low, xaxis.high, yaxis.nbins, yaxis.low, yaxis.high, zaxis.low, zaxis.high, "");
00141 
00142         break;
00143 
00144       default :
00145         break;
00146       }
00147 
00148       if(!me)
00149         throw cms::Exception("InvalidCall") << "ME could not be booked" << std::endl;
00150 
00151       if(logicalDimensions_ > 0){
00152         me->setAxisTitle(xaxis.title, 1);
00153         me->setAxisTitle(yaxis.title, 2);
00154         // For plot tagging in RenderPlugin; default values are 1 for both
00155         me->getTH1()->SetMarkerStyle(actualObject + 2);
00156         me->getTH1()->SetMarkerStyle(data_->btype + 2);
00157       }
00158 
00159       if(logicalDimensions_ == 1 && data_->btype == BinService::kDCC){
00160         if(actualObject == BinService::kEB){
00161           for(int iBin(1); iBin <= me->getNbinsX(); iBin++)
00162             me->setBinLabel(iBin, binService_->channelName(iBin + kEBmLow));
00163         }
00164         else if(actualObject == BinService::kEE){
00165           for(int iBin(1); iBin <= me->getNbinsX() / 2; iBin++){
00166             unsigned dccid((iBin + 2) % 9 + 1);
00167             me->setBinLabel(iBin, binService_->channelName(dccid));
00168           }
00169           for(int iBin(1); iBin <= me->getNbinsX() / 2; iBin++){
00170             unsigned dccid((iBin + 2) % 9 + 46);
00171             me->setBinLabel(iBin + me->getNbinsX() / 2, binService_->channelName(dccid));
00172           }
00173         }
00174         else if(actualObject == BinService::kEEm){
00175           for(int iBin(1); iBin <= me->getNbinsX(); iBin++){
00176             unsigned dccid((iBin + 2) % 9 + 1);
00177             me->setBinLabel(iBin, binService_->channelName(dccid));
00178           }
00179         }
00180         else if(actualObject == BinService::kEEp){
00181           for(int iBin(1); iBin <= me->getNbinsX(); iBin++){
00182             unsigned dccid((iBin + 2) % 9 + 46);
00183             me->setBinLabel(iBin, binService_->channelName(dccid));
00184           }
00185         }
00186       }
00187       
00188       mes_.push_back(me);
00189     }
00190 
00191     // To avoid the ambiguity between "content == 0 because the mean is 0" and "content == 0 because the entry is 0"
00192     // RenderPlugin must be configured accordingly
00193     if(data_->kind == MonitorElement::DQM_KIND_TPROFILE2D)
00194       resetAll(std::numeric_limits<double>::max(), 0., -1.);
00195 
00196     active_ = true;
00197   }
00198 
00199   bool
00200   MESetEcal::retrieve() const
00201   {
00202     clear();
00203 
00204     std::vector<std::string> meNames(generateNames());
00205     if(meNames.size() == 0) return false;
00206 
00207     for(unsigned iME(0); iME < meNames.size(); iME++){
00208       MonitorElement* me(dqmStore_->get(dir_ + "/" + meNames[iME]));
00209       if(me) mes_.push_back(me);
00210       else{
00211         clear();
00212         return false;
00213       }
00214     }
00215 
00216     active_ = true;
00217     return true;
00218   }
00219 
00220   void
00221   MESetEcal::fill(DetId const& _id, double _x/* = 1.*/, double _wy/* = 1.*/, double _w/* = 1.*/)
00222   {
00223     unsigned offset(binService_->findOffset(data_->otype, _id));
00224     if(offset >= mes_.size() || !mes_[offset])
00225       throw cms::Exception("InvalidCall") << "ME array index overflow" << std::endl;
00226 
00227     MESet::fill_(offset, _x, _wy, _w);
00228   }
00229 
00230   void
00231   MESetEcal::fill(unsigned _dcctccid, double _x/* = 1.*/, double _wy/* = 1.*/, double _w/* = 1.*/)
00232   {
00233     unsigned offset(binService_->findOffset(data_->otype, data_->btype, _dcctccid));
00234 
00235     if(offset >= mes_.size() || !mes_[offset])
00236       throw cms::Exception("InvalidCall") << "ME array index overflow" << offset << std::endl;
00237 
00238     MESet::fill_(offset, _x, _wy, _w);
00239   }
00240 
00241   void
00242   MESetEcal::fill(double _x, double _wy/* = 1.*/, double _w/* = 1.*/)
00243   {
00244     if(mes_.size() != 1)
00245       throw cms::Exception("InvalidCall") << "MESet type incompatible" << std::endl;
00246 
00247     MESet::fill_(0, _x, _wy, _w);
00248   }
00249 
00250   void
00251   MESetEcal::setBinContent(DetId const& _id, double _content, double _err/* = 0.*/)
00252   {
00253     find_(_id);
00254 
00255     std::vector<int>& bins(cache_.second);
00256     for(std::vector<int>::iterator binItr(bins.begin()); binItr != bins.end(); ++binItr)
00257       setBinContent_(cache_.first, *binItr, _content, _err);
00258   }
00259 
00260   void
00261   MESetEcal::setBinContent(unsigned _dcctccid, double _content, double _err/* = 0.*/)
00262   {
00263     find_(_dcctccid);
00264 
00265     std::vector<int>& bins(cache_.second);
00266     for(std::vector<int>::iterator binItr(bins.begin()); binItr != bins.end(); ++binItr)
00267       setBinContent_(cache_.first, *binItr, _content, _err);
00268   }
00269 
00270   void
00271   MESetEcal::setBinEntries(DetId const& _id, double _entries)
00272   {
00273     find_(_id);
00274 
00275     std::vector<int>& bins(cache_.second);
00276     for(std::vector<int>::iterator binItr(bins.begin()); binItr != bins.end(); ++binItr)
00277       setBinEntries_(cache_.first, *binItr, _entries);
00278   }
00279 
00280   void
00281   MESetEcal::setBinEntries(unsigned _dcctccid, double _entries)
00282   {
00283     find_(_dcctccid);
00284 
00285     std::vector<int>& bins(cache_.second);
00286     for(std::vector<int>::iterator binItr(bins.begin()); binItr != bins.end(); ++binItr)
00287       setBinEntries_(cache_.first, *binItr, _entries);
00288   }
00289 
00290   double
00291   MESetEcal::getBinContent(DetId const& _id, int) const
00292   {
00293     find_(_id);
00294 
00295     if(cache_.second.size() == 0) return 0.;
00296 
00297     return getBinContent_(cache_.first, cache_.second[0]);
00298   }
00299 
00300   double
00301   MESetEcal::getBinContent(unsigned _dcctccid, int) const
00302   {
00303     find_(_dcctccid);
00304 
00305     if(cache_.second.size() == 0) return 0.;
00306 
00307     return getBinContent_(cache_.first, cache_.second[0]);
00308   }
00309 
00310   double
00311   MESetEcal::getBinError(DetId const& _id, int) const
00312   {
00313     find_(_id);
00314 
00315     if(cache_.second.size() == 0) return 0.;
00316 
00317     return getBinError_(cache_.first, cache_.second[0]);
00318   }
00319 
00320   double
00321   MESetEcal::getBinError(unsigned _dcctccid, int) const
00322   {
00323     find_(_dcctccid);
00324 
00325     if(cache_.second.size() == 0) return 0.;
00326     
00327     return getBinError_(cache_.first, cache_.second[0]);
00328   }
00329 
00330   double
00331   MESetEcal::getBinEntries(DetId const& _id, int) const
00332   {
00333     find_(_id);
00334 
00335     if(cache_.second.size() == 0) return 0.;
00336 
00337     return getBinEntries_(cache_.first, cache_.second[0]);
00338   }
00339 
00340   double
00341   MESetEcal::getBinEntries(unsigned _dcctccid, int) const
00342   {
00343     find_(_dcctccid);
00344 
00345     if(cache_.second.size() == 0) return 0.;
00346     
00347     return getBinEntries_(cache_.first, cache_.second[0]);
00348   }
00349 
00350   void
00351   MESetEcal::reset(double _content/* = 0.*/, double _err/* = 0.*/, double _entries/* = 0.*/)
00352   {
00353     using namespace std;
00354 
00355     if(data_->btype >= unsigned(BinService::nPresetBinnings)){
00356       MESet::reset(_content, _err, _entries);
00357       return;
00358     }
00359 
00360     unsigned nME(1);
00361     switch(data_->otype){
00362     case BinService::kSM:
00363       nME = BinService::nDCC;
00364       break;
00365     case BinService::kSMMEM:
00366       nME = BinService::nDCCMEM;
00367       break;
00368     case BinService::kEcal2P:
00369       nME = 2;
00370       break;
00371     case BinService::kEcal3P:
00372       nME = 3;
00373       break;
00374     case BinService::kEcalMEM2P:
00375       nME = 2;
00376       break;
00377     default:
00378       break;
00379     }
00380 
00381     for(unsigned iME(0); iME < nME; iME++) {
00382       unsigned iObj(iME);
00383 
00384       BinService::ObjectType okey(binService_->objectFromOffset(data_->otype, iObj));
00385       BinService::BinningType bkey(data_->btype);
00386       if(okey == BinService::nObjType)
00387         throw cms::Exception("InvalidCall") << "Undefined object & bin type";
00388 
00389       std::vector<int> const* binMap(binService_->getBinMap(okey, bkey));
00390       if(!binMap)
00391         throw cms::Exception("InvalidCall") << "Cannot retrieve bin map";
00392 
00393       for(std::vector<int>::const_iterator binItr(binMap->begin()); binItr != binMap->end(); ++binItr){
00394         int bin(*binItr - binService_->smOffsetBins(okey, bkey, iObj));
00395         setBinContent_(iME, bin, _content, _err);
00396         setBinEntries_(iME, bin, 0.);
00397       }
00398     }
00399   }
00400 
00401   std::vector<std::string>
00402   MESetEcal::generateNames() const
00403   {
00404     using namespace std;
00405 
00406     unsigned nME(1);
00407     switch(data_->otype){
00408     case BinService::kSM:
00409       nME = BinService::nDCC;
00410       break;
00411     case BinService::kSMMEM:
00412       nME = BinService::nDCCMEM;
00413       break;
00414     case BinService::kEcal2P:
00415       nME = 2;
00416       break;
00417     case BinService::kEcal3P:
00418       nME = 3;
00419       break;
00420     case BinService::kEcalMEM2P:
00421       nME = 2;
00422       break;
00423     default:
00424       break;
00425     }
00426 
00427     std::vector<std::string> names(0);
00428 
00429     for(unsigned iME(0); iME < nME; iME++) {
00430 
00431       unsigned iObj(iME);
00432 
00433       BinService::ObjectType actualObject(binService_->objectFromOffset(data_->otype, iObj));
00434 
00435       string name(name_);
00436       string spacer(" ");
00437 
00438       if(data_->btype == BinService::kProjEta) name += " eta";
00439       else if(data_->btype == BinService::kProjPhi) name += " phi";
00440       else if(data_->btype == BinService::kReport) spacer = "_";
00441 
00442       switch(actualObject){
00443       case BinService::kEB:
00444       case BinService::kEBMEM:
00445         name += spacer + "EB"; break;
00446       case BinService::kEE:
00447       case BinService::kEEMEM:
00448         name += spacer + "EE"; break;
00449       case BinService::kEEm:
00450         name += spacer + "EE-"; break;
00451       case BinService::kEEp:
00452         name += spacer + "EE+"; break;
00453       case BinService::kSM:
00454         name += spacer + binService_->channelName(iObj + 1); break;
00455       case BinService::kSMMEM:
00456         //dccId(unsigned) skips DCCs without MEM
00457         iObj = dccId(iME) - 1;
00458         name += spacer + binService_->channelName(iObj + 1); break;
00459       default:
00460         break;
00461       }
00462 
00463       names.push_back(name);
00464     }
00465 
00466     return names;
00467   }
00468 
00469   void
00470   MESetEcal::find_(uint32_t _id) const
00471   {
00472     if(_id == cacheId_) return;
00473 
00474     DetId id(_id);
00475     if(id.det() == DetId::Ecal)
00476       cache_ = binService_->findBins(data_->otype, data_->btype, id);
00477     else
00478       cache_ = binService_->findBins(data_->otype, data_->btype, unsigned(_id));
00479 
00480     if(cache_.first >= mes_.size() || !mes_[cache_.first])
00481       throw cms::Exception("InvalidCall") << "ME array index overflow" << std::endl;
00482 
00483     // some TTs are apparently empty..!
00484 //     if(cache_.second.size() == 0)
00485 //       throw cms::Exception("InvalidCall") << "No bins to get content from" << std::endl;
00486 
00487     cacheId_ = _id;
00488   }
00489 
00490   void
00491   MESetEcal::fill_(double _w)
00492   {
00493     for(unsigned iBin(0); iBin < cache_.second.size(); iBin++)
00494       MESet::fill_(cache_.first, cache_.second[iBin], _w);
00495   }
00496 
00497 }