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