File indexing completed on 2024-04-06 12:01:52
0001 #ifndef CondCore_Utilities_PayloadInspector_h
0002 #define CondCore_Utilities_PayloadInspector_h
0003
0004 #include "CondCore/CondDB/interface/Utils.h"
0005 #include "CondCore/CondDB/interface/Session.h"
0006 #include "CondCore/CondDB/interface/Exception.h"
0007 #include <iostream>
0008
0009 #include <string>
0010 #include <tuple>
0011 #include <vector>
0012 #include <set>
0013 #include <type_traits>
0014
0015 #include "FWCore/Utilities/interface/GlobalIdentifier.h"
0016 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0017
0018 #include <pybind11/pybind11.h>
0019 #include <pybind11/stl.h>
0020 namespace py = pybind11;
0021
0022 namespace PI {
0023 __attribute__((visibility("default"))) inline py::list mk_input(const std::string& tagName,
0024 cond::Time_t start,
0025 cond::Time_t end) {
0026 py::list ret;
0027 ret.append(py::make_tuple(tagName, std::to_string(start), std::to_string(end)));
0028 return ret;
0029 }
0030 __attribute__((visibility("default"))) inline py::list mk_input(const std::string& tagName0,
0031 cond::Time_t start0,
0032 cond::Time_t end0,
0033 const std::string& tagName1,
0034 cond::Time_t start1,
0035 cond::Time_t end1) {
0036 py::list ret;
0037 ret.append(py::make_tuple(tagName0, std::to_string(start0), std::to_string(end0)));
0038 ret.append(py::make_tuple(tagName1, std::to_string(start1), std::to_string(end1)));
0039 return ret;
0040 }
0041 }
0042
0043 namespace cond {
0044
0045 namespace payloadInspector {
0046
0047
0048 struct PlotAnnotations {
0049 static constexpr const char* const PLOT_TYPE_K = "type";
0050 static constexpr const char* const TITLE_K = "title";
0051 static constexpr const char* const PAYLOAD_TYPE_K = "payload_type";
0052 static constexpr const char* const INFO_K = "info";
0053 static constexpr const char* const XAXIS_K = "x_label";
0054 static constexpr const char* const YAXIS_K = "y_label";
0055 static constexpr const char* const ZAXIS_K = "z_label";
0056 PlotAnnotations();
0057 std::string get(const std::string& key) const;
0058 std::map<std::string, std::string> m;
0059 int ntags = 1;
0060 bool twoTags = false;
0061 bool singleIov = false;
0062 };
0063
0064 static const char* const JSON_FORMAT_VERSION = "1.0";
0065
0066
0067 template <typename V>
0068 std::string serializeValue(const std::string& entryLabel, const V& value) {
0069 std::stringstream ss;
0070
0071
0072
0073
0074
0075
0076
0077 if constexpr (std::is_same_v<V, std::pair<bool, float>>) {
0078 if (value.first) {
0079 ss << "\"" << entryLabel << "\":" << value.second;
0080 }
0081 } else if constexpr (std::is_same_v<V, double>) {
0082 if ((value - int(value)) == 0) {
0083 ss.precision(0);
0084 }
0085 ss << "\"" << entryLabel << "\":" << std::fixed << value;
0086 } else {
0087 ss << "\"" << entryLabel << "\":" << value;
0088 }
0089 return ss.str();
0090 }
0091
0092 template <>
0093 inline std::string serializeValue(const std::string& entryLabel, const std::string& value) {
0094 std::stringstream ss;
0095 ss << "\"" << entryLabel << "\":\"" << value << "\"";
0096 return ss.str();
0097 }
0098
0099
0100 template <typename V>
0101 std::string serializeValue(const std::string& entryLabel, const std::tuple<V, std::string>& value) {
0102 std::stringstream ss;
0103 ss << serializeValue(entryLabel, std::get<0>(value));
0104 ss << ", ";
0105 ss << serializeValue(entryLabel + "_label", std::get<1>(value));
0106 return ss.str();
0107 }
0108
0109
0110 template <typename V>
0111 std::string serializeValue(const std::string& entryLabel, const std::pair<V, V>& value) {
0112 std::stringstream ss;
0113 ss << serializeValue(entryLabel, value.first);
0114 ss << ", ";
0115 ss << serializeValue(entryLabel + "_err", value.second);
0116 return ss.str();
0117 }
0118
0119 inline std::string serializeAnnotations(const PlotAnnotations& annotations) {
0120 std::stringstream ss;
0121 ss << "\"version\": \"" << JSON_FORMAT_VERSION << "\",";
0122 ss << "\"annotations\": {";
0123 bool first = true;
0124 for (const auto& a : annotations.m) {
0125 if (!first)
0126 ss << ",";
0127 ss << "\"" << a.first << "\":\"" << a.second << "\"";
0128 first = false;
0129 }
0130 ss << "}";
0131 return ss.str();
0132 }
0133
0134 template <typename X, typename Y>
0135 std::string serialize(const PlotAnnotations& annotations, const std::vector<std::tuple<X, Y>>& data) {
0136
0137 std::stringstream ss;
0138 ss << "{";
0139 ss << serializeAnnotations(annotations);
0140 ss << ",";
0141 ss << "\"data\": [";
0142 bool first = true;
0143 for (auto d : data) {
0144 auto serializedX = serializeValue("x", std::get<0>(d));
0145 auto serializedY = serializeValue("y", std::get<1>(d));
0146
0147
0148
0149
0150
0151 if (!serializedY.empty()) {
0152 if (!first) {
0153 ss << ",";
0154 }
0155 ss << " { " << serializedX << ", " << serializedY << " }";
0156 first = false;
0157 }
0158 }
0159 ss << "]";
0160 ss << "}";
0161 return ss.str();
0162 }
0163
0164 template <typename X, typename Y, typename Z>
0165 std::string serialize(const PlotAnnotations& annotations, const std::vector<std::tuple<X, Y, Z>>& data) {
0166
0167 std::stringstream ss;
0168 ss << "{";
0169 ss << serializeAnnotations(annotations);
0170 ss << ",";
0171 ss << "\"data\": [";
0172 bool first = true;
0173 for (auto d : data) {
0174 if (!first)
0175 ss << ",";
0176 ss << " { " << serializeValue("x", std::get<0>(d)) << ", " << serializeValue("y", std::get<1>(d)) << ", "
0177 << serializeValue("z", std::get<2>(d)) << " }";
0178 first = false;
0179 }
0180 ss << "]";
0181 ss << "}";
0182 return ss.str();
0183 }
0184
0185 inline std::string serialize(const PlotAnnotations& annotations, const std::string& imageFileName) {
0186 std::stringstream ss;
0187 ss << "{";
0188 ss << serializeAnnotations(annotations);
0189 ss << ",";
0190 ss << "\"file\": \"" << imageFileName << "\"";
0191 ss << "}";
0192 return ss.str();
0193 }
0194
0195 struct ModuleVersion {
0196 static constexpr const char* const label = "2.0";
0197 };
0198
0199 struct TagReference {
0200 TagReference(const std::string& n,
0201 const std::pair<cond::Time_t, cond::Time_t>& b,
0202 const std::vector<std::tuple<cond::Time_t, cond::Hash>>& i)
0203 : name(n), boundary(b), iovs(i) {}
0204 TagReference(const TagReference& rhs) : name(rhs.name), boundary(rhs.boundary), iovs(rhs.iovs) {}
0205 const std::string& name;
0206 const std::pair<cond::Time_t, cond::Time_t>& boundary;
0207 const std::vector<std::tuple<cond::Time_t, cond::Hash>>& iovs;
0208 };
0209
0210
0211 class PlotBase {
0212 public:
0213 PlotBase();
0214 virtual ~PlotBase() = default;
0215
0216 std::string payloadType() const;
0217
0218
0219 std::string title() const;
0220
0221
0222 std::string type() const;
0223
0224
0225 unsigned int ntags() const;
0226
0227
0228 bool isTwoTags() const;
0229
0230
0231 bool isSingleIov() const;
0232
0233
0234 __attribute__((visibility("default"))) py::list inputParams() const;
0235
0236
0237 __attribute__((visibility("default"))) void setInputParamValues(const py::dict& values);
0238
0239
0240 std::string data() const;
0241
0242
0243 __attribute__((visibility("default"))) bool process(const std::string& connectionString,
0244 const py::list& tagsWithTimeBoundaries);
0245
0246
0247 bool exec_process(const std::string& connectionString,
0248 const std::vector<std::tuple<std::string, cond::Time_t, cond::Time_t>>& tagsWithTimeBoundaries);
0249
0250
0251
0252 virtual void init();
0253
0254
0255
0256
0257 virtual std::string processData();
0258
0259
0260 void addInputParam(const std::string& paramName);
0261
0262
0263 template <typename PayloadType>
0264 std::shared_ptr<PayloadType> fetchPayload(const cond::Hash& payloadHash) {
0265 return m_dbSession.fetchPayload<PayloadType>(payloadHash);
0266 }
0267
0268 cond::Tag_t getTagInfo(const std::string& tag);
0269
0270 template <int index>
0271 TagReference getTag() {
0272 size_t sz = m_tagNames.size();
0273 if (sz == 0 || index >= sz) {
0274 cond::throwException("Index out of range", "PlotBase::getTag()");
0275 }
0276 return TagReference(m_tagNames[index], m_tagBoundaries[index], m_tagIovs[index]);
0277 }
0278
0279 const std::map<std::string, std::string>& inputParamValues() const;
0280
0281
0282 cond::persistency::Session dbSession();
0283
0284 protected:
0285
0286 PlotAnnotations m_plotAnnotations;
0287 std::set<std::string> m_inputParams;
0288 std::vector<std::string> m_tagNames;
0289 std::vector<std::pair<cond::Time_t, cond::Time_t>> m_tagBoundaries;
0290 std::vector<std::vector<std::tuple<cond::Time_t, cond::Hash>>> m_tagIovs;
0291 std::map<std::string, std::string> m_inputParamValues;
0292
0293 private:
0294
0295 cond::persistency::Session m_dbSession;
0296 std::string m_data = "";
0297 };
0298
0299 enum IOVMultiplicity { UNSPECIFIED_IOV = 0, MULTI_IOV = 1, SINGLE_IOV = 2 };
0300
0301 inline void setAnnotations(
0302 const std::string& type, const std::string& title, IOVMultiplicity IOV_M, int NTAGS, PlotAnnotations& target) {
0303 target.m[PlotAnnotations::PLOT_TYPE_K] = type;
0304 target.m[PlotAnnotations::TITLE_K] = title;
0305 target.ntags = NTAGS;
0306 target.singleIov = (IOV_M == SINGLE_IOV);
0307 }
0308
0309 template <IOVMultiplicity IOV_M, int NTAGS>
0310 class PlotImpl : public PlotBase {
0311 public:
0312 PlotImpl(const std::string& type, const std::string& title) : PlotBase() {
0313 setAnnotations(type, title, IOV_M, NTAGS, m_plotAnnotations);
0314 }
0315 ~PlotImpl() override = default;
0316
0317 virtual std::string serializeData() = 0;
0318
0319 std::string processData() override {
0320 fill();
0321 return serializeData();
0322 }
0323
0324 virtual bool fill() = 0;
0325 };
0326
0327
0328 template <int NTAGS>
0329 class PlotImpl<UNSPECIFIED_IOV, NTAGS> : public PlotBase {
0330 public:
0331 PlotImpl(const std::string& type, const std::string& title) : PlotBase() {
0332 setAnnotations(type, title, MULTI_IOV, NTAGS, m_plotAnnotations);
0333 }
0334 ~PlotImpl() override = default;
0335
0336 virtual std::string serializeData() = 0;
0337
0338 std::string processData() override {
0339 fill();
0340 return serializeData();
0341 }
0342
0343 virtual bool fill() = 0;
0344
0345 void setSingleIov(bool flag) { m_plotAnnotations.singleIov = flag; }
0346 };
0347
0348 template <>
0349 class PlotImpl<MULTI_IOV, 0> : public PlotBase {
0350 public:
0351 PlotImpl(const std::string& type, const std::string& title) : PlotBase() {
0352 setAnnotations(type, title, MULTI_IOV, 1, m_plotAnnotations);
0353 }
0354 ~PlotImpl() override = default;
0355
0356 virtual std::string serializeData() = 0;
0357
0358 std::string processData() override {
0359 fill();
0360 return serializeData();
0361 }
0362
0363 virtual bool fill() = 0;
0364
0365 void setTwoTags(bool flag) {
0366 if (flag)
0367 m_plotAnnotations.ntags = 2;
0368 else
0369 m_plotAnnotations.ntags = 1;
0370 }
0371 };
0372
0373 template <>
0374 class PlotImpl<SINGLE_IOV, 0> : public PlotBase {
0375 public:
0376 PlotImpl(const std::string& type, const std::string& title) : PlotBase() {
0377 setAnnotations(type, title, SINGLE_IOV, 1, m_plotAnnotations);
0378 }
0379 ~PlotImpl() override = default;
0380
0381 virtual std::string serializeData() = 0;
0382
0383 std::string processData() override {
0384 fill();
0385 return serializeData();
0386 }
0387
0388 virtual bool fill() = 0;
0389
0390 void setTwoTags(bool flag) {
0391 if (flag)
0392 m_plotAnnotations.ntags = 2;
0393 else
0394 m_plotAnnotations.ntags = 1;
0395 }
0396 };
0397
0398 template <>
0399 class PlotImpl<UNSPECIFIED_IOV, 0> : public PlotBase {
0400 public:
0401 PlotImpl(const std::string& type, const std::string& title) : PlotBase() {
0402 setAnnotations(type, title, MULTI_IOV, 1, m_plotAnnotations);
0403 }
0404 ~PlotImpl() override = default;
0405
0406 virtual std::string serializeData() = 0;
0407
0408 std::string processData() override {
0409 fill();
0410 return serializeData();
0411 }
0412
0413 virtual bool fill() {
0414 std::vector<std::tuple<cond::Time_t, cond::Hash>> theIovs = PlotBase::getTag<0>().iovs;
0415 if (m_plotAnnotations.ntags == 2) {
0416 auto tag2iovs = PlotBase::getTag<1>().iovs;
0417 size_t oldSize = theIovs.size();
0418 size_t newSize = oldSize + tag2iovs.size();
0419 theIovs.resize(newSize);
0420 for (size_t i = 0; i < tag2iovs.size(); i++) {
0421 theIovs[i + oldSize] = tag2iovs[i];
0422 }
0423 }
0424 return fill(theIovs);
0425 }
0426
0427 virtual bool fill(const std::vector<std::tuple<cond::Time_t, cond::Hash>>& iovs) { return false; }
0428
0429 void setSingleIov(bool flag) {
0430 m_plotAnnotations.singleIov = flag;
0431 m_singleIovSet = true;
0432 }
0433
0434 void setTwoTags(bool flag) {
0435 if (flag) {
0436 m_plotAnnotations.ntags = 2;
0437 if (!m_singleIovSet)
0438 m_plotAnnotations.singleIov = true;
0439 } else
0440 m_plotAnnotations.ntags = 1;
0441 }
0442
0443 bool m_singleIovSet = false;
0444 };
0445
0446 template <>
0447 class PlotImpl<UNSPECIFIED_IOV, 1> : public PlotBase {
0448 public:
0449 PlotImpl(const std::string& type, const std::string& title) : PlotBase() {
0450 setAnnotations(type, title, MULTI_IOV, 1, m_plotAnnotations);
0451 }
0452 ~PlotImpl() override = default;
0453
0454 virtual std::string serializeData() = 0;
0455
0456 std::string processData() override {
0457 fill();
0458 return serializeData();
0459 }
0460
0461 virtual bool fill() {
0462 std::vector<std::tuple<cond::Time_t, cond::Hash>> theIovs = PlotBase::getTag<0>().iovs;
0463 if (m_plotAnnotations.ntags == 2) {
0464 auto tag2iovs = PlotBase::getTag<1>().iovs;
0465 size_t oldSize = theIovs.size();
0466 size_t newSize = oldSize + tag2iovs.size();
0467 theIovs.resize(newSize);
0468 for (size_t i = 0; i < tag2iovs.size(); i++) {
0469 theIovs[i + oldSize] = tag2iovs[i];
0470 }
0471 }
0472 return fill(theIovs);
0473 }
0474
0475 virtual bool fill(const std::vector<std::tuple<cond::Time_t, cond::Hash>>& iovs) { return false; }
0476
0477 void setSingleIov(bool flag) { m_plotAnnotations.singleIov = flag; }
0478 };
0479
0480
0481 template <typename PayloadType, typename X, typename Y, IOVMultiplicity IOV_M = UNSPECIFIED_IOV, int NTAGS = 0>
0482 class Plot2D : public PlotImpl<IOV_M, NTAGS> {
0483 public:
0484 typedef PlotImpl<IOV_M, NTAGS> Base;
0485 Plot2D(const std::string& type, const std::string& title, const std::string xLabel, const std::string& yLabel)
0486 : Base(type, title), m_plotData() {
0487 Base::m_plotAnnotations.m[PlotAnnotations::XAXIS_K] = xLabel;
0488 Base::m_plotAnnotations.m[PlotAnnotations::YAXIS_K] = yLabel;
0489 Base::m_plotAnnotations.m[PlotAnnotations::PAYLOAD_TYPE_K] = cond::demangledName(typeid(PayloadType));
0490 }
0491 ~Plot2D() override = default;
0492 std::string serializeData() override { return serialize(Base::m_plotAnnotations, m_plotData); }
0493
0494 std::shared_ptr<PayloadType> fetchPayload(const cond::Hash& payloadHash) {
0495 return PlotBase::fetchPayload<PayloadType>(payloadHash);
0496 }
0497
0498 protected:
0499 std::vector<std::tuple<X, Y>> m_plotData;
0500 };
0501
0502 template <typename PayloadType,
0503 typename X,
0504 typename Y,
0505 typename Z,
0506 IOVMultiplicity IOV_M = UNSPECIFIED_IOV,
0507 int NTAGS = 0>
0508 class Plot3D : public PlotImpl<IOV_M, NTAGS> {
0509 public:
0510 typedef PlotImpl<IOV_M, NTAGS> Base;
0511 Plot3D(const std::string& type,
0512 const std::string& title,
0513 const std::string xLabel,
0514 const std::string& yLabel,
0515 const std::string& zLabel)
0516 : Base(type, title), m_plotData() {
0517 Base::m_plotAnnotations.m[PlotAnnotations::XAXIS_K] = xLabel;
0518 Base::m_plotAnnotations.m[PlotAnnotations::YAXIS_K] = yLabel;
0519 Base::m_plotAnnotations.m[PlotAnnotations::ZAXIS_K] = zLabel;
0520 Base::m_plotAnnotations.m[PlotAnnotations::PAYLOAD_TYPE_K] = cond::demangledName(typeid(PayloadType));
0521 }
0522 ~Plot3D() override = default;
0523 std::string serializeData() override { return serialize(Base::m_plotAnnotations, m_plotData); }
0524
0525 std::shared_ptr<PayloadType> fetchPayload(const cond::Hash& payloadHash) {
0526 return PlotBase::fetchPayload<PayloadType>(payloadHash);
0527 }
0528
0529 protected:
0530 std::vector<std::tuple<X, Y, Z>> m_plotData;
0531 };
0532
0533 template <typename PayloadType, typename Y>
0534 class HistoryPlot : public Plot2D<PayloadType, unsigned long long, Y, MULTI_IOV, 1> {
0535 public:
0536 typedef Plot2D<PayloadType, unsigned long long, Y, MULTI_IOV, 1> Base;
0537
0538 HistoryPlot(const std::string& title, const std::string& yLabel) : Base("History", title, "iov_since", yLabel) {}
0539
0540 ~HistoryPlot() override = default;
0541
0542 bool fill() override {
0543 auto tag = PlotBase::getTag<0>();
0544 for (auto iov : tag.iovs) {
0545 std::shared_ptr<PayloadType> payload = Base::fetchPayload(std::get<1>(iov));
0546 if (payload.get()) {
0547 Y value = getFromPayload(*payload);
0548 Base::m_plotData.push_back(std::make_tuple(std::get<0>(iov), value));
0549 }
0550 }
0551 return true;
0552 }
0553 virtual Y getFromPayload(PayloadType& payload) = 0;
0554 };
0555
0556 template <typename PayloadType, typename Y>
0557 class RunHistoryPlot : public Plot2D<PayloadType, std::tuple<float, std::string>, Y, MULTI_IOV, 1> {
0558 public:
0559 typedef Plot2D<PayloadType, std::tuple<float, std::string>, Y, MULTI_IOV, 1> Base;
0560
0561 RunHistoryPlot(const std::string& title, const std::string& yLabel)
0562 : Base("RunHistory", title, "iov_since", yLabel) {}
0563
0564 ~RunHistoryPlot() override = default;
0565
0566 bool fill() override {
0567 auto tag = PlotBase::getTag<0>();
0568
0569 std::map<cond::Time_t, unsigned int> runs;
0570
0571 cond::Tag_t tagInfo = Base::getTagInfo(tag.name);
0572 if (tagInfo.timeType == cond::lumiid) {
0573 for (auto iov : tag.iovs) {
0574 unsigned int run = std::get<0>(iov) >> 32;
0575 auto it = runs.find(run);
0576 if (it == runs.end())
0577 it = runs.insert(std::make_pair(run, 0)).first;
0578 it->second++;
0579 }
0580 }
0581 unsigned int currentRun = 0;
0582 float lumiIndex = 0;
0583 unsigned int lumiSize = 0;
0584 unsigned int rind = 0;
0585 float ind = 0;
0586 std::string label("");
0587 for (auto iov : tag.iovs) {
0588 unsigned long long since = std::get<0>(iov);
0589
0590 if (tagInfo.timeType == cond::lumiid) {
0591 unsigned int run = since >> 32;
0592 unsigned int lumi = since & 0xFFFFFFFF;
0593 if (run != currentRun) {
0594 rind++;
0595 lumiIndex = 0;
0596 auto it = runs.find(run);
0597 if (it == runs.end()) {
0598
0599 return false;
0600 }
0601 lumiSize = it->second;
0602 } else {
0603 lumiIndex++;
0604 }
0605 ind = rind + (lumiIndex / lumiSize);
0606 label = std::to_string(run) + " : " + std::to_string(lumi);
0607 currentRun = run;
0608 } else {
0609 ind++;
0610
0611 if (tagInfo.timeType == cond::timestamp) {
0612 boost::posix_time::ptime t = cond::time::to_boost(since);
0613 label = boost::posix_time::to_simple_string(t);
0614 } else {
0615 label = std::to_string(since);
0616 }
0617 }
0618 std::shared_ptr<PayloadType> payload = Base::fetchPayload(std::get<1>(iov));
0619 if (payload.get()) {
0620 Y value = getFromPayload(*payload);
0621 Base::m_plotData.push_back(std::make_tuple(std::make_tuple(ind, label), value));
0622 }
0623 }
0624 return true;
0625 }
0626
0627 virtual Y getFromPayload(PayloadType& payload) = 0;
0628 };
0629
0630 template <typename PayloadType, typename Y>
0631 class TimeHistoryPlot : public Plot2D<PayloadType, std::tuple<unsigned long long, std::string>, Y, MULTI_IOV, 1> {
0632 public:
0633 typedef Plot2D<PayloadType, std::tuple<unsigned long long, std::string>, Y, MULTI_IOV, 1> Base;
0634
0635 TimeHistoryPlot(const std::string& title, const std::string& yLabel)
0636 : Base("TimeHistory", title, "iov_since", yLabel) {}
0637 ~TimeHistoryPlot() override = default;
0638
0639 bool fill() override {
0640 auto tag = PlotBase::getTag<0>();
0641 cond::persistency::RunInfoProxy runInfo;
0642
0643 cond::Tag_t tagInfo = Base::getTagInfo(tag.name);
0644 if (tagInfo.timeType == cond::lumiid || tagInfo.timeType == cond::runnumber) {
0645 cond::Time_t min = std::get<0>(tag.iovs.front());
0646 cond::Time_t max = std::get<0>(tag.iovs.back());
0647 if (tagInfo.timeType == cond::lumiid) {
0648 min = min >> 32;
0649 max = max >> 32;
0650 }
0651 runInfo = Base::dbSession().getRunInfo(min, max);
0652 }
0653 for (auto iov : tag.iovs) {
0654 cond::Time_t since = std::get<0>(iov);
0655 boost::posix_time::ptime time;
0656 std::string label("");
0657 if (tagInfo.timeType == cond::lumiid || tagInfo.timeType == cond::runnumber) {
0658 unsigned int nlumi = since & 0xFFFFFFFF;
0659 if (tagInfo.timeType == cond::lumiid)
0660 since = since >> 32;
0661 label = std::to_string(since);
0662 auto it = runInfo.find(since);
0663 if (it == runInfo.end()) {
0664
0665 return false;
0666 }
0667 time = (*it).start;
0668
0669 if (tagInfo.timeType == cond::lumiid) {
0670 time += boost::posix_time::seconds(cond::time::SECONDS_PER_LUMI * nlumi);
0671 label += (" : " + std::to_string(nlumi));
0672 }
0673 } else if (tagInfo.timeType == cond::timestamp) {
0674 time = cond::time::to_boost(since);
0675 label = boost::posix_time::to_simple_string(time);
0676 }
0677 std::shared_ptr<PayloadType> payload = Base::fetchPayload(std::get<1>(iov));
0678 if (payload.get()) {
0679 Y value = getFromPayload(*payload);
0680 Base::m_plotData.push_back(std::make_tuple(std::make_tuple(cond::time::from_boost(time), label), value));
0681 }
0682 }
0683 return true;
0684 }
0685
0686 virtual Y getFromPayload(PayloadType& payload) = 0;
0687 };
0688
0689 template <typename PayloadType, typename X, typename Y>
0690 class ScatterPlot : public Plot2D<PayloadType, X, Y, MULTI_IOV, 1> {
0691 public:
0692 typedef Plot2D<PayloadType, X, Y, MULTI_IOV, 1> Base;
0693
0694 ScatterPlot(const std::string& title, const std::string& xLabel, const std::string& yLabel)
0695 : Base("Scatter", title, xLabel, yLabel) {}
0696 ~ScatterPlot() override = default;
0697
0698 bool fill() override {
0699 auto tag = PlotBase::getTag<0>();
0700 for (auto iov : tag.iovs) {
0701 std::shared_ptr<PayloadType> payload = Base::fetchPayload(std::get<1>(iov));
0702 if (payload.get()) {
0703 std::tuple<X, Y> value = getFromPayload(*payload);
0704 Base::m_plotData.push_back(value);
0705 }
0706 }
0707 return true;
0708 }
0709
0710 virtual std::tuple<X, Y> getFromPayload(PayloadType& payload) = 0;
0711 };
0712
0713
0714 template <typename AxisType, typename PayloadType, IOVMultiplicity IOV_M = UNSPECIFIED_IOV>
0715 class Histogram1 : public Plot2D<PayloadType, AxisType, AxisType, IOV_M, 1> {
0716 public:
0717 typedef Plot2D<PayloadType, AxisType, AxisType, IOV_M, 1> Base;
0718
0719 Histogram1(const std::string& title,
0720 const std::string& xLabel,
0721 size_t nbins,
0722 float min,
0723 float max,
0724 const std::string& yLabel = "entries")
0725 : Base("Histo1D", title, xLabel, yLabel), m_nbins(nbins), m_min(min), m_max(max) {}
0726
0727
0728 void init() override {
0729 if (m_nbins < 1) {
0730 edm::LogError("payloadInspector::Histogram1D()")
0731 << " trying to book an histogram with less then 1 bin!" << std::endl;
0732 }
0733
0734 if (m_min > m_max) {
0735 edm::LogError("payloadInspector::Histogram1D()")
0736 << " trying to book an histogram with minimum " << m_min << "> maximum" << m_max << " !" << std::endl;
0737 }
0738
0739 Base::m_plotData.clear();
0740 float binSize = (m_max - m_min) / m_nbins;
0741 if (binSize > 0) {
0742 m_binSize = binSize;
0743 Base::m_plotData.resize(m_nbins);
0744 for (size_t i = 0; i < m_nbins; i++) {
0745 Base::m_plotData[i] = std::make_tuple(m_min + i * m_binSize, 0);
0746 }
0747 }
0748 }
0749
0750
0751 void fillWithValue(AxisType value, AxisType weight = 1) {
0752
0753 if (!Base::m_plotData.empty() && (value < m_max) && (value >= m_min)) {
0754 size_t ibin = (value - m_min) / m_binSize;
0755 std::get<1>(Base::m_plotData[ibin]) += weight;
0756 }
0757 }
0758
0759
0760 void fillWithBinAndValue(size_t bin, AxisType weight = 1) {
0761 if (bin < Base::m_plotData.size()) {
0762 std::get<1>(Base::m_plotData[bin]) = weight;
0763 }
0764 }
0765
0766
0767 bool fill() override {
0768 auto tag = PlotBase::getTag<0>();
0769 for (auto iov : tag.iovs) {
0770 std::shared_ptr<PayloadType> payload = Base::fetchPayload(std::get<1>(iov));
0771 if (payload.get()) {
0772 AxisType value = getFromPayload(*payload);
0773 fillWithValue(value);
0774 }
0775 }
0776 return true;
0777 }
0778
0779
0780 virtual AxisType getFromPayload(PayloadType& payload) { return 0; }
0781
0782 private:
0783 float m_binSize = 0;
0784 size_t m_nbins;
0785 float m_min;
0786 float m_max;
0787 };
0788
0789
0790
0791
0792
0793 template <typename PayloadType, IOVMultiplicity IOV_M = UNSPECIFIED_IOV>
0794 using Histogram1D = Histogram1<float, PayloadType, UNSPECIFIED_IOV>;
0795
0796 template <typename PayloadType, IOVMultiplicity IOV_M = UNSPECIFIED_IOV>
0797 using Histogram1DD = Histogram1<double, PayloadType, UNSPECIFIED_IOV>;
0798
0799
0800 template <typename PayloadType, IOVMultiplicity IOV_M = UNSPECIFIED_IOV>
0801 class Histogram2D : public Plot3D<PayloadType, float, float, float, IOV_M, 1> {
0802 public:
0803 typedef Plot3D<PayloadType, float, float, float, IOV_M, 1> Base;
0804
0805 Histogram2D(const std::string& title,
0806 const std::string& xLabel,
0807 size_t nxbins,
0808 float xmin,
0809 float xmax,
0810 const std::string& yLabel,
0811 size_t nybins,
0812 float ymin,
0813 float ymax)
0814 : Base("Histo2D", title, xLabel, yLabel, "entries"),
0815 m_nxbins(nxbins),
0816 m_xmin(xmin),
0817 m_xmax(xmax),
0818 m_nybins(nybins),
0819 m_ymin(ymin),
0820 m_ymax(ymax) {}
0821
0822
0823 void init() override {
0824
0825 if ((m_nxbins < 1) || (m_nybins < 1)) {
0826 edm::LogError("payloadInspector::Histogram2D()")
0827 << " trying to book an histogram with less then 1 bin!" << std::endl;
0828 }
0829
0830 if (m_xmin > m_xmax) {
0831 edm::LogError("payloadInspector::Histogram2D()") << " trying to book an histogram with x-minimum " << m_xmin
0832 << "> x-maximum" << m_xmax << " !" << std::endl;
0833 }
0834
0835 if (m_ymin > m_ymax) {
0836 edm::LogError("payloadInspector::Histogram2D()") << " trying to book an histogram with y-minimum " << m_ymin
0837 << "> y-maximum" << m_ymax << " !" << std::endl;
0838 }
0839
0840 Base::m_plotData.clear();
0841 float xbinSize = (m_xmax - m_xmin) / m_nxbins;
0842 float ybinSize = (m_ymax - m_ymin) / m_nybins;
0843 if (xbinSize > 0 && ybinSize > 0) {
0844 m_xbinSize = xbinSize;
0845 m_ybinSize = ybinSize;
0846 Base::m_plotData.resize(m_nxbins * m_nybins);
0847 for (size_t i = 0; i < m_nybins; i++) {
0848 for (size_t j = 0; j < m_nxbins; j++) {
0849 Base::m_plotData[i * m_nxbins + j] = std::make_tuple(m_xmin + j * m_xbinSize, m_ymin + i * m_ybinSize, 0);
0850 }
0851 }
0852 }
0853 }
0854
0855
0856 void fillWithValue(float xvalue, float yvalue, float weight = 1) {
0857
0858 if (!Base::m_plotData.empty() && xvalue < m_xmax && xvalue >= m_xmin && yvalue < m_ymax && yvalue >= m_ymin) {
0859 size_t ixbin = (xvalue - m_xmin) / m_xbinSize;
0860 size_t iybin = (yvalue - m_ymin) / m_ybinSize;
0861 std::get<2>(Base::m_plotData[iybin * m_nxbins + ixbin]) += weight;
0862 }
0863 }
0864
0865
0866 bool fill() override {
0867 auto tag = PlotBase::getTag<0>();
0868 for (auto iov : tag.iovs) {
0869 std::shared_ptr<PayloadType> payload = Base::fetchPayload(std::get<1>(iov));
0870 if (payload.get()) {
0871 std::tuple<float, float> value = getFromPayload(*payload);
0872 fillWithValue(std::get<0>(value), std::get<1>(value));
0873 }
0874 }
0875 return true;
0876 }
0877
0878
0879 virtual std::tuple<float, float> getFromPayload(PayloadType& payload) {
0880 float x = 0;
0881 float y = 0;
0882 return std::make_tuple(x, y);
0883 }
0884
0885 private:
0886 size_t m_nxbins;
0887 float m_xbinSize = 0;
0888 float m_xmin;
0889 float m_xmax;
0890 float m_ybinSize = 0;
0891 size_t m_nybins;
0892 float m_ymin;
0893 float m_ymax;
0894 };
0895
0896
0897 template <typename PayloadType, IOVMultiplicity IOV_M = UNSPECIFIED_IOV, int NTAGS = 0>
0898 class PlotImage : public PlotImpl<IOV_M, NTAGS> {
0899 public:
0900 typedef PlotImpl<IOV_M, NTAGS> Base;
0901 explicit PlotImage(const std::string& title) : Base("Image", title) {
0902 std::string payloadTypeName = cond::demangledName(typeid(PayloadType));
0903 Base::m_plotAnnotations.m[PlotAnnotations::PAYLOAD_TYPE_K] = payloadTypeName;
0904 m_imageFileName = edm::createGlobalIdentifier() + ".png";
0905 }
0906
0907 std::string serializeData() override { return serialize(Base::m_plotAnnotations, m_imageFileName); }
0908
0909 std::shared_ptr<PayloadType> fetchPayload(const cond::Hash& payloadHash) {
0910 return PlotBase::fetchPayload<PayloadType>(payloadHash);
0911 }
0912
0913 protected:
0914 std::string m_imageFileName;
0915 };
0916
0917 }
0918
0919 }
0920
0921 #endif