Jpp - the software that should make you happy
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Functions
JPlot2D.cc File Reference

General purpose plot program for 2D ROOT objects. More...

#include <string>
#include <iostream>
#include <vector>
#include <set>
#include <cmath>
#include "TROOT.h"
#include "TFile.h"
#include "TClass.h"
#include "TApplication.h"
#include "TCanvas.h"
#include "TKey.h"
#include "TStyle.h"
#include "TAttMarker.h"
#include "TAttLine.h"
#include "TH2.h"
#include "TH3.h"
#include "TH2D.h"
#include "TGraph.h"
#include "TGraph2D.h"
#include "TGraph2DErrors.h"
#include "TF2.h"
#include "TString.h"
#include "TRegexp.h"
#include "TText.h"
#include "JTools/JRange.hh"
#include "JLang/JSinglePointer.hh"
#include "JROOT/JStyle.hh"
#include "JROOT/JCanvas.hh"
#include "JROOT/JMarkerAttributes.hh"
#include "JGizmo/JRootObjectID.hh"
#include "JGizmo/JRootObject.hh"
#include "JGizmo/JGizmoToolkit.hh"
#include "Jeep/JParser.hh"
#include "Jeep/JMessage.hh"

Go to the source code of this file.

Functions

int main (int argc, char **argv)
 

Detailed Description

General purpose plot program for 2D ROOT objects.

The option -f corresponds to <file name>:<object name>.

Author
mdejong

Definition in file JPlot2D.cc.

Function Documentation

int main ( int  argc,
char **  argv 
)

Definition at line 52 of file JPlot2D.cc.

53 {
54  using namespace std;
55  using namespace JPP;
56 
57  typedef JRange<double> JRange_t;
58  typedef pair<string, int> division_type;
59 
60  vector<JRootObjectID> inputFile;
61  string outputFile;
62  JCanvas canvas;
63  int stats;
64  JRange_t X;
65  JRange_t Y;
66  JRange_t Z;
67  JCounter logx;
68  JCounter logy;
69  bool logz;
70  string project;
71  string xLabel;
72  string yLabel;
73  string zLabel;
74  double markerSize;
75  string option;
76  set<char> grid;
77  bool batch;
78  string title;
79  vector<division_type> Ndivisions;
80  int palette;
81  int debug;
82 
83  try {
84 
85  JParser<> zap("General purpose plot program for 2D ROOT objects.");
86 
87  zap['f'] = make_field(inputFile, "<input file>:<object name>");
88  zap['o'] = make_field(outputFile, "graphics output") = "";
89  zap['w'] = make_field(canvas, "size of canvas <nx>x<ny> [pixels]") = JCanvas(500, 500);
90  zap['s'] = make_field(stats) = -1;
91  zap['x'] = make_field(X, "x-abscissa range") = JRange_t();
92  zap['y'] = make_field(Y, "y-abscissa range") = JRange_t();
93  zap['z'] = make_field(Z, "ordinate range") = JRange_t();
94  zap['X'] = make_field(logx, "logarithmic x-axis (-XX log10 axis)");
95  zap['Y'] = make_field(logy, "logarithmic y-axis (-YY log10 axis)");
96  zap['Z'] = make_field(logz, "logarithmic z-axis");
97  zap['P'] = make_field(project, "projection") = "", "xy", "yx", "xz", "zx", "yz", "zy";
98  zap['>'] = make_field(xLabel, "x-axis label") = "";
99  zap['<'] = make_field(yLabel, "y-axis label") = "";
100  zap['^'] = make_field(zLabel, "z-axis label") = "";
101  zap['S'] = make_field(markerSize, "marker size") = 1.0;
102  zap['O'] = make_field(option, "plotting option") = "";
103  zap['G'] = make_field(grid, "grid lines [X][Y]") = JPARSER::initialised();
104  zap['B'] = make_field(batch, "batch processing");
105  zap['T'] = make_field(title, "title") = "KM3NeT preliminary";
106  zap['N'] = make_field(Ndivisions, "axis divisioning (e.g. \"X 505\")") = JPARSER::initialised();
107  zap['p'] = make_field(palette, "palette") = -1;
108  zap['d'] = make_field(debug) = 0;
109 
110  zap(argc, argv);
111  }
112  catch(const exception &error) {
113  FATAL(error.what() << endl);
114  }
115 
116 
117  gROOT->SetBatch(batch);
118 
119  TApplication* tp = new TApplication("user", NULL, NULL);
120  TCanvas* cv = new TCanvas("c1", "c1", canvas.x, canvas.y);
121 
122  JSinglePointer<TStyle> gStyle(new JStyle("gplot", cv->GetWw(), cv->GetWh()));
123 
124  if (palette != -1) {
125  gStyle->SetPalette(palette);
126  }
127 
128  gROOT->SetStyle("gplot");
129  gROOT->ForceStyle();
130 
131 
132  cv->SetFillStyle(4000);
133  cv->SetFillColor(kWhite);
134  cv->Divide(1,1);
135  cv->cd(1);
136 
137  JMarkerAttributes::getInstance().setMarkerSize(markerSize);
138 
139  Double_t xmin = numeric_limits<double>::max();
140  Double_t xmax = numeric_limits<double>::lowest();
141  Double_t ymin = numeric_limits<double>::max();
142  Double_t ymax = numeric_limits<double>::lowest();
143  Double_t zmin = numeric_limits<double>::max();
144  Double_t zmax = numeric_limits<double>::lowest();
145 
146  vector<JRootObject> listOfObjects;
147 
148  TH2* master = NULL;
149 
150  for (vector<JRootObjectID>::const_iterator input = inputFile.begin(); input != inputFile.end(); ++input) {
151 
152  DEBUG("Input: " << *input << endl);
153 
154  TDirectory* dir = getDirectory(*input);
155 
156  if (dir == NULL) {
157  ERROR("File: " << input->getFullFilename() << " not opened." << endl);
158  continue;
159  }
160 
161  const TRegexp regexp(input->getObjectName());
162 
163  TIter iter(dir->GetListOfKeys());
164 
165  for (TKey* key; (key = (TKey*) iter.Next()) != NULL; ) {
166 
167  const TString tag(key->GetName());
168 
169  DEBUG("Key: " << tag << " match = " << tag.Contains(regexp) << endl);
170 
171  // option match
172 
173  if (tag.Contains(regexp)) {
174 
175  if (title == JName_t) {
176  title = key->GetName();
177  } else if (title == JTitle_t) {
178  title = key->GetTitle();
179  }
180 
181  JRootObject object(key->ReadObj());
182 
183  try {
184 
185  TH3& h3 = dynamic_cast<TH3&>(*object);
186 
187  object = h3.Project3D(project.c_str());
188  }
189  catch(exception&) {}
190 
191  try {
192 
193  TH2& h2 = dynamic_cast<TH2&>(*object);
194 
195  h2.SetStats(stats != -1);
196 
197  xmin = min(xmin, h2.GetXaxis()->GetXmin());
198  xmax = max(xmax, h2.GetXaxis()->GetXmax());
199  ymin = min(ymin, h2.GetYaxis()->GetXmin());
200  ymax = max(ymax, h2.GetYaxis()->GetXmax());
201  zmin = min(zmin, logz ? h2.GetMinimum(0.0) : h2.GetMinimum());
202  zmax = max(zmax, h2.GetMaximum());
203  }
204  catch(exception&) {}
205 
206  try {
207 
208  TGraph& g1 = dynamic_cast<TGraph&>(*object);
209 
210  for (Int_t i = 0; i != g1.GetN(); ++i) {
211  xmin = min(xmin, g1.GetX()[i] - numeric_limits<float>::epsilon());
212  xmax = max(xmax, g1.GetX()[i] + numeric_limits<float>::epsilon());
213  ymin = min(ymin, g1.GetY()[i] - numeric_limits<float>::epsilon());
214  ymax = max(ymax, g1.GetY()[i] + numeric_limits<float>::epsilon());
215  }
216 
217  int ng = 0;
218 
219  for (vector<JRootObject>::iterator i = listOfObjects.begin(); i != listOfObjects.end(); ++i) {
220  if (dynamic_cast<TGraph*>(i->get()) != NULL) {
221  ++ng;
222  }
223  }
224 
225  static_cast<TAttMarker&>(g1) = JMarkerAttributes::getInstance().get(ng);
226  }
227  catch(exception&) {}
228 
229  try {
230 
231  TGraph2D& g2 = dynamic_cast<TGraph2D&>(*object);
232 
233  for (Int_t i = 0; i != g2.GetN(); ++i) {
234  if (!logz || g2.GetZ()[i] > 0.0) {
235  xmin = min(xmin, g2.GetX()[i]);
236  xmax = max(xmax, g2.GetX()[i]);
237  ymin = min(ymin, g2.GetY()[i]);
238  ymax = max(ymax, g2.GetY()[i]);
239  zmin = min(zmin, g2.GetZ()[i]);
240  zmax = max(zmax, g2.GetZ()[i]);
241  }
242  }
243 
244  if (Z != JRange_t()) {
245  g2.SetMinimum(Z.getLowerLimit());
246  g2.SetMaximum(Z.getUpperLimit());
247  }
248  }
249  catch(exception&) {}
250 
251  try {
252 
253  TF2& f2 = dynamic_cast<TF2&>(*object);
254 
255  f2.SetLineColor(kRed);
256  f2.SetTitle((title + ";" + xLabel + ";" + yLabel + ";" + zLabel).c_str());
257 
258  double __xmin;
259  double __xmax;
260  double __ymin;
261  double __ymax;
262 
263  f2.GetRange(__xmin, __ymin, __xmax, __ymax);
264 
265  xmin = min(xmin, __xmin);
266  xmax = max(xmax, __xmax);
267  ymin = min(ymin, __ymin);
268  ymax = max(ymax, __ymax);
269  zmin = min(zmin, f2.GetMinimum());
270  zmax = max(zmax, f2.GetMaximum());
271  }
272  catch(exception&) {}
273 
274  for (TString buffer[] = { object.getLabel(), input->getFilename().c_str(), "" }, *i = buffer; *i != ""; ++i) {
275 
276  *i = (*i)(TRegexp("\\[.*\\]"));
277 
278  if ((*i).Length() > 2) {
279  object.setLabel((*i)(1, (*i).Length() - 2));
280  }
281  }
282 
283  if (dynamic_cast<TH2*> (object.get()) != NULL ||
284  dynamic_cast<TGraph*> (object.get()) != NULL ||
285  dynamic_cast<TGraph2D*>(object.get()) != NULL ||
286  dynamic_cast<TF2*> (object.get()) != NULL) {
287 
288  DEBUG("Add object: " << tag << " with label " << object.getLabel() << endl);
289 
290  if (master == NULL) {
291  master = dynamic_cast<TH2*>(object.get());
292  }
293 
294  listOfObjects.push_back(object);
295 
296  } else {
297  ERROR("For other objects than 2D histograms, use JPlot1D" << endl);
298  }
299  }
300  }
301  }
302 
303  if (listOfObjects.empty()) {
304  ERROR("Nothing to draw." << endl);
305  }
306 
307  // plot frame
308 
309  cv->cd(1);
310 
311  if (option.find("COLZ") != string::npos ||
312  option.find("colz") != string::npos) {
313  gPad->SetRightMargin(0.20);
314  }
315 
316  if (X != JRange_t()) {
317  xmin = X.getLowerLimit();
318  xmax = X.getUpperLimit();
319  }
320 
321  if (Y != JRange_t()) {
322  ymin = Y.getLowerLimit();
323  ymax = Y.getUpperLimit();
324  }
325 
326  if (Z != JRange_t()) {
327  zmin = Z.getLowerLimit();
328  zmax = Z.getUpperLimit();
329  } else {
330  setRange(zmin, zmax, logz);
331  }
332 
333  if (master == NULL) {
334 
335  if (X != JRange_t() &&
336  Y != JRange_t()) {
337 
338  master = new TH2D("__H__", NULL,
339  100, X.getLowerLimit(), X.getUpperLimit(),
340  100, Y.getLowerLimit(), Y.getUpperLimit());
341 
342  master->SetStats(kFALSE);
343 
344  } else if (xmin < xmax && ymin < ymax) {
345 
346  master = new TH2D("__H__", NULL,
347  100, xmin, xmax,
348  100, ymin, ymax);
349 
350  master->SetStats(kFALSE);
351 
352  } else {
353 
354  TText* p = new TText(0.5, 0.5, MAKE_CSTRING("No data"));
355 
356  p->SetTextAlign(21);
357  p->SetTextAngle(45);
358  p->Draw();
359  }
360  }
361 
362  if (master != NULL) {
363 
364  if (logx) { gPad->SetLogx(); }
365  if (logy) { gPad->SetLogy(); }
366  if (logz) { gPad->SetLogz(); }
367 
368  master->GetXaxis()->SetRangeUser(xmin, xmax);
369  master->GetYaxis()->SetRangeUser(ymin, ymax);
370 
371  if (logx > 1) { setLogarithmicX(master); }
372  if (logy > 1) { setLogarithmicY(master); }
373 
374  master->SetTitle(title.c_str());
375 
376  master->SetMinimum(zmin);
377  master->SetMaximum(zmax);
378 
379  if (xLabel != "") { master->GetXaxis()->SetTitle(xLabel.c_str()); master->GetXaxis()->CenterTitle(true); }
380  if (yLabel != "") { master->GetYaxis()->SetTitle(yLabel.c_str()); master->GetYaxis()->CenterTitle(true); }
381  if (zLabel != "") { master->GetZaxis()->SetTitle(zLabel.c_str()); master->GetZaxis()->CenterTitle(true); }
382 
383  master->GetXaxis()->SetMoreLogLabels((logx == 1 && log10(xmax/xmin) < 2) ||
384  (logx > 1 && xmax-xmin < 2));
385  master->GetYaxis()->SetMoreLogLabels((logy == 1 && log10(ymax/ymin) < 2) ||
386  (logy > 1 && ymax-ymin < 2));
387 
388  for (vector<division_type>::const_iterator i = Ndivisions.begin(); i != Ndivisions.end(); ++i) {
389  master->SetNdivisions(i->second, i->first.c_str());
390  }
391 
392  DEBUG("Draw " << master->GetName() << ' ' << option << endl);
393 
394  master->Draw(option.c_str());
395  }
396 
397  if (logx > 1 || logy > 1) {
398  for (vector<JRootObject>::iterator i = listOfObjects.begin(); i != listOfObjects.end(); ++i) {
399  if (dynamic_cast<TH2*>(i->get()) != master) {
400  if (logx > 1) {
401  setLogarithmicX(dynamic_cast<TH2*> (i->get()));
402  setLogarithmicX(dynamic_cast<TGraph2D*>(i->get()));
403  setLogarithmicX(dynamic_cast<TF2*> (i->get()));
404  }
405  if (logy > 1) {
406  setLogarithmicY(dynamic_cast<TH2*> (i->get()));
407  setLogarithmicY(dynamic_cast<TGraph2D*>(i->get()));
408  setLogarithmicY(dynamic_cast<TF2*> (i->get()));
409  }
410  }
411  }
412  }
413 
414  if (grid.count('x') || grid.count('X')) { gPad->SetGridx(); }
415  if (grid.count('y') || grid.count('Y')) { gPad->SetGridy(); }
416 
417  if (stats != -1)
418  gStyle->SetOptStat(stats);
419  else
420  gStyle->SetOptFit(kFALSE);
421 
422  for (vector<JRootObject>::iterator i = listOfObjects.begin(); i != listOfObjects.end(); ++i) {
423 
424  DEBUG("Draw " << (*i)->GetName() << ' ' << (*i)->GetTitle() << endl);
425 
426  string buffer(option);
427 
428  buffer += "SAME";
429 
430  try {
431 
432  TH2& h2 = dynamic_cast<TH2&>(*(*i));
433 
434  h2.SetMinimum(zmin);
435  h2.SetMaximum(zmax);
436  }
437  catch(exception&) {}
438 
439  try {
440 
441  TGraph& g1 = dynamic_cast<TGraph&>(*(*i));
442 
443  buffer = "P";
444  }
445  catch(exception&) {}
446 
447  try {
448 
449  TGraph2D& g2 = dynamic_cast<TGraph2D&>(*(*i));
450 
451  g2.SetMinimum(zmin);
452  g2.SetMaximum(zmax);
453  }
454  catch(exception&) {}
455 
456  try {
457 
458  TF2& f2 = dynamic_cast<TF2&>(*(*i));
459 
460  f2.SetNpx(1000);
461  f2.SetNpy(1000);
462  /*
463  f2.SetRange(xmin, ymin, zmin,
464  xmax, ymax, zmax);
465  */
466  }
467  catch(exception&) {}
468 
469  (*i)->Draw(buffer.c_str());
470  }
471 
472  gPad->RedrawAxis();
473 
474  cv->Update();
475 
476  if (outputFile != "") {
477  cv->SaveAs(outputFile.c_str());
478  }
479 
480  if (!batch) {
481  tp->Run();
482  }
483 
484  return (master != NULL ? 0 : 1);
485 }
Utility class to parse command line options.
Definition: JParser.hh:1500
void setLogarithmicX(TF1 *f1)
Make parameter x of function logarithmic (e.g. after filling with log10()).
std::string getLabel(const JLocation &location)
Get module label for monitoring and other applications.
Definition: JLocation.hh:246
then echo Test string reversed by master(hit< return > to continue)." JProcess -c "JEcho" -rC fi if (( 1 ))
#define MAKE_CSTRING(A)
Make C-string.
Definition: JPrint.hh:151
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
Definition: JParser.hh:66
then fatal Wrong number of arguments fi set_variable STRING $argv[1] set_variable DETECTORXY_TXT $WORKDIR $DETECTORXY_TXT tail read X Y CHI2 RMS printf optimum n $X $Y $CHI2 $RMS awk v Y
string outputFile
T & getInstance(const T &object)
Get static instance from temporary object.
Definition: JObject.hh:75
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition: JParser.hh:1961
#define ERROR(A)
Definition: JMessage.hh:66
then break fi done getCenter read X Y Z let X
int debug
debug level
Definition: JSirene.cc:63
#define FATAL(A)
Definition: JMessage.hh:67
void setRange(double &xmin, double &xmax, const bool logx)
Set axis range.
Auxiliary class to handle multiple boolean-like I/O.
Definition: JParser.hh:221
TDirectory * getDirectory(const JRootObjectID &id)
Get TDirectory pointer.
void setLogarithmicY(TF2 *f2)
Make parameter y of function logarithmic (e.g. after filling with log10()).
#define DEBUG(A)
Message macros.
Definition: JMessage.hh:62
Double_t g1(const Double_t x)
Function.
Definition: JQuantiles.cc:25