CMS 3D CMS Logo

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