Jpp  15.0.0
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 "TEllipse.h"
#include "TLine.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 54 of file JPlot2D.cc.

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