Jpp 19.3.0-rc.1
the software that should make you happy
Loading...
Searching...
No Matches
JPlot1D.cc
Go to the documentation of this file.
1#include <string>
2#include <iostream>
3#include <iomanip>
4#include <vector>
5#include <set>
6#include <cmath>
7#include <memory>
8
9#include "TROOT.h"
10#include "TFile.h"
11#include "TClass.h"
12#include "TApplication.h"
13#include "TCanvas.h"
14#include "TRootCanvas.h"
15#include "TKey.h"
16#include "TStyle.h"
17#include "TAttMarker.h"
18#include "TAttLine.h"
19#include "TH1.h"
20#include "TH2.h"
21#include "TH3.h"
22#include "TF1.h"
23#include "TF2.h"
24#include "THStack.h"
25#include "TGraph.h"
26#include "TGraphErrors.h"
27#include "TGraphAsymmErrors.h"
28#include "TMultiGraph.h"
29#include "TProfile.h"
30#include "TEllipse.h"
31#include "TMarker.h"
32#include "TLine.h"
33#include "TLegend.h"
34#include "TString.h"
35#include "TRegexp.h"
36#include "TText.h"
37
38#include "JTools/JRange.hh"
39#include "JROOT/JStyle.hh"
40#include "JROOT/JCanvas.hh"
43#include "JROOT/JLegend.hh"
45#include "JGizmo/JRootObject.hh"
47
48#include "Jeep/JProperties.hh"
49#include "Jeep/JPrint.hh"
50#include "Jeep/JParser.hh"
51#include "Jeep/JMessage.hh"
52
53namespace {
54
55 using JLANG::JEquals;
56 using JLANG::JType;
57
58
59 template<class JTypelist_t>
60 struct setLog {
61 /**
62 * Constructor.
63 *
64 * \param object pointer to object
65 * \param option option
66 */
67 setLog(TObject* object, const char option) :
68 object(object),
69 option(option),
70 status(false)
71 {
72 using namespace JPP;
73
74 for_each<JTypelist_t>(*this);
75 }
76
77 /**
78 * Apply operation correponding option to object given type.
79 *
80 * \param type type
81 */
82 template<class T>
83 void operator()(const JType<T>& type)
84 {
85 using namespace JPP;
86
87 if (!status) {
88
89 T* p = dynamic_cast<T*>(object);
90
91 if (p != NULL) {
92
93 if (option == 'x' || option == 'X') { setLogarithmicX(p); }
94 if (option == 'y' || option == 'Y') { setLogarithmicY(p); }
95
96 status = true;
97 }
98 }
99 }
100
101 private:
102 TObject* object;
103 const char option;
104 bool status;
105 };
106
107 /**
108 * Auxiliary data structure for legend options.
109 */
110 struct JLegend :
111 public JEquals<JLegend>
112 {
113 /**
114 * Default constructor.
115 */
116 JLegend() :
117 location(),
118 factor (0.0)
119 {}
120
121 /**
122 * Constructor.
123 *
124 * \param location location
125 * \param factor factor
126 */
127 JLegend(const std::string& location,
128 const Double_t factor = 1.0) :
129 location(location),
130 factor (factor)
131 {}
132
133 /**
134 * Check validity.
135 *
136 * \return true if valid; else false
137 */
138 bool is_valid() const
139 {
140 return (location != "" && factor != 0.0);
141 }
142
143 /**
144 * Chek equality.
145 *
146 * \param legend legend
147 * \return input stream
148 */
149 bool equals(const JLegend& legend) const
150 {
151 return (this->location == legend.location);
152 }
153
154 /**
155 * Read legend from input stream.
156 *
157 * \param in input stream
158 * \param legend legend
159 * \return input stream
160 */
161 friend inline std::istream& operator>>(std::istream& in, JLegend& legend)
162 {
163 in >> legend.location;
164
165 if (!(in >> legend.factor)) {
166
167 legend.factor = 1.0;
168
169 in.clear();
170 }
171
172 return in;
173 }
174
175 /**
176 * Write legend to output stream.
177 *
178 * \param out output stream
179 * \param legend legend
180 * \return output stream
181 */
182 friend inline std::ostream& operator<<(std::ostream& out, const JLegend& legend)
183 {
184 return out << legend.location << ' ' << legend.factor;
185 }
186
187 std::string location;
188 Double_t factor;
189 };
190
191
192 /**
193 * Get width of string.
194 *
195 * \param buffer string
196 * \return width
197 */
198 inline Ssiz_t getWidth(const TString& buffer)
199 {
200 double w = 0.0;
201
202 for (Ssiz_t i = 0; i != buffer.Length(); ++i) {
203
204 if (buffer(i) == ' ')
205 w += 0.5;
206 else if (buffer(i) >= 'A' && buffer(i) <= 'Z')
207 w += 1.0;
208 else if (buffer(i) >= 'a' && buffer(i) <= 'z')
209 w += 0.7;
210 else if (buffer(i) >= '0' && buffer(i) <= '9')
211 w += 0.7;
212 else if (buffer(i) == '.' || buffer(i) == ':' || buffer(i) == ';' || buffer(i) == ',' || buffer(i) == '\'')
213 w += 0.5;
214 else
215 w += 0.0;
216 }
217
218 return (Ssiz_t) w;
219 }
220
221
222 const std::string MASTER = "__H__"; //!< Name of prototype
223
224 const char* const JName_t = "?"; //!< Draw histogram name as title of plot
225 const char* const JTitle_t = "%"; //!< Draw histogram title as title of plot
226}
227
228
229/**
230 * \file
231 * General purpose plot program for 1D ROOT objects.
232 * The option <tt>-f</tt> corresponds to <tt><file name>:<object name></tt>.
233 * \author mdejong
234 */
235int main(int argc, char **argv)
236{
237 using namespace std;
238 using namespace JPP;
239
240 typedef JRange<double> JRange_t;
241
242 vector<JRootObjectID> inputFile;
243 string outputFile;
244 JCanvas canvas;
245 JStyle::JParameters parameters;
246 int stats;
247 JLegend legend;
248 JRange_t X;
249 JRange_t Y;
250 JRange_t Z;
251 JCounter logx;
252 JCounter logy;
253 bool logz;
254 char project;
255 string xLabel;
256 string yLabel;
257 JCounter drawLine;
258 int fillArea;
259 int lineWidth;
260 double markerSize;
261 string option;
262 set<char> grid;
263 bool batch;
264 string title;
265 map<string, int> Ndivisions;
266 size_t group;
267 int debug;
268 string xTimeFormat;
269
270 try {
271
272 JProperties properties = parameters.getProperties();
273
274 JParser<> zap("General purpose plot program for 1D ROOT objects.");
275
276 zap['f'] = make_field(inputFile, "<input file>:<object name>");
277 zap['o'] = make_field(outputFile, "graphics output") = "";
278 zap['w'] = make_field(canvas, "size of canvas <nx>x<ny> [pixels]") = JCanvas(500, 500);
279 zap['@'] = make_field(properties) = JPARSER::initialised();
280 zap['s'] = make_field(stats) = -1;
281 zap['L'] = make_field(legend, "position legend e.g. TR [factor]") = JLegend(), JLegend("TL"), JLegend("TR"), JLegend("BR"), JLegend("BL");
282 zap['x'] = make_field(X, "abscissa range") = JRange_t::DEFAULT_RANGE();
283 zap['y'] = make_field(Y, "ordinate range") = JRange_t::DEFAULT_RANGE();
284 zap['z'] = make_field(Z, "ordinate range of projection)") = JRange_t::DEFAULT_RANGE();
285 zap['X'] = make_field(logx, "logarithmic x-axis (-XX log10 axis)");
286 zap['Y'] = make_field(logy, "logarithmic y-axis (-YY log10 axis)");
287 zap['Z'] = make_field(logz, "logarithmic y-axis; after projection");
288 zap['P'] = make_field(project, "projection") = '\0', 'x', 'X', 'y', 'Y';
289 zap['>'] = make_field(xLabel, "x-axis label") = "";
290 zap['^'] = make_field(yLabel, "y-axis label") = "";
291 zap['C'] = make_field(drawLine, "draw line (-C black-and-white -CC colour)");
292 zap['F'] = make_field(fillArea, "fill area") = 0;
293 zap['l'] = make_field(lineWidth, "line width") = 2;
294 zap['S'] = make_field(markerSize, "marker size") = 1.0;
295 zap['O'] = make_field(option, "plotting option") = "";
296 zap['G'] = make_field(grid, "grid lines [X][Y]") = JPARSER::initialised();
297 zap['B'] = make_field(batch, "batch processing");
298 zap['T'] = make_field(title, "graphics title ("
299 << "\"" << JName_t << "\" -> ROOT name; "
300 << "\"" << JTitle_t << "\" -> ROOT title)") = "KM3NeT preliminary";
301 zap['N'] = make_field(Ndivisions, "axis divisioning (e.g. \"X 505\")") = JPARSER::initialised();
302 zap['g'] = make_field(group, "group colour codes of objects") = 1;
303 zap['t'] = make_field(xTimeFormat, "set time format for x-axis, e.g. \%d\\/\%m\\/\\%y%F1970-01-01 00:00:00") = "";
304 zap['d'] = make_field(debug) = 0;
305
306 zap(argc, argv);
307 }
308 catch(const exception &error) {
309 FATAL(error.what() << endl);
310 }
311
312
313 gROOT->SetBatch(batch);
314
315 TApplication* tp = new TApplication("user", NULL, NULL);
316 TCanvas* cv = new TCanvas("c1", "c1", canvas.x, canvas.y);
317
318 if (!batch) {
319 ((TRootCanvas *) cv->GetCanvasImp())->Connect("CloseWindow()", "TApplication", tp, "Terminate()");
320 }
321
322 unique_ptr<TStyle> gStyle(new JStyle("gplot", cv->GetWw(), cv->GetWh(), parameters));
323
324 if (logy || logz) {
325 gStyle->SetTitleOffset(gStyle->GetTitleOffset() * 1.3, "Y");
326 }
327
328 gROOT->SetStyle("gplot");
329 gROOT->ForceStyle();
330
331 cv->SetFillStyle(4000);
332 cv->SetFillColor(kWhite);
333 cv->Divide(1,1);
334 cv->cd(1);
335
336
337 JMarkerAttributes::getInstance().setMarkerSize(markerSize);
338 JLineAttributes ::getInstance().setLineWidth (lineWidth);
339
340
341 Double_t xmin = numeric_limits<double>::max();
342 Double_t xmax = numeric_limits<double>::lowest();
343
344 Double_t ymin = numeric_limits<double>::max();
345 Double_t ymax = numeric_limits<double>::lowest();
346
347
348 vector<JRootObject> listOfObjects;
349
350 const bool px = (project == 'x' || project == 'X'); // projection on x-axis of (2|3)D histogram
351 const bool py = (project == 'y' || project == 'Y'); // projection on y-axis of (2|3)D histogram
352 const bool pz = (project == 'z' || project == 'Z'); // projection on z-axis of 3D histogram
353
354 if (logz) {
355 logy = logz;
356 }
357
358 if (px) {
359 swap(Y, Z); // Y becomes range in TH2::ProjectionX() and Z becomes y-axis range
360 }
361
362 if (py) {
363 swap(X, Z); // X becomes range in TH2::ProjectionY()
364 swap(Y, X); // Y becomes x-axis range and Z becomes y-axis range
365 }
366
367 TH1* master = NULL;
368
369 for (vector<JRootObjectID>::const_iterator input = inputFile.begin(); input != inputFile.end(); ++input) {
370
371 DEBUG("Input: " << *input << endl);
372
373 TDirectory* dir = getDirectory(*input);
374
375 if (dir == NULL) {
376 ERROR("File: " << input->getFullFilename() << " not opened." << endl);
377 continue;
378 }
379
380 const TRegexp regexp(input->getObjectName());
381
382 TIter iter(dir->GetListOfKeys());
383
384 for (TKey* key; (key = (TKey*) iter.Next()) != NULL; ) {
385
386 const TString tag(key->GetName());
387
388 DEBUG("Key: " << tag << " match = " << tag.Contains(regexp) << endl);
389
390 // option match
391
392 if (tag.Contains(regexp) && isTObject(key)) {
393
394 if (title == JName_t) {
395 title = key->GetName();
396 } else if (title == JTitle_t) {
397 title = key->GetTitle();
398 }
399
400 JRootObject object(key->ReadObj());
401
402 TAttMarker marker = JMarkerAttributes::getInstance().get(0);
403 TAttLine line = JLineAttributes ::getInstance().get(0);
404
405 if (group != 0) {
406 marker.SetMarkerColor(JMarkerAttributes::getInstance().get(listOfObjects.size()/group).GetMarkerColor());
407 }
408
409 if (drawLine == 1)
410 line = JLineAttributes::getInstance().get(listOfObjects.size());
411 else
412 line.SetLineColor(marker.GetMarkerColor());
413
414 // projections
415
416 try {
417
418 TProfile& h1 = dynamic_cast<TProfile&>(*object);
419
420 object = h1.ProjectionX();
421 }
422 catch(exception&) {}
423
424 try {
425
426 TH2& h2 = dynamic_cast<TH2&>(*object);
427
428 if (px) {
429
430 if (Z.is_valid())
431 object = h2.ProjectionX(MAKE_CSTRING(h2.GetName() << "_px" << LABEL_TERMINATOR << listOfObjects.size()),
432 h2.GetYaxis()->FindBin(Z.getLowerLimit()),
433 h2.GetYaxis()->FindBin(Z.getUpperLimit()) - 1);
434 else
435 object = h2.ProjectionX(MAKE_CSTRING(h2.GetName() << "_px" << LABEL_TERMINATOR << listOfObjects.size()),
436 1,
437 h2.GetYaxis()->GetNbins());
438
439 } else if (py) {
440
441 if (Z.is_valid())
442 object = h2.ProjectionY(MAKE_CSTRING(h2.GetName() << "_py" << LABEL_TERMINATOR << listOfObjects.size()),
443 h2.GetXaxis()->FindBin(Z.getLowerLimit()),
444 h2.GetXaxis()->FindBin(Z.getUpperLimit()) - 1);
445 else
446 object = h2.ProjectionY(MAKE_CSTRING(h2.GetName() << "_py" << LABEL_TERMINATOR << listOfObjects.size()),
447 1,
448 h2.GetXaxis()->GetNbins());
449
450 } else {
451
452 ERROR("For 2D histograms, use option option -P for projections or use JPlot2D" << endl);
453
454 continue;
455 }
456 }
457 catch(exception&) {}
458
459 try {
460
461 TH3& h3 = dynamic_cast<TH3&>(*object);
462
463 if (px) {
464
465 object = h3.ProjectionX(MAKE_CSTRING(h3.GetName() << "_px" << LABEL_TERMINATOR << listOfObjects.size()));
466
467 } else if (py) {
468
469 object = h3.ProjectionY(MAKE_CSTRING(h3.GetName() << "_py" << LABEL_TERMINATOR << listOfObjects.size()));
470
471 } else if (pz) {
472
473 object = h3.ProjectionZ(MAKE_CSTRING(h3.GetName() << "_pz" << LABEL_TERMINATOR << listOfObjects.size()));
474
475 } else {
476
477 ERROR("For 3D histograms, use option option -P for projections or use JPlot2D -P <projection>" << endl);
478
479 continue;
480 }
481 }
482 catch(exception&) {}
483
484 // colouring
485
486 try {
487 if (dynamic_cast<TMarker*>(object.get()) == NULL) {
488 dynamic_cast<TAttMarker&>(*object) = marker;
489 }
490 }
491 catch(exception&) {}
492
493 try {
494 if (dynamic_cast<TLine*>(object.get()) == NULL) {
495 dynamic_cast<TAttLine&> (*object) = line;
496 }
497 }
498 catch(exception&) {}
499
500 if (fillArea != 0) {
501
502 try {
503
504 TAttFill& fill = dynamic_cast<TAttFill&>(*object);
505
506 if (!isTAttLine(object) || fillArea < 0) {
507 fill.SetFillColor(marker.GetMarkerColor());
508 fill.SetFillStyle(abs(fillArea));
509 }
510 }
511 catch(exception&) {}
512 }
513
514 // set errors
515
516 if (drawLine) {
517
518 try {
519
520 TH1& h1 = dynamic_cast<TH1&>(*object);
521
522 for (int i = 1; i <= h1.GetNbinsX(); ++i) {
523 h1.SetBinError(i, 0.0);
524 }
525 }
526 catch(exception&) {}
527
528 try {
529
530 TGraphErrors& g1 = dynamic_cast<TGraphErrors&>(*object);
531
532 for (Int_t i = 0; i != g1.GetN(); ++i) {
533 g1.GetEX()[i] = 0.0;
534 g1.GetEY()[i] = 0.0;
535 }
536 }
537 catch(exception&) {}
538 }
539
540 // min-max
541
542 try {
543
544 TH1& h1 = dynamic_cast<TH1&>(*object);
545
546 h1.SetStats(stats != -1);
547
548 xmin = min(xmin, h1.GetXaxis()->GetXmin());
549 xmax = max(xmax, h1.GetXaxis()->GetXmax());
550 ymin = min(ymin, logy ? h1.GetMinimum(0.0) : h1.GetMinimum());
551 ymax = max(ymax, h1.GetMaximum());
552
553 if (!logy && h1.GetListOfFunctions() != NULL) {
554 for (unique_ptr<TIterator> iterator(h1.GetListOfFunctions()->MakeIterator()); TF1* f1 = (TF1*) iterator->Next(); ) {
555 ymin = min(ymin, f1->GetMinimum(h1.GetXaxis()->GetXmin(), h1.GetXaxis()->GetXmax()));
556 ymax = max(ymax, f1->GetMaximum(h1.GetXaxis()->GetXmin(), h1.GetXaxis()->GetXmax()));
557 }
558 }
559 }
560 catch(exception&) {}
561
562 try {
563
564 TGraph& g1 = dynamic_cast<TGraph&>(*object);
565
566 for (Int_t i = 0; i != g1.GetN(); ++i) {
567
568 xmin = min(xmin, g1.GetX()[i]);
569 xmax = max(xmax, g1.GetX()[i]);
570
571 if (!logy || g1.GetY()[i] > 0.0) {
572 ymin = min(ymin, g1.GetY()[i]);
573 ymax = max(ymax, g1.GetY()[i]);
574 }
575 }
576 }
577 catch(exception&) {}
578
579 try {
580
581 TGraphErrors& g1 = dynamic_cast<TGraphErrors&>(*object);
582
583 for (Int_t i = 0; i != g1.GetN(); ++i) {
584 if (!logy || g1.GetY()[i] - g1.GetEY()[i] > 0.0) { ymin = min(ymin, g1.GetY()[i] - g1.GetEY()[i]); }
585 if (!logy || g1.GetY()[i] + g1.GetEY()[i] > 0.0) { ymax = max(ymax, g1.GetY()[i] + g1.GetEY()[i]); }
586 }
587 }
588 catch(exception&) {}
589
590 try {
591
592 TMultiGraph& m1 = dynamic_cast<TMultiGraph&>(*object);
593
594 for (TIter i1(m1.GetListOfGraphs()); TGraph* g1 = dynamic_cast<TGraph*>(i1()); ) {
595
596 for (Int_t i = 0; i != g1->GetN(); ++i) {
597
598 xmin = min(xmin, g1->GetX()[i]);
599 xmax = max(xmax, g1->GetX()[i]);
600
601 if (!logy || g1->GetY()[i] > 0.0) {
602 ymin = min(ymin, g1->GetY()[i]);
603 ymax = max(ymax, g1->GetY()[i]);
604 }
605 }
606 }
607 }
608 catch(exception&) {}
609
610 try {
611
612 TF2& f2 = dynamic_cast<TF2&>(*object);
613 TF1* f1 = NULL;
614
615 TString formula = f2.GetExpFormula();
616 TString _z_ = TString::Format("%f", 0.5 * (Z.getLowerLimit() + Z.getUpperLimit()));
617
618 double __xmin;
619 double __xmax;
620 double __ymin;
621 double __ymax;
622
623 f2.GetRange(__xmin, __ymin, __xmax, __ymax);
624
625 if (px) {
626
627 formula.ReplaceAll("y", _z_);
628
629 f1 = new TF1(MAKE_CSTRING(f2.GetName() << "_px" << LABEL_TERMINATOR << listOfObjects.size()), formula);
630
631 f1->SetRange(__xmin, __xmax);
632
633 } else if (py) {
634
635 formula.ReplaceAll("x", _z_);
636 formula.ReplaceAll("y", "x");
637
638 f1 = new TF1(MAKE_CSTRING(f2.GetName() << "_py" << LABEL_TERMINATOR << listOfObjects.size()), formula);
639
640 f1->SetRange(__ymin, __ymax);
641
642 } else {
643
644 ERROR("For 2D functions, use option option -P for projections or use JPlot2D" << endl);
645
646 continue;
647 }
648
649 DEBUG("TF1: " << f1->GetExpFormula() << endl);
650
651 f1->SetParameters(f2.GetParameters());
652
653 object = f1;
654 }
655 catch(exception&) {}
656
657 try {
658
659 TF1& f1 = dynamic_cast<TF1&>(*object);
660
661 double __xmin;
662 double __xmax;
663
664 f1.GetRange(__xmin, __xmax);
665
666 xmin = min(xmin, __xmin);
667 xmax = max(xmax, __xmax);
668 ymin = min(ymin, f1.GetMinimum());
669 ymax = max(ymax, f1.GetMaximum());
670 }
671 catch(exception&) {}
672
673 try {
674
675 THStack& hs = dynamic_cast<THStack&>(*object);
676
677 NOTICE("THStack" << endl);
678
679 unique_ptr<TIterator> iterator(hs.GetHists()->MakeIterator());
680
681 for (size_t index = 1; TObject* i = iterator->Next(); ++index) {
682
683 TH1& h1 = dynamic_cast<TH1&>(*i);
684
685 NOTICE("TH1[" << index << "] " << h1.GetName() << endl);
686
687 xmin = min(xmin, h1.GetXaxis()->GetXmin());
688 xmax = max(xmax, h1.GetXaxis()->GetXmax());
689
690 ymin = min(ymin, logy ? h1.GetMinimum(0.0) : h1.GetMinimum());
691 ymax = max(ymax, h1.GetMaximum());
692
693 h1.SetLineWidth(1);
694 h1.SetLineColor(kBlack);
695
696 h1.SetFillColor(JMarkerAttributes::getInstance().get(index).GetMarkerColor());
697 }
698 }
699 catch(exception&) {}
700
701 try {
702
703 TLine& h1 = dynamic_cast<TLine&>(*object);
704
705 xmin = min(xmin, h1.GetX1());
706 xmax = max(xmax, h1.GetX2());
707 ymin = min(ymin, h1.GetY1());
708 ymax = max(ymax, h1.GetY2());
709 }
710 catch(exception&) {}
711
712 // label
713
714 for (TString buffer[] = { object.getLabel(), input->getFilename().c_str(), "" }, *i = buffer; *i != ""; ++i) {
715
716 *i = (*i)(TRegexp("\\[.*\\]"));
717
718 if (i->Length() > 2) {
719 object.setLabel((*i)(1, i->Length() - 2));
720 }
721 }
722
723 DEBUG("Add object: " << tag << " with label <" << object.getLabel() << ">" << endl);
724
725 if (master == NULL) {
726 master = dynamic_cast<TH1*>(object.get());
727 }
728
729 listOfObjects.push_back(object);
730 }
731 }
732 }
733
734 if (listOfObjects.empty()) {
735 ERROR("Nothing to draw." << endl);
736 }
737
738 for (vector<JRootObject>::iterator i = listOfObjects.begin(); i != listOfObjects.end(); ++i) {
739
740 // set line attributes of associated functions
741 // for single objects, change colour if same range else change style
742 // for multiple objecs, keep colour and change style
743
744 TH1* h1 = dynamic_cast<TH1*> (i->get());
745 TGraph* g1 = dynamic_cast<TGraph*> (i->get());
746 TMultiGraph* m1 = dynamic_cast<TMultiGraph*>(i->get());
747 TAttLine* ls = dynamic_cast<TAttLine*> (i->get());
748
749 TList list;
750
751 unique_ptr<TIterator> iterator;
752
753 if (h1 != NULL) {
754
755 iterator.reset(h1->GetListOfFunctions()->MakeIterator());
756
757 } else if (g1 != NULL) {
758
759 iterator.reset(g1->GetListOfFunctions()->MakeIterator());
760
761 } else if (m1 != NULL) {
762
763 for (TIter i1(m1->GetListOfGraphs()); TGraph* gi = dynamic_cast<TGraph*>(i1()); ) {
764 for (TIter i2(gi->GetListOfFunctions()); TF1* fi = dynamic_cast<TF1*>(i2()); ) {
765 list.Add(fi);
766 }
767 }
768
769 iterator.reset(list.MakeIterator());
770 }
771
772 if (iterator != NULL) {
773
774 Double_t x1[] = { numeric_limits<Double_t>::max(), numeric_limits<Double_t>::max() };
775 Double_t x2[] = { numeric_limits<Double_t>::lowest(), numeric_limits<Double_t>::lowest() };
776
777 for (int nf = 0, ns = 0, nc = 1; TF1* f1 = (TF1*) iterator->Next(); ++nf) {
778
779 f1->GetRange(x1[1], x2[1]);
780 f1->SetNpx(5000);
781
782 dynamic_cast<TAttLine&>(*f1) = JLineAttributes::getInstance().get(0);
783
784 if (listOfObjects.size() == 1) {
785
786 if (x1[0] == x1[1] &&
787 x2[0] == x2[1])
788 ++nc; // change colour
789 else if (nf != 0)
790 ++ns; // change style
791
792 f1->SetLineStyle(JLineAttributes ::getInstance().get(ns).GetLineStyle());
793 f1->SetLineColor(JMarkerAttributes::getInstance().get(nc).GetMarkerColor());
794
795 } else {
796
797 // keep colour of base object and accordingly modify line style.
798
799 f1->SetLineColor(ls->GetLineColor());
800 f1->SetLineStyle(JLineAttributes::getInstance().get(ns++).GetLineStyle());
801 }
802
803 x1[0] = x1[1];
804 x2[0] = x2[1];
805
806 // set limits
807 /*
808 double __xmin;
809 double __xmax;
810
811 f1->GetRange(__xmin, __xmax);
812
813 ymin = min(ymin, f1->GetMinimum(__xmin, __xmax));
814 ymax = max(ymax, f1->GetMaximum(__xmin, __xmax));
815 */
816 }
817 }
818 }
819
820 // plot frame
821
822 if (X.is_valid()) {
823 xmin = X.getLowerLimit();
824 xmax = X.getUpperLimit();
825 }
826
827 if (Y.is_valid()) {
828 ymin = Y.getLowerLimit();
829 ymax = Y.getUpperLimit();
830 } else if (ymax > ymin) {
831 setRange(ymin, ymax, logy == 1);
832 }
833
834 if (logy > 1) {
835 ymin = pow(10.0, ymin);
836 ymax = pow(10.0, ymax);
837 }
838
839 cv->cd(1);
840
841 if (!listOfObjects.empty()) {
842
843 if (master == NULL) {
844
845 master = new TH1D(MASTER.c_str(), NULL, 1000, xmin, xmax);
846
847 master->SetStats(kFALSE);
848
849 for (Int_t i = 1; i <= master->GetXaxis()->GetNbins(); ++i) {
850 master->SetBinContent(i, ymin);
851 }
852 }
853 }
854
855 if (master == NULL) {
856
857 TText* p = new TText(0.5, 0.5, MAKE_CSTRING("No data"));
858
859 p->SetTextAlign(21);
860 p->SetTextAngle(45);
861 p->Draw();
862
863 } else {
864
865 if (logx) { gPad->SetLogx(); }
866 if (logy) { gPad->SetLogy(); }
867
868 master->SetTitle(title.c_str());
869
870 master->GetXaxis()->SetRangeUser(xmin, xmax);
871
872 if (logx > 1) { setLogarithmicX(master); }
873 if (logx > 2) { master->GetXaxis()->SetNoExponent(); }
874
875 if (logy > 1) { setLogarithmicY(master); }
876 if (logy > 2) { master->GetYaxis()->SetNoExponent(); }
877
878 master->SetMinimum(ymin);
879 master->SetMaximum(ymax);
880
881 if (xLabel != "") { master->GetXaxis()->SetTitle(xLabel.c_str()); master->GetXaxis()->CenterTitle(true); }
882 if (yLabel != "") { master->GetYaxis()->SetTitle(yLabel.c_str()); master->GetYaxis()->CenterTitle(true); }
883
884 master->GetXaxis()->SetMoreLogLabels((logx == 1 && log10(xmax/xmin) < 2) ||
885 (logx > 1 && (xmax-xmin) < 2));
886 master->GetYaxis()->SetMoreLogLabels((logy == 1 && log10(ymax/ymin) < 2) ||
887 (logy > 1 && (ymax-ymin) < 2));
888
889 for (map<string, int>::const_iterator i = Ndivisions.begin(); i != Ndivisions.end(); ++i) {
890 master->SetNdivisions(i->second, i->first.c_str());
891 }
892
893 if (xTimeFormat != "") {
894
895 master->GetXaxis()->SetTimeDisplay(1);
896
897 if (xTimeFormat == "utc") {
898 master->GetXaxis()->SetTimeFormat("#splitline{}{#splitline{%d-%m-%y}{ %H:%M}}");
899 master->GetXaxis()->SetTimeOffset(0.0, "gmt");
900 } else if (xTimeFormat == "UTC") {
901 master->GetXaxis()->SetTimeFormat("%d-%m-%y");
902 master->GetXaxis()->SetTimeOffset(0.0, "gmt");
903 } else {
904 master->GetXaxis()->SetTimeFormat(xTimeFormat.c_str());
905 }
906 }
907
908 master->Draw(option.c_str());
909 }
910
911 {
913
914 for (vector<JRootObject>::iterator i = listOfObjects.begin(); i != listOfObjects.end(); ++i) {
915 if (dynamic_cast<TH1*>(i->get()) != master) {
916 if (logx > 1) { setLog<typelist> X(i->get(), 'X'); }
917 if (logy > 1) { setLog<typelist> Y(i->get(), 'Y'); }
918 }
919 }
920 }
921
922 if (grid.count('x') || grid.count('X')) { gPad->SetGridx(); }
923 if (grid.count('y') || grid.count('Y')) { gPad->SetGridy(); }
924
925 if (stats != -1)
926 gStyle->SetOptStat(stats);
927 else
928 gStyle->SetOptFit(kFALSE);
929
930
931 for (vector<JRootObject>::const_iterator i = listOfObjects.begin(); i != listOfObjects.end(); ++i) {
932
933 DEBUG("Draw " << (*i)->GetName() << ' ' << (*i)->GetTitle() << endl);
934
935 string buffer(option);
936
937 //if (!dynamic_cast<THStack*>(i->get())) {
938 // buffer += "SAMES";
939 //}
940
941 buffer += "SAME";
942
943 TF1* f1 = dynamic_cast<TF1*> (i->get());
944 TGraph* g1 = dynamic_cast<TGraph*> (i->get());
945 TMultiGraph* q1 = dynamic_cast<TMultiGraph*>(i->get());
946
947 if (f1 != NULL) {
948 f1->SetNpx(5000);
949 }
950
951 if (g1 != NULL) {
952 if (g1->GetN() > 1 && drawLine)
953 buffer += "L"; // drawing cut line
954 else if (fillArea == 0 ||
955 (dynamic_cast<TGraphErrors*> (g1) == NULL &&
956 dynamic_cast<TGraphAsymmErrors*>(g1) == NULL))
957 buffer += "P"; // drawing point(s)
958 }
959
960 if (q1 != NULL) {
961
962 for (TIter i1(q1->GetListOfGraphs()); TGraph* gi = dynamic_cast<TGraph*>(i1()); ) {
963
964 string zbuf = buffer;
965
966 if (gi->GetN() > 1 && drawLine)
967 zbuf += "L"; // drawing cut line
968 else
969 zbuf += "P"; // drawing point(s)
970
971 gi->Draw(zbuf.c_str());
972 }
973
974 } else {
975
976 (*i).Draw(buffer.c_str());
977 }
978 }
979
980 //gPad->RedrawAxis();
981
982 if (legend.is_valid()) {
983
984 if (group == 0) {
985 group = listOfObjects.size();
986 }
987
988 Ssiz_t height = listOfObjects.size()/group;
989 Ssiz_t width = 1;
990
991 for (vector<JRootObject>::const_iterator i = listOfObjects.begin(); i != listOfObjects.end(); ++i) {
992 width = max(width, getWidth(i->getLabel()));
993 }
994
995 TLegend* lg = getLegend(width, height, legend.location, legend.factor);
996
997 for (size_t i = 0; i < listOfObjects.size(); i += group) {
998
999 const JRootObject& object = listOfObjects[i];
1000
1001 if (dynamic_cast<TMarker*>(object.get()) == NULL &&
1002 dynamic_cast<TLine*> (object.get()) == NULL &&
1003 dynamic_cast<TText*> (object.get()) == NULL) {
1004 lg->AddEntry(object, " " + object.getLabel(), isTAttLine(object) ? "L" : isTAttFill(object) && fillArea != 0 ? "F" : "P");
1005 }
1006 }
1007
1008 lg->Draw();
1009 }
1010
1011 cv->Update();
1012
1013 if (outputFile != "") {
1014 cv->SaveAs(outputFile.c_str());
1015 }
1016
1017 if (!batch) {
1018 tp->Run();
1019 }
1020
1021 return (master != NULL ? 0 : 1);
1022}
string outputFile
std::istream & operator>>(std::istream &in, JAANET::JHead &header)
Read header from input.
Definition JHead.hh:1832
General purpose messaging.
#define DEBUG(A)
Message macros.
Definition JMessage.hh:62
#define ERROR(A)
Definition JMessage.hh:66
#define NOTICE(A)
Definition JMessage.hh:64
#define FATAL(A)
Definition JMessage.hh:67
int debug
debug level
Definition JSirene.cc:72
Utility class to parse command line options.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition JParser.hh:2142
int main(int argc, char **argv)
Definition JPlot1D.cc:235
I/O formatting auxiliaries.
#define MAKE_CSTRING(A)
Make C-string.
Definition JPrint.hh:72
Utility class to parse parameter values.
Double_t g1(const Double_t x)
Function.
Definition JQuantiles.cc:25
Auxiliary class to define a range between two values.
Utility class to parse parameter values.
Auxiliary data structure for TObject with a user defined label.
Auxiliary class to handle multiple boolean-like I/O.
Definition JParser.hh:423
Utility class to parse command line options.
Definition JParser.hh:1698
Data structure for size of TCanvas.
Definition JCanvas.hh:26
int y
number of pixels in Y
Definition JCanvas.hh:99
int x
number of pixels in X
Definition JCanvas.hh:98
Wrapper class around ROOT TStyle.
Definition JStyle.hh:24
Range of values.
Definition JRange.hh:42
std::ostream & operator<<(std::ostream &stream, const CLBCommonHeader &header)
void setLogarithmicX(TList *list)
Make x-axis of objects in list logarithmic (e.g. after using log10()).
void setLogarithmicY(TList *list)
Make y-axis of objects in list logarithmic (e.g. after using log10()).
bool equals(const JFirst_t &first, const JSecond_t &second, const double precision=std::numeric_limits< double >::min())
Check equality.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
bool is_valid(const json &js)
Check validity of JSon data.
Template definition of auxiliary base class for comparison of data structures.
Definition JEquals.hh:84
Type list.
Definition JTypeList.hh:23
Auxiliary class for a type holder.
Definition JType.hh:19
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
Definition JParser.hh:68
JProperties getProperties()
Get properties of this class.
Definition JStyle.hh:44
Auxiliary data structure to list files in directory.