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