CMS 3D CMS Logo

SiPixelAliPCLThresholdsPayloadInspectorHelper.h
Go to the documentation of this file.
1 #ifndef CONDCORE_PCLCONFIGPLUGINS_SIPIXELALIPCLTHRESHOLDSPAYLOADINSPECTORHELPER_H
2 #define CONDCORE_PCLCONFIGPLUGINS_SIPIXELALIPCLTHRESHOLDSPAYLOADINSPECTORHELPER_H
3 
7 
8 // the data format of the condition to be inspected
11 
12 #include <memory>
13 #include <sstream>
14 #include <iostream>
15 #include <functional>
16 #include <fmt/printf.h>
17 
18 // include ROOT
19 #include "TH2F.h"
20 #include "TLegend.h"
21 #include "TCanvas.h"
22 #include "TLatex.h"
23 #include "TLine.h"
24 #include "TStyle.h"
25 
27 
28  enum types { DELTA = 0, SIG = 1, MAXMOVE = 2, MAXERR = 3, FRACTION_CUT = 4, END_OF_TYPES = 5 };
29 
30  /************************************************/
32  switch (coord) {
34  return "X";
36  return "Y";
38  return "Z";
40  return "#theta_{X}";
42  return "#theta_{Y}";
44  return "#theta_{Z}";
45  default:
46  return "should never be here";
47  }
48  }
49 
50  /************************************************/
52  switch (type) {
53  case types::DELTA:
54  return "#Delta";
55  case types::SIG:
56  return "#Delta/#sigma ";
57  case types::MAXMOVE:
58  return "max. move ";
59  case types::MAXERR:
60  return "max. err ";
62  return "fraction cut ";
63  default:
64  return "should never be here";
65  }
66  }
67 
68  /************************************************/
69  inline std::string replaceAll(const std::string& str, const std::string& from, const std::string& to) {
71 
72  if (from.empty())
73  return out;
74  size_t start_pos = 0;
75  while ((start_pos = out.find(from, start_pos)) != std::string::npos) {
76  out.replace(start_pos, from.length(), to);
77  start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
78  }
79  return out;
80  }
81 
82  /************************************************
83  Display of AlignPCLThreshold
84  *************************************************/
85  template <class PayloadType>
87  : public cond::payloadInspector::PlotImage<PayloadType, cond::payloadInspector::SINGLE_IOV> {
88  public:
90  : cond::payloadInspector::PlotImage<PayloadType, cond::payloadInspector::SINGLE_IOV>(
91  "Display of threshold parameters for SiPixelAli PCL") {
92  if constexpr (std::is_same_v<PayloadType, AlignPCLThresholdsHG>) {
93  isHighGranularity_ = true;
94  label_ = "AlignPCLThresholdsHG_PayloadInspector";
95  } else {
96  isHighGranularity_ = false;
97  label_ = "AlignPCLThresholds_PayloadInspector";
98  }
99  }
100 
101  bool fill() override {
102  // to be able to see zeros
103  gStyle->SetHistMinimumZero(kTRUE);
104 
105  auto tag = cond::payloadInspector::PlotBase::getTag<0>();
106  auto iov = tag.iovs.front();
107  std::shared_ptr<PayloadType> payload = this->fetchPayload(std::get<1>(iov));
108  auto alignables = payload->getAlignableList();
109 
110  TCanvas canvas("Alignment PCL thresholds summary", "Alignment PCL thresholds summary", 1500, 800);
111  canvas.cd();
112 
113  canvas.SetTopMargin(0.07);
114  canvas.SetBottomMargin(isHighGranularity_ ? 0.20 : 0.06);
115  canvas.SetLeftMargin(0.11);
116  canvas.SetRightMargin(0.05);
117  canvas.Modified();
118  canvas.SetGrid();
119 
120  // needed for the internal loop
121  const auto& local_end_of_types = isHighGranularity_ ? END_OF_TYPES : FRACTION_CUT;
122  const int N_Y_BINS = AlignPCLThresholds::extra_DOF * local_end_of_types;
123 
124  auto Thresholds =
125  std::make_unique<TH2F>("Thresholds", "", alignables.size(), 0, alignables.size(), N_Y_BINS, 0, N_Y_BINS);
126  Thresholds->SetStats(false);
127  Thresholds->GetXaxis()->SetLabelSize(0.028);
128 
129  std::function<float(types, std::string, AlignPCLThresholds::coordType)> cutFunctor =
130  [&payload](types my_type, std::string alignable, AlignPCLThresholds::coordType coord) {
131  float ret(-999.);
132  switch (my_type) {
133  case DELTA:
134  return payload->getCut(alignable, coord);
135  case SIG:
136  return payload->getSigCut(alignable, coord);
137  case MAXMOVE:
138  return payload->getMaxMoveCut(alignable, coord);
139  case MAXERR:
140  return payload->getMaxErrorCut(alignable, coord);
141  case FRACTION_CUT: {
142  if constexpr (std::is_same_v<PayloadType, AlignPCLThresholdsHG>) {
143  const AlignPCLThresholdsHG::param_map& floatMap = payload->getFloatMap();
144  if (floatMap.find(alignable) != floatMap.end()) {
145  return payload->getFractionCut(alignable, coord);
146  } else {
147  return 0.f;
148  }
149  } else {
150  assert(false); /* cannot be here */
151  }
152  }
153  case END_OF_TYPES:
154  return ret;
155  default:
156  return ret;
157  }
158  };
159 
160  unsigned int xBin = 0;
161  for (const auto& alignable : alignables) {
162  xBin++;
163  auto xLabel = replaceAll(replaceAll(alignable, "minus", "(-)"), "plus", "(+)");
164  Thresholds->GetXaxis()->SetBinLabel(xBin, (xLabel).c_str());
165  unsigned int yBin = N_Y_BINS;
166  for (int foo = PayloadType::X; foo != PayloadType::extra_DOF; foo++) {
168  for (int bar = DELTA; bar != local_end_of_types; bar++) {
169  types type = static_cast<types>(bar);
171  if (xBin == 1) {
172  Thresholds->GetYaxis()->SetBinLabel(yBin, theLabel.c_str());
173  }
174 
175  Thresholds->SetBinContent(xBin, yBin, cutFunctor(type, alignable, coord));
176 
177  yBin--;
178  } // loop on types
179  } // loop on coordinates
180  } // loop on alignables
181 
182  Thresholds->GetXaxis()->LabelsOption(isHighGranularity_ ? "v" : "h");
183  Thresholds->Draw("TEXT");
184 
185  auto ltx = TLatex();
186  ltx.SetTextFont(62);
187  //ltx.SetTextColor(kBlue);
188  ltx.SetTextSize(0.047);
189  ltx.SetTextAlign(11);
190  std::string ltxText =
191  fmt::sprintf("#color[4]{%s} IOV: #color[4]{%s}", tag.name, std::to_string(std::get<0>(iov)));
192  ltx.DrawLatexNDC(gPad->GetLeftMargin(), 1 - gPad->GetTopMargin() + 0.01, ltxText.c_str());
193 
195  canvas.SaveAs(fileName.c_str());
196 
197  return true;
198  }
199 
200  private:
203  };
204 
205  /************************************************
206  Compare AlignPCLThresholdsHG mapping
207  *************************************************/
208  template <class PayloadType, cond::payloadInspector::IOVMultiplicity nIOVs, int ntags>
209  class AlignPCLThresholds_CompareBase : public cond::payloadInspector::PlotImage<PayloadType, nIOVs, ntags> {
210  public:
212  : cond::payloadInspector::PlotImage<PayloadType, nIOVs, ntags>("Table of AlignPCLThresholdsHG comparison") {
213  if constexpr (std::is_same_v<PayloadType, AlignPCLThresholdsHG>) {
214  isHighGranularity_ = true;
215  label_ = "AlignPCLThresholdsHG_PayloadInspector";
216  } else {
217  isHighGranularity_ = false;
218  label_ = "AlignPCLThresholds_PayloadInspector";
219  }
220  }
221 
222  bool fill() override {
223  gStyle->SetPalette(kTemperatureMap);
224 
225  // to be able to see zeros
226  gStyle->SetHistMinimumZero(kTRUE);
227 
228  // trick to deal with the multi-ioved tag and two tag case at the same time
229  auto theIOVs = cond::payloadInspector::PlotBase::getTag<0>().iovs;
230  auto f_tagname = cond::payloadInspector::PlotBase::getTag<0>().name;
231  std::string l_tagname = "";
232  auto firstiov = theIOVs.front();
233  std::tuple<cond::Time_t, cond::Hash> lastiov;
234 
235  // we don't support (yet) comparison with more than 2 tags
236  assert(this->m_plotAnnotations.ntags < 3);
237 
238  if (this->m_plotAnnotations.ntags == 2) {
239  auto tag2iovs = cond::payloadInspector::PlotBase::getTag<1>().iovs;
240  l_tagname = cond::payloadInspector::PlotBase::getTag<1>().name;
241  lastiov = tag2iovs.front();
242  } else {
243  lastiov = theIOVs.back();
244  }
245 
246  std::shared_ptr<PayloadType> l_payload = this->fetchPayload(std::get<1>(lastiov));
247  std::shared_ptr<PayloadType> f_payload = this->fetchPayload(std::get<1>(firstiov));
248 
249  std::string lastIOVsince = std::to_string(std::get<0>(lastiov));
250  std::string firstIOVsince = std::to_string(std::get<0>(firstiov));
251 
252  const auto& alignables = l_payload->getAlignableList();
253  const auto& alignables2 = f_payload->getAlignableList();
254 
255  std::vector<std::string> v_intersection;
256 
257  if (!isEqual(alignables, alignables2)) {
259  << "Cannot compare directly the two AlignPCLThresholds objects, as the list of alignables differs";
260  std::set_intersection(alignables.begin(),
261  alignables.end(),
262  alignables2.begin(),
263  alignables2.end(),
264  std::back_inserter(v_intersection));
265 
266  std::vector<std::string> not_in_first_keys, not_in_last_keys;
267 
268  // find the elements not in common
269  std::set_difference(alignables.begin(),
270  alignables.end(),
271  alignables2.begin(),
272  alignables2.end(),
273  std::inserter(not_in_last_keys, not_in_last_keys.begin()));
274 
275  std::stringstream ss;
276  ss << "the following keys are not in the last IoV: ";
277  for (const auto& key : not_in_last_keys) {
278  ss << key << ",";
279  }
280  ss << std::endl;
281  edm::LogWarning(label_) << ss.str();
282  ss.str(std::string()); /* clear the stream */
283 
284  std::set_difference(alignables2.begin(),
285  alignables2.end(),
286  alignables.begin(),
287  alignables.end(),
288  std::inserter(not_in_first_keys, not_in_first_keys.begin()));
289 
290  ss << "the following keys are not in the first IoV: ";
291  for (const auto& key : not_in_first_keys) {
292  ss << key << ",";
293  }
294  ss << std::endl;
295  edm::LogWarning(label_) << ss.str();
296  } else {
297  // vectors are the same, just copy one
298  v_intersection = alignables;
299  }
300 
301  TCanvas canvas("Alignment PCL thresholds summary", "Alignment PCL thresholds summary", 1500, 800);
302  canvas.cd();
303 
304  canvas.SetTopMargin(0.07);
305  canvas.SetBottomMargin(isHighGranularity_ ? 0.20 : 0.06);
306  canvas.SetLeftMargin(0.11);
307  canvas.SetRightMargin(0.12);
308  canvas.Modified();
309  canvas.SetGrid();
310 
311  // needed for the internal loop
312  const auto& local_end_of_types = isHighGranularity_ ? END_OF_TYPES : FRACTION_CUT;
313  const int N_Y_BINS = AlignPCLThresholds::extra_DOF * local_end_of_types;
314 
315  auto Thresholds = std::make_unique<TH2F>(
316  "Thresholds", "", v_intersection.size(), 0, v_intersection.size(), N_Y_BINS, 0, N_Y_BINS);
317  Thresholds->SetStats(false);
318  Thresholds->GetXaxis()->SetLabelSize(0.028);
319 
320  auto ThresholdsColor = std::make_unique<TH2F>(
321  "ThresholdsC", "", v_intersection.size(), 0, v_intersection.size(), N_Y_BINS, 0, N_Y_BINS);
322  ThresholdsColor->SetStats(false);
323  ThresholdsColor->GetXaxis()->SetLabelSize(0.028);
324 
325  std::function<float(types, std::string, AlignPCLThresholds::coordType)> cutFunctor =
326  [&f_payload, &l_payload](types my_type, std::string alignable, AlignPCLThresholds::coordType coord) {
327  float ret(-999.);
328  switch (my_type) {
329  case DELTA:
330  return l_payload->getCut(alignable, coord) - f_payload->getCut(alignable, coord);
331  case SIG:
332  return l_payload->getSigCut(alignable, coord) - f_payload->getSigCut(alignable, coord);
333  case MAXMOVE:
334  return l_payload->getMaxMoveCut(alignable, coord) - f_payload->getMaxMoveCut(alignable, coord);
335  case MAXERR:
336  return l_payload->getMaxErrorCut(alignable, coord) - f_payload->getMaxErrorCut(alignable, coord);
337  case FRACTION_CUT: {
338  if constexpr (std::is_same_v<PayloadType, AlignPCLThresholdsHG>) {
339  const AlignPCLThresholdsHG::param_map& f_floatMap = f_payload->getFloatMap();
340  const AlignPCLThresholdsHG::param_map& l_floatMap = l_payload->getFloatMap();
341  if (f_floatMap.find(alignable) != f_floatMap.end() &&
342  l_floatMap.find(alignable) != l_floatMap.end()) {
343  return l_payload->getFractionCut(alignable, coord) - f_payload->getFractionCut(alignable, coord);
344  } else {
345  return +999.f;
346  }
347  } else {
348  assert(false); /* cannot be here */
349  }
350  }
351  case END_OF_TYPES:
352  return ret;
353  default:
354  return ret;
355  }
356  };
357 
358  unsigned int xBin = 0;
359  for (const auto& alignable : v_intersection) {
360  xBin++;
361  auto xLabel = replaceAll(replaceAll(alignable, "minus", "(-)"), "plus", "(+)");
362  Thresholds->GetXaxis()->SetBinLabel(xBin, (xLabel).c_str());
363  ThresholdsColor->GetXaxis()->SetBinLabel(xBin, (xLabel).c_str());
364  unsigned int yBin = N_Y_BINS;
365  for (int foo = PayloadType::X; foo != PayloadType::extra_DOF; foo++) {
367  for (int bar = DELTA; bar != local_end_of_types; bar++) {
368  types type = static_cast<types>(bar);
370  if (xBin == 1) {
371  Thresholds->GetYaxis()->SetBinLabel(yBin, theLabel.c_str());
372  ThresholdsColor->GetYaxis()->SetBinLabel(yBin, theLabel.c_str());
373  }
374 
375  const auto& value = cutFunctor(type, alignable, coord);
376  Thresholds->SetBinContent(xBin, yBin, value);
377  ThresholdsColor->SetBinContent(xBin, yBin, value);
378 
379  yBin--;
380  } // loop on types
381  } // loop on coordinates
382  } // loop on alignables
383 
384  ThresholdsColor->Draw("COLZ0");
385  ThresholdsColor->GetXaxis()->LabelsOption(isHighGranularity_ ? "v" : "h");
386  Thresholds->Draw("TEXTsame");
387  Thresholds->GetXaxis()->LabelsOption(isHighGranularity_ ? "v" : "h");
388 
389  auto ltx = TLatex();
390  ltx.SetTextFont(62);
391  //ltx.SetTextColor(kBlue);
392  ltx.SetTextSize(0.047);
393  ltx.SetTextAlign(11);
394  std::string ltxText;
395  if (this->m_plotAnnotations.ntags == 2) {
396  ltxText = fmt::sprintf("#color[2]{%s, %s} vs #color[4]{%s, %s}",
397  f_tagname,
398  std::to_string(std::get<0>(firstiov)),
399  l_tagname,
400  std::to_string(std::get<0>(lastiov)));
401  } else {
402  ltxText = fmt::sprintf("%s IOV: #color[2]{%s} vs IOV: #color[4]{%s}",
403  f_tagname,
404  std::to_string(std::get<0>(firstiov)),
405  std::to_string(std::get<0>(lastiov)));
406  }
407  ltx.DrawLatexNDC(gPad->GetLeftMargin(), 1 - gPad->GetTopMargin() + 0.01, ltxText.c_str());
408 
410  canvas.SaveAs(fileName.c_str());
411 
412  return true;
413  }
414 
415  private:
416  template <typename T>
417  bool isEqual(std::vector<T> const& v1, std::vector<T> const& v2) {
418  return (v1.size() == v2.size() && std::equal(v1.begin(), v1.end(), v2.begin()));
419  }
422  };
423 } // namespace AlignPCLThresholdPlotHelper
424 
425 #endif
std::unordered_map< std::string, std::vector< float > > param_map
const std::string getStringFromCoordEnum(const AlignPCLThresholds::coordType &coord)
bool isEqual(std::vector< T > const &v1, std::vector< T > const &v2)
ret
prodAgent to be discontinued
const std::string getStringFromTypeEnum(const types &type)
#define X(str)
Definition: MuonsGrabber.cc:38
assert(be >=bs)
static std::string to_string(const XMLCh *ch)
bool equal(const T &first, const T &second)
Definition: Equal.h:32
std::string replaceAll(const std::string &str, const std::string &from, const std::string &to)
Definition: value.py:1
def canvas(sub, attr)
Definition: svgfig.py:482
Log< level::Warning, false > LogWarning
#define str(s)
std::vector< std::string > set_difference(std::vector< std::string > const &v1, std::vector< std::string > const &v2)
std::shared_ptr< PayloadType > fetchPayload(const cond::Hash &payloadHash)
std::vector< std::string > set_intersection(std::vector< std::string > const &v1, std::vector< std::string > const &v2)