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  TString printOnlyGlobal
32  ) :
33  _output_directory(output_directory + TString(output_directory.EndsWith("/") ? "" : "/")),
34  _output_filename("comparison.root"),
35  _print_option("pdf"),
36  _module_plot_option(modulesToPlot),
37  _alignment_name(alignmentName),
38  _reference_name(referenceName),
39  _print_only_global(printOnlyGlobal),
40  _print(true), // print the graphs in a file (e.g. pdf)
41  _legend(true), // print the graphs in a file (e.g. pdf)
42  _write(true), // write the graphs in a root file
43  _batchMode(
44 #ifdef DEBUG
45  false // false = display canvases (very time- and resource-consuming)
46 #else
47  true // true = no canvases
48 #endif
49  ),
50  _1dModule(true), // cut on 1d modules
51  _2dModule(true), // cut on 2d modules
52  _levelCut (DEFAULT_LEVEL), // module level (see branch of same name)
53  _grid_x(0), // by default no display the grid in the canvases
54  _grid_y(0), // by default no display the grid in the canvases
55  _window_width(DEFAULT_WINDOW_WIDTH),
56  _window_height(DEFAULT_WINDOW_HEIGHT)
57 {
58 #ifdef TALKATIVE
59  cout << ">>> TALKATIVE MODE ACTIVATED <<<" << endl;
60 #endif
61 #ifdef DEBUG
62  cout << ">>> DEBUG MODE ACTIVATED <<<" << endl;
63  cout << __FILE__ << ":"<< __LINE__ << ":Info: inside constructor of GeometryComparisonPlotter utility"<< endl;
64 #endif
65 
66  //_sublevel_names = {"PXB", "PXF", "TIB", "TID", "TOB", "TEC"}; // C++11
67  _sublevel_names[0] = TString("PXB");
68  _sublevel_names[1] = TString("PXF");
69  _sublevel_names[2] = TString("TIB");
70  _sublevel_names[3] = TString("TID");
71  _sublevel_names[4] = TString("TOB");
72  _sublevel_names[5] = TString("TEC");
73  // TO DO: handle other structures
74 
75  // read tree
76  tree_file = new TFile(tree_file_name, "UPDATE");
77  data = (TTree*) tree_file->Get("alignTree");
78  // int branches
79  data->SetBranchAddress("id" ,&branch_i["id"]);
80  data->SetBranchAddress("inModuleList" ,&branch_i["inModuleList"]);
81  data->SetBranchAddress("badModuleQuality" ,&branch_i["badModuleQuality"]);
82  data->SetBranchAddress("mid" ,&branch_i["mid"]);
83  data->SetBranchAddress("level" ,&branch_i["level"]);
84  data->SetBranchAddress("mlevel" ,&branch_i["mlevel"]);
85  data->SetBranchAddress("sublevel" ,&branch_i["sublevel"]);
86  data->SetBranchAddress("useDetId" ,&branch_i["useDetId"]);
87  data->SetBranchAddress("detDim" ,&branch_i["detDim"]);
88  // float branches
89  data->SetBranchAddress("x" ,&branch_f["x"]);
90  data->SetBranchAddress("y" ,&branch_f["y"]);
91  data->SetBranchAddress("z" ,&branch_f["z"]);
92  data->SetBranchAddress("alpha" ,&branch_f["alpha"]);
93  data->SetBranchAddress("beta" ,&branch_f["beta"]);
94  data->SetBranchAddress("gamma" ,&branch_f["gamma"]);
95  data->SetBranchAddress("phi" ,&branch_f["phi"]);
96  data->SetBranchAddress("eta" ,&branch_f["eta"]);
97  data->SetBranchAddress("r" ,&branch_f["r"]);
98  data->SetBranchAddress("dx" ,&branch_f["dx"]);
99  data->SetBranchAddress("dy" ,&branch_f["dy"]);
100  data->SetBranchAddress("dz" ,&branch_f["dz"]);
101  data->SetBranchAddress("dphi" ,&branch_f["dphi"]);
102  data->SetBranchAddress("dr" ,&branch_f["dr"]);
103  data->SetBranchAddress("dalpha" ,&branch_f["dalpha"]);
104  data->SetBranchAddress("dbeta" ,&branch_f["dbeta"]);
105  data->SetBranchAddress("dgamma" ,&branch_f["dgamma"]);
106  if (data->GetBranch("rdphi") == 0x0) // in the case of rdphi branch not existing, it is created from r and dphi branches
107  {
108 #ifdef TALKATIVE
109  cout << __FILE__ << ":" << __LINE__ << ":Info: computing the rdphi branch from r and dphi branches (assuming they exist...)" << endl;
110 #endif
111  TBranch * br_rdphi = data->Branch("rdphi", &branch_f["rdphi"], "rdphi/F");
112  for (unsigned int ientry = 0 ; ientry < data->GetEntries() ; ientry++)
113  {
114  data->GetEntry(ientry);
115  branch_f["rdphi"] = branch_f["r"]*branch_f["dphi"];
116  br_rdphi->Fill();
117  }
118  }
119  else
120  data->SetBranchAddress("rdphi",&branch_f["rdphi"]);
121 
122 #ifdef DEBUG
123  cout << __FILE__ << ":" << __LINE__ << ":Info: branch addresses set" << endl;
124 #endif
125 
126  // style
127  gROOT->Reset();
128 
129  data->SetMarkerSize(0.5);
130  data->SetMarkerStyle(6);
131 
132  gStyle->SetOptStat("emr");
133  gStyle->SetTitleAlign(22);
134  gStyle->SetTitleX(0.5);
135  gStyle->SetTitleY(0.97);
136  gStyle->SetTitleFont(62);
137  //gStyle->SetOptTitle(0);
138 
139  gStyle->SetTextFont(132);
140  gStyle->SetTextSize(0.08);
141  gStyle->SetLabelFont(132,"x");
142  gStyle->SetLabelFont(132,"y");
143  gStyle->SetLabelFont(132,"z");
144  gStyle->SetTitleSize(0.08,"x");
145  gStyle->SetTitleSize(0.08,"y");
146  gStyle->SetTitleSize(0.08,"z");
147  gStyle->SetLabelSize(0.08,"x");
148  gStyle->SetLabelSize(0.08,"y");
149  gStyle->SetLabelSize(0.08,"z");
150 
151  gStyle->SetMarkerStyle(8);
152  gStyle->SetHistLineWidth(2);
153  gStyle->SetLineStyleString(2,"[12 12]"); // postscript dashes
154 
155  gStyle->SetFrameBorderMode(0);
156  gStyle->SetCanvasBorderMode(0);
157  gStyle->SetPadBorderMode(0);
158  gStyle->SetPadColor(0);
159  gStyle->SetCanvasColor(0);
160  gStyle->SetTitleColor(1);
161  gStyle->SetStatColor(0);
162  gStyle->SetStatBorderSize(1);
163  gStyle->SetFrameFillColor(0);
164 
165  gStyle->SetPadTickX(1);
166  gStyle->SetPadTickY(1);
167 
168  gStyle->SetPadTopMargin(0.1);
169  gStyle->SetPadRightMargin(0.05);
170  gStyle->SetPadBottomMargin(0.16);
171  gStyle->SetPadLeftMargin(0.18);
172 
173 #ifdef DEBUG
174  cout << __FILE__ << ":" << __LINE__ << ":Info: end of constructor" << endl;
175 #endif
176 }
177 
179 {
180 #ifdef DEBUG
181  cout << __FILE__ << ":" << __LINE__ << ":Info: in destructor of the GeometryComparisonPlotter utility" << endl;
182 #endif
183  tree_file->Close();
184 #ifdef DEBUG
185  cout << __FILE__ << ":" << __LINE__ << ":Info: ending." << endl;
186 #endif
187 }
188 
189 // MAIN METHOD
190 void GeometryComparisonPlotter::MakePlots (vector<TString> x, // axes to combine to plot
191  vector<TString> y, // every combination (except the ones such that x=y) will be perfomed
192  vector<float> dyMin, // Minimum of y-variable to enable fixed ranges of the histogram
193  vector<float> dyMax) // Minimum of y-variable
194 {
196  // (we use a macro to avoid copy/paste)
197 #define CHECK_BRANCHES(branchname_vector) \
198  for (unsigned int i = 0 ; i < branchname_vector.size() ; i++) \
199  { \
200  if (branch_f.find(branchname_vector[i]) == branch_f.end()) \
201  { \
202  cout << __FILE__ << ":" << __LINE__ << ":Error: The branch " << branchname_vector[i] << " is not recognised." << endl; \
203  return; \
204  } \
205  }
206  CHECK_BRANCHES(x);
207  CHECK_BRANCHES(y);
208 
209  const unsigned int nentries = data->GetEntries();
210 
211 #ifdef TALKATIVE
212  cout << __FILE__ << ":" << __LINE__ << ":Info: "; INSIDE_VECTOR(x); cout << endl
213  << __FILE__ << ":" << __LINE__ << ":Info: "; INSIDE_VECTOR(y); cout << endl;
214 #endif
215 
217  // the max and min of the graphs are computed from the tree if they have not been manually input yet
218  // (we use a macro to avoid copy/paste)
219 #define LIMITS(axes_vector) \
220  for (unsigned int i = 0 ; i < axes_vector.size() ; i++) \
221  { \
222  if ( _SF.find(axes_vector[i]) == _SF.end()) _SF[axes_vector[i]] = 1.; \
223  if (_min.find(axes_vector[i]) == _min.end()) _min[axes_vector[i]] = _SF[axes_vector[i]]*data->GetMinimum(axes_vector[i]); \
224  if (_max.find(axes_vector[i]) == _max.end()) _max[axes_vector[i]] = _SF[axes_vector[i]]*data->GetMaximum(axes_vector[i]); \
225  }
226  LIMITS(x);
227  LIMITS(y);
228 
229 #ifdef TALKATIVE
230  CHECK_MAP_CONTENT(_min,float);
231  CHECK_MAP_CONTENT(_max,float);
232  CHECK_MAP_CONTENT(_SF ,float);
233 #endif
234 
236  // the idea is to produce at the end a table of 7 TMultiGraphs:
237  // - 0=Tracker, with color code for the different sublevels
238  // - 1..6=different sublevels, with color code for z < or > 0
239  // (convention: the six first (resp. last) correspond to z>0 (resp. z<0))
240  // Modules with bad quality and in a list of modules that is given
241  // by the user (e.g. list of bad/untouched modules, default: empty list)
242  // are stored in seperate graphs and might be plotted (depends on the module
243  // plot option, default: all modules plotted)
244  // This means that 3*2*6 TGraphs will be filled during the loop on the TTree,
245  // and will be arranged differently with different color codes in the TMultiGraphs
246 #ifndef NB_SUBLEVELS
247 #define NB_SUBLEVELS 6
248 #endif
249 #define NB_Z_SLICES 2
250 #define NB_MODULE_QUALITY 3
251 
252  TGraph * graphs[x.size()][y.size()][NB_SUBLEVELS*NB_Z_SLICES*NB_MODULE_QUALITY];
253  long int ipoint[x.size()][y.size()][NB_SUBLEVELS*NB_Z_SLICES*NB_MODULE_QUALITY];
254 
255  TMultiGraph * mgraphs[x.size()][y.size()][1+NB_SUBLEVELS]; // the 0th is for global plots, the 1..6th for sublevel plots
256  TCanvas * c[x.size()][y.size()][1+NB_SUBLEVELS],
257  * c_global[1+NB_SUBLEVELS];
258  canvas_index++; // this static index is a safety used in case the MakePlots method is used several times to avoid overloading
259 
260 
261  for (unsigned int ic = 0 ; ic <= NB_SUBLEVELS ; ic++)
262  {
263  c_global[ic] = new TCanvas (TString::Format("global_%s_%d", ic==0?"tracker":_sublevel_names[ic-1].Data(),
264  canvas_index),
265  TString::Format("Global overview of the %s variables", ic==0?"tracker":_sublevel_names[ic-1].Data()),
268  c_global[ic]->Divide(x.size(),y.size());
269  }
270 
271  for (unsigned int ix = 0 ; ix < x.size() ; ix++)
272  {
273  for (unsigned int iy = 0 ; iy < y.size() ; iy++)
274  {
275  //if (x[ix] == y[iy]) continue; // do not plot graphs like (r,r) or (phi,phi)
276  for (unsigned int igraph = 0 ; igraph < NB_SUBLEVELS*NB_Z_SLICES*NB_MODULE_QUALITY ; igraph++)
277  {
278  // declaring
279  ipoint[ix][iy][igraph] = 0; // the purpose of an index for every graph is to avoid thousands of points at the origin of each
280  graphs[ix][iy][igraph] = new TGraph ();
281 #define COLOR_CODE(icolor) int(icolor/4)+icolor+1
282  graphs[ix][iy][igraph]->SetMarkerColor(COLOR_CODE(igraph));
283  graphs[ix][iy][igraph]->SetMarkerStyle(6);
284  // pimping
285  graphs[ix][iy][igraph]->SetName (x[ix]+y[iy]+_sublevel_names[igraph%NB_SUBLEVELS]
286  +TString(igraph%(NB_SUBLEVELS*NB_Z_SLICES)>=NB_SUBLEVELS ? "n" : "p" ) // graphs for negative/positive z
287  +TString(igraph >= NB_SUBLEVELS*NB_Z_SLICES ?
288  ( igraph >= 2*NB_SUBLEVELS*NB_Z_SLICES ? "bad" : "list") : "good" ));// graphs for good, bad modules and from a list
289  graphs[ix][iy][igraph]->SetTitle( _sublevel_names[igraph%NB_SUBLEVELS]
290  +TString(igraph%(NB_SUBLEVELS*NB_Z_SLICES)>=NB_SUBLEVELS ? " at z<0": " at z>=0")
291  +TString(igraph >= NB_SUBLEVELS*NB_Z_SLICES ?
292  ( igraph >= 2*NB_SUBLEVELS*NB_Z_SLICES ? " bad modules" : " in list") : " good modules" )
293  + TString (";") + LateXstyle(x[ix]) + " /" + _units[x[ix]]
294  + TString (";") + LateXstyle(y[iy]) + " /" + _units[y[iy]]);
295  graphs[ix][iy][igraph]->SetMarkerStyle(igraph >= NB_SUBLEVELS*NB_Z_SLICES ?
296  ( igraph >= 2*NB_SUBLEVELS*NB_Z_SLICES ? 4 : 5) : 6); // empty circle for bad modules, X for those in list, dot for good ones
297  }
298  }
299  }
300 
301 #ifdef DEBUG
302  cout << __FILE__ << ":" << __LINE__ << ":Info: Creation of the TGraph[" << x.size() << "][" << y.size() << "][" << NB_SUBLEVELS*NB_Z_SLICES*NB_MODULE_QUALITY << "] ended." << endl;
303 #endif
304 
306 #ifdef DEBUG
307  cout << __FILE__ << ":" << __LINE__ << ":Info: Looping on the TTree" << endl;
308 #endif
309 #ifdef TALKATIVE
310  unsigned int progress = 0;
311  cout << __FILE__ << ":" << __LINE__ << ":Info: 0%" << endl;
312 #endif
313  for (unsigned int ientry = 0 ; ientry < nentries ; ientry++)
314  {
315 #ifdef TALKATIVE
316  if (10*ientry/nentries != progress)
317  {
318  progress = 10*ientry/nentries;
319  cout << __FILE__ << ":" << __LINE__ << ":Info: " << 10*progress << "%" << endl;
320  }
321 #endif
322  // load current tree entry
323  data->GetEntry(ientry);
324 
325  // CUTS on entry
326  if (branch_i["level"] != _levelCut) continue;
327  if (!_1dModule && branch_i["detDim"] == 1) continue;
328  if (!_2dModule && branch_i["detDim"] == 2) continue;
329 
330  // loop on the different couples of variables to plot in a graph
331  for (unsigned int ix = 0 ; ix < x.size() ; ix++)
332  {
333  // CUTS on x[ix]
334  if (_SF[x[ix]]*branch_f[x[ix]] > _max[x[ix]] || _SF[x[ix]]*branch_f[x[ix]] < _min[x[ix]])
335  {
336 //#ifdef DEBUG
337 // cout << "branch_f[x[ix]]=" << branch_f[x[ix]] << endl;
338 //#endif
339  continue;
340  }
341 
342  for (unsigned int iy = 0 ; iy < y.size() ; iy++)
343  {
344  // CUTS on y[iy]
345  //if (x[ix] == y[iy]) continue; // TO DO: handle display when such a case occurs
346  if (branch_i["sublevel"] < 1 || branch_i["sublevel"] > NB_SUBLEVELS) continue;
347  if (_SF[y[iy]]*branch_f[y[iy]] > _max[y[iy]] || _SF[y[iy]]*branch_f[y[iy]] < _min[y[iy]])
348  {
349 //#ifdef DEBUG
350 // cout << "branch_f[y[iy]]=" << branch_f[y[iy]] << endl;
351 //#endif
352  continue;
353  }
354 
355  // FILLING GRAPH
356  if (y.size() >= x.size()){
357  if (branch_i["inModuleList"]==0 && branch_i["badModuleQuality"]==0 ){
358  const short int igraph = (branch_i["sublevel"]-1)
359  + (branch_f["z"]>=0?0:NB_SUBLEVELS);
360  graphs[ix][iy][igraph]->SetPoint(ipoint[ix][iy][igraph],
361  _SF[x[ix]]*branch_f[x[ix]],
362  _SF[y[iy]]*branch_f[y[iy]]);
363  ipoint[ix][iy][igraph]++;
364  }
365  if (branch_i["inModuleList"]>0){
366  const short int igraph = (branch_i["sublevel"]-1)
367  + (branch_f["z"]>=0?0:NB_SUBLEVELS)
369  graphs[ix][iy][igraph]->SetPoint(ipoint[ix][iy][igraph],
370  _SF[x[ix]]*branch_f[x[ix]],
371  _SF[y[iy]]*branch_f[y[iy]]);
372  ipoint[ix][iy][igraph]++;
373  }
374  if (branch_i["badModuleQuality"]>0){
375  const short int igraph = (branch_i["sublevel"]-1)
376  + (branch_f["z"]>=0?0:NB_SUBLEVELS)
378  graphs[ix][iy][igraph]->SetPoint(ipoint[ix][iy][igraph],
379  _SF[x[ix]]*branch_f[x[ix]],
380  _SF[y[iy]]*branch_f[y[iy]]);
381  ipoint[ix][iy][igraph]++;
382  }
383  }
384  else{
385  if (branch_i["inModuleList"]==0 && branch_i["badModuleQuality"]==0 ){
386  const short int igraph = (branch_i["sublevel"]-1)
387  + (branch_f["z"]>=0?0:NB_SUBLEVELS);
388  graphs[iy][ix][igraph]->SetPoint(ipoint[iy][ix][igraph],
389  _SF[x[ix]]*branch_f[x[ix]],
390  _SF[y[iy]]*branch_f[y[iy]]);
391  ipoint[iy][ix][igraph]++;
392  }
393  if (branch_i["inModuleList"]>0){
394  const short int igraph = (branch_i["sublevel"]-1)
395  + (branch_f["z"]>=0?0:NB_SUBLEVELS)
397  graphs[iy][ix][igraph]->SetPoint(ipoint[iy][ix][igraph],
398  _SF[x[ix]]*branch_f[x[ix]],
399  _SF[y[iy]]*branch_f[y[iy]]);
400  ipoint[iy][ix][igraph]++;
401  }
402  if (branch_i["badModuleQuality"]>0){
403  const short int igraph = (branch_i["sublevel"]-1)
404  + (branch_f["z"]>=0?0:NB_SUBLEVELS)
406  graphs[iy][ix][igraph]->SetPoint(ipoint[ix][iy][igraph],
407  _SF[x[ix]]*branch_f[x[ix]],
408  _SF[y[iy]]*branch_f[y[iy]]);
409  ipoint[iy][ix][igraph]++;
410  }
411  }
412  }
413  }
414  }
415 #ifdef TALKATIVE
416  cout << __FILE__ << ":" << __LINE__ << ":Info: 100%\tLoop ended" << endl;
417 #endif
418 
420  gROOT->SetBatch(_batchMode); // if true, then equivalent to "root -b", i.e. no canvas
421  if (_write)
422  { // opening the file to write the graphs
423  output = new TFile(_output_directory+TString(_output_filename), "UPDATE"); // possibly existing file will be updated, otherwise created
424  if (output->IsZombie())
425  {
426  cout << __FILE__ << ":" << __LINE__ << ":Error: Opening of " << _output_directory+TString(_output_filename) << " failed" << endl;
427  exit(-1);
428  }
429 #ifdef TALKATIVE
430  cout << __FILE__ << ":"<< __LINE__ << ":Info: output file is " << _output_directory+TString(_output_filename) << endl;
431 #endif
432  }
433  // declaring TMultiGraphs and TCanvas
434  // Usually more y variables than x variables
435  // creating TLegend
436  TLegend * legend = MakeLegend(.1,.92,.9,1.);
437  if (_write) legend->Write();
438 
439  // check which modules are supposed to be plotted
440  unsigned int n_module_types = 1;
441  if (_module_plot_option == "all"){
442  n_module_types = 3; //plot all modules (good, list and bad )
443  }
444  else if (_module_plot_option == "list"){
445  n_module_types = 2; // plot good modules and those in the list
446  }
447  else if (_module_plot_option == "good"){
448  n_module_types = 1; // only plot the modules that are neither bad or in the list
449  }
450 
451 
452 #define INDEX_IN_GLOBAL_CANVAS(i1,i2) 1 + i1 + i2*x.size()
453  // running on the TGraphs to produce the TMultiGraph and draw/print them
454  for (unsigned int ix = 0 ; ix < x.size() ; ix++)
455  {
456 #ifdef DEBUG
457  cout << __FILE__ << ":" << __LINE__ << ":Info: x[" << ix << "]="<< x[ix] << endl;
458 #endif
459 
460  // looping on Y axes
461  for (unsigned int iy = 0 ; iy < y.size() ; iy++)
462  {
463 
464 
465 #ifdef DEBUG
466  cout << __FILE__ << ":" << __LINE__ << ":Info: x[" << ix << "]=" << x[ix]
467  << " and y[" << iy << "]=" << y[iy]
468  << "\t-> creating TMultiGraph" << endl;
469 #endif
470  mgraphs[ix][iy][0] = new TMultiGraph (TString::Format("mgr_%s_vs_%s_tracker_%d", x[ix].Data(),
471  y[iy].Data(),
472  canvas_index), // name
473  //LateXstyle(x[ix]) + TString(" vs. ") + LateXstyle(y[iy]) + TString(" for Tracker") // graph title
474  TString (";") + LateXstyle(x[ix]) + " /" + _units[x[ix]] // x axis title
475  + TString (";") + LateXstyle(y[iy]) + " /" + _units[y[iy]]); // y axis title
476 
478  // fixing ranges and filling TMultiGraph
479  // for (unsigned short int jgraph = NB_SUBLEVELS*NB_Z_SLICES-1 ; jgraph >= 0 ; --jgraph)
480  for (unsigned short int jgraph = 0 ; jgraph < NB_SUBLEVELS*NB_Z_SLICES*n_module_types ; jgraph++)
481  {
482  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)
483 
484 #ifdef DEBUG
485  cout << __FILE__ << ":" << __LINE__ << ":Info: writing TGraph to file" << endl;
486 #endif
487  // write into root file
488  if (_write) graphs[ix][iy][igraph]->Write();
489  if (graphs[ix][iy][igraph]->GetN() == 0)
490  {
491 #ifdef TALKATIVE
492  cout << __FILE__ << ":" << __LINE__ << ":Info: " << graphs[ix][iy][igraph]->GetName() << " is empty." << endl;
493 #endif
494  continue;
495  }
496 #ifdef DEBUG
497  cout << __FILE__ << ":" << __LINE__ << ":Info: cloning, coloring and adding TGraph "
498  << _sublevel_names[igraph%NB_SUBLEVELS]
499  << (igraph >= NB_SUBLEVELS ? "(z<0)" : "(z>0)")
500  << " to global TMultiGraph" << endl;
501 #endif
502  // clone to prevent any injure on the graph
503  TGraph * gr = (TGraph *) graphs[ix][iy][igraph]->Clone();
504  // color
505  gr->SetMarkerColor(COLOR_CODE(igraph%NB_SUBLEVELS));
506  mgraphs[ix][iy][0]->Add(gr, "P");//, (mgraphs[ix][iy][0]->GetListOfGraphs()==0?"AP":"P"));
507 
508  }
509 
511  for (unsigned int isublevel = 1 ; isublevel <= NB_SUBLEVELS ; isublevel++)
512  {
513 #ifdef DEBUG
514  cout << __FILE__ << ":" << __LINE__ << ":Info: cloning, coloring and adding TGraph "
515  << _sublevel_names[isublevel-1] << " to sublevel TMultiGraph" << endl;
516 #endif
517  mgraphs[ix][iy][isublevel] = new TMultiGraph (TString::Format("%s_vs_%s_%s_%d", x[ix].Data(),
518  y[iy].Data(),
519  _sublevel_names[isublevel-1].Data(),
520  canvas_index), // name
521  //LateXstyle(x[ix]) + TString(" vs. ") + LateXstyle(y[iy]) + TString(" for ") +
522  _sublevel_names[isublevel-1] // graph title
523  + TString (";") + LateXstyle(x[ix]) + " /" + _units[x[ix]] // x axis title
524  + TString (";") + LateXstyle(y[iy]) + " /" + _units[y[iy]]); // y axis title
525 
526  graphs[ix][iy][ isublevel-1]->SetMarkerColor(kBlack);
527  graphs[ix][iy][NB_SUBLEVELS+isublevel-1]->SetMarkerColor(kRed);
528  graphs[ix][iy][2*NB_SUBLEVELS+isublevel-1]->SetMarkerColor(kGray+1);
529  graphs[ix][iy][3*NB_SUBLEVELS+isublevel-1]->SetMarkerColor(kRed-7);
530  graphs[ix][iy][4*NB_SUBLEVELS+isublevel-1]->SetMarkerColor(kGray+1);
531  graphs[ix][iy][5*NB_SUBLEVELS+isublevel-1]->SetMarkerColor(kRed-7);
532  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
533 #ifdef TALKATIVE
534  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;
535 #endif
536  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
537 #ifdef TALKATIVE
538  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;
539 #endif
540 #if NB_Z_SLICES!=2
541  cout << __FILE__ << ":" << __LINE__ << ":Error: color code incomplete for Z slices..." << endl;
542 #endif
543  if (_module_plot_option == "all"){
544  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");
545  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");
546  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");
547  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");
548  }
549  if (_module_plot_option == "list"){
550  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");
551  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");
552  }
553  }
554 
555 
556  // fixing ranges, saving, and drawing of TMultiGraph (tracker AND sublevels, i.e. 1+NB_SUBLEVELS objects)
557  // the individual canvases are saved, but the global are just drawn and will be saved later
558  for (unsigned short int imgr = 0 ; imgr <= NB_SUBLEVELS ; imgr++)
559  {
560 #ifdef DEBUG
561  cout << __FILE__ << ":" << __LINE__ << ":Info: treating individual canvases." << endl;
562 #endif
563  // drawing into individual canvas and printing it (including a legend for the tracker canvas)
564  c[ix][iy][imgr] = new TCanvas (TString::Format("c_%s_vs_%s_%s_%d", x[ix].Data(),
565  y[iy].Data(),
566  imgr==0?"tracker":_sublevel_names[imgr-1].Data(),
567  canvas_index),
568  TString::Format("%s vs. %s at %s level", x[ix].Data(),
569  y[iy].Data(),
570  imgr==0?"tracker":_sublevel_names[imgr-1].Data()),
573  c[ix][iy][imgr]->SetGrid(_grid_x,_grid_y); // grid
574 
575 
576  if (mgraphs[ix][iy][imgr]->GetListOfGraphs() != 0) {
577  if (dyMin[iy] != -99999) {
578  mgraphs[ix][iy][imgr]->SetMinimum(dyMin[iy]);
579  }
580  if (dyMax[iy] != -99999) {
581  mgraphs[ix][iy][imgr]->SetMaximum(dyMax[iy]);
582  }
583  mgraphs[ix][iy][imgr]->Draw("A");
584  }
585  if (imgr == 0 && _legend) legend->Draw(); // only for the tracker
586  if (_print && _print_only_global != "true") c[ix][iy][imgr]->Print(_output_directory + mgraphs[ix][iy][imgr]->GetName() + ExtensionFromPrintOption(_print_option), _print_option);
587 
588  // writing into root file
589  if (_write) mgraphs[ix][iy][imgr]->Write();
590 
591  // drawing into global canvas
592  c_global[imgr]->cd(INDEX_IN_GLOBAL_CANVAS(ix,iy));
593  c_global[imgr]->GetPad(INDEX_IN_GLOBAL_CANVAS(ix,iy))->SetFillStyle(4000); // make the pad transparent
594  c_global[imgr]->GetPad(INDEX_IN_GLOBAL_CANVAS(ix,iy))->SetGrid(_grid_x,_grid_y); // grid
595  if (mgraphs[ix][iy][imgr]->GetListOfGraphs() != 0) {
596  if (dyMin[iy] != -99999) {
597  mgraphs[ix][iy][imgr]->SetMinimum(dyMin[iy]);
598  }
599  if (dyMax[iy] != -99999) {
600  mgraphs[ix][iy][imgr]->SetMaximum(dyMax[iy]);
601  }
602  mgraphs[ix][iy][imgr]->Draw("A");
603  }
604  // printing will be performed after customisation (e.g. legend or title) just after the loops on ix and iy
605  }
606  } // end of loop on y
607  } // end of loop on x
608 
609 
610 
611  // CUSTOMISATION
612  gStyle->SetOptTitle(0); // otherwise, the title is repeated in every pad of the global canvases
613  // -> instead, we will write it in the upper part in a TPaveText or in a TLegend
614  for (unsigned int ic = 0 ; ic <= NB_SUBLEVELS ; ic++)
615  {
616  c_global[ic]->Draw();
617 
618  // setting legend to tracker canvases
619  if (!_legend) break;
620  TCanvas * c_temp = (TCanvas *) c_global[ic]->Clone(c_global[ic]->GetTitle() + TString("_sub"));
621  c_temp->Draw();
622  c_global[ic] = new TCanvas (c_temp->GetName() + TString("_final"), c_temp->GetTitle(), c_temp->GetWindowWidth(), c_temp->GetWindowHeight());
623  c_global[ic]->Draw();
624  TPad * p_up = new TPad (TString("legend_") + c_temp->GetName(), "",
625  0., 0.9, 1., 1., // relative position
626  -1, 0, 0), // display options
627  * p_down = new TPad (TString("main_") + c_temp->GetName(), "",
628  0., 0., 1., 0.9,
629  -1, 0, 0);
630  // in the lower part, draw the plots
631  p_down->Draw();
632  p_down->cd();
633  c_temp->DrawClonePad();
634  c_global[ic]->cd();
635  // in the upper part, pimp the canvas :p
636  p_up->Draw();
637  p_up->cd();
638  if (ic == 0) // tracker
639  {
640  TLegend * global_legend = MakeLegend(.05,.1,.7,.8);//, "brNDC");
641  global_legend->Draw();
642  TPaveText * pt_geom = new TPaveText(.75,.1,.95,.8, "NB");
643  pt_geom->SetFillColor(0);
644  pt_geom->SetTextSize(0.25);
645  pt_geom->AddText(TString("x: ")+_alignment_name);
646  pt_geom->AddText(TString("y: ")+_alignment_name+TString(" - ")+_reference_name);
647  pt_geom->Draw();
648  }
649  else // sublevels
650  {
651  TPaveText * pt = new TPaveText(.05,.1,.7,.8, "NB");
652  pt->SetFillColor(0);
653  pt->AddText(_sublevel_names[ic-1]);
654  pt->Draw();
655  TPaveText * pt_geom = new TPaveText(.6,.1,.95,.8, "NB");
656  pt_geom->SetFillColor(0);
657  pt_geom->SetTextSize(0.3);
658  pt_geom->AddText(TString("x: ")+_alignment_name);
659  pt_geom->AddText(TString("y: ")+_alignment_name+TString(" - ")+_reference_name);
660  pt_geom->Draw();
661  }
662  // printing
663  if (_print) c_global[ic]->Print(_output_directory + c_global[ic]->GetName() + ExtensionFromPrintOption(_print_option), _print_option);
664  if (_write) c_global[ic]->Write();
665  }
666 
667  // printing global canvases
668  if (_write) output->Close();
669 #ifdef TALKATIVE
670  cout << __FILE__ << ":" << __LINE__ << ":Info: End of MakePlots method" << endl;
671 #endif
672 
673 }
674 
675 // OPTION METHODS
676 void GeometryComparisonPlotter::SetPrint (const bool kPrint) { _print = kPrint ; }
677 void GeometryComparisonPlotter::SetLegend (const bool kLegend) { _legend = kLegend ; }
678 void GeometryComparisonPlotter::SetWrite (const bool kWrite) { _write = kWrite ; }
679 void GeometryComparisonPlotter::Set1dModule (const bool k1dModule) { _1dModule = k1dModule ; }
680 void GeometryComparisonPlotter::Set2dModule (const bool k2dModule) { _2dModule = k2dModule ; }
681 void GeometryComparisonPlotter::SetLevelCut (const int kLevelCut) { _levelCut = kLevelCut ; }
682 void GeometryComparisonPlotter::SetBatchMode (const bool kBatchMode) { _batchMode = kBatchMode ; }
683 void GeometryComparisonPlotter::SetGrid (const int kGridX,
684  const int kGridY) { _grid_x = kGridX ;
685  _grid_y = kGridY ; }
686 void GeometryComparisonPlotter::SetBranchMax (const TString branchname,
687  const float max) { _max[branchname] = max ; }
688 void GeometryComparisonPlotter::SetBranchMin (const TString branchname,
689  const float min) { _min[branchname] = min ; }
690 void GeometryComparisonPlotter::SetBranchSF (const TString branchname,
691  const float SF) { _SF[branchname] = SF ; }
692 void GeometryComparisonPlotter::SetBranchUnits (const TString branchname,
693  const TString units) { _units[branchname] = units ; }
694 void GeometryComparisonPlotter::SetPrintOption (const Option_t * print_option) { _print_option = print_option ; }
695 void GeometryComparisonPlotter::SetCanvasSize (const int window_width,
696  const int window_height) { _window_width = window_width ;
697  _window_height = window_height ; }
700  + TString(name.EndsWith("/") ? "" : "/") ; }
701 
702 // PRIVATE METHODS
704 {
705  word.ToLower();
706  if (word.BeginsWith("d")) word.ReplaceAll("d", "#Delta");
707  if (word == TString("rdphi")) word = "r#Delta#phi"; // TO DO: find something less ad hoc...
708  else if (word.EndsWith("phi")) word.ReplaceAll("phi", "#phi");
709  else if (word.EndsWith("alpha")) word.ReplaceAll("alpha", "#alpha");
710  else if (word.EndsWith("beta")) word.ReplaceAll("beta" , "#beta");
711  else if (word.EndsWith("gamma")) word.ReplaceAll("gamma", "#gamma");
712  else if (word.EndsWith("eta")) word.ReplaceAll("eta", "#eta");
713  return word;
714 }
715 
717 {
718  if (print_option.Contains("pdf" )) return TString(".pdf" );
719  else if (print_option.Contains("eps" )) return TString(".eps" );
720  else if (print_option.Contains("ps" )) return TString(".ps" );
721  else if (print_option.Contains("svg" )) return TString(".svg" );
722  else if (print_option.Contains("tex" )) return TString(".tex" );
723  else if (print_option.Contains("gif" )) return TString(".gif" );
724  else if (print_option.Contains("xpm" )) return TString(".xpm" );
725  else if (print_option.Contains("png" )) return TString(".png" );
726  else if (print_option.Contains("jpg" )) return TString(".jpg" );
727  else if (print_option.Contains("tiff")) return TString(".tiff");
728  else if (print_option.Contains("cxx" )) return TString(".cxx" );
729  else if (print_option.Contains("xml" )) return TString(".xml" );
730  else if (print_option.Contains("root")) return TString(".root");
731  else
732  {
733  cout << __FILE__ << ":" << __LINE__ << ":Warning: unknown format. Returning .pdf, but possibly wrong..." << endl;
734  return TString(".pdf");
735  }
736 }
737 
739  double y1,
740  double x2,
741  double y2,
742  const TString title)
743 {
744  TLegend * legend = new TLegend (x1, y1, x2, y2, title.Data(), "NBNDC");
745  legend->SetNColumns(NB_SUBLEVELS);
746  legend->SetFillColor(0);
747  legend->SetLineColor(0); // redundant with option
748  legend->SetLineWidth(0); // redundant with option
749  for (unsigned int isublevel = 0 ; isublevel < NB_SUBLEVELS ; isublevel++)
750  {
751  TGraph * g = new TGraph (0);
752  g->SetMarkerColor(COLOR_CODE(isublevel));
753  g->SetFillColor(COLOR_CODE(isublevel));
754  g->SetMarkerStyle(kFullSquare);
755  g->SetMarkerSize(10);
756  legend->AddEntry(g,_sublevel_names[isublevel], "p");
757  }
758  return legend;
759 }
#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)
GeometryComparisonPlotter(TString tree_file_name, TString outputDirname="output/", TString modulesToPlot="all", TString referenceName="Ideal", TString alignmentName="Alignment", TString plotOnlyGlobal="false")
#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="")
void SetOutputDirectoryName(const TString)
void SetPrintOption(const Option_t *)
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_SUBLEVELS
graphs
Definition: cuy.py:960
#define DEFAULT_WINDOW_HEIGHT
#define COLOR_CODE(icolor)
void SetBranchMin(const TString, const float)
#define INSIDE_VECTOR(vector)
#define NB_MODULE_QUALITY