CMS 3D CMS Logo

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