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) :
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{
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
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
00192
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, double _wy, double _w)
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, double _wy, double _w)
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, double _w)
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)
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)
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, double _err, double _entries)
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
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
00484
00485
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 }