Jpp master_rocky-44-g75b7c4f75
the software that should make you happy
Loading...
Searching...
No Matches
JRootToolkit.hh
Go to the documentation of this file.
1#ifndef __JROOT__JROOTTOOLKIT__
2#define __JROOT__JROOTTOOLKIT__
3
4#include <string>
5#include <istream>
6#include <ostream>
7#include <limits>
8#include <cctype>
9#include <vector>
10
11#pragma GCC diagnostic push
12#pragma GCC diagnostic ignored "-Wall"
13#include "TString.h"
14#include "TObjString.h"
15#include "TRegexp.h"
16#include "TPRegexp.h"
17#include "TFormula.h"
18#include "TFile.h"
19#include "TStreamerInfo.h"
20#include "TList.h"
21#include "TIterator.h"
22#include "TF1.h"
23#include "TH1.h"
24#include "TH2.h"
25#include "TH3.h"
26#include "TGraph.h"
27#include "TGraphErrors.h"
28#include "TGraphAsymmErrors.h"
29#include "TGraph2D.h"
30#include "TGraph2DErrors.h"
31#include "TMultiGraph.h"
32#include "TNtuple.h"
33#pragma GCC diagnostic pop
34
35#include "JLang/JType.hh"
36#include "JLang/JLangToolkit.hh"
37
38#include "Jeep/JPrint.hh"
39
40#include "JROOT/JRootFile.hh"
42#include "JROOT/JRootPrinter.hh"
43
44/**
45 * \author mdejong, mlincett
46 */
47
48namespace JROOT {}
49namespace JPP { using namespace JROOT; }
50
51namespace JROOT {
52
53 using JLANG::JType;
54
55
56 /**
57 * Get ROOT name of given data type.
58 *
59 * \return name of object to be read
60 */
61 template<class T>
62 inline const char* getName()
63 {
64 return getName(JType<T>());
65 }
66
67
68 /**
69 * Get ROOT name of given data type.
70 *
71 * \param type data type
72 * \return name of object to be read
73 */
74 template<class T>
75 inline const char* getName(const JType<T>& type)
76 {
77 return T::Class_Name();
78 }
79
80
81 /**
82 * Reset TH3 object.
83 *
84 * \param h3 pointer to TH3 object
85 * \param reset reset contents if true
86 */
87 inline void resetObject(TH3* h3, const bool reset = false)
88 {
89 if (h3 != NULL) {
90
91 for (int ix = 1; ix <= h3->GetXaxis()->GetNbins(); ++ix) {
92 for (int iy = 1; iy <= h3->GetYaxis()->GetNbins(); ++iy) {
93 for (int iz = 1; iz <= h3->GetZaxis()->GetNbins(); ++iz) {
94
95 h3->SetBinError(ix, iy, iz, 0.0);
96
97 if (reset) {
98 h3->SetBinContent(ix, iy, iz, 0.0);
99 }
100 }
101 }
102 }
103 }
104 }
105
106
107 /**
108 * Reset TH2 object.
109 *
110 * \param h2 pointer to TH2 object
111 * \param reset reset contents if true
112 */
113 inline void resetObject(TH2* h2, const bool reset = false)
114 {
115 if (h2 != NULL) {
116
117 for (int ix = 1; ix <= h2->GetXaxis()->GetNbins(); ++ix) {
118 for (int iy = 1; iy <= h2->GetYaxis()->GetNbins(); ++iy) {
119
120 h2->SetBinError(ix, iy, 0.0);
121
122 if (reset) {
123 h2->SetBinContent(ix, iy, 0.0);
124 }
125 }
126 }
127 }
128 }
129
130
131 /**
132 * Reset TH1 object.
133 *
134 * \param h1 pointer to TH1 object
135 * \param reset reset contents if true
136 */
137 inline void resetObject(TH1* h1, const bool reset = false)
138 {
139#define RESET_OBJECT(T, P, O) if (dynamic_cast<T*>(P) != NULL) { resetObject(dynamic_cast<T*>(P), O); return; }
140
141 if (h1 != NULL) {
142
143 if (reset) {
144
145 h1->Reset();
146
147 } else {
148
149 RESET_OBJECT(TH3, h1, reset);
150 RESET_OBJECT(TH2, h1, reset);
151
152 for (int ix = 1; ix <= h1->GetXaxis()->GetNbins(); ++ix) {
153
154 h1->SetBinError(ix, 0.0);
155
156 if (reset) {
157 h1->SetBinContent(ix, 0.0);
158 }
159 }
160 }
161 }
162
163#undef RESET_OBJECT
164 }
165
166
167 /**
168 * Reset TGraph object.
169 *
170 * \param g1 pointer to TGraph object
171 * \param reset reset contents if true
172 */
173 inline void resetObject(TGraph* g1, const bool reset = false)
174 {
175 if (g1 != NULL) {
176
177 for (int i = 0; i != g1->GetN(); ++i) {
178
179 if (reset) {
180 g1->SetPoint(i, g1->GetX()[i], 0.0);
181 }
182 }
183 }
184 }
185
186
187 /**
188 * Reset TGraphErrors object.
189 *
190 * \param g1 pointer to TGraphErrors object
191 * \param reset reset contents if true
192 */
193 inline void resetObject(TGraphErrors* g1, const bool reset = false)
194 {
195 if (g1 != NULL) {
196
197 for (int i = 0; i != g1->GetN(); ++i) {
198
199 g1->SetPointError(i, 0.0, 0.0);
200
201 if (reset) {
202 g1->SetPoint(i, g1->GetX()[i], 0.0);
203 }
204 }
205 }
206 }
207
208
209 /**
210 * Reset TGraphAsymmErrors object.
211 *
212 * \param g1 pointer to TGraphErrors object
213 * \param reset reset contents if true
214 */
215 inline void resetObject(TGraphAsymmErrors* g1, const bool reset = false)
216 {
217 if (g1 != NULL) {
218
219 for (int i = 0; i != g1->GetN(); ++i) {
220
221 g1->SetPointError(i, 0.0, 0.0, 0.0, 0.0);
222
223 if (reset) {
224 g1->SetPoint(i, g1->GetX()[i], 0.0);
225 }
226 }
227 }
228 }
229
230
231 /**
232 * Reset TGraph2D object.
233 *
234 * \param g2 pointer to TGraph2D object
235 * \param reset reset contents if true
236 */
237 inline void resetObject(TGraph2D* g2, const bool reset = false)
238 {
239 if (g2 != NULL) {
240
241 for (int i = 0; i != g2->GetN(); ++i) {
242
243 if (reset) {
244 g2->SetPoint(i, g2->GetX()[i], g2->GetY()[i], 0.0);
245 }
246 }
247 }
248 }
249
250
251 /**
252 * Reset TGraph2DErrors object.
253 *
254 * \param g2 pointer to TGraph2DErrors object
255 * \param reset reset contents if true
256 */
257 inline void resetObject(TGraph2DErrors* g2, const bool reset = false)
258 {
259 if (g2 != NULL) {
260
261 for (int i = 0; i != g2->GetN(); ++i) {
262
263 g2->SetPointError(i, 0.0, 0.0, 0.0);
264
265 if (reset) {
266 g2->SetPoint(i, g2->GetX()[i], g2->GetY()[i], 0.0);
267 }
268 }
269 }
270 }
271
272
273 /**
274 * Reset TMultiGraph object.
275 *
276 * \param gs pointer to TMultiGraph object
277 * \param reset reset contents if true
278 */
279 inline void resetObject(TMultiGraph* gs, const bool reset = false)
280 {
281#define RESET_OBJECT(T, P, O) if (dynamic_cast<T*>(P) != NULL) { resetObject(dynamic_cast<T*>(P), O); continue; }
282
283 if (gs != NULL) {
284
285 for (TIter next(gs->GetListOfGraphs()); TGraph* graph = (TGraph*) next(); ) {
286 RESET_OBJECT(TGraphAsymmErrors, graph, reset);
287 RESET_OBJECT(TGraphErrors, graph, reset);
288 RESET_OBJECT(TGraph, graph, reset);
289 }
290 }
291
292#undef RESET_OBJECT
293 }
294
295
296 /**
297 * Add point to TGraph.
298 *
299 * \param g1 pointer to valid ROOT TGraph object
300 * \param x x value
301 * \param y y value
302 */
303 inline void AddPoint(TGraph* g1,
304 const Double_t x,
305 const Double_t y)
306 {
307 const Int_t n = g1->GetN();
308
309 g1->Set(n + 1);
310 g1->SetPoint(n, x, y);
311 }
312
313
314 /**
315 * Add point to TGraphErrors.
316 *
317 * \param g1 pointer to valid ROOT TGraph object
318 * \param x x value
319 * \param y y value
320 * \param ex x error
321 * \param ey y error
322 */
323 inline void AddPoint(TGraphErrors* g1,
324 const Double_t x,
325 const Double_t y,
326 const Double_t ex,
327 const Double_t ey)
328 {
329 const Int_t n = g1->GetN();
330
331 g1->Set(n + 1);
332 g1->SetPoint(n, x, y);
333 g1->SetPointError(n, ex, ey);
334 }
335
336
337 /**
338 * Add point to TGraphAsymmErrors.
339 *
340 * \param g1 pointer to valid ROOT TGraph object
341 * \param x x value
342 * \param y y value
343 * \param exl x error low
344 * \param exh x error high
345 * \param eyl y error low
346 * \param eyh y error high
347 */
348 inline void AddPoint(TGraphAsymmErrors* g1,
349 const Double_t x,
350 const Double_t y,
351 const Double_t exl,
352 const Double_t exh,
353 const Double_t eyl,
354 const Double_t eyh)
355 {
356 const Int_t n = g1->GetN();
357
358 g1->Set(n + 1);
359 g1->SetPoint(n, x, y);
360 g1->SetPointError(n, exl, exh, eyl, eyh);
361 }
362
363
364 /**
365 * Add point to TGraph2D.
366 *
367 * \param g1 pointer to valid ROOT TGraph object
368 * \param x x value
369 * \param y y value
370 * \param z z value
371 */
372 inline void AddPoint(TGraph2D* g1,
373 const Double_t x,
374 const Double_t y,
375 const Double_t z)
376 {
377 const Int_t n = g1->GetN();
378
379 g1->Set(n + 1);
380 g1->SetPoint(n, x, y, z);
381 }
382
383
384 /**
385 * Add point to TGraph2DErrors.
386 *
387 * \param g1 pointer to valid ROOT TGraph object
388 * \param x x value
389 * \param y y value
390 * \param z z value
391 * \param ex x error
392 * \param ey y error
393 * \param ez z error
394 */
395 inline void AddPoint(TGraph2DErrors* g1,
396 const Double_t x,
397 const Double_t y,
398 const Double_t z,
399 const Double_t ex,
400 const Double_t ey,
401 const Double_t ez)
402 {
403 const Int_t n = g1->GetN();
404
405 g1->Set(n + 1);
406 g1->SetPoint(n, x, y, z);
407 g1->SetPointError(n, ex, ey, ez);
408 }
409
410
411 /**
412 * Write object to ROOT file.
413 *
414 * \param file ROOT file
415 * \param object ROOT object
416 * \return ROOT file
417 */
418 inline TFile& operator<<(TFile& file, const TObject& object)
419 {
420 file.WriteTObject(&object);
421
422 return file;
423 }
424
425
426 /**
427 * Get ROOT streamer information of class with given name.
428 * Note that the class name should include the name space, if any.
429 *
430 * \param file pointer to ROOT file
431 * \param name class name
432 * \return pointer to TStreamerInfo (NULL in case of error)
433 */
434 inline const TStreamerInfo* getStreamerInfo(TFile* file, const char* const name)
435 {
436 if (file != NULL && file->IsOpen()) {
437
438 const TString buffer(name);
439
440 TIter iter(file->GetStreamerInfoList());
441
442 for (const TStreamerInfo* pStreamerInfo; (pStreamerInfo = (TStreamerInfo*) iter.Next()) != NULL; ) {
443 if (buffer == TString(pStreamerInfo->GetName())) {
444 return pStreamerInfo;
445 }
446 }
447 }
448
449 return NULL;
450 }
451
452
453 /**
454 * Get ROOT streamer information of class with given name.
455 * Note that the class name should include the name space, if any.
456 *
457 * \param file_name file name
458 * \param name class name
459 * \return pointer to TStreamerInfo (NULL in case of error)
460 */
461 inline const TStreamerInfo* getStreamerInfo(const char* const file_name, const char* const name)
462 {
463 JRootInputFile file(file_name);
464
465 return getStreamerInfo(file.getFile(), name);
466 }
467
468
469 /**
470 * Get ROOT streamer version of class with given name.
471 * Note that the class name should include the name space, if any.
472 *
473 * \param file pointer to ROOT file
474 * \param name class name
475 * \return streamer version; (-1 in case of error)
476 */
477 inline int getStreamerVersion(TFile* file, const char* const name)
478 {
479 const TStreamerInfo* pStreamerInfo = getStreamerInfo(file, name);
480
481 if (pStreamerInfo != NULL)
482 return pStreamerInfo->GetClassVersion();
483 else
484 return -1;
485 }
486
487
488 /**
489 * Get ROOT streamer version of class with given name.
490 * Note that the class name should include the name space, if any.
491 *
492 * \param file_name file name
493 * \param name class name
494 * \return streamer version; (-1 in case of error)
495 */
496 inline int getStreamerVersion(const char* const file_name, const char* const name)
497 {
498 JRootInputFile file(file_name);
499
500 return getStreamerVersion(file.getFile(), name);
501 }
502
503
504 /**
505 * Match a regular expression with given string and return the specified matched parts.
506 *
507 * If no matches are found corresponding to the specified index, the original string is returned.
508 *
509 * \param regexp regular expression
510 * \param string input string
511 * \param index index of matched parts (starting at 1)
512 * \return matched part of string
513 */
514 inline TString parse(const TPRegexp& regexp, const TString& string, const int index = 1)
515 {
516 TPRegexp buffer = regexp;
517 TObjArray* array = buffer.MatchS(string);
518 TString result = string;
519
520 if (index - 1 < array->GetLast()) {
521 result = ((TObjString*) array->At(index))->GetName();
522 }
523
524 delete array;
525
526 return result;
527 }
528
529
530 /**
531 * Auxiliary data structure for a parameter index and its value.
532 */
534 /**
535 * Default constructor.
536 */
538 index(0),
539 value(0.0)
540 {}
541
542
543 /**
544 * Constructor.
545 *
546 * \param index parameter index
547 * \param value parameter value
548 */
550 const Double_t value) :
551 index(index),
552 value(value)
553 {}
554
555
556 /**
557 * Type conversion operator
558 *
559 *
560 * \return index
561 */
562 inline operator Int_t() const
563 {
564 return index;
565 }
566
567
568 Int_t index;
569 Double_t value;
570 };
571
572
573 /**
574 * Set fit parameter.
575 *
576 * \param f1 fit function
577 * \param parameter parameter index and value
578 */
579 inline bool setParameter(TF1& f1, const JFitParameter_t& parameter)
580 {
581 if (parameter.index >= 0 && parameter.index < f1.GetNpar()) {
582
583 f1.SetParameter(parameter.index, parameter.value);
584
585 return true;
586
587 } else {
588
589 return false;
590 }
591 }
592
593
594 /**
595 * Fix fit parameter.
596 *
597 * \param f1 fit function
598 * \param parameter parameter index and value
599 */
600 inline bool fixParameter(TF1& f1, const JFitParameter_t& parameter)
601 {
602 if (parameter.index >= 0 && parameter.index < f1.GetNpar()) {
603
604 f1.FixParameter(parameter.index, parameter.value);
605
606 return true;
607
608 } else {
609
610 return false;
611 }
612 }
613
614
615 /**
616 * Release fit parameter.
617 *
618 * \param f1 fit function
619 * \param index parameter index
620 */
621 inline bool releaseParameter(TF1& f1, const Int_t index)
622 {
623 if (index >= 0 && index < f1.GetNpar()) {
624
625 f1.ReleaseParameter(index);
626
627 return true;
628
629 } else {
630
631 return false;
632 }
633 }
634
635
636 /**
637 * Set fit parameter limits.
638 *
639 * \param f1 fit function
640 * \param index parameter index
641 * \param xmin lower limit
642 * \param xmax upper limit
643 */
644 inline bool setParLimits(TF1& f1, const Int_t index, Double_t xmin, Double_t xmax)
645 {
646 using namespace std;
647
648 if (index >= 0 && index < f1.GetNpar()) {
649
650 if (xmin == 0.0) { xmin = -numeric_limits<Double_t>::min(); }
651 if (xmax == 0.0) { xmax = +numeric_limits<Double_t>::min(); }
652
653 f1.SetParLimits(index, xmin, xmax);
654
655 return true;
656
657 } else {
658
659 return false;
660 }
661 }
662
663
664 /**
665 * Check if fit parameter is fixed.
666 *
667 * \param f1 fit function
668 * \param index parameter index
669 */
670 inline bool isParameterFixed(const TF1& f1, const Int_t index)
671 {
672 if (index >= 0 && index < f1.GetNpar()) {
673
674 Double_t xmin;
675 Double_t xmax;
676
677 f1.GetParLimits(index, xmin, xmax);
678
679 return (xmin != 0.0 && xmax != 0.0 && xmin >= xmax);
680
681 } else {
682
683 return false;
684 }
685 }
686
687
688 /**
689 * Get result of given textual formula.
690 *
691 * The formula may contain names of data members of the given object.
692 * For example:
693 * <pre>
694 * getResult("a / b.value", object, ..);
695 * </pre>
696 * In this, the corresponding data type should have (at least) data members <tt>a</tt> and <tt>b</tt>
697 * and <tt>b</tt> should have (at least) data member <tt>value</tt>.
698 *
699 * \param text text
700 * \param object object
701 * \param dictionary dictionary
702 * \return value
703 */
704 template<class T>
705 inline Double_t getResult(const TString& text,
706 const T& object,
708 {
709 using namespace std;
710 using namespace JPP;
711
712 const TRegexp DOUBLE("[0-9.][eE][+-0-9]");
713
714 string buffer = (const char*) text;
715
716 for (string::size_type pos = 0; pos != buffer.size(); ) {
717
718 if (isalpha(buffer[pos]) || buffer[pos] == '_') {
719
720 string::size_type len = 1;
721
722 while (pos + len != buffer.size() && (isalnum(buffer[pos+len]) || buffer[pos+len] == '_' || buffer[pos+len] == '.')) {
723 ++len;
724 }
725
726 if (len != 1 || pos == 0 || TString(buffer.substr(pos-1).c_str()).Index(DOUBLE) != 0) {
727
728 ostringstream os;
729
730 os.setf(ios::fixed);
731 os.precision(10);
732
733 JRootPrinter::print(os, object, buffer.substr(pos,len), dictionary);
734
735 buffer.replace(pos, len, os.str());
736
737 pos += os.str().size();
738
739 continue;
740 }
741 }
742
743 pos += 1;
744 }
745
746 return TFormula("/tmp", buffer.c_str()).Eval(0.0);
747 }
748
749
750 /**
751 * Helper method to convert a 1D histogram to a graph.
752 *
753 * The graph consists of:
754 * - bin centers as x values;
755 * - bin contents as y values.
756 *
757 * Note that underflow and overflow bins are ignored.
758 *
759 * \param h1 1D histogram
760 * \return pointer to newly create graph
761 */
762 inline TGraph* histogramToGraph(const TH1& h1)
763 {
764 const int N = h1.GetNbinsX();
765
766 std::vector<double> x(N), y(N);
767
768 for (int i = 0; i < N; i++) {
769 x[i] = h1.GetBinCenter (i + 1);
770 y[i] = h1.GetBinContent(i + 1);
771 }
772
773 return new TGraph(N, &x[0], &y[0]);
774 }
775
776
777 /**
778 * Helper method for ROOT histogram projections.
779 *
780 * \param h2 2D histogram
781 * \param xmin lower limit
782 * \param xmax upper limit
783 * \param projection projection (x|X|y|Y)
784 * \return pointer to newly created 1D histogram
785 */
786 inline TH1* projectHistogram(const TH2& h2, const Double_t xmin, const Double_t xmax, const char projection)
787 {
788 switch (projection) {
789
790 case 'x':
791 case 'X':
792 return h2.ProjectionX("_px", h2.GetYaxis()->FindBin(xmin), h2.GetYaxis()->FindBin(xmax));
793
794 case 'y':
795 case 'Y':
796 return h2.ProjectionY("_py", h2.GetXaxis()->FindBin(xmin), h2.GetXaxis()->FindBin(xmax));
797
798 default:
799 return NULL;
800 }
801 }
802}
803
804
805/**
806 * Read regular expression from input stream
807 *
808 * \param in input stream
809 * \param object regular expression
810 * \return output stream
811 */
812inline std::istream& operator>>(std::istream& in, TRegexp& object)
813{
814 std::string buffer;
815
816 if (in >> buffer) {
817 object = TRegexp(buffer.c_str());
818 }
819
820 return in;
821}
822
823
824/**
825 * Write regular expression to output stream
826 *
827 * \param out output stream
828 * \param object regular expression
829 * \return output stream
830 */
831inline std::ostream& operator<<(std::ostream& out, const TRegexp& object)
832{
833 return out;
834}
835
836
837/**
838 * Read formula from input stream.
839 *
840 * \param in input stream
841 * \param object formula
842 * \return input stream
843 */
844inline std::istream& operator>>(std::istream& in, TFormula& object)
845{
846 std::string buffer;
847
848 if (getline(in,buffer)) {
849 object = TFormula("", buffer.c_str());
850 }
851
852 return in;
853}
854
855
856/**
857 * Write formula to output stream.
858 *
859 * \param out output stream
860 * \param object formula
861 * \return output stream
862 */
863inline std::ostream& operator<<(std::ostream& out, const TFormula& object)
864{
865 return out << object.GetExpFormula();
866}
867
868#endif
869
I/O formatting auxiliaries.
Double_t g1(const Double_t x)
Function.
Definition JQuantiles.cc:25
Print objects in ASCII format using ROOT dictionary.
std::istream & operator>>(std::istream &in, TRegexp &object)
Read regular expression from input stream.
#define RESET_OBJECT(T, P, O)
std::ostream & operator<<(std::ostream &out, const TRegexp &object)
Write regular expression to output stream.
TFile * getFile() const
Get file.
Definition JRootFile.hh:66
ROOT input file.
Definition JRootFile.hh:97
char text[TEXT_SIZE]
Definition elog.cc:72
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Auxiliary classes and methods for ROOT I/O.
Double_t getResult(const TString &text, const T &object, const JRootDictionary_t &dictionary=JRootDictionary::getInstance())
Get result of given textual formula.
const TStreamerInfo * getStreamerInfo(TFile *file, const char *const name)
Get ROOT streamer information of class with given name.
bool fixParameter(TF1 &f1, const JFitParameter_t &parameter)
Fix fit parameter.
TGraph * histogramToGraph(const TH1 &h1)
Helper method to convert a 1D histogram to a graph.
TFile & operator<<(TFile &file, const TObject &object)
Write object to ROOT file.
void AddPoint(TGraph *g1, const Double_t x, const Double_t y)
Add point to TGraph.
int getStreamerVersion(TFile *file, const char *const name)
Get ROOT streamer version of class with given name.
void resetObject(JManager< JKey_t, JValue_t > *object, const bool reset=false)
Reset JManager object.
Definition JManager.hh:394
TH1 * projectHistogram(const TH2 &h2, const Double_t xmin, const Double_t xmax, const char projection)
Helper method for ROOT histogram projections.
bool setParameter(TF1 &f1, const JFitParameter_t &parameter)
Set fit parameter.
bool isParameterFixed(const TF1 &f1, const Int_t index)
Check if fit parameter is fixed.
bool releaseParameter(TF1 &f1, const Int_t index)
Release fit parameter.
TString parse(const TPRegexp &regexp, const TString &string, const int index=1)
Match a regular expression with given string and return the specified matched parts.
bool setParLimits(TF1 &f1, const Int_t index, Double_t xmin, Double_t xmax)
Set fit parameter limits.
const char * getName()
Get ROOT name of given data type.
static data_type & getInstance()
Get unique instance of template class.
Definition JSingleton.hh:27
Auxiliary class for a type holder.
Definition JType.hh:19
Auxiliary data structure for a parameter index and its value.
JFitParameter_t(const Int_t index, const Double_t value)
Constructor.
JFitParameter_t()
Default constructor.
Type definition of ROOT based dictionary for ASCII I/O.
static void print(JRootWriter &writer, const JRootWritableClass &cls)
Write class contents to output.