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