CMS 3D CMS Logo

GeometryComparisonPlotter.cc
Go to the documentation of this file.
1 //#include "GeometryComparisonPlotter.h"
3 
4 /***********************************************************************************/
5 /* GEOMETRY COMPARISON PLOTTER */
6 /* See the talk of 15 January 2015 for short documentation and the example script. */
7 /* This code is highly commented if need be to upgrade it. */
8 /* Any further question is to be asked to Patrick Connor (patrick.connor@desy.de). */
9 /* Thanks a million <3 */
10 /***********************************************************************************/
11 
12 // NOTE: look for "TO DO" as a keyword to now what should be upgraded in later versions....
13 
14 // modes
15 //#define TALKATIVE // get some comments while processing
16 //#define DEBUG // get a lot of comments while processing + canvases -> resource-consuming!
17 
18 // MACROS
19 #define INSIDE_VECTOR(vector) \
20  std::cout << #vector << "={"; \
21  for (unsigned int i = 0; i < vector.size() - 1; i++) \
22  std::cout << vector[i] << ","; \
23  std::cout << vector.back() << "}";
24 #define CHECK_MAP_CONTENT(m, type) \
25  for (std::map<TString, type>::iterator it = m.begin(); it != m.end(); it++) \
26  std::cout << __FILE__ << ":" << __LINE__ << ":Info: " << #m << "[" << it->first << "]=" << it->second << std::endl;
27 /*
28  TString _sublevel_names[NB_SUBLEVELS],
29  _output_directory,
30  _output_filename,
31  _print_option,
32  _module_plot_option,
33  _alignment_name,
34  _reference_name;
35  bool _print,
36  _legend,
37  _write,
38  _print_only_global,
39  _make_profile_plots,
40  _batchMode,
41  _1dModule,
42  _2dModule;
43  int _levelCut,
44  _grid_x,
45  _grid_y,
46  _window_width,
47  _window_height;
48  */
49 
50 // CONSTRUCTOR AND DESTRUCTOR
52  TString output_directory,
53  TString modulesToPlot,
54  TString alignmentName,
55  TString referenceName,
56  bool printOnlyGlobal,
57  bool makeProfilePlots,
58  int canvas_idx)
59  : _output_directory(output_directory + TString(output_directory.EndsWith("/") ? "" : "/")),
60  _output_filename("comparison.root"),
61  _print_option("pdf"),
62  _module_plot_option(modulesToPlot),
63  _alignment_name(alignmentName),
64  _reference_name(referenceName),
65  _print(true), // print the graphs in a file (e.g. pdf)
66  _legend(true), // print the graphs in a file (e.g. pdf)
67  _write(true), // write the graphs in a root file
68  _print_only_global(printOnlyGlobal),
69  _make_profile_plots(makeProfilePlots),
70  _batchMode(
71 #ifdef DEBUG
72  false // false = display canvases (very time- and resource-consuming)
73 #else
74  true // true = no canvases
75 #endif
76  ),
77  _1dModule(true), // cut on 1d modules
78  _2dModule(true), // cut on 2d modules
79  _levelCut(DEFAULT_LEVEL), // module level (see branch of same name)
80  _grid_x(0), // by default no display the grid in the canvases
81  _grid_y(0), // by default no display the grid in the canvases
82  _window_width(DEFAULT_WINDOW_WIDTH),
83  _window_height(DEFAULT_WINDOW_HEIGHT),
84  _canvas_index(canvas_idx) {
85 #ifdef TALKATIVE
86  std::cout << ">>> TALKATIVE MODE ACTIVATED <<<" << std::endl;
87 #endif
88 #ifdef DEBUG
89  std::cout << ">>> DEBUG MODE ACTIVATED <<<" << std::endl;
90  std::cout << __FILE__ << ":" << __LINE__ << ":Info: inside constructor of GeometryComparisonPlotter utility"
91  << std::endl;
92 #endif
93  // _canvas_index
94  //_canvas_index = 0;
95 
96  //_sublevel_names = {"PXB", "PXF", "TIB", "TID", "TOB", "TEC"}; // C++11
97  _sublevel_names[0] = TString("PXB");
98  _sublevel_names[1] = TString("PXF");
99  _sublevel_names[2] = TString("TIB");
100  _sublevel_names[3] = TString("TID");
101  _sublevel_names[4] = TString("TOB");
102  _sublevel_names[5] = TString("TEC");
103  // TO DO: handle other structures
104 
105  // read tree
106  tree_file = new TFile(tree_file_name, "UPDATE");
107  data = (TTree *)tree_file->Get("alignTree");
108  // int branches
109  data->SetBranchAddress("id", &branch_i["id"]);
110  data->SetBranchAddress("inModuleList", &branch_i["inModuleList"]);
111  data->SetBranchAddress("badModuleQuality", &branch_i["badModuleQuality"]);
112  data->SetBranchAddress("mid", &branch_i["mid"]);
113  data->SetBranchAddress("level", &branch_i["level"]);
114  data->SetBranchAddress("mlevel", &branch_i["mlevel"]);
115  data->SetBranchAddress("sublevel", &branch_i["sublevel"]);
116  data->SetBranchAddress("useDetId", &branch_i["useDetId"]);
117  data->SetBranchAddress("detDim", &branch_i["detDim"]);
118  // float branches
119  data->SetBranchAddress("x", &branch_f["x"]);
120  data->SetBranchAddress("y", &branch_f["y"]);
121  data->SetBranchAddress("z", &branch_f["z"]);
122  data->SetBranchAddress("alpha", &branch_f["alpha"]);
123  data->SetBranchAddress("beta", &branch_f["beta"]);
124  data->SetBranchAddress("gamma", &branch_f["gamma"]);
125  data->SetBranchAddress("phi", &branch_f["phi"]);
126  data->SetBranchAddress("eta", &branch_f["eta"]);
127  data->SetBranchAddress("r", &branch_f["r"]);
128  data->SetBranchAddress("dx", &branch_f["dx"]);
129  data->SetBranchAddress("dy", &branch_f["dy"]);
130  data->SetBranchAddress("dz", &branch_f["dz"]);
131  data->SetBranchAddress("dphi", &branch_f["dphi"]);
132  data->SetBranchAddress("dr", &branch_f["dr"]);
133  data->SetBranchAddress("dalpha", &branch_f["dalpha"]);
134  data->SetBranchAddress("dbeta", &branch_f["dbeta"]);
135  data->SetBranchAddress("dgamma", &branch_f["dgamma"]);
136  if (data->GetBranch("rdphi") ==
137  nullptr) // in the case of rdphi branch not existing, it is created from r and dphi branches
138  {
139 #ifdef TALKATIVE
140  std::cout << __FILE__ << ":" << __LINE__
141  << ":Info: computing the rdphi branch from r and dphi branches (assuming they exist...)" << std::endl;
142 #endif
143  TBranch *br_rdphi = data->Branch("rdphi", &branch_f["rdphi"], "rdphi/F");
144  for (unsigned int ientry = 0; ientry < data->GetEntries(); ientry++) {
145  data->GetEntry(ientry);
146  branch_f["rdphi"] = branch_f["r"] * branch_f["dphi"];
147  br_rdphi->Fill();
148  }
149  } else
150  data->SetBranchAddress("rdphi", &branch_f["rdphi"]);
151 
152 #ifdef DEBUG
153  std::cout << __FILE__ << ":" << __LINE__ << ":Info: branch addresses set" << std::endl;
154 #endif
155 
156  // style
157  data->SetMarkerSize(0.5);
158  data->SetMarkerStyle(6);
159 
160  gStyle->SetOptStat("emr");
161  gStyle->SetTitleAlign(22);
162  gStyle->SetTitleX(0.5);
163  gStyle->SetTitleY(0.97);
164  gStyle->SetTitleFont(62);
165  //gStyle->SetOptTitle(0);
166 
167  gStyle->SetTextFont(132);
168  gStyle->SetTextSize(0.08);
169  gStyle->SetLabelFont(132, "x");
170  gStyle->SetLabelFont(132, "y");
171  gStyle->SetLabelFont(132, "z");
172  gStyle->SetTitleSize(0.08, "x");
173  gStyle->SetTitleSize(0.08, "y");
174  gStyle->SetTitleSize(0.08, "z");
175  gStyle->SetLabelSize(0.08, "x");
176  gStyle->SetLabelSize(0.08, "y");
177  gStyle->SetLabelSize(0.08, "z");
178 
179  gStyle->SetMarkerStyle(8);
180  gStyle->SetHistLineWidth(2);
181  gStyle->SetLineStyleString(2, "[12 12]"); // postscript dashes
182 
183  gStyle->SetFrameBorderMode(0);
184  gStyle->SetCanvasBorderMode(0);
185  gStyle->SetPadBorderMode(0);
186  gStyle->SetPadColor(0);
187  gStyle->SetCanvasColor(0);
188  gStyle->SetTitleColor(1);
189  gStyle->SetStatColor(0);
190  gStyle->SetStatBorderSize(1);
191  gStyle->SetFrameFillColor(0);
192 
193  gStyle->SetPadTickX(1);
194  gStyle->SetPadTickY(1);
195 
196  gStyle->SetPadTopMargin(0.1);
197  gStyle->SetPadRightMargin(0.05);
198  gStyle->SetPadBottomMargin(0.16);
199  gStyle->SetPadLeftMargin(0.18);
200 
201 #ifdef DEBUG
202  std::cout << __FILE__ << ":" << __LINE__ << ":Info: end of constructor" << std::endl;
203 #endif
204 }
205 
207 #ifdef DEBUG
208  std::cout << __FILE__ << ":" << __LINE__ << ":Info: in destructor of the GeometryComparisonPlotter utility"
209  << std::endl;
210 #endif
211  tree_file->Close();
212 #ifdef DEBUG
213  std::cout << __FILE__ << ":" << __LINE__ << ":Info: ending." << std::endl;
214 #endif
215 }
216 
217 // MAIN METHOD
219  std::vector<TString> x, // axes to combine to plot
220  std::vector<TString> y, // every combination (except the ones such that x=y) will be perfomed
221  pt::ptree CFG) // property tree storing the min and max values under <var>_min and <var>_max
222 {
224  // (we use a macro to avoid copy/paste)
225 #define CHECK_BRANCHES(branchname_vector) \
226  for (unsigned int i = 0; i < branchname_vector.size(); i++) { \
227  if (branch_f.find(branchname_vector[i]) == branch_f.end()) { \
228  std::cout << __FILE__ << ":" << __LINE__ << ":Error: The branch " << branchname_vector[i] \
229  << " is not recognised." << std::endl; \
230  return; \
231  } \
232  }
233  CHECK_BRANCHES(x);
234  CHECK_BRANCHES(y);
235 
236  const unsigned int nentries = data->GetEntries();
237 
238 #ifdef TALKATIVE
239  std::cout << __FILE__ << ":" << __LINE__ << ":Info: ";
240  INSIDE_VECTOR(x);
241  std::cout << std::endl << __FILE__ << ":" << __LINE__ << ":Info: ";
242  INSIDE_VECTOR(y);
243  std::cout << std::endl;
244 #endif
245 
247  // the max and min of the graphs are computed from the tree if they have not been manually input yet
248  // (we use a macro to avoid copy/paste)
249 #define LIMITS(axes_vector) \
250  for (unsigned int i = 0; i < axes_vector.size(); i++) { \
251  if (_SF.find(axes_vector[i]) == _SF.end()) \
252  _SF[axes_vector[i]] = 1.; \
253  if (_min.find(axes_vector[i]) == _min.end()) \
254  _min[axes_vector[i]] = _SF[axes_vector[i]] * data->GetMinimum(axes_vector[i]); \
255  if (_max.find(axes_vector[i]) == _max.end()) \
256  _max[axes_vector[i]] = _SF[axes_vector[i]] * data->GetMaximum(axes_vector[i]); \
257  }
258  LIMITS(x);
259  LIMITS(y);
260 
261 #ifdef TALKATIVE
262  CHECK_MAP_CONTENT(_min, float);
263  CHECK_MAP_CONTENT(_max, float);
264  CHECK_MAP_CONTENT(_SF, float);
265 #endif
266 
268  // the idea is to produce at the end a table of 8 TMultiGraphs and histograms:
269  // - 0=Tracker, with color code for the different sublevels
270  // - 1..6=different sublevels, with color code for z < or > 0
271  // - 7=only pixel with color code for BPIX and FPIX
272 
273  // (convention: the six first (resp. last) correspond to z>0 (resp. z<0))
274  // Modules with bad quality and in a list of modules that is given
275  // by the user (e.g. list of bad/untouched modules, default: empty list)
276  // are stored in seperate graphs and might be plotted (depends on the module
277  // plot option, default: all modules plotted)
278  // This means that 3*2*6 TGraphs will be filled during the loop on the TTree,
279  // and will be arranged differently with different color codes in the TMultiGraphs
280 
281  // For the profile plots
282  // Either all modules, only good modules or good modules + those in a given list will be plotted
283  // This means that 2*6 TH2F will be filled during the loop on the TTree,
284  // and will be arranged differently with different color codes in the Histograms
285 #ifndef NB_SUBLEVELS
286 #define NB_SUBLEVELS 6
287 #endif
288 #define NB_Z_SLICES 2
289 #define NB_MODULE_QUALITY 3
290 #define COLOR_CODE(icolor) int(icolor / 4) + icolor + 1
291 
292  TGraph *graphs[x.size()][y.size()][NB_SUBLEVELS * NB_Z_SLICES * NB_MODULE_QUALITY];
293  long int ipoint[x.size()][y.size()][NB_SUBLEVELS * NB_Z_SLICES * NB_MODULE_QUALITY];
294 
295  TMultiGraph
296  *mgraphs[x.size()][y.size()]
297  [2 + NB_SUBLEVELS]; // the 0th is for global plots, the 1..6th for sublevel plots, 7th for pixel only
298  TCanvas *c[x.size()][y.size()][2 + NB_SUBLEVELS], *c_global[2 + NB_SUBLEVELS];
299  _canvas_index++; // this static index is a safety used in case the MakePlots method is used several times to avoid overloading
300 
301  // histograms for profile plots,
302  // 2D-hists to store the data
303  // 1D-hists to calculate mean and sigma of y-values for each x-bin of the 2D-hists and for the final profile hist
304  TH2F *histos2D[x.size()][y.size()][NB_SUBLEVELS * NB_Z_SLICES];
305  TH1F *histos[x.size()][y.size()][NB_SUBLEVELS * NB_Z_SLICES];
306  TH1F *histosYValues[x.size()][y.size()]
307  [NB_SUBLEVELS * NB_Z_SLICES]; // Used to calculate the mean and RMS for each x-bin of the 2D-hist
308  TH1F *histosTracker
309  [x.size()][y.size()]
310  [NB_SUBLEVELS *
311  NB_Z_SLICES]; // for the tracker plots all histos are copied to avoid using the same hists in different canvas
312 
313  TCanvas *c_hist[x.size()][y.size()][2 + NB_SUBLEVELS], *c_global_hist[2 + NB_SUBLEVELS];
314 
315  unsigned int nXBins; // Sensible number of x-bins differs depending on the variable
316 
317  for (unsigned int ic = 0; ic <= NB_SUBLEVELS + 1; ic++) {
318  c_global[ic] = new TCanvas(
319  TString::Format(
320  "global_%s_%d", ic == 0 ? "tracker" : (ic == 7 ? "pixel" : _sublevel_names[ic - 1].Data()), _canvas_index),
321  TString::Format("Global overview of the %s variables",
322  ic == 0 ? "tracker" : (ic == 7 ? "pixel" : _sublevel_names[ic - 1].Data())),
325  c_global[ic]->Divide(x.size(), y.size());
326 
327  if (_make_profile_plots) {
328  c_global_hist[ic] =
329  new TCanvas(TString::Format("global_profile_plots_%s_%d",
330  ic == 0 ? "tracker" : (ic == 7 ? "pixel" : _sublevel_names[ic - 1].Data()),
331  _canvas_index),
332  TString::Format("Global overview profile plots of the %s variables",
333  ic == 0 ? "tracker" : (ic == 7 ? "pixel" : _sublevel_names[ic - 1].Data())),
336  c_global_hist[ic]->Divide(x.size(), y.size());
337  }
338  }
339 
340  for (unsigned int ix = 0; ix < x.size(); ix++) {
341  for (unsigned int iy = 0; iy < y.size(); iy++) {
342  //if (x[ix] == y[iy]) continue; // do not plot graphs like (r,r) or (phi,phi)
343  for (unsigned int igraph = 0; igraph < NB_SUBLEVELS * NB_Z_SLICES * NB_MODULE_QUALITY; igraph++) {
344  // declaring
345  ipoint[ix][iy][igraph] =
346  0; // the purpose of an index for every graph is to avoid thousands of points at the origin of each
347  graphs[ix][iy][igraph] = new TGraph();
348 
349  graphs[ix][iy][igraph]->SetMarkerColor(COLOR_CODE(igraph));
350  graphs[ix][iy][igraph]->SetMarkerStyle(6);
351  // pimping
352  graphs[ix][iy][igraph]->SetName(
353  x[ix] + y[iy] + _sublevel_names[igraph % NB_SUBLEVELS] +
354  TString(igraph % (NB_SUBLEVELS * NB_Z_SLICES) >= NB_SUBLEVELS ? "n"
355  : "p") // graphs for negative/positive z
356  + TString(igraph >= NB_SUBLEVELS * NB_Z_SLICES ? (igraph >= 2 * NB_SUBLEVELS * NB_Z_SLICES ? "bad" : "list")
357  : "good")); // graphs for good, bad modules and from a list
358  graphs[ix][iy][igraph]->SetTitle(
359  _sublevel_names[igraph % NB_SUBLEVELS] +
360  TString(igraph % (NB_SUBLEVELS * NB_Z_SLICES) >= NB_SUBLEVELS ? " at z<0" : " at z>=0") +
361  TString(igraph >= NB_SUBLEVELS * NB_Z_SLICES
362  ? (igraph >= 2 * NB_SUBLEVELS * NB_Z_SLICES ? " bad modules" : " in list")
363  : " good modules") +
364  TString(";") + LateXstyle(x[ix]) + " /" + _units[x[ix]] + TString(";") + LateXstyle(y[iy]) + " /" +
365  _units[y[iy]]);
366  graphs[ix][iy][igraph]->SetMarkerStyle(
367  igraph >= NB_SUBLEVELS * NB_Z_SLICES
368  ? (igraph >= 2 * NB_SUBLEVELS * NB_Z_SLICES ? 4 : 5)
369  : 6); // empty circle for bad modules, X for those in list, dot for good ones
370  }
371  }
372  }
373 
374  // Use seperate loop for the profile histograms since we do not produce histograms for the different module qualities
375  if (_make_profile_plots) {
376  for (unsigned int ix = 0; ix < x.size(); ix++) {
377  if (x[ix] == "phi")
378  nXBins = 10;
379  else
380  nXBins = 40;
381 
382  for (unsigned int iy = 0; iy < y.size(); iy++) {
383  for (unsigned int igraph = 0; igraph < NB_SUBLEVELS * NB_Z_SLICES; igraph++) {
384  // declaring
385  histos2D[ix][iy][igraph] =
386  new TH2F("2Dhist" + x[ix] + y[iy] + _sublevel_names[igraph % NB_SUBLEVELS] +
387  TString(igraph % (NB_SUBLEVELS * NB_Z_SLICES) >= NB_SUBLEVELS ? "n" : "p") +
389  "",
390  nXBins,
391  _min[x[ix]],
392  _max[x[ix]],
393  1000,
394  _min[y[iy]],
395  _max[y[iy]] + 1.);
396  }
397  }
398  }
399  }
400 
401 #ifdef DEBUG
402  std::cout << __FILE__ << ":" << __LINE__ << ":Info: Creation of the TGraph[" << x.size() << "][" << y.size() << "]["
403  << NB_SUBLEVELS * NB_Z_SLICES * NB_MODULE_QUALITY << "] ended." << std::endl;
404 #endif
405 
407 #ifdef DEBUG
408  std::cout << __FILE__ << ":" << __LINE__ << ":Info: Looping on the TTree" << std::endl;
409 #endif
410 #ifdef TALKATIVE
411  unsigned int progress = 0;
412  std::cout << __FILE__ << ":" << __LINE__ << ":Info: 0%" << std::endl;
413 #endif
414  for (unsigned int ientry = 0; ientry < nentries; ientry++) {
415 #ifdef TALKATIVE
416  if (10 * ientry / nentries != progress) {
417  progress = 10 * ientry / nentries;
418  std::cout << __FILE__ << ":" << __LINE__ << ":Info: " << 10 * progress << "%" << std::endl;
419  }
420 #endif
421  // load current tree entry
422  data->GetEntry(ientry);
423 
424  // CUTS on entry
425  if (branch_i["level"] != _levelCut)
426  continue;
427  if (!_1dModule && branch_i["detDim"] == 1)
428  continue;
429  if (!_2dModule && branch_i["detDim"] == 2)
430  continue;
431 
432  // loop on the different couples of variables to plot in a graph
433  for (unsigned int ix = 0; ix < x.size(); ix++) {
434  // CUTS on x[ix]
435  if (_SF[x[ix]] * branch_f[x[ix]] > _max[x[ix]] || _SF[x[ix]] * branch_f[x[ix]] < _min[x[ix]]) {
436  //#ifdef DEBUG
437  // std::cout << "branch_f[x[ix]]=" << branch_f[x[ix]] << std::endl;
438  //#endif
439  continue;
440  }
441 
442  for (unsigned int iy = 0; iy < y.size(); iy++) {
443  // CUTS on y[iy]
444  //if (x[ix] == y[iy]) continue; // TO DO: handle display when such a case occurs
445  if (branch_i["sublevel"] < 1 || branch_i["sublevel"] > NB_SUBLEVELS)
446  continue;
447 
448  // FILLING histograms take even those outside the plotted range into account
449  if (_make_profile_plots) {
450  if (_module_plot_option == "all") {
451  const short int igraph = (branch_i["sublevel"] - 1) + (branch_f["z"] >= 0 ? 0 : NB_SUBLEVELS);
452  histos2D[ix][iy][igraph]->Fill(_SF[x[ix]] * branch_f[x[ix]], _SF[y[iy]] * branch_f[y[iy]]);
453  } else if (_module_plot_option == "good" && branch_i["badModuleQuality"] == 0) {
454  const short int igraph = (branch_i["sublevel"] - 1) + (branch_f["z"] >= 0 ? 0 : NB_SUBLEVELS);
455  histos2D[ix][iy][igraph]->Fill(_SF[x[ix]] * branch_f[x[ix]], _SF[y[iy]] * branch_f[y[iy]]);
456  } else if (_module_plot_option == "list" &&
457  (branch_i["inModuleList"] == 1 || branch_i["badModuleQuality"] == 0)) {
458  const short int igraph = (branch_i["sublevel"] - 1) + (branch_f["z"] >= 0 ? 0 : NB_SUBLEVELS);
459  histos2D[ix][iy][igraph]->Fill(_SF[x[ix]] * branch_f[x[ix]], _SF[y[iy]] * branch_f[y[iy]]);
460  }
461  }
462 
463  // restrict scatter plots to chosen range
464  if (_SF[y[iy]] * branch_f[y[iy]] > _max[y[iy]] || _SF[y[iy]] * branch_f[y[iy]] < _min[y[iy]]) {
465  //#ifdef DEBUG
466  // std::cout << "branch_f[y[iy]]=" << branch_f[y[iy]] << std::endl;
467  //#endif
468  continue;
469  }
470 
471  // FILLING GRAPH
472  if (y.size() >= x.size()) {
473  if (branch_i["inModuleList"] == 0 && branch_i["badModuleQuality"] == 0) {
474  const short int igraph = (branch_i["sublevel"] - 1) + (branch_f["z"] >= 0 ? 0 : NB_SUBLEVELS);
475  graphs[ix][iy][igraph]->SetPoint(
476  ipoint[ix][iy][igraph], _SF[x[ix]] * branch_f[x[ix]], _SF[y[iy]] * branch_f[y[iy]]);
477  ipoint[ix][iy][igraph]++;
478  }
479  if (branch_i["inModuleList"] > 0) {
480  const short int igraph =
481  (branch_i["sublevel"] - 1) + (branch_f["z"] >= 0 ? 0 : NB_SUBLEVELS) + NB_SUBLEVELS * NB_Z_SLICES;
482  graphs[ix][iy][igraph]->SetPoint(
483  ipoint[ix][iy][igraph], _SF[x[ix]] * branch_f[x[ix]], _SF[y[iy]] * branch_f[y[iy]]);
484  ipoint[ix][iy][igraph]++;
485  }
486  if (branch_i["badModuleQuality"] > 0) {
487  const short int igraph =
488  (branch_i["sublevel"] - 1) + (branch_f["z"] >= 0 ? 0 : NB_SUBLEVELS) + 2 * NB_SUBLEVELS * NB_Z_SLICES;
489  graphs[ix][iy][igraph]->SetPoint(
490  ipoint[ix][iy][igraph], _SF[x[ix]] * branch_f[x[ix]], _SF[y[iy]] * branch_f[y[iy]]);
491  ipoint[ix][iy][igraph]++;
492  }
493  } else {
494  if (branch_i["inModuleList"] == 0 && branch_i["badModuleQuality"] == 0) {
495  const short int igraph = (branch_i["sublevel"] - 1) + (branch_f["z"] >= 0 ? 0 : NB_SUBLEVELS);
496  graphs[iy][ix][igraph]->SetPoint(
497  ipoint[iy][ix][igraph], _SF[x[ix]] * branch_f[x[ix]], _SF[y[iy]] * branch_f[y[iy]]);
498  ipoint[iy][ix][igraph]++;
499  }
500  if (branch_i["inModuleList"] > 0) {
501  const short int igraph =
502  (branch_i["sublevel"] - 1) + (branch_f["z"] >= 0 ? 0 : NB_SUBLEVELS) + NB_SUBLEVELS * NB_Z_SLICES;
503  graphs[iy][ix][igraph]->SetPoint(
504  ipoint[iy][ix][igraph], _SF[x[ix]] * branch_f[x[ix]], _SF[y[iy]] * branch_f[y[iy]]);
505  ipoint[iy][ix][igraph]++;
506  }
507  if (branch_i["badModuleQuality"] > 0) {
508  const short int igraph =
509  (branch_i["sublevel"] - 1) + (branch_f["z"] >= 0 ? 0 : NB_SUBLEVELS) + 2 * NB_SUBLEVELS * NB_Z_SLICES;
510  graphs[iy][ix][igraph]->SetPoint(
511  ipoint[ix][iy][igraph], _SF[x[ix]] * branch_f[x[ix]], _SF[y[iy]] * branch_f[y[iy]]);
512  ipoint[iy][ix][igraph]++;
513  }
514  }
515  }
516  }
517  }
518 #ifdef TALKATIVE
519  std::cout << __FILE__ << ":" << __LINE__ << ":Info: 100%\tLoop ended" << std::endl;
520 #endif
521 
523  gROOT->SetBatch(_batchMode); // if true, then equivalent to "root -b", i.e. no canvas
524  if (_write) { // opening the file to write the graphs
525  output = new TFile(_output_directory + TString(_output_filename),
526  "UPDATE"); // possibly existing file will be updated, otherwise created
527  if (output->IsZombie()) {
528  std::cout << __FILE__ << ":" << __LINE__ << ":Error: Opening of " << _output_directory + TString(_output_filename)
529  << " failed" << std::endl;
530  exit(-1);
531  }
532 #ifdef TALKATIVE
533  std::cout << __FILE__ << ":" << __LINE__ << ":Info: output file is "
534  << _output_directory + TString(_output_filename) << std::endl;
535 #endif
536  }
537  // declaring TMultiGraphs and TCanvas
538  // Usually more y variables than x variables
539  // creating TLegend
540  TLegend *legend = MakeLegend(.1, .92, .9, 1., NB_SUBLEVELS);
541  if (_write)
542  legend->Write();
543 
544  // check which modules are supposed to be plotted
545  unsigned int n_module_types = 1;
546  if (_module_plot_option == "all") {
547  n_module_types = 3; //plot all modules (good, list and bad )
548  } else if (_module_plot_option == "list") {
549  n_module_types = 2; // plot good modules and those in the list
550  } else if (_module_plot_option == "good") {
551  n_module_types = 1; // only plot the modules that are neither bad or in the list
552  }
553 
554 #define INDEX_IN_GLOBAL_CANVAS(i1, i2) 1 + i1 + i2 *x.size()
555  // running on the TGraphs to produce the TMultiGraph and draw/print them
556  for (unsigned int ix = 0; ix < x.size(); ix++) {
557 #ifdef DEBUG
558  std::cout << __FILE__ << ":" << __LINE__ << ":Info: x[" << ix << "]=" << x[ix] << std::endl;
559 #endif
560 
561  // looping on Y axes
562  for (unsigned int iy = 0; iy < y.size(); iy++) {
563  TString min_branch = TString::Format("%s_min", y[iy].Data());
564  TString max_branch = TString::Format("%s_max", y[iy].Data());
565 
566 #ifdef DEBUG
567  std::cout << __FILE__ << ":" << __LINE__ << ":Info: x[" << ix << "]=" << x[ix] << " and y[" << iy << "]=" << y[iy]
568  << "\t-> creating TMultiGraph" << std::endl;
569 #endif
570  mgraphs[ix][iy][0] = new TMultiGraph(
571  TString::Format("mgr_%s_vs_%s_tracker_%d",
572  x[ix].Data(),
573  y[iy].Data(),
574  _canvas_index), // name
575  //LateXstyle(x[ix]) + TString(" vs. ") + LateXstyle(y[iy]) + TString(" for Tracker") // graph title
576  TString(";") + LateXstyle(x[ix]) + " /" + _units[x[ix]] // x axis title
577  + TString(";") + LateXstyle(y[iy]) + " /" + _units[y[iy]]); // y axis title
578 
579  mgraphs[ix][iy][7] = new TMultiGraph(
580  TString::Format("mgr_%s_vs_%s_pixel_%d",
581  x[ix].Data(),
582  y[iy].Data(),
583  _canvas_index), // name
584  //LateXstyle(x[ix]) + TString(" vs. ") + LateXstyle(y[iy]) + TString(" for Tracker") // graph title
585  TString(";") + LateXstyle(x[ix]) + " /" + _units[x[ix]] // x axis title
586  + TString(";") + LateXstyle(y[iy]) + " /" + _units[y[iy]]); // y axis title
587 
589  // fixing ranges and filling TMultiGraph
590  // for (unsigned short int jgraph = NB_SUBLEVELS*NB_Z_SLICES-1 ; jgraph >= 0 ; --jgraph)
591  for (unsigned short int jgraph = 0; jgraph < NB_SUBLEVELS * NB_Z_SLICES * n_module_types; jgraph++) {
592  unsigned short int igraph =
593  NB_SUBLEVELS * NB_Z_SLICES * n_module_types - jgraph -
594  1; // reverse counting for humane readability (one of the sublevel takes much more place than the others)
595 
596 #ifdef DEBUG
597  std::cout << __FILE__ << ":" << __LINE__ << ":Info: writing TGraph to file" << std::endl;
598 #endif
599  // write into root file
600  if (_write)
601  graphs[ix][iy][igraph]->Write();
602  if (graphs[ix][iy][igraph]->GetN() == 0) {
603 #ifdef TALKATIVE
604  std::cout << __FILE__ << ":" << __LINE__ << ":Info: " << graphs[ix][iy][igraph]->GetName() << " is empty."
605  << std::endl;
606 #endif
607  continue;
608  }
609 #ifdef DEBUG
610  std::cout << __FILE__ << ":" << __LINE__ << ":Info: cloning, coloring and adding TGraph "
611  << _sublevel_names[igraph % NB_SUBLEVELS] << (igraph >= NB_SUBLEVELS ? "(z<0)" : "(z>0)")
612  << " to global TMultiGraph" << std::endl;
613 #endif
614  // clone to prevent any injure on the graph
615  TGraph *gr = (TGraph *)graphs[ix][iy][igraph]->Clone();
616  // color
617  gr->SetMarkerColor(COLOR_CODE(igraph % NB_SUBLEVELS));
618  mgraphs[ix][iy][0]->Add(gr, "P"); //, (mgraphs[ix][iy][0]->GetListOfGraphs()==0?"AP":"P"));
619 
620  if (igraph % NB_SUBLEVELS == 0 || igraph % NB_SUBLEVELS == 1)
621  mgraphs[ix][iy][7]->Add(gr, "P"); // Add BPIX (0) and FPIX (1) to pixel plot
622  }
623 
625  for (unsigned int isublevel = 1; isublevel <= NB_SUBLEVELS; isublevel++) {
626 #ifdef DEBUG
627  std::cout << __FILE__ << ":" << __LINE__ << ":Info: cloning, coloring and adding TGraph "
628  << _sublevel_names[isublevel - 1] << " to sublevel TMultiGraph" << std::endl;
629 #endif
630  mgraphs[ix][iy][isublevel] =
631  new TMultiGraph(TString::Format("%s_vs_%s_%s_%d",
632  x[ix].Data(),
633  y[iy].Data(),
634  _sublevel_names[isublevel - 1].Data(),
635  _canvas_index), // name
636  //LateXstyle(x[ix]) + TString(" vs. ") + LateXstyle(y[iy]) + TString(" for ") +
637  _sublevel_names[isublevel - 1] // graph title
638  + TString(";") + LateXstyle(x[ix]) + " /" + _units[x[ix]] // x axis title
639  + TString(";") + LateXstyle(y[iy]) + " /" + _units[y[iy]]); // y axis title
640 
641  graphs[ix][iy][isublevel - 1]->SetMarkerColor(kBlack);
642  graphs[ix][iy][NB_SUBLEVELS + isublevel - 1]->SetMarkerColor(kRed);
643  graphs[ix][iy][2 * NB_SUBLEVELS + isublevel - 1]->SetMarkerColor(kGray + 1);
644  graphs[ix][iy][3 * NB_SUBLEVELS + isublevel - 1]->SetMarkerColor(kRed - 7);
645  graphs[ix][iy][4 * NB_SUBLEVELS + isublevel - 1]->SetMarkerColor(kGray + 1);
646  graphs[ix][iy][5 * NB_SUBLEVELS + isublevel - 1]->SetMarkerColor(kRed - 7);
647  if (graphs[ix][iy][isublevel - 1]->GetN() > 0)
648  mgraphs[ix][iy][isublevel]->Add(
649  graphs[ix][iy][isublevel - 1],
650  "P"); //(mgraphs[ix][iy][isublevel-1]->GetListOfGraphs()==0?"AP":"P")); // z>0
651 #ifdef TALKATIVE
652  else
653  std::cout << __FILE__ << ":" << __LINE__
654  << ":Info: graphs[ix][iy][isublevel-1]=" << graphs[ix][iy][isublevel - 1]->GetName()
655  << " is empty -> not added into " << mgraphs[ix][iy][isublevel]->GetName() << std::endl;
656 #endif
657  if (graphs[ix][iy][NB_SUBLEVELS + isublevel - 1]->GetN() > 0)
658  mgraphs[ix][iy][isublevel]->Add(
659  graphs[ix][iy][NB_SUBLEVELS + isublevel - 1],
660  "P"); //(mgraphs[ix][iy][isublevel-1]->GetListOfGraphs()==0?"AP":"P")); // z<0
661 #ifdef TALKATIVE
662  else
663  std::cout << __FILE__ << ":" << __LINE__ << ":Info: graphs[ix][iy][NB_SUBLEVEL+isublevel-1]="
664  << graphs[ix][iy][NB_Z_SLICES + isublevel - 1]->GetName() << " is empty -> not added into "
665  << mgraphs[ix][iy][isublevel]->GetName() << std::endl;
666 #endif
667 #if NB_Z_SLICES != 2
668  std::cout << __FILE__ << ":" << __LINE__ << ":Error: color code incomplete for Z slices..." << std::endl;
669 #endif
670  if (_module_plot_option == "all") {
671  if (graphs[ix][iy][2 * NB_SUBLEVELS + isublevel - 1]->GetN() > 0)
672  mgraphs[ix][iy][isublevel]->Add(graphs[ix][iy][2 * NB_SUBLEVELS + isublevel - 1], "P");
673  if (graphs[ix][iy][3 * NB_SUBLEVELS + isublevel - 1]->GetN() > 0)
674  mgraphs[ix][iy][isublevel]->Add(graphs[ix][iy][3 * NB_SUBLEVELS + isublevel - 1], "P");
675  if (graphs[ix][iy][4 * NB_SUBLEVELS + isublevel - 1]->GetN() > 0)
676  mgraphs[ix][iy][isublevel]->Add(graphs[ix][iy][4 * NB_SUBLEVELS + isublevel - 1], "P");
677  if (graphs[ix][iy][5 * NB_SUBLEVELS + isublevel - 1]->GetN() > 0)
678  mgraphs[ix][iy][isublevel]->Add(graphs[ix][iy][5 * NB_SUBLEVELS + isublevel - 1], "P");
679  }
680  if (_module_plot_option == "list") {
681  if (graphs[ix][iy][2 * NB_SUBLEVELS + isublevel - 1]->GetN() > 0)
682  mgraphs[ix][iy][isublevel]->Add(graphs[ix][iy][2 * NB_SUBLEVELS + isublevel - 1], "P");
683  if (graphs[ix][iy][3 * NB_SUBLEVELS + isublevel - 1]->GetN() > 0)
684  mgraphs[ix][iy][isublevel]->Add(graphs[ix][iy][3 * NB_SUBLEVELS + isublevel - 1], "P");
685  }
686  }
687 
688  // fixing ranges, saving, and drawing of TMultiGraph (tracker AND sublevels AND pixel, i.e. 2+NB_SUBLEVELS objects)
689  // the individual canvases are saved, but the global are just drawn and will be saved later
690  for (unsigned short int imgr = 0; imgr <= NB_SUBLEVELS + 1; imgr++) {
691 #ifdef DEBUG
692  std::cout << __FILE__ << ":" << __LINE__ << ":Info: treating individual canvases." << std::endl;
693 #endif
694  // drawing into individual canvas and printing it (including a legend for the tracker canvas)
695  c[ix][iy][imgr] = new TCanvas(
696  TString::Format("c_%s_vs_%s_%s_%d",
697  x[ix].Data(),
698  y[iy].Data(),
699  imgr == 0 ? "tracker" : (imgr == 7 ? "pixel" : _sublevel_names[imgr - 1].Data()),
700  _canvas_index),
701  TString::Format("%s vs. %s at %s level",
702  x[ix].Data(),
703  y[iy].Data(),
704  imgr == 0 ? "tracker" : (imgr == 7 ? "pixel" : _sublevel_names[imgr - 1].Data())),
707  c[ix][iy][imgr]->SetGrid(_grid_x, _grid_y); // grid
708 
709  if (mgraphs[ix][iy][imgr]->GetListOfGraphs() != nullptr) {
710  if (CFG.count(min_branch.Data()) > 0) {
711  mgraphs[ix][iy][imgr]->SetMinimum(CFG.get<float>(min_branch.Data()));
712  }
713  if (CFG.count(max_branch.Data()) > 0) {
714  mgraphs[ix][iy][imgr]->SetMaximum(CFG.get<float>(max_branch.Data()));
715  }
716  mgraphs[ix][iy][imgr]->Draw("A");
717  }
718  if (imgr == 0 && _legend)
719  legend->Draw(); // only for the tracker
720  if (_print && !_print_only_global)
721  c[ix][iy][imgr]->Print(
722  _output_directory + mgraphs[ix][iy][imgr]->GetName() + ExtensionFromPrintOption(_print_option),
723  _print_option);
724 
725  // writing into root file
726  if (_write)
727  mgraphs[ix][iy][imgr]->Write();
728 
729  // drawing into global canvas
730  c_global[imgr]->cd(INDEX_IN_GLOBAL_CANVAS(ix, iy));
731  c_global[imgr]->GetPad(INDEX_IN_GLOBAL_CANVAS(ix, iy))->SetFillStyle(4000); // make the pad transparent
732  c_global[imgr]->GetPad(INDEX_IN_GLOBAL_CANVAS(ix, iy))->SetGrid(_grid_x, _grid_y); // grid
733  if (mgraphs[ix][iy][imgr]->GetListOfGraphs() != nullptr) {
734  if (CFG.count(min_branch.Data()) > 0) {
735  mgraphs[ix][iy][imgr]->SetMinimum(CFG.get<float>(min_branch.Data()));
736  }
737  if (CFG.count(max_branch.Data()) > 0) {
738  mgraphs[ix][iy][imgr]->SetMaximum(CFG.get<float>(max_branch.Data()));
739  }
740  mgraphs[ix][iy][imgr]->Draw("A");
741  }
742  // printing will be performed after customisation (e.g. legend or title) just after the loops on ix and iy
743  }
744  } // end of loop on y
745  } // end of loop on x
746 
747  // CUSTOMISATION
748  gStyle->SetOptTitle(0); // otherwise, the title is repeated in every pad of the global canvases
749  // -> instead, we will write it in the upper part in a TPaveText or in a TLegend
750  for (unsigned int ic = 0; ic <= NB_SUBLEVELS + 1; ic++) {
751  c_global[ic]->Draw();
752 
753  // setting legend to tracker canvases
754  if (!_legend)
755  break;
756  TCanvas *c_temp = (TCanvas *)c_global[ic]->Clone(c_global[ic]->GetTitle() + TString("_sub"));
757  c_temp->Draw();
758  c_global[ic] = new TCanvas(
759  c_temp->GetName() + TString("_final"), c_temp->GetTitle(), c_temp->GetWindowWidth(), c_temp->GetWindowHeight());
760  c_global[ic]->Draw();
761  TPad *p_up = new TPad(TString("legend_") + c_temp->GetName(),
762  "",
763  0.,
764  0.9,
765  1.,
766  1., // relative position
767  -1,
768  0,
769  0), // display options
770  *p_down = new TPad(TString("main_") + c_temp->GetName(), "", 0., 0., 1., 0.9, -1, 0, 0);
771  // in the lower part, draw the plots
772  p_down->Draw();
773  p_down->cd();
774  c_temp->DrawClonePad();
775  c_global[ic]->cd();
776  // in the upper part, pimp the canvas :p
777  p_up->Draw();
778  p_up->cd();
779  if (ic == 0) // tracker
780  {
781  TLegend *global_legend = MakeLegend(.05, .1, .7, .8, NB_SUBLEVELS); //, "brNDC");
782  global_legend->Draw();
783  TPaveText *pt_geom = new TPaveText(.75, .1, .95, .8, "NB");
784  pt_geom->SetFillColor(0);
785  pt_geom->SetTextSize(0.25);
786  pt_geom->AddText(TString("x: ") + _reference_name);
787  pt_geom->AddText(TString("y: ") + _alignment_name + TString(" - ") + _reference_name);
788  pt_geom->Draw();
789  } else if (ic == 7) // pixel
790  {
791  TLegend *global_legend = MakeLegend(.05, .1, .7, .8, 2); //, "brNDC");
792  global_legend->Draw();
793  TPaveText *pt_geom = new TPaveText(.75, .1, .95, .8, "NB");
794  pt_geom->SetFillColor(0);
795  pt_geom->SetTextSize(0.25);
796  pt_geom->AddText(TString("x: ") + _reference_name);
797  pt_geom->AddText(TString("y: ") + _alignment_name + TString(" - ") + _reference_name);
798  pt_geom->Draw();
799  } else // sublevels
800  {
801  TPaveText *pt = new TPaveText(.05, .1, .7, .8, "NB");
802  pt->SetFillColor(0);
803  pt->AddText(_sublevel_names[ic - 1]);
804  pt->Draw();
805  TPaveText *pt_geom = new TPaveText(.6, .1, .95, .8, "NB");
806  pt_geom->SetFillColor(0);
807  pt_geom->SetTextSize(0.3);
808  pt_geom->AddText(TString("x: ") + _reference_name);
809  pt_geom->AddText(TString("y: ") + _alignment_name + TString(" - ") + _reference_name);
810  pt_geom->Draw();
811  }
812  // printing
813  if (_print)
814  c_global[ic]->Print(_output_directory + c_global[ic]->GetName() + ExtensionFromPrintOption(_print_option),
815  _print_option);
816  if (_write)
817  c_global[ic]->Write();
818  }
819 
820  // printing global canvases
821  if (_write)
822  output->Close();
823 
824  // Now produce the profile plots if the option is chosen
825  // Use seperate loops since no seperate plots are produced for different module qualities
826  if (_make_profile_plots) {
827  // Fill Content of 2D-hists into 1D-hists for the profile plots
828  // Loop over all y-bins for a certain x-bin, calculate mean and RMS as entries of the 1D-hists
829  bool entries = false;
830  for (unsigned int ix = 0; ix < x.size(); ix++) {
831  for (unsigned int iy = 0; iy < y.size(); iy++) {
832  TString min_branch = TString::Format("%s_min", y[iy].Data());
833  TString max_branch = TString::Format("%s_max", y[iy].Data());
834  for (unsigned int igraph = 0; igraph < NB_SUBLEVELS * NB_Z_SLICES; igraph++) {
835  // Declare hists which will be plotted for the profile plots
836  histos[ix][iy][igraph] =
837  new TH1F("1Dhist" + x[ix] + y[iy] + _sublevel_names[igraph % NB_SUBLEVELS] +
838  TString(igraph % (NB_SUBLEVELS * NB_Z_SLICES) >= NB_SUBLEVELS ? "n" : "p") +
840  "",
841  histos2D[ix][iy][igraph]->GetXaxis()->GetNbins(),
842  _min[x[ix]],
843  _max[x[ix]]);
844  histos[ix][iy][igraph]->SetMarkerColor(COLOR_CODE(igraph));
845  histos[ix][iy][igraph]->SetLineColor(COLOR_CODE(igraph));
846  histos[ix][iy][igraph]->StatOverflows(kTRUE);
847 
848  // Loop over x bins
849  for (int binx = 0; binx <= histos2D[ix][iy][igraph]->GetXaxis()->GetNbins(); binx++) {
850  entries = false;
851  // Declare y-histogram for each x bin
852  histosYValues[ix][iy][igraph] =
853  new TH1F("1Dhist_Y-Values" + x[ix] + y[iy] + _sublevel_names[igraph % NB_SUBLEVELS] +
854  TString(igraph % (NB_SUBLEVELS * NB_Z_SLICES) >= NB_SUBLEVELS ? "n" : "p") +
856  "",
857  histos2D[ix][iy][igraph]->GetYaxis()->GetNbins(),
858  _min[y[iy]],
859  _max[y[iy]] + 1.);
860  histosYValues[ix][iy][igraph]->StatOverflows(kTRUE);
861  // Loop over y-bins for each x-bin of the 2D histogram and put it into the 1-d y histograms
862  // Take overflow bin into account
863  for (int biny = 0; biny <= histos2D[ix][iy][igraph]->GetYaxis()->GetNbins() + 1; biny++) {
864  if (histos2D[ix][iy][igraph]->GetBinContent(binx, biny) > 1.) {
865  histosYValues[ix][iy][igraph]->SetBinContent(biny, histos2D[ix][iy][igraph]->GetBinContent(binx, biny));
866  entries = true;
867  }
868  }
869  if (entries) {
870  histos[ix][iy][igraph]->SetBinContent(binx, histosYValues[ix][iy][igraph]->GetMean());
871  histos[ix][iy][igraph]->SetBinError(binx, histosYValues[ix][iy][igraph]->GetRMS());
872  } else
873  histos[ix][iy][igraph]->SetBinContent(binx, -999999.);
874  }
875  }
876 
877  // Customize and print the histograms
878 
880  // fixing ranges and draw profile plot histos
881 
882  c_hist[ix][iy][0] =
883  new TCanvas(TString::Format("c_hist_%s_vs_%s_tracker_%d", x[ix].Data(), y[iy].Data(), _canvas_index),
884  TString::Format("Profile plot %s vs. %s at tracker level", x[ix].Data(), y[iy].Data()),
887  c_hist[ix][iy][0]->SetGrid(_grid_x, _grid_y); // grid
888  // Draw the frame that will contain the histograms
889  // One needs to specify the binning and title
890  c_hist[ix][iy][0]->GetPad(0)->DrawFrame(
891  _min[x[ix]],
892  CFG.count(min_branch.Data()) > 0 ? CFG.get<float>(min_branch.Data()) : _min[y[iy]],
893  _max[x[ix]],
894  CFG.count(max_branch.Data()) > 0 ? CFG.get<float>(max_branch.Data()) : _max[y[iy]],
895  TString(";") + LateXstyle(x[ix]) + " /" + _units[x[ix]] + TString(";") + LateXstyle(y[iy]) + " /" +
896  _units[y[iy]]);
897  if (_legend)
898  legend->Draw("same");
899 
900  for (unsigned short int jgraph = 0; jgraph < NB_SUBLEVELS * NB_Z_SLICES; jgraph++) {
901  unsigned short int igraph =
902  NB_SUBLEVELS * NB_Z_SLICES - jgraph -
903  1; // reverse counting for humane readability (one of the sublevel takes much more place than the others)
904 
905  // clone to prevent any injure on the graph
906  histosTracker[ix][iy][igraph] = (TH1F *)histos[ix][iy][igraph]->Clone();
907  // color
908  histosTracker[ix][iy][igraph]->SetMarkerColor(COLOR_CODE(igraph % NB_SUBLEVELS));
909  histosTracker[ix][iy][igraph]->SetLineColor(COLOR_CODE(igraph % NB_SUBLEVELS));
910  histosTracker[ix][iy][igraph]->SetMarkerStyle(6);
911  histosTracker[ix][iy][igraph]->Draw("same pe0");
912  }
913 
914  if (_print && !_print_only_global)
915  c_hist[ix][iy][0]->Print(
917  TString::Format("Profile_plot_%s_vs_%s_tracker_%d", x[ix].Data(), y[iy].Data(), _canvas_index) +
919  _print_option);
920 
921  //Draw into profile hists global tracker canvas
922  c_global_hist[0]->cd(INDEX_IN_GLOBAL_CANVAS(ix, iy));
923  c_global_hist[0]->GetPad(INDEX_IN_GLOBAL_CANVAS(ix, iy))->SetFillStyle(4000); // make the pad transparent
924  c_global_hist[0]->GetPad(INDEX_IN_GLOBAL_CANVAS(ix, iy))->SetGrid(_grid_x, _grid_y); // grid
925  c_global_hist[0]
926  ->GetPad(INDEX_IN_GLOBAL_CANVAS(ix, iy))
927  ->DrawFrame(_min[x[ix]],
928  CFG.count(min_branch.Data()) > 0 ? CFG.get<float>(min_branch.Data()) : _min[y[iy]],
929  _max[x[ix]],
930  CFG.count(max_branch.Data()) > 0 ? CFG.get<float>(max_branch.Data()) : _max[y[iy]],
931  TString(";") + LateXstyle(x[ix]) + " /" + _units[x[ix]] + TString(";") + LateXstyle(y[iy]) +
932  " /" + _units[y[iy]]);
933 
934  for (unsigned short int jgraph = 0; jgraph < NB_SUBLEVELS * NB_Z_SLICES; jgraph++) {
935  unsigned short int igraph =
936  NB_SUBLEVELS * NB_Z_SLICES - jgraph -
937  1; // reverse counting for humane readability (one of the sublevel takes much more place than the others)
938  histosTracker[ix][iy][igraph]->Draw("same pe0");
939  }
940 
942  // fixing ranges and draw profile plot histos
943 
944  c_hist[ix][iy][7] =
945  new TCanvas(TString::Format("c_hist_%s_vs_%s_pixel_%d", x[ix].Data(), y[iy].Data(), _canvas_index),
946  TString::Format("Profile plot %s vs. %s at pixel level", x[ix].Data(), y[iy].Data()),
949  c_hist[ix][iy][7]->SetGrid(_grid_x, _grid_y); // grid
950  // Draw the frame that will contain the histograms
951  // One needs to specify the binning and title
952  c_hist[ix][iy][7]->GetPad(0)->DrawFrame(
953  _min[x[ix]],
954  CFG.count(min_branch.Data()) > 0 ? CFG.get<float>(min_branch.Data()) : _min[y[iy]],
955  _max[x[ix]],
956  CFG.count(max_branch.Data()) > 0 ? CFG.get<float>(max_branch.Data()) : _max[y[iy]],
957  TString(";") + LateXstyle(x[ix]) + " /" + _units[x[ix]] + TString(";") + LateXstyle(y[iy]) + " /" +
958  _units[y[iy]]);
959  if (_legend)
960  legend->Draw("same");
961 
962  for (unsigned short int jgraph = 0; jgraph < NB_SUBLEVELS * NB_Z_SLICES; jgraph++) {
963  unsigned short int igraph =
964  NB_SUBLEVELS * NB_Z_SLICES - jgraph -
965  1; // reverse counting for humane readability (one of the sublevel takes much more place than the others)
966 
967  if (igraph % NB_SUBLEVELS == 0 || igraph % NB_SUBLEVELS == 1) //Only BPIX and FPIX
968  {
969  // clone to prevent any injure on the graph
970  histosTracker[ix][iy][igraph] = (TH1F *)histos[ix][iy][igraph]->Clone();
971  // color
972  histosTracker[ix][iy][igraph]->SetMarkerColor(COLOR_CODE(igraph % NB_SUBLEVELS));
973  histosTracker[ix][iy][igraph]->SetLineColor(COLOR_CODE(igraph % NB_SUBLEVELS));
974  histosTracker[ix][iy][igraph]->SetMarkerStyle(6);
975  histosTracker[ix][iy][igraph]->Draw("same pe0");
976  }
977  }
978 
979  if (_print && !_print_only_global)
980  c_hist[ix][iy][7]->Print(
982  TString::Format("Profile_plot_%s_vs_%s_pixel_%d", x[ix].Data(), y[iy].Data(), _canvas_index) +
984  _print_option);
985 
986  //Draw into profile hists global tracker canvas
987  c_global_hist[7]->cd(INDEX_IN_GLOBAL_CANVAS(ix, iy));
988  c_global_hist[7]->GetPad(INDEX_IN_GLOBAL_CANVAS(ix, iy))->SetFillStyle(4000); // make the pad transparent
989  c_global_hist[7]->GetPad(INDEX_IN_GLOBAL_CANVAS(ix, iy))->SetGrid(_grid_x, _grid_y); // grid
990  c_global_hist[7]
991  ->GetPad(INDEX_IN_GLOBAL_CANVAS(ix, iy))
992  ->DrawFrame(_min[x[ix]],
993  CFG.count(min_branch.Data()) > 0 ? CFG.get<float>(min_branch.Data()) : _min[y[iy]],
994  _max[x[ix]],
995  CFG.count(max_branch.Data()) > 0 ? CFG.get<float>(max_branch.Data()) : _max[y[iy]],
996  TString(";") + LateXstyle(x[ix]) + " /" + _units[x[ix]] + TString(";") + LateXstyle(y[iy]) +
997  " /" + _units[y[iy]]);
998 
999  for (unsigned short int jgraph = 0; jgraph < NB_SUBLEVELS * NB_Z_SLICES; jgraph++) {
1000  unsigned short int igraph =
1001  NB_SUBLEVELS * NB_Z_SLICES - jgraph -
1002  1; // reverse counting for humane readability (one of the sublevel takes much more place than the others)
1003  histosTracker[ix][iy][igraph]->Draw("same pe0");
1004  }
1005  // printing will be performed after customisation (e.g. legend or title) just after the loops on ix and iy
1007  for (unsigned int isublevel = 1; isublevel <= NB_SUBLEVELS; isublevel++) {
1008  // Draw and print profile histograms
1009  c_hist[ix][iy][isublevel] =
1010  new TCanvas(TString::Format("c_hist_%s_vs_%s_%s_%d",
1011  x[ix].Data(),
1012  y[iy].Data(),
1013  isublevel == 0 ? "tracker" : _sublevel_names[isublevel - 1].Data(),
1014  _canvas_index),
1015  TString::Format("Profile plot %s vs. %s at %s level",
1016  x[ix].Data(),
1017  y[iy].Data(),
1018  isublevel == 0 ? "tracker" : _sublevel_names[isublevel - 1].Data()),
1019  _window_width,
1020  _window_height);
1021  c_hist[ix][iy][isublevel]->SetGrid(_grid_x, _grid_y); // grid
1022  c_hist[ix][iy][isublevel]->GetPad(0)->DrawFrame(
1023  _min[x[ix]],
1024  CFG.count(min_branch.Data()) > 0 ? CFG.get<float>(min_branch.Data()) : _min[y[iy]],
1025  _max[x[ix]],
1026  CFG.count(max_branch.Data()) > 0 ? CFG.get<float>(max_branch.Data()) : _max[y[iy]],
1027  TString(";") + LateXstyle(x[ix]) + " /" + _units[x[ix]] + TString(";") + LateXstyle(y[iy]) + " /" +
1028  _units[y[iy]]);
1029 
1030  histos[ix][iy][isublevel - 1]->SetMarkerColor(kBlack);
1031  histos[ix][iy][isublevel - 1]->SetLineColor(kBlack);
1032  histos[ix][iy][NB_SUBLEVELS + isublevel - 1]->SetMarkerColor(kRed);
1033  histos[ix][iy][NB_SUBLEVELS + isublevel - 1]->SetLineColor(kRed);
1034 
1035  histos[ix][iy][isublevel - 1]->Draw("same pe0");
1036  histos[ix][iy][NB_SUBLEVELS + isublevel - 1]->Draw("same pe0");
1037 
1038  if (_print && !_print_only_global)
1039  c_hist[ix][iy][isublevel]->Print(_output_directory +
1040  TString::Format("Profile_plot_%s_vs_%s_%s_%d",
1041  x[ix].Data(),
1042  y[iy].Data(),
1043  _sublevel_names[isublevel - 1].Data(),
1044  _canvas_index) +
1046  _print_option);
1047 
1048  // draw into global canvas
1049  // printing will be performed after customisation (e.g. legend or title) just after the loops on ix and iy
1050  c_global_hist[isublevel]->cd(INDEX_IN_GLOBAL_CANVAS(ix, iy));
1051  c_global_hist[isublevel]
1052  ->GetPad(INDEX_IN_GLOBAL_CANVAS(ix, iy))
1053  ->SetFillStyle(4000); // make the pad transparent
1054  c_global_hist[isublevel]->GetPad(INDEX_IN_GLOBAL_CANVAS(ix, iy))->SetGrid(_grid_x, _grid_y); // grid
1055  c_global_hist[isublevel]
1056  ->GetPad(INDEX_IN_GLOBAL_CANVAS(ix, iy))
1057  ->DrawFrame(_min[x[ix]],
1058  CFG.count(min_branch.Data()) > 0 ? CFG.get<float>(min_branch.Data()) : _min[y[iy]],
1059  _max[x[ix]],
1060  CFG.count(max_branch.Data()) > 0 ? CFG.get<float>(max_branch.Data()) : _max[y[iy]],
1061  TString(";") + LateXstyle(x[ix]) + " /" + _units[x[ix]] + TString(";") + LateXstyle(y[iy]) +
1062  " /" + _units[y[iy]]);
1063 
1064  histos[ix][iy][isublevel - 1]->Draw("same pe0");
1065  histos[ix][iy][NB_SUBLEVELS + isublevel - 1]->Draw("same pe0");
1066  }
1067 
1068  } // end of loop on y
1069  } // end of loop on x
1070 
1071  // CUSTOMISATION
1072  gStyle->SetOptTitle(0); // otherwise, the title is repeated in every pad of the global canvases
1073  // -> instead, we will write it in the upper part in a TPaveText or in a TLegend
1074  for (unsigned int ic = 0; ic <= NB_SUBLEVELS; ic++) {
1075  // setting legend to tracker canvases
1076  if (!_legend)
1077  break;
1078 
1079  // setting legend to tracker canvases
1080  if (!_legend)
1081  break;
1082  TCanvas *c_temp_hist = (TCanvas *)c_global_hist[ic]->Clone(c_global_hist[ic]->GetTitle() + TString("_sub"));
1083  c_temp_hist->Draw();
1084  c_global_hist[ic] = new TCanvas(c_temp_hist->GetName() + TString("_final"),
1085  c_temp_hist->GetTitle(),
1086  c_temp_hist->GetWindowWidth(),
1087  c_temp_hist->GetWindowHeight());
1088  c_global_hist[ic]->Draw();
1089  TPad *p_up = new TPad(TString("legend_") + c_temp_hist->GetName(),
1090  "",
1091  0.,
1092  0.9,
1093  1.,
1094  1., // relative position
1095  -1,
1096  0,
1097  0), // display options
1098  *p_down = new TPad(TString("main_") + c_temp_hist->GetName(), "", 0., 0., 1., 0.9, -1, 0, 0);
1099  // in the lower part, draw the plots
1100  p_down->Draw();
1101  p_down->cd();
1102  c_temp_hist->DrawClonePad();
1103  c_global_hist[ic]->cd();
1104  // in the upper part, pimp the canvas :p
1105  p_up->Draw();
1106  p_up->cd();
1107  if (ic == 0) // tracker
1108  {
1109  TLegend *global_legend = MakeLegend(.05, .1, .7, .8, NB_SUBLEVELS); //, "brNDC");
1110  global_legend->Draw();
1111  TPaveText *pt_geom = new TPaveText(.75, .1, .95, .8, "NB");
1112  pt_geom->SetFillColor(0);
1113  pt_geom->SetTextSize(0.25);
1114  pt_geom->AddText(TString("x: ") + _reference_name);
1115  pt_geom->AddText(TString("y: ") + _alignment_name + TString(" - ") + _reference_name);
1116  pt_geom->Draw();
1117  } else if (ic == 7) // pixel
1118  {
1119  TLegend *global_legend = MakeLegend(.05, .1, .7, .8, 2); //, "brNDC");
1120  global_legend->Draw();
1121  TPaveText *pt_geom = new TPaveText(.75, .1, .95, .8, "NB");
1122  pt_geom->SetFillColor(0);
1123  pt_geom->SetTextSize(0.25);
1124  pt_geom->AddText(TString("x: ") + _reference_name);
1125  pt_geom->AddText(TString("y: ") + _alignment_name + TString(" - ") + _reference_name);
1126  pt_geom->Draw();
1127  } else // sublevels
1128  {
1129  TPaveText *pt = new TPaveText(.05, .1, .7, .8, "NB");
1130  pt->SetFillColor(0);
1131  pt->AddText(_sublevel_names[ic - 1]);
1132  pt->Draw();
1133  TPaveText *pt_geom = new TPaveText(.6, .1, .95, .8, "NB");
1134  pt_geom->SetFillColor(0);
1135  pt_geom->SetTextSize(0.3);
1136  pt_geom->AddText(TString("x: ") + _reference_name);
1137  pt_geom->AddText(TString("y: ") + _alignment_name + TString(" - ") + _reference_name);
1138  pt_geom->Draw();
1139  }
1140  // printing
1141  if (_print)
1142  c_global_hist[ic]->Print(
1143  _output_directory + c_global_hist[ic]->GetName() + ExtensionFromPrintOption(_print_option), _print_option);
1144  }
1145  }
1146 
1147 #ifdef TALKATIVE
1148  std::cout << __FILE__ << ":" << __LINE__ << ":Info: End of MakePlots method" << std::endl;
1149 #endif
1150 }
1151 
1152 // Make additional table for the mean/RMS values of differences
1154  std::vector<TString> x, // axes to combine to plot
1155  std::vector<TString> y, // only requires the differences (y values in the plots) and ranges
1156  pt::ptree CFG) // property tree storing the min and max values under <var>_min and <var>_max
1157 {
1159  // (we use a macro to avoid copy/paste)
1160 #define CHECK_BRANCHES(branchname_vector) \
1161  for (unsigned int i = 0; i < branchname_vector.size(); i++) { \
1162  if (branch_f.find(branchname_vector[i]) == branch_f.end()) { \
1163  std::cout << __FILE__ << ":" << __LINE__ << ":Error: The branch " << branchname_vector[i] \
1164  << " is not recognised." << std::endl; \
1165  return; \
1166  } \
1167  }
1168  CHECK_BRANCHES(x);
1169  CHECK_BRANCHES(y);
1170 
1171  const unsigned int nentries = data->GetEntries();
1172 
1173 #ifdef TALKATIVE
1174  std::cout << __FILE__ << ":" << __LINE__ << ":Info: ";
1175  INSIDE_VECTOR(x);
1176  std::cout << std::endl;
1177  std::cout << __FILE__ << ":" << __LINE__ << ":Info: ";
1178  INSIDE_VECTOR(y);
1179  std::cout << std::endl;
1180 #endif
1181 
1183  // the max and min of the graphs are computed from the tree if they have not been manually input yet
1184  // (we use a macro to avoid copy/paste)
1185 #define LIMITS(axes_vector) \
1186  for (unsigned int i = 0; i < axes_vector.size(); i++) { \
1187  if (_SF.find(axes_vector[i]) == _SF.end()) \
1188  _SF[axes_vector[i]] = 1.; \
1189  if (_min.find(axes_vector[i]) == _min.end()) \
1190  _min[axes_vector[i]] = _SF[axes_vector[i]] * data->GetMinimum(axes_vector[i]); \
1191  if (_max.find(axes_vector[i]) == _max.end()) \
1192  _max[axes_vector[i]] = _SF[axes_vector[i]] * data->GetMaximum(axes_vector[i]); \
1193  }
1194  LIMITS(x);
1195  LIMITS(y);
1196 
1197 #ifdef TALKATIVE
1198  CHECK_MAP_CONTENT(_min, float);
1199  CHECK_MAP_CONTENT(_max, float);
1200  CHECK_MAP_CONTENT(_SF, float);
1201 #endif
1202 
1204  // the idea is to produce tables of the differences and the absolute positions containing mean and RMS values
1205  // for the different subdetectors - 0..5=different sublevels.
1206  // Values for each endcap detector are to be split in +/-z, for the barrel detectors in +/- x (half barrels)
1207  // Since it is easier to handle in the loops, all subdetectors will be split in
1208  // 4 parts at first: (+/-x)X(+/-z)
1209  // This means that 2*2*6 histograms will be filled during the loop on the TTree
1210  // Pairs of histograms need to be combined afterwards again
1211  // Histograms 0-5 are at +x and +z, 6-11 at +x and -z, 12-17 at -x and +z, and 18-23 at -x and -z
1212  //
1213  // Two version of the table containing the differences are produced. Once using Gaussian fits (more stable
1214  // vs single outliers but perform poorly if the distributions are non-Gaussian) and once using
1215  // the mean and RMS of the histograms (more stable but outliers have a strong impact on the RMS).
1216  // For the absolute positions, only mean+RMS are used since the detector layout is not Gaussian
1217  // (structures due to layers/rings etc)
1218 #ifndef NB_SUBLEVELS
1219 #define NB_SUBLEVELS 6
1220 #endif
1221 #define NB_Z_SLICES 2
1222 #define NB_X_SLICES 2
1223 
1224  TH1F *histosx[x.size()][NB_SUBLEVELS * NB_Z_SLICES * NB_X_SLICES];
1225  float meanValuex[x.size()][NB_SUBLEVELS * NB_Z_SLICES * NB_X_SLICES];
1226  float RMSx[x.size()][NB_SUBLEVELS * NB_Z_SLICES * NB_X_SLICES];
1227 
1228  TH1F *histos[y.size()][NB_SUBLEVELS * NB_Z_SLICES * NB_X_SLICES];
1229  TF1 *gausFit[y.size()][NB_SUBLEVELS * NB_Z_SLICES * NB_X_SLICES];
1230  float meanValue[y.size()][NB_SUBLEVELS * NB_Z_SLICES * NB_X_SLICES];
1231  float meanValueGaussian[y.size()][NB_SUBLEVELS * NB_Z_SLICES * NB_X_SLICES];
1232  float RMS[y.size()][NB_SUBLEVELS * NB_Z_SLICES * NB_X_SLICES];
1233  float RMSGaussian[y.size()][NB_SUBLEVELS * NB_Z_SLICES * NB_X_SLICES];
1234 
1235  for (unsigned int iy = 0; iy < y.size(); iy++) {
1236  for (unsigned int ihist = 0; ihist < NB_SUBLEVELS * NB_Z_SLICES * NB_X_SLICES; ihist++) {
1237  // Create and correctly name a histogram for each subdetector*Z_Slice*X_Slice
1238  histos[iy][ihist] = new TH1F("hist" + y[iy] + _sublevel_names[ihist % NB_SUBLEVELS] +
1239  TString(ihist % (NB_SUBLEVELS * NB_Z_SLICES) >= NB_SUBLEVELS ? "zn" : "zp") +
1240  TString(ihist >= NB_SUBLEVELS * NB_Z_SLICES ? "xn" : "xp"),
1241  "",
1242  1000,
1243  _min[y[iy]],
1244  _max[y[iy]] + 1.);
1245  histos[iy][ihist]->StatOverflows(kTRUE);
1246  }
1247  }
1248 
1249  for (unsigned int ix = 0; ix < x.size(); ix++) {
1250  for (unsigned int ihist = 0; ihist < NB_SUBLEVELS * NB_Z_SLICES * NB_X_SLICES; ihist++) {
1251  // Create and correctly name a histogram for each subdetector*Z_Slice*ModuleType
1252  histosx[ix][ihist] = new TH1F("histx" + x[ix] + _sublevel_names[ihist % NB_SUBLEVELS] +
1253  TString(ihist % (NB_SUBLEVELS * NB_Z_SLICES) >= NB_SUBLEVELS ? "zn" : "zp") +
1254  TString(ihist >= NB_SUBLEVELS * NB_Z_SLICES ? "xn" : "xp"),
1255  "",
1256  1000,
1257  _min[x[ix]],
1258  _max[x[ix]] + 1.);
1259  histosx[ix][ihist]->StatOverflows(kTRUE);
1260  }
1261  }
1262 
1263 #ifdef DEBUG
1264  std::cout << __FILE__ << ":" << __LINE__ << ":Info: Creation of the TH1F[" << y.size() << "]["
1265  << NB_SUBLEVELS * NB_Z_SLICES * NB_X_SLICES << "] ended." << std::endl;
1266 #endif
1267 
1269 #ifdef DEBUG
1270  std::cout << __FILE__ << ":" << __LINE__ << ":Info: Looping on the TTree" << std::endl;
1271 #endif
1272 #ifdef TALKATIVE
1273  unsigned int progress = 0;
1274  std::cout << __FILE__ << ":" << __LINE__ << ":Info: 0%" << std::endl;
1275 #endif
1276  for (unsigned int ientry = 0; ientry < nentries; ientry++) {
1277 #ifdef TALKATIVE
1278  if (10 * ientry / nentries != progress) {
1279  progress = 10 * ientry / nentries;
1280  std::cout << __FILE__ << ":" << __LINE__ << ":Info: " << 10 * progress << "%" << std::endl;
1281  }
1282 #endif
1283  // load current tree entry
1284  data->GetEntry(ientry);
1285 
1286  // CUTS on entry
1287  if (branch_i["level"] != _levelCut)
1288  continue;
1289  if (!_1dModule && branch_i["detDim"] == 1)
1290  continue;
1291  if (!_2dModule && branch_i["detDim"] == 2)
1292  continue;
1293 
1294  for (unsigned int iy = 0; iy < y.size(); iy++) {
1295  if (branch_i["sublevel"] < 1 || branch_i["sublevel"] > NB_SUBLEVELS)
1296  continue;
1297  if (_SF[y[iy]] * branch_f[y[iy]] > _max[y[iy]] || _SF[y[iy]] * branch_f[y[iy]] < _min[y[iy]]) {
1298  //#ifdef DEBUG
1299  // std::cout << "branch_f[y[iy]]=" << branch_f[y[iy]] << std::endl;
1300  //#endif
1301  continue;
1302  }
1303 
1304  // FILLING HISTOGRAMS
1305 
1306  // histogram for all modules
1307  const short int ihisto = (branch_i["sublevel"] - 1) + (branch_f["z"] >= 0 ? 0 : NB_SUBLEVELS) +
1308  (branch_f["x"] >= 0 ? 0 : NB_SUBLEVELS * NB_Z_SLICES);
1309 
1310  if (_module_plot_option == "all")
1311  histos[iy][ihisto]->Fill(_SF[y[iy]] * branch_f[y[iy]]);
1312 
1313  // Only good modules
1314  else if (_module_plot_option == "good" && branch_i["badModuleQuality"] == 0)
1315  histos[iy][ihisto]->Fill(_SF[y[iy]] * branch_f[y[iy]]);
1316 
1317  // Only good modules and those in the list
1318  else if (_module_plot_option == "list" && (branch_i["inModuleList"] == 1 || branch_i["badModuleQuality"] == 0))
1319  histos[iy][ihisto]->Fill(_SF[y[iy]] * branch_f[y[iy]]);
1320  }
1321 
1322  for (unsigned int ix = 0; ix < x.size(); ix++) {
1323  if (branch_i["sublevel"] < 1 || branch_i["sublevel"] > NB_SUBLEVELS)
1324  continue;
1325  if (_SF[x[ix]] * branch_f[x[ix]] > _max[x[ix]] || _SF[x[ix]] * branch_f[x[ix]] < _min[x[ix]]) {
1326  //#ifdef DEBUG
1327  // std::cout << "branch_f[y[iy]]=" << branch_f[y[iy]] << std::endl;
1328  //#endif
1329  continue;
1330  }
1331 
1332  // FILLING HISTOGRAMS
1333 
1334  // histogram for all modules
1335  const short int ihistosx = (branch_i["sublevel"] - 1) + (branch_f["z"] >= 0 ? 0 : NB_SUBLEVELS) +
1336  (branch_f["x"] >= 0 ? 0 : NB_SUBLEVELS * NB_Z_SLICES);
1337 
1338  if (_module_plot_option == "all")
1339  histosx[ix][ihistosx]->Fill(_SF[x[ix]] * branch_f[x[ix]]);
1340 
1341  // Only good modules
1342  else if (_module_plot_option == "good" && branch_i["badModuleQuality"] == 0)
1343  histosx[ix][ihistosx]->Fill(_SF[x[ix]] * branch_f[x[ix]]);
1344 
1345  // Only good modules and those in the list
1346  else if (_module_plot_option == "list" && (branch_i["inModuleList"] == 1 || branch_i["badModuleQuality"] == 0))
1347  histosx[ix][ihistosx]->Fill(_SF[x[ix]] * branch_f[x[ix]]);
1348  }
1349  }
1350 #ifdef TALKATIVE
1351  std::cout << __FILE__ << ":" << __LINE__ << ":Info: 100%\tLoop ended" << std::endl;
1352 #endif
1353 
1354  //~ TString rangeLabel = "";
1355  // Calculate mean and standard deviation for each histogram
1356  for (unsigned int iy = 0; iy < y.size(); iy++) {
1357  for (unsigned int ihist = 0; ihist < NB_SUBLEVELS * NB_Z_SLICES * NB_X_SLICES; ihist++) {
1358  // combine +/-z histograms for barrel detectors
1359  if (ihist % (NB_SUBLEVELS * NB_Z_SLICES) == 0 || ihist % (NB_SUBLEVELS * NB_Z_SLICES) == 2 ||
1360  ihist % (NB_SUBLEVELS * NB_Z_SLICES) == 4) {
1361  histos[iy][ihist]->Add(histos[iy][ihist + NB_SUBLEVELS]);
1362  }
1363  // combine +/-x histograms for endcap detectors (only used for half shells in barrel)
1364  if (ihist < NB_SUBLEVELS * NB_Z_SLICES &&
1365  (ihist % NB_SUBLEVELS == 1 || ihist % NB_SUBLEVELS == 3 || ihist % NB_SUBLEVELS == 5)) {
1366  histos[iy][ihist]->Add(histos[iy][ihist + NB_SUBLEVELS * NB_Z_SLICES]);
1367  }
1368  meanValue[iy][ihist] = histos[iy][ihist]->GetMean();
1369  RMS[iy][ihist] = histos[iy][ihist]->GetRMS();
1370 
1371  histos[iy][ihist]->Fit("gaus");
1372  gausFit[iy][ihist] = histos[iy][ihist]->GetFunction("gaus");
1373  meanValueGaussian[iy][ihist] = gausFit[iy][ihist]->GetParameter(1);
1374  RMSGaussian[iy][ihist] = gausFit[iy][ihist]->GetParameter(2);
1375  }
1376  }
1377 
1378  for (unsigned int ix = 0; ix < x.size(); ix++) {
1379  for (unsigned int ihist = 0; ihist < NB_SUBLEVELS * NB_Z_SLICES * NB_X_SLICES; ihist++) {
1380  // combine +/-z histograms for barrel detectors
1381  if (ihist % (NB_SUBLEVELS * NB_Z_SLICES) == 0 || ihist % (NB_SUBLEVELS * NB_Z_SLICES) == 2 ||
1382  ihist % (NB_SUBLEVELS * NB_Z_SLICES) == 4) {
1383  histosx[ix][ihist]->Add(histosx[ix][ihist + NB_SUBLEVELS]);
1384  }
1385  // combine +/-x histograms for endcap detectors (only used for half shells in barrel)
1386  if (ihist < NB_SUBLEVELS * NB_Z_SLICES &&
1387  (ihist % NB_SUBLEVELS == 1 || ihist % NB_SUBLEVELS == 3 || ihist % NB_SUBLEVELS == 5)) {
1388  histosx[ix][ihist]->Add(histosx[ix][ihist + NB_SUBLEVELS * NB_Z_SLICES]);
1389  }
1390  meanValuex[ix][ihist] = histosx[ix][ihist]->GetMean();
1391  RMSx[ix][ihist] = histosx[ix][ihist]->GetRMS();
1392  }
1393  }
1394 
1395  TString tableFileName, tableCaption, tableAlign, tableHeadline;
1396  TString PXBpLine, PXBmLine, PXFpLine, PXFmLine, TIBpLine, TIBmLine, TOBpLine, TOBmLine, TIDpLine, TIDmLine, TECpLine,
1397  TECmLine;
1398 
1399  // table using mean and RMS, round to integers in µm etc.
1400  tableFileName = "table_differences.tex";
1401  if (_module_plot_option == "all")
1402  tableCaption = "Means and standard deviations of " + _alignment_name + " - " + _reference_name +
1403  " for each subdetector, all modules used.";
1404  else if (_module_plot_option == "good")
1405  tableCaption = "Means and standard deviations of " + _alignment_name + " - " + _reference_name +
1406  " for each subdetector, only good modules used.";
1407  else if (_module_plot_option == "list")
1408  tableCaption = "Means and standard deviations of " + _alignment_name + " - " + _reference_name +
1409  " for each subdetector, good modules and those in given list used.";
1410 
1411  WriteTable(y, NB_SUBLEVELS * NB_Z_SLICES * NB_X_SLICES, meanValue, RMS, "0", tableCaption, tableFileName);
1412 
1413  //~ // table using Gaussian fit, round to integers in µm etc.
1414  tableFileName = "table_differences_Gaussian.tex";
1415  if (_module_plot_option == "all")
1416  tableCaption = "Means and standard deviations for Gaussian fit of " + _alignment_name + " - " + _reference_name +
1417  " for each subdetector, all modules used.";
1418  else if (_module_plot_option == "good")
1419  tableCaption = "Means and standard deviations for Gaussian fit of " + _alignment_name + " - " + _reference_name +
1420  " for each subdetector, only good modules used.";
1421  else if (_module_plot_option == "list")
1422  tableCaption = "Means and standard deviations for Gaussian fit of " + _alignment_name + " - " + _reference_name +
1423  " for each subdetector, good modules and those in given list used.";
1424 
1425  WriteTable(
1426  y, NB_SUBLEVELS * NB_Z_SLICES * NB_X_SLICES, meanValueGaussian, RMSGaussian, "0", tableCaption, tableFileName);
1427 
1428  // Table for the mean positions on the x-axis, round to 3 digits in cm etc.
1429  tableFileName = "table_meanPos.tex";
1430 
1431  if (_module_plot_option == "all")
1432  tableCaption = "Mean positions and standard deviations in " + _reference_name +
1433  " geometry for each subdetector, all modules used.";
1434  else if (_module_plot_option == "good")
1435  tableCaption = "Mean positions and standard deviations in " + _reference_name +
1436  " geometry for each subdetector, only good modules used.";
1437  else if (_module_plot_option == "list")
1438  tableCaption = "Mean positions and standard deviations in " + _reference_name +
1439  " geometry for each subdetector, good modules and those in given list used.";
1440 
1441  WriteTable(x, NB_SUBLEVELS * NB_Z_SLICES * NB_X_SLICES, meanValuex, RMSx, "3", tableCaption, tableFileName);
1442 
1443 #ifdef TALKATIVE
1444  std::cout << __FILE__ << ":" << __LINE__ << ":Info: End of MakeLegends method" << std::endl;
1445 #endif
1446 }
1447 
1448 // OPTION METHODS
1449 void GeometryComparisonPlotter::SetPrint(const bool kPrint) { _print = kPrint; }
1450 void GeometryComparisonPlotter::SetLegend(const bool kLegend) { _legend = kLegend; }
1451 void GeometryComparisonPlotter::SetWrite(const bool kWrite) { _write = kWrite; }
1452 void GeometryComparisonPlotter::Set1dModule(const bool k1dModule) { _1dModule = k1dModule; }
1453 void GeometryComparisonPlotter::Set2dModule(const bool k2dModule) { _2dModule = k2dModule; }
1454 void GeometryComparisonPlotter::SetLevelCut(const int kLevelCut) { _levelCut = kLevelCut; }
1455 void GeometryComparisonPlotter::SetBatchMode(const bool kBatchMode) { _batchMode = kBatchMode; }
1456 void GeometryComparisonPlotter::SetGrid(const int kGridX, const int kGridY) {
1457  _grid_x = kGridX;
1458  _grid_y = kGridY;
1459 }
1460 void GeometryComparisonPlotter::SetBranchMax(const TString branchname, const float max) { _max[branchname] = max; }
1461 void GeometryComparisonPlotter::SetBranchMin(const TString branchname, const float min) { _min[branchname] = min; }
1462 void GeometryComparisonPlotter::SetBranchSF(const TString branchname, const float SF) { _SF[branchname] = SF; }
1463 void GeometryComparisonPlotter::SetBranchUnits(const TString branchname, const TString units) {
1464  _units[branchname] = units;
1465 }
1466 void GeometryComparisonPlotter::SetPrintOption(const Option_t *print_option) { _print_option = print_option; }
1467 void GeometryComparisonPlotter::SetCanvasSize(const int window_width, const int window_height) {
1468  _window_width = window_width;
1469  _window_height = window_height;
1470 }
1473  _output_directory = name + TString(name.EndsWith("/") ? "" : "/");
1474 }
1475 
1476 // PRIVATE METHODS
1478  word.ToLower();
1479  if (word.BeginsWith("d"))
1480  word.ReplaceAll("d", "#Delta");
1481  if (word == TString("rdphi"))
1482  word = "r#Delta#phi"; // TO DO: find something less ad hoc...
1483  else if (word.EndsWith("phi"))
1484  word.ReplaceAll("phi", "#phi");
1485  else if (word.EndsWith("alpha"))
1486  word.ReplaceAll("alpha", "#alpha");
1487  else if (word.EndsWith("beta"))
1488  word.ReplaceAll("beta", "#beta");
1489  else if (word.EndsWith("gamma"))
1490  word.ReplaceAll("gamma", "#gamma");
1491  else if (word.EndsWith("eta"))
1492  word.ReplaceAll("eta", "#eta");
1493  return word;
1494 }
1495 
1497  word.ToLower();
1498  if (word.BeginsWith("d"))
1499  word.ReplaceAll("d", "$\\Delta$");
1500  if (word == TString("rdphi"))
1501  word = "r$\\Delta\\phi$"; // TO DO: find something less ad hoc...
1502  else if (word.EndsWith("phi"))
1503  word.ReplaceAll("phi", "$\\phi$");
1504  else if (word.EndsWith("alpha"))
1505  word.ReplaceAll("alpha", "$\\alpha$");
1506  else if (word.EndsWith("beta"))
1507  word.ReplaceAll("beta", "$\\beta$");
1508  else if (word.EndsWith("gamma"))
1509  word.ReplaceAll("gamma", "#$\\gamma$");
1510  else if (word.EndsWith("eta"))
1511  word.ReplaceAll("eta", "$\\eta$");
1512  return word;
1513 }
1514 
1516  if (print_option.Contains("pdf"))
1517  return TString(".pdf");
1518  else if (print_option.Contains("eps"))
1519  return TString(".eps");
1520  else if (print_option.Contains("ps"))
1521  return TString(".ps");
1522  else if (print_option.Contains("svg"))
1523  return TString(".svg");
1524  else if (print_option.Contains("tex"))
1525  return TString(".tex");
1526  else if (print_option.Contains("gif"))
1527  return TString(".gif");
1528  else if (print_option.Contains("xpm"))
1529  return TString(".xpm");
1530  else if (print_option.Contains("png"))
1531  return TString(".png");
1532  else if (print_option.Contains("jpg"))
1533  return TString(".jpg");
1534  else if (print_option.Contains("tiff"))
1535  return TString(".tiff");
1536  else if (print_option.Contains("cxx"))
1537  return TString(".cxx");
1538  else if (print_option.Contains("xml"))
1539  return TString(".xml");
1540  else if (print_option.Contains("root"))
1541  return TString(".root");
1542  else {
1543  std::cout << __FILE__ << ":" << __LINE__ << ":Warning: unknown format. Returning .pdf, but possibly wrong..."
1544  << std::endl;
1545  return TString(".pdf");
1546  }
1547 }
1548 
1550  double x1, double y1, double x2, double y2, int nPlottedSublevels, const TString title) {
1551  TLegend *legend = new TLegend(x1, y1, x2, y2, title.Data(), "NBNDC");
1552  legend->SetNColumns(nPlottedSublevels);
1553  legend->SetFillColor(0);
1554  legend->SetLineColor(0); // redundant with option
1555  legend->SetLineWidth(0); // redundant with option
1556  for (int isublevel = 0; isublevel < nPlottedSublevels;
1557  isublevel++) // nPlottedSublevels is either NB_SUBLEVELS for the tracker or 2 for the pixel
1558  {
1559  TGraph *g = new TGraph(0);
1560  g->SetMarkerColor(COLOR_CODE(isublevel));
1561  g->SetFillColor(COLOR_CODE(isublevel));
1562  g->SetMarkerStyle(kFullSquare);
1563  g->SetMarkerSize(10);
1564  legend->AddEntry(g, _sublevel_names[isublevel], "p");
1565  }
1566  return legend;
1567 }
1568 
1569 void GeometryComparisonPlotter::WriteTable(std::vector<TString> x,
1570  unsigned int nLevelsTimesSlices,
1571  float meanValue[10][24],
1572  float RMS[10][24],
1573  const TString nDigits,
1574  const TString tableCaption,
1575  const TString tableFileName) {
1576  std::ofstream output(_output_directory + tableFileName);
1577 
1578  TString tableAlign, tableHeadline;
1579  TString PXBpLine, PXBmLine, PXFpLine, PXFmLine, TIBpLine, TIBmLine, TOBpLine, TOBmLine, TIDpLine, TIDmLine, TECpLine,
1580  TECmLine;
1581  char meanChar[x.size()][nLevelsTimesSlices][10];
1582  char RMSChar[x.size()][nLevelsTimesSlices][10];
1583 
1584  tableAlign = "l";
1585  tableHeadline = "";
1586  PXBpLine = "PXB x$+$";
1587  PXBmLine = "PXB x$-$";
1588  PXFpLine = "PXF z$+$";
1589  PXFmLine = "PXF z$-$";
1590  TIBpLine = "TIB x$+$";
1591  TIBmLine = "TIB x$-$";
1592  TIDpLine = "TID z$+$";
1593  TIDmLine = "TID z$-$";
1594  TOBpLine = "TOB x$+$";
1595  TOBmLine = "TOB x$-$";
1596  TECpLine = "TEC z$+$";
1597  TECmLine = "TEC z$-$";
1598 
1599  for (unsigned int ix = 0; ix < x.size(); ix++) {
1600  for (unsigned int isubDet = 0; isubDet < nLevelsTimesSlices; isubDet++) {
1601  sprintf(meanChar[ix][isubDet], "%." + nDigits + "f", meanValue[ix][isubDet]);
1602  sprintf(RMSChar[ix][isubDet], "%." + nDigits + "f", RMS[ix][isubDet]);
1603  }
1604  tableAlign += "|c";
1605  tableHeadline += " & " + LateXstyleTable(x[ix]) + " / " + _units[x[ix]].ReplaceAll("#mum", "$\\mu$m");
1606 
1607  PXBpLine += " & $";
1608  PXBpLine += meanChar[ix][0];
1609  PXBpLine += "\\pm";
1610  PXBpLine += RMSChar[ix][0];
1611  PXBpLine += " $";
1612  PXBmLine += " & $";
1613  PXBmLine += meanChar[ix][12];
1614  PXBmLine += "\\pm";
1615  PXBmLine += RMSChar[ix][12];
1616  PXBmLine += " $";
1617  PXFpLine += " & $";
1618  PXFpLine += meanChar[ix][1];
1619  PXFpLine += "\\pm";
1620  PXFpLine += RMSChar[ix][1];
1621  PXFpLine += " $";
1622  PXFmLine += " & $";
1623  PXFmLine += meanChar[ix][7];
1624  PXFmLine += "\\pm";
1625  PXFmLine += RMSChar[ix][7];
1626  PXFmLine += " $";
1627  TIBpLine += " & $";
1628  TIBpLine += meanChar[ix][2];
1629  TIBpLine += "\\pm";
1630  TIBpLine += RMSChar[ix][2];
1631  TIBpLine += " $";
1632  TIBmLine += " & $";
1633  TIBmLine += meanChar[ix][14];
1634  TIBmLine += "\\pm";
1635  TIBmLine += RMSChar[ix][14];
1636  TIBmLine += " $";
1637  TIDpLine += " & $";
1638  TIDpLine += meanChar[ix][3];
1639  TIDpLine += "\\pm";
1640  TIDpLine += RMSChar[ix][3];
1641  TIDpLine += " $";
1642  TIDmLine += " & $";
1643  TIDmLine += meanChar[ix][9];
1644  TIDmLine += "\\pm";
1645  TIDmLine += RMSChar[ix][9];
1646  TIDmLine += " $";
1647  TOBpLine += " & $";
1648  TOBpLine += meanChar[ix][4];
1649  TOBpLine += "\\pm";
1650  TOBpLine += RMSChar[ix][4];
1651  TOBpLine += " $";
1652  TOBmLine += " & $";
1653  TOBmLine += meanChar[ix][16];
1654  TOBmLine += "\\pm";
1655  TOBmLine += RMSChar[ix][16];
1656  TOBmLine += " $";
1657  TECpLine += " & $";
1658  TECpLine += meanChar[ix][5];
1659  TECpLine += "\\pm";
1660  TECpLine += RMSChar[ix][5];
1661  TECpLine += " $";
1662  TECmLine += " & $";
1663  TECmLine += meanChar[ix][11];
1664  TECmLine += "\\pm";
1665  TECmLine += RMSChar[ix][11];
1666  TECmLine += " $";
1667  }
1668 
1669  // Write the table to the tex file
1670  output << "\\begin{table}" << std::endl;
1671  output << "\\caption{" << tableCaption << "}" << std::endl;
1672  output << "\\begin{tabular}{" << tableAlign << "}" << std::endl;
1673  output << "\\hline" << std::endl;
1674  output << tableHeadline << " \\\\" << std::endl;
1675  output << "\\hline" << std::endl;
1676  output << PXBpLine << " \\\\" << std::endl;
1677  output << PXBmLine << " \\\\" << std::endl;
1678  output << PXFpLine << " \\\\" << std::endl;
1679  output << PXFmLine << " \\\\" << std::endl;
1680  output << TIBpLine << " \\\\" << std::endl;
1681  output << TIBmLine << " \\\\" << std::endl;
1682  output << TIDpLine << " \\\\" << std::endl;
1683  output << TIDmLine << " \\\\" << std::endl;
1684  output << TOBpLine << " \\\\" << std::endl;
1685  output << TOBmLine << " \\\\" << std::endl;
1686  output << TECpLine << " \\\\" << std::endl;
1687  output << TECmLine << " \\\\" << std::endl;
1688  output << "\\hline" << std::endl;
1689  output << "\\end{tabular}" << std::endl;
1690  output << "\\end{table}" << std::endl;
1691 }
void SetCanvasSize(const int window_width=3508, const int window_height=2480)
std::map< TString, float > branch_f
void SetGrid(const int, const int)
void MakePlots(const std::vector< TString >, const std::vector< TString >, pt::ptree CFG)
#define DEFAULT_LEVEL
#define LIMITS(axes_vector)
GeometryComparisonPlotter(TString tree_file_name, TString outputDirname="output/", TString modulesToPlot="all", TString referenceName="Ideal", TString alignmentName="Alignment", bool plotOnlyGlobal=false, bool makeProfilePlots=false, int canvas_idx=0)
std::map< TString, float > _SF
void WriteTable(const std::vector< TString > x, unsigned int nLevelsTimesSlices, float meanValue[10][24], float RMS[10][24], const TString nDigits, const TString tableCaption, const TString tableFileName)
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
#define INDEX_IN_GLOBAL_CANVAS(i1, i2)
static std::string to_string(const XMLCh *ch)
std::map< TString, int > branch_i
void SetBranchMax(const TString, const float)
std::map< TString, float > _max
void SetBranchUnits(const TString, const TString)
std::map< TString, TString > _units
uint64_t word
#define DEFAULT_WINDOW_WIDTH
std::map< TString, float > _min
void MakeTables(const std::vector< TString >, const std::vector< TString >, pt::ptree CFG)
#define CHECK_MAP_CONTENT(m, type)
ALPAKA_FN_ACC ALPAKA_FN_INLINE uint32_t ix(uint32_t id)
#define NB_Z_SLICES
histos
Definition: combine.py:4
void SetBranchSF(const TString, const float)
TString units(TString variable, Char_t axis)
#define DEBUG
Definition: DMRChecker.cc:120
#define CHECK_BRANCHES(branchname_vector)
float x
ALPAKA_FN_ACC ALPAKA_FN_INLINE uint32_t iy(uint32_t id)
#define NB_X_SLICES
Definition: output.py:1
#define NB_SUBLEVELS
graphs
Definition: cuy.py:961
TLegend * MakeLegend(double x1, double y1, double x2, double y2, int nPlottedSublevels, const TString title="")
#define DEFAULT_WINDOW_HEIGHT
#define COLOR_CODE(icolor)
void SetBranchMin(const TString, const float)
#define INSIDE_VECTOR(vector)
#define NB_MODULE_QUALITY
def exit(msg="")