CMS 3D CMS Logo

BeamSpotPayloadInspectorHelper.h
Go to the documentation of this file.
1 #ifndef CONDCORE_BEAMSPOTPLUGINS_BEAMSPOTPAYLOADINSPECTORHELPER_H
2 #define CONDCORE_BEAMSPOTPLUGINS_BEAMSPOTPAYLOADINSPECTORHELPER_H
3 
4 // User includes
10 
11 // system includes
12 #include <ctime>
13 #include <fmt/printf.h>
14 #include <memory>
15 #include <sstream>
16 #include <regex>
17 
18 // ROOT includes
19 #include "TCanvas.h"
20 #include "TH2F.h"
21 #include "TLatex.h"
22 #include "TStyle.h"
23 
24 //#define MMDEBUG /* to make it verbose */
25 
26 namespace beamSpotPI {
27 
28  inline std::pair<unsigned int, unsigned int> unpack(cond::Time_t since) {
29  auto kLowMask = 0XFFFFFFFF;
30  auto run = (since >> 32);
31  auto lumi = (since & kLowMask);
32  return std::make_pair(run, lumi);
33  }
34 
35  enum parameters {
36  X = 0, // 0 regular BS methods
37  Y = 1, // 1
38  Z = 2, // 2
39  sigmaX = 3, // 3
40  sigmaY = 4, // 4
41  sigmaZ = 5, // 5
42  dxdz = 6, // 6
43  dydz = 7, // 7
44  lastLumi = 8, // 8 additional int's
45  lastRun = 9, // 9
46  lastFill = 10, // 10
47  nTracks = 11, // 11
48  nPVs = 12, // 12
49  nUsedEvents = 13, // 13
50  maxPVs = 14, // 14
51  meanPV = 15, // 15 additional float's
52  meanErrorPV = 16, // 16
53  rmsPV = 17, // 17
54  rmsErrorPV = 18, // 18
55  creationTime = 19, // 19 additional cond::Time_t
56  startTimeStamp = 20, // 20
57  endTimeStamp = 21, // 21
58  startTime = 22, // 22 additional std::string
59  endTime = 23, // 23
60  lumiRange = 24, // 24
62  };
63 
64  /************************************************/
65  // Function to convert cond::Time_t (in microseconds) to human-readable date string
66  inline std::string convertTimeToDateString(cond::Time_t timeValue, bool hasMicros = false, bool toUTC = true) {
67  // Convert microseconds to seconds
68  std::time_t unixTime = static_cast<std::time_t>(hasMicros ? timeValue / 1000000 : timeValue);
69 
70  // Convert std::time_t to struct tm (to UTC, or not)
71  std::tm* timeInfo = toUTC ? std::gmtime(&unixTime) : std::localtime(&unixTime);
72 
73  // Convert struct tm to human-readable string format
74  char buffer[80];
75  std::strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", timeInfo);
76 
77  // Append microseconds to the string
78  std::string dateString(buffer);
79  //dateString += "." + std::to_string(timeValue % 1000000);
80 
81  return dateString;
82  }
83 
84  /************************************************/
86  const bool addUnits = false /*not used by default*/) {
87  switch (parameter) {
88  case X:
89  return (addUnits ? "X [cm]" : "X");
90  case Y:
91  return (addUnits ? "Y [cm]" : "Y");
92  case Z:
93  return (addUnits ? "Z [cm]" : "Z");
94  case sigmaX:
95  return (addUnits ? "#sigma_{X} [cm]" : "sigmaX");
96  case sigmaY:
97  return (addUnits ? "#sigma_{Y} [cm]" : "sigmaY");
98  case sigmaZ:
99  return (addUnits ? "#sigma_{Z} [cm]" : "sigmaZ");
100  case dxdz:
101  return (addUnits ? "#frac{dX}{dZ} [rad]" : "dx/dz");
102  case dydz:
103  return (addUnits ? "#frac{dY}{dZ} [rad]" : "dy/dz");
104  default:
105  return "should never be here";
106  }
107  }
108 
114  template <class PayloadType>
116  typedef std::array<double, parameters::lastLumi> bshelpdata;
117 
118  public:
119  BSParamsHelper(const std::shared_ptr<PayloadType>& bs) {
120  // fill in the central values
122  m_values[parameters::sigmaX] = bs->beamWidthX(), m_values[parameters::sigmaY] = bs->beamWidthY(),
123  m_values[parameters::sigmaZ] = bs->sigmaZ();
124  m_values[parameters::dxdz] = bs->dxdz(), m_values[parameters::dydz] = bs->dydz();
125 
126  // fill in the errors
127  m_errors[parameters::X] = bs->xError(), m_errors[parameters::Y] = bs->yError(),
128  m_errors[parameters::Z] = bs->zError();
129  m_errors[parameters::sigmaX] = bs->beamWidthXError(), m_errors[parameters::sigmaY] = bs->beamWidthYError(),
130  m_errors[parameters::sigmaZ] = bs->sigmaZError();
131  m_errors[parameters::dxdz] = bs->dxdzError(), m_errors[parameters::dydz] = bs->dydzError();
132  }
133 
134  void printDebug(std::stringstream& ss) {
135  ss << "Dumping BeamSpot parameters Data:" << std::endl;
136  for (uint i = parameters::X; i <= parameters::dydz; i++) {
137  parameters par = static_cast<parameters>(i);
138  ss << getStringFromParamEnum(par) << " : " << m_values[i] << std::endl;
139  ss << getStringFromParamEnum(par) << " error: " << m_errors[i] << std::endl;
140  ss << std::endl;
141  }
142  }
143 
144  inline const bshelpdata centralValues() const { return m_values; }
145  inline const bshelpdata errors() const { return m_errors; }
146 
147  // get the difference in values
148  const bshelpdata diffCentralValues(const BSParamsHelper& bs2, const bool isPull = false) const {
149  bshelpdata ret;
150  for (uint i = parameters::X; i <= parameters::dydz; i++) {
151  ret[i] = this->centralValues()[i] - bs2.centralValues()[i];
152  if (isPull)
153  (this->centralValues()[i] != 0.) ? ret[i] /= this->centralValues()[i] : 0.;
154  }
155  return ret;
156  }
157 
158  // get the difference in errors
159  const bshelpdata diffErrors(const BSParamsHelper& bs2, const bool isPull = false) const {
160  bshelpdata ret;
161  for (uint i = parameters::X; i <= parameters::dydz; i++) {
162  ret[i] = this->errors()[i] - bs2.errors()[i];
163  if (isPull)
164  (this->errors()[i] != 0.) ? ret[i] /= this->errors()[i] : 0.;
165  }
166  return ret;
167  }
168 
169  private:
170  bshelpdata m_values; /* central values */
171  bshelpdata m_errors; /* errors */
172  };
173 
174  /************************************************
175  template classes (history)
176  *************************************************/
177 
178  template <parameters my_param, class PayloadType>
179  class BeamSpot_history : public cond::payloadInspector::HistoryPlot<PayloadType, std::pair<double, double> > {
180  public:
182  : cond::payloadInspector::HistoryPlot<PayloadType, std::pair<double, double> >(
183  getStringFromParamEnum(my_param) + " vs run number", getStringFromParamEnum(my_param)) {}
184 
185  std::pair<double, double> getFromPayload(PayloadType& payload) override {
186  auto ret = std::make_pair<double, double>(-9999., -9999.);
187 
188  switch (my_param) {
189  case X:
190  return std::make_pair<double, double>(payload.x(), payload.xError());
191  case Y:
192  return std::make_pair<double, double>(payload.y(), payload.yError());
193  case Z:
194  return std::make_pair<double, double>(payload.z(), payload.zError());
195  case sigmaX:
196  return std::make_pair<double, double>(payload.beamWidthX(), payload.beamWidthXError());
197  case sigmaY:
198  return std::make_pair<double, double>(payload.beamWidthY(), payload.beamWidthYError());
199  case sigmaZ:
200  return std::make_pair<double, double>(payload.sigmaZ(), payload.sigmaZError());
201  case dxdz:
202  return std::make_pair<double, double>(payload.dxdz(), payload.dxdzError());
203  case dydz:
204  return std::make_pair<double, double>(payload.dydz(), payload.dydzError());
205  case END_OF_TYPES:
206  return ret;
207  default:
208  return ret;
209  }
210  }
211  };
212 
213  /************************************************
214  template classes (run history)
215  *************************************************/
216 
217  template <parameters my_param, class PayloadType>
218  class BeamSpot_runhistory : public cond::payloadInspector::RunHistoryPlot<PayloadType, std::pair<double, double> > {
219  public:
221  : cond::payloadInspector::RunHistoryPlot<PayloadType, std::pair<double, double> >(
222  getStringFromParamEnum(my_param) + " vs run number", getStringFromParamEnum(my_param)) {}
223 
224  std::pair<double, double> getFromPayload(PayloadType& payload) override {
225  auto ret = std::make_pair<double, double>(-9999., -9999.);
226 
227  switch (my_param) {
228  case X:
229  return std::make_pair<double, double>(payload.x(), payload.xError());
230  case Y:
231  return std::make_pair<double, double>(payload.y(), payload.yError());
232  case Z:
233  return std::make_pair<double, double>(payload.z(), payload.zError());
234  case sigmaX:
235  return std::make_pair<double, double>(payload.beamWidthX(), payload.beamWidthXError());
236  case sigmaY:
237  return std::make_pair<double, double>(payload.beamWidthY(), payload.beamWidthYError());
238  case sigmaZ:
239  return std::make_pair<double, double>(payload.sigmaZ(), payload.sigmaZError());
240  case dxdz:
241  return std::make_pair<double, double>(payload.dxdz(), payload.dxdzError());
242  case dydz:
243  return std::make_pair<double, double>(payload.dydz(), payload.dydzError());
244  case END_OF_TYPES:
245  return ret;
246  default:
247  return ret;
248  }
249  }
250  };
251 
252  /************************************************
253  template classes (time history)
254  *************************************************/
255 
256  template <parameters my_param, class PayloadType>
257  class BeamSpot_timehistory : public cond::payloadInspector::TimeHistoryPlot<PayloadType, std::pair<double, double> > {
258  public:
260  : cond::payloadInspector::TimeHistoryPlot<PayloadType, std::pair<double, double> >(
261  getStringFromParamEnum(my_param) + " vs time", getStringFromParamEnum(my_param)) {}
262 
263  std::pair<double, double> getFromPayload(PayloadType& payload) override {
264  auto ret = std::make_pair<double, double>(-9999., -9999.);
265 
266  switch (my_param) {
267  case X:
268  return std::make_pair<double, double>(payload.x(), payload.xError());
269  case Y:
270  return std::make_pair<double, double>(payload.y(), payload.yError());
271  case Z:
272  return std::make_pair<double, double>(payload.z(), payload.zError());
273  case sigmaX:
274  return std::make_pair<double, double>(payload.beamWidthX(), payload.beamWidthXError());
275  case sigmaY:
276  return std::make_pair<double, double>(payload.beamWidthY(), payload.beamWidthYError());
277  case sigmaZ:
278  return std::make_pair<double, double>(payload.sigmaZ(), payload.sigmaZError());
279  case dxdz:
280  return std::make_pair<double, double>(payload.dxdz(), payload.dxdzError());
281  case dydz:
282  return std::make_pair<double, double>(payload.dydz(), payload.dydzError());
283  case END_OF_TYPES:
284  return ret;
285  default:
286  return ret;
287  }
288  }
289  };
290 
291  /************************************************
292  X-Y correlation plot
293  *************************************************/
294  template <class PayloadType>
295  class xyCorrelation : public cond::payloadInspector::ScatterPlot<PayloadType, double, double> {
296  public:
297  xyCorrelation() : cond::payloadInspector::ScatterPlot<PayloadType, double, double>("BeamSpot x vs y", "x", "y") {}
298 
299  std::tuple<double, double> getFromPayload(PayloadType& payload) override {
300  return std::make_tuple(payload.x(), payload.y());
301  }
302  };
303 
304  /************************************************
305  Display of Beam Spot parameters
306  *************************************************/
307  template <class PayloadType>
308  class DisplayParameters : public cond::payloadInspector::PlotImage<PayloadType, cond::payloadInspector::SINGLE_IOV> {
309  public:
311  : cond::payloadInspector::PlotImage<PayloadType, cond::payloadInspector::SINGLE_IOV>(
312  "Display of BeamSpot parameters") {
313  if constexpr (std::is_same_v<PayloadType, BeamSpotOnlineObjects>) {
314  isOnline_ = true;
315  } else {
316  isOnline_ = false;
317  }
318  }
319 
320  bool fill() override {
321  auto tag = cond::payloadInspector::PlotBase::getTag<0>();
322  auto tagname = tag.name;
323  auto iov = tag.iovs.front();
324 
325  gStyle->SetHistMinimumZero(kTRUE);
326 
327  m_payload = this->fetchPayload(std::get<1>(iov));
328 
329  TCanvas canvas("Beam Spot Parameters Summary", "BeamSpot Parameters summary", isOnline_ ? 1500 : 1000, 1000);
330  if (isOnline_) {
331  canvas.Divide(2, 1);
332  }
333  canvas.cd(1);
334 
335  canvas.cd(1)->SetTopMargin(0.05);
336  canvas.cd(1)->SetBottomMargin(0.06);
337  canvas.cd(1)->SetLeftMargin(0.15);
338  canvas.cd(1)->SetRightMargin(0.01);
339  canvas.cd(1)->Modified();
340  canvas.cd(1)->SetGrid();
341 
342  auto h2_BSParameters = std::make_unique<TH2F>("Parameters", "", 2, 0.0, 2.0, 8, 0, 8.);
343  h2_BSParameters->SetStats(false);
344 
345  std::function<double(parameters, bool)> cutFunctor = [this](parameters my_param, bool isError) {
346  double ret(-999.);
347  if (!isError) {
348  switch (my_param) {
349  case X:
350  return m_payload->x();
351  case Y:
352  return m_payload->y();
353  case Z:
354  return m_payload->z();
355  case sigmaX:
356  return m_payload->beamWidthX();
357  case sigmaY:
358  return m_payload->beamWidthY();
359  case sigmaZ:
360  return m_payload->sigmaZ();
361  case dxdz:
362  return m_payload->dxdz();
363  case dydz:
364  return m_payload->dydz();
365  case END_OF_TYPES:
366  return ret;
367  default:
368  return ret;
369  }
370  } else {
371  switch (my_param) {
372  case X:
373  return m_payload->xError();
374  case Y:
375  return m_payload->yError();
376  case Z:
377  return m_payload->zError();
378  case sigmaX:
379  return m_payload->beamWidthXError();
380  case sigmaY:
381  return m_payload->beamWidthYError();
382  case sigmaZ:
383  return m_payload->sigmaZError();
384  case dxdz:
385  return m_payload->dxdzError();
386  case dydz:
387  return m_payload->dydzError();
388  case END_OF_TYPES:
389  return ret;
390  default:
391  return ret;
392  }
393  }
394  };
395 
396  h2_BSParameters->GetXaxis()->SetBinLabel(1, "Value");
397  h2_BSParameters->GetXaxis()->SetBinLabel(2, "Error");
398 
399  unsigned int yBin = 8;
400  for (int foo = parameters::X; foo <= parameters::dydz; foo++) {
401  parameters param = static_cast<parameters>(foo);
402  std::string theLabel = getStringFromTypeEnum(param);
403  h2_BSParameters->GetYaxis()->SetBinLabel(yBin, theLabel.c_str());
404  h2_BSParameters->SetBinContent(1, yBin, cutFunctor(param, false));
405  h2_BSParameters->SetBinContent(2, yBin, cutFunctor(param, true));
406  yBin--;
407  }
408 
409  h2_BSParameters->GetXaxis()->LabelsOption("h");
410  h2_BSParameters->GetYaxis()->SetLabelSize(0.05);
411  h2_BSParameters->GetXaxis()->SetLabelSize(0.05);
412  h2_BSParameters->SetMarkerSize(1.5);
413  h2_BSParameters->Draw("TEXT");
414 
415  auto ltx = TLatex();
416  ltx.SetTextFont(62);
417  if (isOnline_) {
418  ltx.SetTextSize(0.030);
419  } else {
420  ltx.SetTextSize(0.025);
421  }
422  ltx.SetTextAlign(11);
423 
424  auto runLS = beamSpotPI::unpack(std::get<0>(iov));
425 
426  ltx.DrawLatexNDC(
427  gPad->GetLeftMargin(),
428  1 - gPad->GetTopMargin() + 0.01,
429  (tagname + " IOV: #color[4]{" + std::to_string(runLS.first) + "," + std::to_string(runLS.second) + "}")
430  .c_str());
431 
432  if (isOnline_) {
433  canvas.cd(2);
434  canvas.cd(2)->SetTopMargin(0.05);
435  canvas.cd(2)->SetBottomMargin(0.06);
436  canvas.cd(2)->SetLeftMargin(0.25);
437  canvas.cd(2)->SetRightMargin(0.01);
438  canvas.cd(2)->Modified();
439  canvas.cd(2)->SetGrid();
440 
441  auto extras = fillTheExtraHistogram();
442  if (extras) {
443  for (int bin = 1; bin <= extras->GetNbinsY(); bin++) {
444  edm::LogVerbatim("BeamSpotPayloadInspectorHelper")
445  << extras->GetYaxis()->GetBinLabel(bin) << ": " << extras->GetBinContent(1, bin) << "\n";
446  }
447  }
448  extras->Draw("TEXT");
449 
450  ltx.DrawLatexNDC(
451  gPad->GetLeftMargin(),
452  1 - gPad->GetTopMargin() + 0.01,
453  (tagname + " IOV: #color[4]{" + std::to_string(runLS.first) + "," + std::to_string(runLS.second) + "}")
454  .c_str());
455 
456  if constexpr (std::is_same_v<PayloadType, BeamSpotOnlineObjects>) {
457  // protections needed against old payload that do not have these data members persisted
458  const auto& creationTime = test_<cond::Time_t, std::out_of_range>(
459  [&]() {
460  return m_payload->creationTime();
461  }, // Lambda function capturing m_payload and calling creationTime
462  better_error);
463 
464  const auto& startTime = test_<cond::Time_t, std::out_of_range>(
465  [&]() {
466  return m_payload->startTimeStamp();
467  }, // Lambda function capturing m_payload and calling startTimeStamp
468  better_error);
469 
470  const auto& endTime = test_<cond::Time_t, std::out_of_range>(
471  [&]() {
472  return m_payload->endTimeStamp();
473  }, // Lambda function capturing m_payload and calling endTimeStamp
474  better_error);
475  canvas.cd(2);
476  ltx.SetTextSize(0.025);
477  ltx.DrawLatexNDC(
478  gPad->GetLeftMargin() + 0.01,
479  gPad->GetBottomMargin() + 0.15,
480  ("#color[2]{(" + beamSpotPI::convertTimeToDateString(creationTime, /*has us*/ true) + ")}").c_str());
481 
482  ltx.DrawLatexNDC(gPad->GetLeftMargin() + 0.01,
483  gPad->GetBottomMargin() + 0.085,
484  ("#color[2]{(" + beamSpotPI::convertTimeToDateString(startTime) + ")}").c_str());
485 
486  ltx.DrawLatexNDC(gPad->GetLeftMargin() + 0.01,
487  gPad->GetBottomMargin() + 0.025,
488  ("#color[2]{(" + beamSpotPI::convertTimeToDateString(endTime) + ")}").c_str());
489 
490  ltx.DrawLatexNDC(
491  gPad->GetLeftMargin(), gPad->GetBottomMargin() - 0.05, "#color[4]{N.B.} TimeStamps are in UTC");
492  }
493 
495  canvas.SaveAs(fileName.c_str());
496 
497  return true;
498  } else {
500  canvas.SaveAs(fileName.c_str());
501 
502  return true;
503  }
504  }
505 
506  public:
507  virtual std::shared_ptr<TH2F> fillTheExtraHistogram() const { return nullptr; }
508 
509  protected:
510  bool isOnline_;
511  std::shared_ptr<PayloadType> m_payload;
512 
518  switch (parameter) {
519  case X:
520  return "X [cm]";
521  case Y:
522  return "Y [cm]";
523  case Z:
524  return "Z [cm]";
525  case sigmaX:
526  return "#sigma_{X} [cm]";
527  case sigmaY:
528  return "#sigma_{Y} [cm]";
529  case sigmaZ:
530  return "#sigma_{Z} [cm]";
531  case dxdz:
532  return "#frac{dX}{dZ} [rad]";
533  case dydz:
534  return "#frac{dY}{dZ} [rad]";
535  default:
536  return "should never be here";
537  }
538  }
539 
540  // Slightly better error handler
541  static void better_error(const std::exception& e) { edm::LogError("DisplayParameters") << e.what() << '\n'; }
542 
543  // Method to catch exceptions
544  template <typename T, class Except, class Func, class Response>
545  T test_(Func f, Response r) const {
546  try {
547  LogDebug("DisplayParameters") << "I have tried" << std::endl;
548  return f();
549  } catch (const Except& e) {
550  LogDebug("DisplayParameters") << "I have caught!" << std::endl;
551  r(e);
552  return static_cast<T>(1);
553  }
554  }
555  };
556 
557  /************************************************
558  Display of Beam Spot parameters difference
559  *************************************************/
560  template <class PayloadType, cond::payloadInspector::IOVMultiplicity nIOVs, int ntags>
561  class DisplayParametersDiff : public cond::payloadInspector::PlotImage<PayloadType, nIOVs, ntags> {
562  public:
564  : cond::payloadInspector::PlotImage<PayloadType, nIOVs, ntags>("Display of BeamSpot parameters differences") {
565  if constexpr (std::is_same_v<PayloadType, BeamSpotOnlineObjects>) {
566  isOnline_ = true;
567  } else {
568  isOnline_ = false;
569  }
570  }
571 
572  bool fill() override {
573  // trick to deal with the multi-ioved tag and two tag case at the same time
574  auto theIOVs = cond::payloadInspector::PlotBase::getTag<0>().iovs;
575  auto f_tagname = cond::payloadInspector::PlotBase::getTag<0>().name;
576  std::string l_tagname = "";
577  auto firstiov = theIOVs.front();
578  std::tuple<cond::Time_t, cond::Hash> lastiov;
579 
580  // we don't support (yet) comparison with more than 2 tags
581  assert(this->m_plotAnnotations.ntags < 3);
582 
583  if (this->m_plotAnnotations.ntags == 2) {
584  auto tag2iovs = cond::payloadInspector::PlotBase::getTag<1>().iovs;
585  l_tagname = cond::payloadInspector::PlotBase::getTag<1>().name;
586  lastiov = tag2iovs.front();
587  } else {
588  lastiov = theIOVs.back();
589  }
590 
591  l_payload = this->fetchPayload(std::get<1>(lastiov));
592  f_payload = this->fetchPayload(std::get<1>(firstiov));
593 
594  std::string lastIOVsince = std::to_string(std::get<0>(lastiov));
595  std::string firstIOVsince = std::to_string(std::get<0>(firstiov));
596 
597  TCanvas canvas("Beam Spot Parameters Difference Summary", "Beam Spot Parameters Difference summary", 1000, 1000);
598  canvas.cd(1);
599 
600  canvas.cd(1)->SetTopMargin(0.08);
601  canvas.cd(1)->SetBottomMargin(0.06);
602  canvas.cd(1)->SetLeftMargin(0.14);
603  canvas.cd(1)->SetRightMargin(0.16);
604  canvas.cd(1)->Modified();
605  canvas.cd(1)->SetGrid();
606 
607  // for the "text"-filled histogram
608  auto h2_BSParameters = std::make_unique<TH2F>("Parameters", "", 2, 0.0, 2.0, 8, 0, 8.);
609  h2_BSParameters->SetStats(false);
610  h2_BSParameters->GetXaxis()->SetBinLabel(1, "Value");
611  h2_BSParameters->GetXaxis()->SetBinLabel(2, "Error");
612  h2_BSParameters->GetXaxis()->LabelsOption("h");
613  h2_BSParameters->GetYaxis()->SetLabelSize(0.05);
614  h2_BSParameters->GetXaxis()->SetLabelSize(0.05);
615  h2_BSParameters->SetMarkerSize(1.5);
616 
617  // prepare the arrays to fill the histogram
620 
621 #ifdef MM_DEBUG
622  std::stringstream ss1, ss2;
623  edm::LogPrint("") << "**** first payload";
624  fBS.printDebug(ss1);
625  edm::LogPrint("") << ss1.str();
626  edm::LogPrint("") << "**** last payload";
627  lBS.printDebug(ss2);
628  edm::LogPrint("") << ss2.str();
629 #endif
630 
631  const auto diffPars = fBS.diffCentralValues(lBS);
632  const auto diffErrors = fBS.diffErrors(lBS);
633  //const auto pullPars = fBS.diffCentralValues(lBS,true /*normalize*/);
634  //const auto pullErrors = fBS.diffErrors(lBS,true /*normalize*/);
635 
636  unsigned int yBin = 8;
637  for (int foo = parameters::X; foo <= parameters::dydz; foo++) {
638  parameters param = static_cast<parameters>(foo);
639  std::string theLabel = beamSpotPI::getStringFromParamEnum(param, true /*use units*/);
640  h2_BSParameters->GetYaxis()->SetBinLabel(yBin, theLabel.c_str());
641  h2_BSParameters->SetBinContent(1, yBin, diffPars[foo]); /* profiting of the parameters enum indexing */
642  h2_BSParameters->SetBinContent(2, yBin, diffErrors[foo]);
643  yBin--;
644  }
645 
646  // for the "colz"-filled histogram (clonde from the text-based one)
647  auto h2_BSShadow = (TH2F*)(h2_BSParameters->Clone("shadow"));
648  h2_BSShadow->GetZaxis()->SetTitle("#Delta Parameter(payload A - payload B)");
649  h2_BSShadow->GetZaxis()->CenterTitle();
650  h2_BSShadow->GetZaxis()->SetTitleOffset(1.5);
651 
652  // this is the fine gradient palette (blue to red)
653  double max = h2_BSShadow->GetMaximum();
654  double min = h2_BSShadow->GetMinimum();
655  double val_white = 0.;
656  double per_white = (max != min) ? ((val_white - min) / (max - min)) : 0.5;
657 
658  const int number = 3;
659  double Red[number] = {0., 1., 1.};
660  double Green[number] = {0., 1., 0.};
661  double Blue[number] = {1., 1., 0.};
662  double Stops[number] = {0., per_white, 1.};
663  int nb = 256;
664  h2_BSShadow->SetContour(nb);
665  TColor::CreateGradientColorTable(number, Stops, Red, Green, Blue, nb);
666 
667  h2_BSShadow->Draw("colz");
668  h2_BSParameters->Draw("TEXTsame");
669 
670  auto ltx = TLatex();
671  ltx.SetTextFont(62);
672  ltx.SetTextSize(0.025);
673  ltx.SetTextAlign(11);
674 
675  // compute the (run,LS) pairs
676  auto l_runLS = beamSpotPI::unpack(std::get<0>(lastiov));
677  std::string l_runLSs = "(" + std::to_string(l_runLS.first) + "," + std::to_string(l_runLS.second) + ")";
678  auto f_runLS = beamSpotPI::unpack(std::get<0>(firstiov));
679  std::string f_runLSs = "(" + std::to_string(f_runLS.first) + "," + std::to_string(f_runLS.second) + ")";
680 
681  if (this->m_plotAnnotations.ntags == 2) {
682  ltx.DrawLatexNDC(
683  gPad->GetLeftMargin() - 0.1,
684  1 - gPad->GetTopMargin() + 0.015,
685  (fmt::sprintf(
686  "#splitline{A = #color[4]{%s}: %s}{B = #color[4]{%s}: %s}", f_tagname, f_runLSs, l_tagname, l_runLSs))
687  .c_str());
688  } else {
689  ltx.DrawLatexNDC(
690  gPad->GetLeftMargin() - 0.1,
691  1 - gPad->GetTopMargin() + 0.015,
692  (fmt::sprintf("#splitline{#color[4]{%s}}{A = %s | B = %s}", f_tagname, l_runLSs, f_runLSs)).c_str());
693  }
694 
696  canvas.SaveAs(fileName.c_str());
697 
698  return true;
699  }
700 
701  public:
705  virtual std::shared_ptr<TH2F> fillTheExtraHistogram() const { return nullptr; }
706 
707  protected:
708  bool isOnline_;
709  std::shared_ptr<PayloadType> f_payload;
710  std::shared_ptr<PayloadType> l_payload;
711  };
712 } // namespace beamSpotPI
713 
714 // Similar namespace for SimBeamSpotObject
715 namespace simBeamSpotPI {
716 
717  enum parameters {
718  X = 0, // 0 - Positions
719  Y = 1, // 1
720  Z = 2, // 2
721  meanX = 3, // 3
722  meanY = 4, // 4
723  meanZ = 5, // 5
724  sigmaX = 6, // 6 - Widths
725  sigmaY = 7, // 7
726  sigmaZ = 8, // 8
727  betaStar = 9, // 9
728  emittance = 10, // 10
729  phi = 11, // 11 - Additional parameters
730  alpha = 12, // 12
731  timeOffset = 13, // 13
733  };
734 
735  /************************************************/
736  inline std::string getStringFromParamEnum(const parameters& parameter, const bool addUnits = false) {
737  switch (parameter) {
738  case X:
739  return (addUnits ? "X [cm]" : "X");
740  case Y:
741  return (addUnits ? "Y [cm]" : "Y");
742  case Z:
743  return (addUnits ? "Z [cm]" : "Z");
744  case meanX:
745  return (addUnits ? "MeanX [cm]" : "meanX");
746  case meanY:
747  return (addUnits ? "MeanY [cm]" : "meanY");
748  case meanZ:
749  return (addUnits ? "MeanZ [cm]" : "meanZ");
750  case sigmaX:
751  return (addUnits ? "#sigma_{X} [#mum]" : "sigmaX");
752  case sigmaY:
753  return (addUnits ? "#sigma_{Y} [#mum]" : "sigmaY");
754  case sigmaZ:
755  return (addUnits ? "#sigma_{Z} [cm]" : "sigmaZ");
756  case betaStar:
757  return (addUnits ? "#beta* [cm]" : "BetaStar");
758  case emittance:
759  return (addUnits ? "Emittance [cm]" : "Emittance");
760  case phi:
761  return (addUnits ? "Phi [rad]" : "Phi");
762  case alpha:
763  return (addUnits ? "Alpha [rad]" : "Alpha");
764  case timeOffset:
765  return (addUnits ? "TimeOffset [ns]" : "TimeOffset");
766  default:
767  return "should never be here";
768  }
769  }
770 
776  template <class PayloadType>
778  typedef std::array<double, parameters::END_OF_TYPES> bshelpdata;
779 
780  public:
781  SimBSParamsHelper(const std::shared_ptr<PayloadType>& bs) {
782  // fill in the values
784  m_values[parameters::meanX] = bs->meanX(), m_values[parameters::meanY] = bs->meanY();
785  m_values[parameters::meanZ] = bs->meanZ();
786  m_values[parameters::sigmaX] = bs->sigmaX() * 10000.f;
787  m_values[parameters::sigmaY] = bs->sigmaY() * 10000.f;
788  m_values[parameters::sigmaZ] = bs->sigmaZ();
789  m_values[parameters::betaStar] = bs->betaStar(), m_values[parameters::emittance] = bs->emittance();
790  m_values[parameters::phi] = bs->phi(), m_values[parameters::alpha] = bs->alpha(),
791  m_values[parameters::timeOffset] = bs->timeOffset();
792  }
793 
794  void printDebug(std::stringstream& ss) {
795  ss << "Dumping SimBeamSpot parameters Data:" << std::endl;
796  for (uint i = parameters::X; i <= parameters::timeOffset; i++) {
797  parameters par = static_cast<parameters>(i);
798  ss << getStringFromParamEnum(par) << " : " << m_values[i] << std::endl;
799  ss << std::endl;
800  }
801  }
802 
803  inline const bshelpdata centralValues() const { return m_values; }
804 
805  // get the difference in values
806  const bshelpdata diffCentralValues(const SimBSParamsHelper& bs2, const bool isPull = false) const {
807  bshelpdata ret;
808  for (uint i = parameters::X; i <= parameters::timeOffset; i++) {
809  ret[i] = this->centralValues()[i] - bs2.centralValues()[i];
810  if (isPull)
811  (this->centralValues()[i] != 0.) ? ret[i] /= this->centralValues()[i] : 0.;
812  }
813  return ret;
814  }
815 
816  private:
817  bshelpdata m_values;
818  };
819 
820  /************************************************
821  Display of Sim Beam Spot parameters
822  *************************************************/
823  template <class PayloadType>
824  class DisplayParameters : public cond::payloadInspector::PlotImage<PayloadType, cond::payloadInspector::SINGLE_IOV> {
825  public:
827  : cond::payloadInspector::PlotImage<PayloadType, cond::payloadInspector::SINGLE_IOV>(
828  "Display of SimBeamSpot parameters") {}
829 
830  bool fill() override {
831  auto tag = cond::payloadInspector::PlotBase::getTag<0>();
832  auto tagname = tag.name;
833  auto iov = tag.iovs.front();
834 
835  gStyle->SetHistMinimumZero(kTRUE);
836 
837  m_payload = this->fetchPayload(std::get<1>(iov));
838 
839  TCanvas canvas("Sim Beam Spot Parameters Summary", "Sim BeamSpot Parameters summary", 1000, 1000);
840  canvas.cd(1);
841  canvas.cd(1)->SetTopMargin(0.05);
842  canvas.cd(1)->SetBottomMargin(0.06);
843  canvas.cd(1)->SetLeftMargin(0.25);
844  canvas.cd(1)->SetRightMargin(0.01);
845  canvas.cd(1)->Modified();
846  canvas.cd(1)->SetGrid();
847 
848  auto h2_SimBSParameters = std::make_unique<TH2F>("Parameters", "", 1, 0.0, 1.0, END_OF_TYPES, 0, END_OF_TYPES);
849  h2_SimBSParameters->SetStats(false);
850 
851  std::function<double(parameters)> cutFunctor = [this](parameters my_param) {
852  double ret(-999.);
853  switch (my_param) {
854  case X:
855  return m_payload->x();
856  case Y:
857  return m_payload->y();
858  case Z:
859  return m_payload->z();
860  case meanX:
861  return m_payload->meanX();
862  case meanY:
863  return m_payload->meanY();
864  case meanZ:
865  return m_payload->meanZ();
866  case sigmaX:
867  return m_payload->sigmaX() * cmToUm;
868  case sigmaY:
869  return m_payload->sigmaY() * cmToUm;
870  case sigmaZ:
871  return m_payload->sigmaZ();
872  case betaStar:
873  return m_payload->betaStar();
874  case emittance:
875  return m_payload->emittance();
876  case phi:
877  return m_payload->phi();
878  case alpha:
879  return m_payload->alpha();
880  case timeOffset:
881  return m_payload->timeOffset();
882  case END_OF_TYPES:
883  return ret;
884  default:
885  return ret;
886  }
887  };
888 
889  h2_SimBSParameters->GetXaxis()->SetBinLabel(1, "Value");
890 
891  unsigned int yBin = END_OF_TYPES;
892  for (int foo = parameters::X; foo <= parameters::timeOffset; foo++) {
893  parameters param = static_cast<parameters>(foo);
894  std::string theLabel = getStringFromParamEnum(param, true);
895  h2_SimBSParameters->GetYaxis()->SetBinLabel(yBin, theLabel.c_str());
896  h2_SimBSParameters->SetBinContent(1, yBin, cutFunctor(param));
897  yBin--;
898  }
899 
900  h2_SimBSParameters->GetXaxis()->LabelsOption("h");
901  h2_SimBSParameters->GetYaxis()->SetLabelSize(0.05);
902  h2_SimBSParameters->GetXaxis()->SetLabelSize(0.05);
903  h2_SimBSParameters->SetMarkerSize(1.5);
904  h2_SimBSParameters->Draw("TEXT");
905 
906  auto ltx = TLatex();
907  ltx.SetTextFont(62);
908  ltx.SetTextSize(0.025);
909  //ltx.SetTextAlign(11);
910 
911  auto runLS = beamSpotPI::unpack(std::get<0>(iov));
912 
913  ltx.SetTextAlign(32); // Set text alignment to left (left-aligned)
914  ltx.DrawLatexNDC(1 - gPad->GetRightMargin(),
915  1 - gPad->GetTopMargin() + 0.01,
916  ("#color[2]{" + tagname + "} IOV: #color[4]{" + std::to_string(runLS.first) + "," +
917  std::to_string(runLS.second) + "}")
918  .c_str());
919 
921  canvas.SaveAs(fileName.c_str());
922 
923  return true;
924  }
925 
926  protected:
927  std::shared_ptr<PayloadType> m_payload;
928 
929  private:
930  static constexpr double cmToUm = 10000.f;
931  };
932 
933  /************************************************
934  Display of Sim Beam Spot parameters difference
935  *************************************************/
936  template <class PayloadType, cond::payloadInspector::IOVMultiplicity nIOVs, int ntags>
937  class DisplayParametersDiff : public cond::payloadInspector::PlotImage<PayloadType, nIOVs, ntags> {
938  public:
940  : cond::payloadInspector::PlotImage<PayloadType, nIOVs, ntags>(
941  "Display of Sim BeamSpot parameters differences") {}
942 
943  bool fill() override {
944  // trick to deal with the multi-ioved tag and two tag case at the same time
945  auto theIOVs = cond::payloadInspector::PlotBase::getTag<0>().iovs;
946  auto f_tagname = cond::payloadInspector::PlotBase::getTag<0>().name;
947  std::string l_tagname = "";
948  auto firstiov = theIOVs.front();
949  std::tuple<cond::Time_t, cond::Hash> lastiov;
950 
951  // we don't support (yet) comparison with more than 2 tags
952  assert(this->m_plotAnnotations.ntags < 3);
953 
954  if (this->m_plotAnnotations.ntags == 2) {
955  auto tag2iovs = cond::payloadInspector::PlotBase::getTag<1>().iovs;
956  l_tagname = cond::payloadInspector::PlotBase::getTag<1>().name;
957  lastiov = tag2iovs.front();
958  } else {
959  lastiov = theIOVs.back();
960  }
961 
962  l_payload = this->fetchPayload(std::get<1>(lastiov));
963  f_payload = this->fetchPayload(std::get<1>(firstiov));
964 
965  std::string lastIOVsince = std::to_string(std::get<0>(lastiov));
966  std::string firstIOVsince = std::to_string(std::get<0>(firstiov));
967 
968  TCanvas canvas(
969  "Sim Beam Spot Parameters Difference Summary", "Sim Beam Spot Parameters Difference summary", 1000, 1000);
970  canvas.cd(1);
971  canvas.cd(1)->SetTopMargin(0.10);
972  canvas.cd(1)->SetBottomMargin(0.06);
973  canvas.cd(1)->SetLeftMargin(0.23);
974  canvas.cd(1)->SetRightMargin(0.16);
975  canvas.cd(1)->Modified();
976  canvas.cd(1)->SetGrid();
977 
978  // for the "text"-filled histogram
979  auto h2_SimBSParameters = std::make_unique<TH2F>("Parameters", "", 1, 0.0, 1.0, END_OF_TYPES, 0, END_OF_TYPES);
980  h2_SimBSParameters->SetStats(false);
981  h2_SimBSParameters->GetXaxis()->SetBinLabel(1, "Value");
982  h2_SimBSParameters->GetXaxis()->LabelsOption("h");
983  h2_SimBSParameters->GetYaxis()->SetLabelSize(0.05);
984  h2_SimBSParameters->GetXaxis()->SetLabelSize(0.05);
985  h2_SimBSParameters->SetMarkerSize(1.5);
986 
987  // prepare the arrays to fill the histogram
990 
991 #ifdef MM_DEBUG
992  std::stringstream ss1, ss2;
993  edm::LogPrint("") << "**** first payload";
994  fBS.printDebug(ss1);
995  edm::LogPrint("") << ss1.str();
996  edm::LogPrint("") << "**** last payload";
997  lBS.printDebug(ss2);
998  edm::LogPrint("") << ss2.str();
999 #endif
1000 
1001  const auto diffPars = fBS.diffCentralValues(lBS);
1002  //const auto pullPars = fBS.diffCentralValues(lBS,true /*normalize*/);
1003 
1004  unsigned int yBin = END_OF_TYPES;
1005  for (int foo = parameters::X; foo <= parameters::timeOffset; foo++) {
1006  parameters param = static_cast<parameters>(foo);
1007  std::string theLabel = simBeamSpotPI::getStringFromParamEnum(param, true /*use units*/);
1008  h2_SimBSParameters->GetYaxis()->SetBinLabel(yBin, theLabel.c_str());
1009  h2_SimBSParameters->SetBinContent(1, yBin, diffPars[foo]); /* profiting of the parameters enum indexing */
1010  yBin--;
1011  }
1012 
1013  // for the "colz"-filled histogram (clonde from the text-based one)
1014  auto h2_SimBSShadow = (TH2F*)(h2_SimBSParameters->Clone("shadow"));
1015  h2_SimBSShadow->GetZaxis()->SetTitle("#Delta Parameter(payload A - payload B)");
1016  h2_SimBSShadow->GetZaxis()->CenterTitle();
1017  h2_SimBSShadow->GetZaxis()->SetTitleOffset(1.5);
1018 
1019  // this is the fine gradient palette (blue to red)
1020  double max = h2_SimBSShadow->GetMaximum();
1021  double min = h2_SimBSShadow->GetMinimum();
1022  double val_white = 0.;
1023  double per_white = (max != min) ? ((val_white - min) / (max - min)) : 0.5;
1024 
1025  const int number = 3;
1026  double Red[number] = {0., 1., 1.};
1027  double Green[number] = {0., 1., 0.};
1028  double Blue[number] = {1., 1., 0.};
1029  double Stops[number] = {0., per_white, 1.};
1030  int nb = 256;
1031  h2_SimBSShadow->SetContour(nb);
1032  TColor::CreateGradientColorTable(number, Stops, Red, Green, Blue, nb);
1033 
1034  h2_SimBSShadow->Draw("colz");
1035  h2_SimBSParameters->Draw("TEXTsame");
1036 
1037  auto ltx = TLatex();
1038  ltx.SetTextFont(62);
1039  ltx.SetTextSize(0.025);
1040  ltx.SetTextAlign(11);
1041 
1042  // compute the (run,LS) pairs
1043  auto l_runLS = beamSpotPI::unpack(std::get<0>(lastiov));
1044  std::string l_runLSs = "(" + std::to_string(l_runLS.first) + "," + std::to_string(l_runLS.second) + ")";
1045  auto f_runLS = beamSpotPI::unpack(std::get<0>(firstiov));
1046  std::string f_runLSs = "(" + std::to_string(f_runLS.first) + "," + std::to_string(f_runLS.second) + ")";
1047 
1048  if (this->m_plotAnnotations.ntags == 2) {
1049  ltx.DrawLatexNDC(
1050  gPad->GetLeftMargin(),
1051  1 - gPad->GetTopMargin() + 0.025,
1052  (fmt::sprintf(
1053  "#splitline{A = #color[4]{%s}: %s}{B = #color[4]{%s}: %s}", f_tagname, f_runLSs, l_tagname, l_runLSs))
1054  .c_str());
1055  } else {
1056  ltx.DrawLatexNDC(
1057  gPad->GetLeftMargin(),
1058  1 - gPad->GetTopMargin() + 0.025,
1059  (fmt::sprintf("#splitline{#color[4]{%s}}{A = %s | B = %s}", f_tagname, l_runLSs, f_runLSs)).c_str());
1060  }
1061 
1063  canvas.SaveAs(fileName.c_str());
1064 
1065  return true;
1066  }
1067 
1068  protected:
1069  std::shared_ptr<PayloadType> f_payload;
1070  std::shared_ptr<PayloadType> l_payload;
1071  };
1072 
1073 } // namespace simBeamSpotPI
1074 
1075 #endif
Log< level::Info, true > LogVerbatim
const bshelpdata diffErrors(const BSParamsHelper &bs2, const bool isPull=false) const
float dydz
std::pair< double, double > getFromPayload(PayloadType &payload) override
virtual std::shared_ptr< TH2F > fillTheExtraHistogram() const
float dxdz
ret
prodAgent to be discontinued
#define X(str)
Definition: MuonsGrabber.cc:38
const Time_t kLowMask(0xFFFFFFFF)
std::shared_ptr< PayloadType > m_payload
std::array< double, parameters::END_OF_TYPES > bshelpdata
std::string getStringFromParamEnum(const parameters &parameter, const bool addUnits=false)
Log< level::Error, false > LogError
assert(be >=bs)
std::pair< double, double > getFromPayload(PayloadType &payload) override
std::array< double, parameters::lastLumi > bshelpdata
const bshelpdata diffCentralValues(const BSParamsHelper &bs2, const bool isPull=false) const
static std::string to_string(const XMLCh *ch)
ScatterPlot(const std::string &title, const std::string &xLabel, const std::string &yLabel)
unsigned long long Time_t
Definition: Time.h:14
std::string convertTimeToDateString(cond::Time_t timeValue, bool hasMicros=false, bool toUTC=true)
std::pair< unsigned int, unsigned int > unpack(cond::Time_t since)
double f[11][100]
std::pair< double, double > getFromPayload(PayloadType &payload) override
std::string getStringFromParamEnum(const parameters &parameter, const bool addUnits=false)
Log< level::Warning, true > LogPrint
void printDebug(std::stringstream &ss)
virtual std::string getStringFromTypeEnum(const parameters &parameter) const
const bshelpdata diffCentralValues(const SimBSParamsHelper &bs2, const bool isPull=false) const
static void better_error(const std::exception &e)
SimBSParamsHelper(const std::shared_ptr< PayloadType > &bs)
HistoryPlot(const std::string &title, const std::string &yLabel)
std::tuple< double, double > getFromPayload(PayloadType &payload) override
def canvas(sub, attr)
Definition: svgfig.py:482
BSParamsHelper(const std::shared_ptr< PayloadType > &bs)
long double T
virtual std::shared_ptr< TH2F > fillTheExtraHistogram() const
std::shared_ptr< PayloadType > fetchPayload(const cond::Hash &payloadHash)
#define LogDebug(id)