CMS 3D CMS Logo

ListGroups.cc
Go to the documentation of this file.
1 #include <iomanip>
2 #include <iostream>
3 #include <map>
4 #include <string>
5 #include <vector>
6 
7 #include <fmt/printf.h>
8 
9 // ROOT
10 #include <TCanvas.h>
11 #include <TColor.h>
12 #include <TFrame.h>
13 #include <TLegend.h>
14 #include <TLegendEntry.h>
15 #include <TLine.h>
16 #include <TProfile2D.h>
17 #include <TROOT.h>
18 #include <TStyle.h>
19 #include <TText.h>
20 
35 
38 
40  std::vector<const DDsvalues_type *> result;
41  view.specificsV(result);
42  for (std::vector<const DDsvalues_type *>::iterator it = result.begin(); it != result.end(); ++it) {
44  if (DDfetch(*it, parameter)) {
45  if (parameter.strings().size() == 1) {
46  value = parameter.strings().front();
47  return true;
48  } else {
49  throw cms::Exception("Configuration") << " ERROR: multiple " << name << " tags encountered";
50  return false;
51  }
52  }
53  }
54  return false;
55 }
56 
57 /*
58 static inline
59 double dddGetDouble(const std::string & s, DDFilteredView const & view) {
60  std::string value;
61  if (dddGetStringRaw(view, s, value))
62  return double(::atof(value.c_str()));
63  else
64  return NAN;
65 }
66 */
67 
68 static inline std::string dddGetString(const std::string &s, DDFilteredView const &view) {
70  if (dddGetStringRaw(view, s, value))
71  return value;
72  else
73  return std::string();
74 }
75 
76 class ListGroups : public edm::one::EDAnalyzer<> {
77 public:
79  ~ListGroups() override;
80 
81 private:
82  void analyze(const edm::Event &, const edm::EventSetup &) override;
83  void beginJob() override {}
84  void endJob() override;
85  void fillColor();
87  void fillGradient();
88  std::vector<std::pair<std::shared_ptr<TLine>, std::shared_ptr<TText> > > overlayEtaReferences();
90 
91  const bool m_saveSummaryPlot;
93  std::vector<TH2F *> m_plots;
94  std::set<std::string> m_group_names;
95  std::vector<MaterialAccountingGroup *> m_groups;
96  std::vector<unsigned int> m_color;
97  std::vector<int> m_gradient;
98 
99  // The following maps are automatically filled by the script
100  // dumpFullXML, when run with -c,--compare flag, and are injected in
101  // this code via the header ListGroupsMaterialDifference.h, which is
102  // included below. The first value of the pair in m_diff represents
103  // the relative difference ((new - old)/old * 100, in %) of
104  // radiation length, while the second referes to the energy loss (in
105  // GeV/cm) changes. The values in m_values are ordered in the very
106  // same way, ie. they contain the new values for radiation length
107  // and energy loss, respectively.
108  std::map<std::string, std::pair<float, float> > m_diff;
109  std::map<std::string, std::pair<float, float> > m_values;
110 };
111 
113  : m_saveSummaryPlot(iPSet.getUntrackedParameter<bool>("SaveSummaryPlot")),
115  m_plots.clear();
116  m_groups.clear();
117  TColor::InitializeColors();
118  fillColor();
120  fillGradient();
121 }
122 
124  for (auto plot : m_plots)
125  delete plot;
126 
127  if (!m_groups.empty())
128  for (auto g : m_groups)
129  delete g;
130 }
131 
133 
135  m_gradient.reserve(200);
136  unsigned int steps = 100;
137  // if no index was given, find the highest used one and start from that plus one
138  unsigned int index = ((TObjArray *)gROOT->GetListOfColors())->GetLast() + 1;
139 
140  float r1, g1, b1, r2, g2, b2;
141  static_cast<TColor *>(gROOT->GetListOfColors()->At(kBlue + 1))->GetRGB(r1, g1, b1);
142  static_cast<TColor *>(gROOT->GetListOfColors()->At(kAzure + 10))->GetRGB(r2, g2, b2);
143  float delta_r = (r2 - r1) / (steps - 1);
144  float delta_g = (g2 - g1) / (steps - 1);
145  float delta_b = (b2 - b1) / (steps - 1);
146 
147  m_gradient.push_back(kBlue + 4); // Underflow lowest bin
148  unsigned int ii = 0;
149  for (unsigned int i = 0; i < steps; ++i, ++ii) {
150  new TColor(static_cast<Int_t>(index + ii), r1 + delta_r * i, g1 + delta_g * i, b1 + delta_b * i);
151  m_gradient.push_back(index + ii);
152  }
153 
154  m_gradient.push_back(kWhite); // 0 level perfectly white
155 
156  static_cast<TColor *>(gROOT->GetListOfColors()->At(kOrange))->GetRGB(r1, g1, b1);
157  static_cast<TColor *>(gROOT->GetListOfColors()->At(kOrange + 7))->GetRGB(r2, g2, b2);
158  delta_r = (r2 - r1) / (steps - 1);
159  delta_g = (g2 - g1) / (steps - 1);
160  delta_b = (b2 - b1) / (steps - 1);
161  for (unsigned int i = 0; i < steps; ++i, ++ii) {
162  new TColor(static_cast<Int_t>(index + ii), r1 + delta_r * i, g1 + delta_g * i, b1 + delta_b * i);
163  m_gradient.push_back(index + ii);
164  }
165  m_gradient.push_back(kRed); // Overflow highest bin
166 }
167 
169  // With the introduction of the support for PhaseI and PhaseII detectors it
170  // became quite difficult to maintain a list of colors that is in sync with
171  // the real number of grouping used in the different scenarios. We therefore
172  // define some reasonable set and loop over it in case the number of grouping
173  // is larger than the number of colors.
174 
175  m_color.push_back(kBlack); // unassigned
176 
177  m_color.push_back(kAzure); // PixelBarrelLayer0_Z0
178  m_color.push_back(kAzure - 1); // PixelBarrelLayer0_Z20
179  m_color.push_back(kAzure + 1); // Layer1_Z0
180  m_color.push_back(kAzure + 2); // Layer1_Z20
181 
182  m_color.push_back(kGreen); // EndCapDisk1_R0
183  m_color.push_back(kGreen + 2); // EndcapDisk1_R11
184  m_color.push_back(kGreen + 4); // EndcapDisk1_R7
185  m_color.push_back(kSpring + 9); // EndcapDisk2_R0
186  m_color.push_back(kSpring + 4); // EndcapDisk2_R7
187  m_color.push_back(kSpring); // EndcapDisk2_R7
188 
189  m_color.push_back(kRed); // TECDisk0_R20
190  m_color.push_back(kRed + 2); // TECDisk0_R40
191  m_color.push_back(kRed - 7); // TECDisk0_R50
192  m_color.push_back(kRed - 5); // TECDisk0_R60
193  m_color.push_back(kRed - 10); // TECDisk0_R90
194  m_color.push_back(kRed - 1); // TECDisk1_Inner
195  m_color.push_back(kRed - 2); // TECDisk1_Outer
196  m_color.push_back(kRed - 3); // TECDisk1_R20
197  m_color.push_back(kPink - 2); // TECDisk2_Inner
198  m_color.push_back(kPink - 3); // TECDisk2_Outer
199  m_color.push_back(kPink - 4); // TECDisk2_R20
200  m_color.push_back(kPink + 9); // TECDisk3_Inner
201  m_color.push_back(kPink + 8); // TECDisk3_Outer
202  m_color.push_back(kPink + 7); // TECDisk3
203  m_color.push_back(kMagenta - 2); // TECDisk4_Inner
204  m_color.push_back(kMagenta - 3); // TECDisk4_Outer
205  m_color.push_back(kMagenta - 4); // TECDisk4_R33
206  m_color.push_back(kMagenta - 5); // TECDisk5_Inner
207  m_color.push_back(kMagenta - 6); // TECDisk5_Outer
208  m_color.push_back(kMagenta - 7); // TECDisk5_R33
209  m_color.push_back(kRed); // TECDisk6
210  m_color.push_back(kMagenta - 9); // TECDisk7_R40
211  m_color.push_back(kViolet); // TECDisk8
212 
213  m_color.push_back(kOrange + 9); // TIBLayer0_Z0
214  m_color.push_back(kOrange + 7); // TIBLayer0_Z20
215  m_color.push_back(kOrange + 5); // TIBLayer0_Z40
216  m_color.push_back(kOrange - 2); // TIBLayer1_Z0
217  m_color.push_back(kOrange - 3); // TIBLayer1_Z30
218  m_color.push_back(kOrange - 6); // TIBLayer1_Z60
219  m_color.push_back(kOrange + 4); // TIBLayer2_Z0
220  m_color.push_back(kOrange - 7); // TIBLayer2_Z40
221  m_color.push_back(kOrange); // TIBLayer3_Z0
222  m_color.push_back(kOrange + 10); // TIBLayer3_Z50
223 
224  m_color.push_back(kViolet + 10); // TIDDisk1_R0
225  m_color.push_back(kViolet + 6); // TIDDisk1_R30
226  m_color.push_back(kViolet + 3); // TIDDisk1_R40
227  m_color.push_back(kViolet - 7); // TIDDisk2_R25
228  m_color.push_back(kViolet - 1); // TIDDisk2_R30
229  m_color.push_back(kViolet + 9); // TIDDisk2_R40
230  m_color.push_back(kViolet - 5); // TIDDisk3_R24
231  m_color.push_back(kViolet - 3); // TIDDisk3_R30
232  m_color.push_back(kViolet); // TIDDisk3_R40
233 
234  m_color.push_back(kAzure); // TOBLayer0_Z0
235  m_color.push_back(kAzure + 8); // TOBLayer0_Z20
236  m_color.push_back(kAzure + 2); // TOBLayer0_Z70
237  m_color.push_back(kAzure + 4); // TOBLayer0_Z80
238  m_color.push_back(kCyan + 1); // TOBLayer1_Z0
239  m_color.push_back(kCyan - 9); // TOBLayer1_Z20
240  m_color.push_back(kCyan + 3); // TOBLayer1_Z80
241  m_color.push_back(kCyan + 4); // TOBLayer1_Z90
242  m_color.push_back(kAzure); // TOBLayer2_Z0
243  m_color.push_back(kAzure + 8); // TOBLayer2_Z25
244  m_color.push_back(kAzure + 2); // TOBLayer2_Z80
245  m_color.push_back(kAzure + 5); // TOBLayer2_Z90
246  m_color.push_back(kCyan + 1); // TOBLayer3_Z0
247  m_color.push_back(kCyan - 9); // TOBLayer3_Z25
248  m_color.push_back(kCyan + 3); // TOBLayer3_Z80
249  m_color.push_back(kCyan + 4); // TOBLayer3_Z90
250  m_color.push_back(kAzure); // TOBLayer4_Z0
251  m_color.push_back(kAzure + 8); // TOBLayer4_Z25
252  m_color.push_back(kAzure + 2); // TOBLayer4_Z80
253  m_color.push_back(kAzure + 5); // TOBLayer4_Z90
254  m_color.push_back(kCyan + 1); // TOBLayer5_Z0
255  m_color.push_back(kCyan - 9); // TOBLayer5_Z25
256  m_color.push_back(kCyan + 3); // TOBLayer5_Z80
257  m_color.push_back(kCyan + 4); // TOBLayer5_Z90
258 }
259 
260 std::vector<std::pair<std::shared_ptr<TLine>, std::shared_ptr<TText> > > ListGroups::overlayEtaReferences() {
261  std::vector<std::pair<std::shared_ptr<TLine>, std::shared_ptr<TText> > > lines;
262 
263  lines.reserve(40);
264  std::pair<float, float> deltaZ(293, 298);
265  std::pair<float, float> deltaR(115, 118);
266  float text_size = 0.033;
267 
268  for (float eta = 0.; eta <= 3.8; eta += 0.2) {
269  float theta = 2. * atan(exp(-eta));
270  if (eta >= 1.8) {
271  lines.push_back(std::make_pair<std::shared_ptr<TLine>, std::shared_ptr<TText> >(
272  std::make_shared<TLine>(deltaZ.first, deltaZ.first * tan(theta), deltaZ.second, deltaZ.second * tan(theta)),
273  std::make_shared<TText>(deltaZ.first, deltaZ.first * tan(theta), fmt::sprintf("%2.1f", eta).c_str())));
274  lines.back().second->SetTextFont(42);
275  lines.back().second->SetTextSize(text_size);
276  lines.back().second->SetTextAlign(33);
277  lines.push_back(std::make_pair<std::shared_ptr<TLine>, std::shared_ptr<TText> >(
278  std::make_shared<TLine>(-deltaZ.first, deltaZ.first * tan(theta), -deltaZ.second, deltaZ.second * tan(theta)),
279  std::make_shared<TText>(-deltaZ.first, deltaZ.first * tan(theta), fmt::sprintf("-%2.1f", eta).c_str())));
280  lines.back().second->SetTextFont(42);
281  lines.back().second->SetTextSize(text_size);
282  lines.back().second->SetTextAlign(13);
283  } else {
284  lines.push_back(std::make_pair<std::shared_ptr<TLine>, std::shared_ptr<TText> >(
285  std::make_shared<TLine>(deltaR.first / tan(theta), deltaR.first, deltaR.second / tan(theta), deltaR.second),
286  std::make_shared<TText>(deltaR.first / tan(theta), deltaR.first, fmt::sprintf("%2.1f", eta).c_str())));
287  lines.back().second->SetTextFont(42);
288  lines.back().second->SetTextSize(text_size);
289  lines.back().second->SetTextAlign(23);
290  if (eta != 0) {
291  lines.push_back(std::make_pair<std::shared_ptr<TLine>, std::shared_ptr<TText> >(
292  std::make_shared<TLine>(
293  -deltaR.first / tan(theta), deltaR.first, -deltaR.second / tan(theta), deltaR.second),
294  std::make_shared<TText>(-deltaR.first / tan(theta), deltaR.first, fmt::sprintf("-%2.1f", eta).c_str())));
295  lines.back().second->SetTextFont(42);
296  lines.back().second->SetTextSize(text_size);
297  lines.back().second->SetTextAlign(23);
298  }
299  }
300  }
301  return lines;
302 }
303 
305  const double scale = 10.;
306  std::vector<TText *> nukem_text;
307  static int markerStyles[10] = {kFullCircle,
308  kFullSquare,
309  kFullTriangleUp,
310  kFullTriangleDown,
311  kOpenCircle,
312  kOpenSquare,
313  kOpenTriangleUp,
314  kOpenDiamond,
315  kOpenCross,
316  kFullStar};
317 
318  edm::ESTransientHandle<DDCompactView> hDdd = setup.getTransientHandle(ddToken_);
319 
320  for (const auto &n : m_group_names) {
321  m_groups.push_back(new MaterialAccountingGroup(n, *hDdd));
322  };
323 
324  std::unique_ptr<TCanvas> canvas(
325  new TCanvas("Grouping_rz", "Grouping - RZ view", (int)(600 * scale * 1.25), (int)(120 * scale * 1.50)));
326  canvas->GetFrame()->SetFillColor(kWhite);
327  gStyle->SetOptStat(0);
328 
329  unsigned int color_index = 1;
330  // Setup the legend
331  std::unique_ptr<TLegend> leg(new TLegend(0.1, 0.1, 0.23, 0.34));
332  leg->SetHeader("Tracker Material Grouping");
333  leg->SetTextFont(42);
334  leg->SetTextSize(0.008);
335  leg->SetNColumns(3);
336  std::unique_ptr<TProfile2D> radlen(
337  new TProfile2D("OverallRadLen", "OverallRadLen", 600., -300., 300, 120., 0., 120.));
338  std::unique_ptr<TProfile2D> eneloss(
339  new TProfile2D("OverallEnergyLoss", "OverallEnergyLoss", 600., -300., 300, 120., 0., 120.));
340  std::unique_ptr<TProfile2D> radlen_diff(
341  new TProfile2D("OverallDifferencesRadLen", "OverallDifferencesRadLen", 600., -300., 300, 120., 0., 120.));
342  std::unique_ptr<TProfile2D> eneloss_diff(
343  new TProfile2D("OverallDifferencesEnergyLoss", "OverallDifferencesEnergyLoss", 600., -300., 300, 120., 0., 120.));
344 
345  for (auto g : m_groups) {
346  m_plots.push_back(
347  new TH2F(g->name().c_str(), g->name().c_str(), 6000., -300., 300, 1200., 0., 120.)); // 10x10 points per cm2
348  TH2F &current = *m_plots.back();
349  current.SetMarkerColor(m_color[color_index]);
350  current.SetMarkerStyle(markerStyles[color_index % 10]);
351  current.SetMarkerSize(0.8);
352  current.SetLineWidth(1);
353  for (const auto &element : g->elements()) {
354  current.Fill(element.z(), element.perp());
355  radlen->Fill(element.z(), element.perp(), m_values[g->name()].first);
356  eneloss->Fill(element.z(), element.perp(), m_values[g->name()].second);
357  radlen_diff->Fill(element.z(), element.perp(), m_diff[g->name()].first);
358  eneloss_diff->Fill(element.z(), element.perp(), m_diff[g->name()].second);
359  }
360 
361  if (color_index == 1)
362  current.Draw();
363  else
364  current.Draw("SAME");
365 
366  leg->AddEntry(&current, g->name().c_str(), "lp")->SetTextColor(m_color[color_index]);
367  color_index++;
368 
369  // Loop over the same chromatic scale in case the number of
370  // allocated colors is not big enough.
371  color_index = color_index % m_color.size();
372  }
373  leg->Draw();
374  canvas->SaveAs("Grouping.png");
375 
376  std::vector<std::pair<std::shared_ptr<TLine>, std::shared_ptr<TText> > > lines = overlayEtaReferences();
377 
378  canvas->Clear();
379  radlen->SetMinimum(0);
380  radlen->SetMaximum(0.25);
381  radlen->Draw("COLZ");
382  for (const auto &line : lines) {
383  line.first->SetLineWidth(5);
384  line.first->Draw();
385  line.second->Draw();
386  }
387  canvas->SaveAs("RadLenValues.png");
388 
389  canvas->Clear();
390  eneloss->SetMinimum(0.00001);
391  eneloss->SetMaximum(0.0005);
392  eneloss->Draw("COLZ");
393  for (const auto &line : lines) {
394  line.first->SetLineWidth(5);
395  line.first->Draw();
396  line.second->Draw();
397  }
398  canvas->SaveAs("EnergyLossValues.png");
399 
400  canvas->Clear();
401  gStyle->SetPalette(m_gradient.size(), &m_gradient.front());
402  gStyle->SetNumberContours(m_gradient.size());
403  radlen_diff->SetMinimum(-100);
404  radlen_diff->SetMaximum(100);
405  radlen_diff->Draw("COLZ");
406  for (const auto &line : lines) {
407  line.first->SetLineWidth(5);
408  line.first->Draw();
409  line.second->Draw();
410  }
411  canvas->SaveAs("RadLenChanges.png");
412 
413  canvas->Clear();
414  eneloss_diff->SetMinimum(-100);
415  eneloss_diff->SetMaximum(100);
416  eneloss_diff->Draw("COLZ");
417  for (const auto &line : lines) {
418  line.first->SetLineWidth(5);
419  line.first->Draw();
420  line.second->Draw();
421  }
422  canvas->SaveAs("EnergyLossChanges.png");
423 
424  for (auto g : nukem_text)
425  delete g;
426 }
427 
429  edm::ESTransientHandle<DDCompactView> hDdd = setup.getTransientHandle(ddToken_);
430 
431  DDSpecificsHasNamedValueFilter filter{"TrackingMaterialGroup"};
432  DDFilteredView fv(*hDdd, filter);
433 
434  while (fv.next()) {
435  // print the group name and full hierarchy of all items
436  std::cout << dddGetString("TrackingMaterialGroup", fv) << '\t';
437  m_group_names.insert(dddGetString("TrackingMaterialGroup", fv));
438 
439  // start from 2 to skip the leading /OCMS[0]/CMSE[1] part
440  const DDGeoHistory &history = fv.geoHistory();
441  std::cout << '/';
442  for (unsigned int h = 2; h < history.size(); ++h)
443  std::cout << '/' << history[h].logicalPart().name().name() << '[' << history[h].copyno() << ']';
444 
445  // DD3Vector and DDTranslation are the same type as math::XYZVector
446  math::XYZVector position = fv.translation() / 10.; // mm -> cm
447  std::cout << "\t(" << position.x() << ", " << position.y() << ", " << position.z() << ") "
448  << "[rho] " << position.Rho() << std::endl;
449  };
450  std::cout << std::endl;
451 
452  if (m_saveSummaryPlot)
454 }
455 
457 
458 //-------------------------------------------------------------------------
459 // define as a plugin
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
void endJob() override
Definition: ListGroups.cc:456
void fillColor()
Definition: ListGroups.cc:168
void analyze(const edm::Event &, const edm::EventSetup &) override
Definition: ListGroups.cc:428
Compact representation of the geometrical detector hierarchy.
Definition: DDCompactView.h:81
std::vector< TH2F * > m_plots
Definition: ListGroups.cc:93
bool DDfetch(const DDsvalues_type *, DDValue &)
helper for retrieving DDValues from DDsvalues_type *.
Definition: DDsvalues.cc:79
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
Definition: Activities.doc:4
void beginJob() override
Definition: ListGroups.cc:83
std::vector< unsigned int > m_color
Definition: ListGroups.cc:96
std::vector< std::pair< std::shared_ptr< TLine >, std::shared_ptr< TText > > > overlayEtaReferences()
Definition: ListGroups.cc:260
void produceAndSaveSummaryPlot(const edm::EventSetup &)
Definition: ListGroups.cc:304
bool next()
set current node to the next node in the filtered tree
double delta_r(const Fourvec &a, const Fourvec &b)
Find the distance between two four-vectors in the two-dimensional space .
Definition: fourvec.cc:238
Tan< T >::type tan(const T &t)
Definition: Tan.h:22
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
Definition: value.py:1
ii
Definition: cuy.py:589
std::map< std::string, std::pair< float, float > > m_diff
Definition: ListGroups.cc:108
bias2_t b2[25]
Definition: b2.h:9
std::vector< DDExpandedNode > DDGeoHistory
Geometrical &#39;path&#39; of the current node up to the root-node.
const edm::ESGetToken< DDCompactView, IdealGeometryRecord > ddToken_
Definition: ListGroups.cc:92
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:31
const bool m_saveSummaryPlot
Definition: ListGroups.cc:91
const DDGeoHistory & geoHistory() const
The list of ancestors up to the root-node of the current node.
void fillGradient()
Definition: ListGroups.cc:134
std::set< std::string > m_group_names
Definition: ListGroups.cc:94
std::vector< MaterialAccountingGroup * > m_groups
Definition: ListGroups.cc:95
static int position[264][3]
Definition: ReadPGInfo.cc:289
ListGroups(const edm::ParameterSet &)
Definition: ListGroups.cc:112
def canvas(sub, attr)
Definition: svgfig.py:482
std::vector< int > m_gradient
Definition: ListGroups.cc:97
static bool dddGetStringRaw(const DDFilteredView &view, const std::string &name, std::string &value)
Definition: ListGroups.cc:39
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4
const DDTranslation & translation() const
The absolute translation of the current node.
Geom::Theta< T > theta() const
~ListGroups() override
Definition: ListGroups.cc:123
static constexpr float b1
std::map< std::string, std::pair< float, float > > m_values
Definition: ListGroups.cc:109
static std::string dddGetString(const std::string &s, DDFilteredView const &view)
Definition: ListGroups.cc:68