Jpp
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
JGizmoToolkit.hh
Go to the documentation of this file.
1 #ifndef __JGIZMOTOOLKIT__
2 #define __JGIZMOTOOLKIT__
3 
4 #include <string>
5 #include <map>
6 #include <cmath>
7 
8 #include "TError.h"
9 #include "TFile.h"
10 #include "TClass.h"
11 #include "TObject.h"
12 #include "TKey.h"
13 #include "TH1.h"
14 #include "TH2.h"
15 #include "TGraph.h"
16 #include "TGraph2D.h"
17 #include "TString.h"
18 #include "TRegexp.h"
19 #include "TFormula.h"
20 #include "TIterator.h"
21 #include "TMethod.h"
22 #include "TMethodCall.h"
23 #include "TAxis.h"
24 #include "TMath.h"
25 
26 #include "JLang/JException.hh"
27 #include "JGizmo/JRootObjectID.hh"
28 
30 
31 
32 /**
33  * \author mdejong
34  */
35 
36 namespace JGIZMO {}
37 namespace JPP { using namespace JGIZMO; }
38 
39 /**
40  * Auxiliary applications for use of ROOT and more.
41  */
42 namespace JGIZMO {
43 
44  using JLANG::JParseError;
47 
48 
49  /**
50  * Auxiliary data structure for JOpera1D.cc and JOpera2D.cc applications.
51  */
52  struct JOpera {
53  //
54  // Histogram name.
55  //
56  static const char* const SAME_AS_OPERATION() { return "%"; } //!< Set name of output histogram to name of operation
57  static const char* const SAME_AS_INPUT() { return "="; } //!< Set name of output histogram to name of input histogram
58 
59  //
60  // Histogram operations.
61  //
62  static const char* const Add() { return "Add"; } //!< ROOT TH1::Add
63  static const char* const add() { return "add"; } //!< Add contents with lookup bin in second histogram
64  static const char* const Subtract() { return "Subtract"; } //!< ROOT TH1::Subtract
65  static const char* const subtract() { return "subtract"; } //!< Subtract contents with lookup bin in second histogram
66  static const char* const Multiply() { return "Multiply"; } //!< ROOT TH1::Multiply
67  static const char* const multiply() { return "multiply"; } //!< Multiply contents with lookup bin in second histogram
68  static const char* const Divide() { return "Divide"; } //!< ROOT TH1::Divide
69  static const char* const divide() { return "divide"; } //!< Divide contents with lookup bin in second histogram
70  static const char* const efficiency() { return "efficiency"; } //!< Divide contents and multiply errors with inefficiency
71  static const char* const stdev() { return "stdev"; } //!< Set contents to standard deviation
72  static const char* const sqrt() { return "sqrt"; } //!< Set contents to signed difference between squares
73  };
74 
75 
76  /**
77  * Time stamp of earliest UTC time.
78  */
79  static const char* const TIMESTAMP = "#splitline{}{#splitline{%d:%m:%y}{ %H:%M}}%F1970-01-01 00:00:00";
80 
81  /**
82  * Get TFile pointer.\n
83  * The TFile pointer of an already opened file is recovered, else a new file is opened.
84  *
85  * \param file_name file name
86  * \param option TFile::Open option
87  * \return pointer to TFile
88  */
89  inline TFile* getFile(const std::string& file_name, const std::string& option = "exist")
90  {
91  using namespace std;
92 
93  gErrorIgnoreLevel = kError;
94 
95  static map<string, TFile*> zmap;
96 
97  map<string, TFile*>::iterator i = zmap.find(file_name);
98 
99  if (i == zmap.end() || i->second == NULL || !i->second->IsOpen()) {
100 
101  TFile* file = TFile::Open(file_name.c_str(), option.c_str());
102 
103  zmap[file_name] = file;
104 
105  return file;
106 
107  } else {
108 
109  return i->second;
110  }
111  }
112 
113 
114  /**
115  * Get TDirectory pointer.\n
116  * The TFile pointer of an already opened file is recovered, else a new file is opened.
117  *
118  * \param id identifier
119  * \return pointer to TDirectory
120  */
121  inline TDirectory* getDirectory(const JRootObjectID& id)
122  {
123  TFile* in = getFile(id.getFilename().c_str(), "exist");
124 
125  if (in == NULL || !in->IsOpen()) {
126  return NULL;
127  }
128 
129  if (id.getDirectory() != "")
130  return in->GetDirectory(id.getDirectory());
131  else
132  return in;
133  }
134 
135 
136  /**
137  * Get TObject.
138  *
139  * \param id identifier
140  * \return pointer to TObject (or NULL)
141  */
142  inline TObject* getObject(const JRootObjectID& id)
143  {
144  TDirectory* dir = getDirectory(id);
145 
146  if (dir != NULL) {
147 
148  const TRegexp regexp(id.getObjectName());
149 
150  TIter iter(dir->GetListOfKeys());
151 
152  for (TKey* key; (key = (TKey*) iter.Next()) != NULL; ) {
153 
154  const TString tag(key->GetName());
155 
156  // option match
157 
158  if (tag.Index(regexp) != -1) {
159  return key->ReadObj();
160  }
161  }
162  }
163 
164  return NULL;
165  }
166 
167 
168  /**
169  * Get drawing option of TH1.
170  *
171  * \param object pointer to TObject
172  * \return true if TH1 looks a line; else false
173  */
174  inline bool isTAttLine(const TObject* object)
175  {
176  const TH1* h1 = dynamic_cast<const TH1*>(object);
177 
178  if (h1 != NULL) {
179 
180  if (h1->GetSumw2N()) {
181 
182  for (Int_t i = 1; i <= h1->GetNbinsX(); ++i) {
183 
184  if (h1->GetBinError(i) != 0.0) {
185  return false;
186  }
187  }
188  }
189 
190  return true;
191 
192  } else {
193 
194  return false;
195  }
196  }
197 
198 
199  /**
200  * Get result of given textual formula.\n
201  * The formula may contain names of member methods of the object pointed to.
202  * These methods should have no arguments and the return type <tt>Double_t</tt>.
203  * Example:
204  * <pre>
205  * getResult("1.0/GetEntries", TH1*);
206  * </pre>
207  *
208  * \param text text
209  * \param object pointer to object
210  * \return value
211  */
212  inline Double_t getResult(const TString& text, TObject* object = NULL)
213  {
214  TString buffer(text);
215 
216  if (object != NULL) {
217 
218  TClass* p = TClass::GetClass(object->ClassName());
219 
220  if (p != NULL) {
221 
222  TIterator* iter = p->GetListOfAllPublicMethods()->MakeIterator();
223 
224  for (TMethod* method; (method = (TMethod*) iter->Next()) != NULL; ) {
225 
226  for (Ssiz_t index; (index = buffer.Index(method->GetName())) != -1; ) {
227 
228  const TRegexp fp("([^)]*)"); // function call
229 
230  Ssiz_t len;
231  Ssiz_t pos = buffer.Index(fp, &len, index);
232 
233  Double_t value;
234 
235  if (pos == -1) {
236 
237  TMethodCall(p, method->GetName(), NULL).Execute(object, value);
238 
239  len = strlen(method->GetName());
240 
241  } else if (pos == index + (Ssiz_t) strlen(method->GetName())) {
242 
243  TMethodCall(p, method->GetName(), NULL).Execute(object, TString(buffer(pos + 1, len - 2)), value);
244 
245  len += strlen(method->GetName());
246 
247  } else {
248 
249  continue;
250  }
251 
252  buffer.Replace(index, len, TString::Format("%f", value));
253  }
254  }
255  }
256  }
257 
258  return TFormula("/tmp", buffer.Data()).Eval(0.0);
259  }
260 
261 
262  /**
263  * Get result of given textual formula.\n
264  * The formula may contain names of member methods of the object pointed to.
265  * These methods should have no arguments and the return type <tt>Double_t</tt>.
266  * Example:
267  * <pre>
268  * getResult("1.0/GetEntries", TH1*);
269  * </pre>
270  *
271  * \param text text
272  * \param object pointer to object
273  * \return value
274  */
275  inline Double_t getResult(const std::string& text, TObject* object = NULL)
276  {
277  return getResult(TString(text.c_str()), object);
278  }
279 
280 
281  /**
282  * Get parameter number from text string.\n
283  * The number corresponds to the value <tt>[0-9]*</tt> in the expression <tt>"p[0-9]* = .."</tt>.
284  *
285  * \param text text
286  * \return parameter number
287  */
288  inline int getParameter(const std::string& text)
289  {
290  const char* regexp("p[0-9]* *=");
291 
292  TString buffer(text.c_str());
293 
294  buffer = buffer(TRegexp(regexp));
295  buffer = buffer(1, buffer.Length() - 2);
296 
297  if (!buffer.IsDigit()) {
298  THROW(JParseError, "Text is not a number " << text << ' ' << regexp);
299  }
300 
301  return buffer.Atoi();
302  }
303 
304 
305  /**
306  * Get parameter value from text string.\n
307  * The formula may contain names of member methods of the object pointed to.
308  * These methods should have no arguments and the return type <tt>Double_t</tt>.
309  * Example:
310  * <pre>
311  * getValue("p[..] = 2*GetMaximum", TH1*);
312  * </pre>
313  *
314  * \param text text
315  * \param object pointer to object
316  * \return value
317  */
318  inline Double_t getValue(const std::string& text, TObject* object = NULL)
319  {
320  const char* regexp("=.*");
321 
322  TString buffer(text.c_str());
323 
324  buffer = buffer(TRegexp(regexp));
325  buffer = buffer(1, buffer.Length() - 1);
326 
327  return getResult(std::string(buffer), object);
328  }
329 
330 
331  /**
332  * Make axis logarithmic (e.g. after filling with log10()).
333  *
334  * \param axis axis
335  */
336  inline void setLogarithm(TAxis* axis)
337  {
338  if (axis != NULL) {
339 
340  const int N = axis->GetNbins();
341  Double_t buffer[N+1];
342 
343  buffer[0] = TMath::Power(10.0, axis->GetBinLowEdge(1));
344 
345  for (int i = 1; i <= N; ++i) {
346  buffer[i] = TMath::Power(10.0, axis->GetBinLowEdge(i) + axis->GetBinWidth(i));
347  }
348 
349  axis->Set(N, buffer);
350  }
351  }
352 
353 
354  /**
355  * Convert 1D histogram to PDF.
356  *
357  * Possible options are:
358  * - N normalise to histogram contents;
359  * - W divide by bin width;
360  * - E convert also bin errors.
361  *
362  * \param h1 histogram
363  * \param option option
364  * \param factor scaling factor
365  */
366  inline void convertToPDF(TH1& h1, const std::string& option = "NW", const double factor = 1.0)
367  {
368  using namespace std;
369 
370  const bool normalise = (option.find('N') != string::npos || option.find('n') != string::npos);
371  const bool bin_width = (option.find('W') != string::npos || option.find('w') != string::npos);
372  const bool use_error = (option.find('E') != string::npos || option.find('e') != string::npos);
373 
374  Double_t W = 1.0;
375 
376  if (normalise) {
377 
378  W = 0.0;
379 
380  for (Int_t i = 1; i <= h1.GetXaxis()->GetNbins(); ++i) {
381  W += h1.GetBinContent(i);
382  }
383  }
384 
385  if (W != 0.0) {
386 
387  for (Int_t i = 1; i <= h1.GetXaxis()->GetNbins(); ++i) {
388 
389  const Double_t w = W * (bin_width ? h1.GetXaxis()->GetBinWidth(i) : 1.0);
390 
391  h1.SetBinContent(i, h1.GetBinContent(i) * factor / w);
392 
393  if (use_error) {
394  h1.SetBinError(i, h1.GetBinError(i) * factor / w);
395  }
396  }
397  }
398  }
399 
400 
401  /**
402  * Convert 2D histogram to PDF.
403  *
404  * Possible options are:
405  * - N normalise to histogram contents;
406  * - X convert x-axis to PDF;
407  * - Y convert y-axis to PDF;
408  * - W divide by bin width;
409  * - E convert also bin errors.
410  *
411  * \param h2 histogram
412  * \param option option
413  * \param factor scaling factor
414  */
415  inline void convertToPDF(TH2& h2, const std::string& option = "NXYW", const double factor = 1.0)
416  {
417  using namespace std;
418 
419  const bool normalise = (option.find('N') != string::npos || option.find('n') != string::npos);
420  const bool X = (option.find('X') != string::npos || option.find('x') != string::npos);
421  const bool Y = (option.find('Y') != string::npos || option.find('y') != string::npos);
422  const bool bin_width = (option.find('W') != string::npos || option.find('w') != string::npos);
423  const bool use_error = (option.find('E') != string::npos || option.find('e') != string::npos);
424 
425  Double_t W = 1.0;
426 
427  if (X && Y) {
428 
429  if (normalise) {
430 
431  W = 0.0;
432 
433  for (Int_t i = 1; i <= h2.GetXaxis()->GetNbins(); ++i) {
434  for (Int_t j = 1; j <= h2.GetYaxis()->GetNbins(); ++j) {
435  W += h2.GetBinContent(i,j);
436  }
437  }
438  }
439 
440  if (W != 0.0) {
441 
442  for (Int_t i = 1; i <= h2.GetXaxis()->GetNbins(); ++i) {
443  for (Int_t j = 1; j <= h2.GetYaxis()->GetNbins(); ++j) {
444 
445  const Double_t w = W * (bin_width ? h2.GetXaxis()->GetBinWidth(i) * h2.GetYaxis()->GetBinWidth(j) : 1.0);
446 
447  h2.SetBinContent(i, j, h2.GetBinContent(i,j) * factor / w);
448 
449  if (use_error) {
450  h2.SetBinError(i, j, h2.GetBinError(i,j) * factor / w);
451  }
452  }
453  }
454  }
455 
456  } else if (X) {
457 
458  for (Int_t j = 1; j <= h2.GetYaxis()->GetNbins(); ++j) {
459 
460  if (normalise) {
461 
462  W = 0.0;
463 
464  for (Int_t i = 1; i <= h2.GetXaxis()->GetNbins(); ++i) {
465  W += h2.GetBinContent(i,j);
466  }
467  }
468 
469  if (W != 0.0) {
470 
471  for (Int_t i = 1; i <= h2.GetXaxis()->GetNbins(); ++i) {
472 
473  const Double_t w = W * (bin_width ? h2.GetXaxis()->GetBinWidth(i) : 1.0);
474 
475  h2.SetBinContent(i, j, h2.GetBinContent(i,j) * factor / w);
476 
477  if (use_error) {
478  h2.SetBinError(i, j, h2.GetBinError(i,j) * factor / w);
479  }
480  }
481  }
482  }
483 
484  } else if (Y) {
485 
486  for (Int_t i = 1; i <= h2.GetXaxis()->GetNbins(); ++i) {
487 
488  if (normalise) {
489 
490  W = 0.0;
491 
492  for (Int_t j = 1; j <= h2.GetYaxis()->GetNbins(); ++j) {
493  W += h2.GetBinContent(i,j);
494  }
495  }
496 
497  if (W != 0.0) {
498 
499  for (Int_t j = 1; j <= h2.GetYaxis()->GetNbins(); ++j) {
500 
501  const Double_t w = W * (bin_width ? h2.GetYaxis()->GetBinWidth(j) : 1.0);
502 
503  h2.SetBinContent(i, j, h2.GetBinContent(i,j) / w);
504 
505  if (use_error) {
506  h2.SetBinError(i, j, h2.GetBinError(i,j) / w);
507  }
508  }
509  }
510  }
511  }
512  }
513 
514 
515  /**
516  * Set limits of TGraph.
517  *
518  * \param g1 graph
519  */
520  inline void setLimits(TGraph& g1)
521  {
522  using namespace std;
523 
524  Double_t ymin = +numeric_limits<Double_t>::max();
525  Double_t ymax = -numeric_limits<Double_t>::max();
526 
527  for (Int_t i = 0; i != g1.GetN(); ++i) {
528 
529  const Double_t y = g1.GetY()[i];
530 
531  if (y > ymax) { ymax = y; }
532  if (y < ymin) { ymin = y; }
533  }
534 
535  g1.SetMinimum(ymin);
536  g1.SetMaximum(ymax);
537  }
538 
539 
540  /**
541  * Set limits of TGraph2D.
542  *
543  * \param g2 graph
544  */
545  inline void setLimits(TGraph2D& g2)
546  {
547  using namespace std;
548 
549  Double_t zmin = +numeric_limits<Double_t>::max();
550  Double_t zmax = -numeric_limits<Double_t>::max();
551 
552  for (Int_t i = 0; i != g2.GetN(); ++i) {
553 
554  const Double_t z = g2.GetZ()[i];
555 
556  if (z > zmax) { zmax = z; }
557  if (z < zmin) { zmin = z; }
558  }
559 
560  g2.SetMinimum(zmin);
561  g2.SetMaximum(zmax);
562  }
563 
564 
565  /**
566  * Set axis range.
567  *
568  * \param xmin lower limit (I/O)
569  * \param xmax upper limit (I/O)
570  * \param logx logarithmic
571  */
572  inline void setRange(double& xmin,
573  double& xmax,
574  const bool logx)
575  {
576  if (logx) {
577  xmin = log(xmin);
578  xmax = log(xmax);
579  }
580 
581  double dx = (xmax - xmin) * 0.1;
582 
583  if (xmin > dx || xmin < 0.0)
584  xmin -= dx;
585  else
586  xmin = 0.0;
587 
588  xmax += dx;
589 
590  if (logx) {
591  xmin = exp(xmin);
592  xmax = exp(xmax);
593  }
594  }
595 
596 
597  /**
598  * initialize axis with PMT address labels
599  *
600  * \param axis axis
601  * \param memo default module address map
602  */
603  inline void setAxisLabels(TAxis *axis, const JModuleAddressMap& memo)
604  {
605  using namespace JPP;
606 
607  if (axis->GetNbins() == (int) memo.size()) {
608 
609  for (int i = 0; i < axis->GetNbins(); i++) {
610 
611  const JPMTPhysicalAddress& pmtAddress = memo[i];
612 
613  axis->SetBinLabel(i + 1, TString(pmtAddress.toString()));
614  }
615 
616  } else {
617 
618  THROW(JValueOutOfRange, "Number of bins " << axis->GetNbins() << " != " << memo.size());
619  }
620  }
621 }
622 
623 #endif
static const char *const sqrt()
Set contents to signed difference between squares.
data_type w[N+1][M+1]
Definition: JPolint.hh:708
Exceptions.
TObject * getObject(const JRootObjectID &id)
Get TObject.
double getValue(const JScale_t scale)
Get numerical value corresponding to scale.
Definition: JScale.hh:47
int getParameter(const std::string &text)
Get parameter number from text string.
static const char *const Divide()
ROOT TH1::Divide.
static const char *const Subtract()
ROOT TH1::Subtract.
static const char *const SAME_AS_INPUT()
Set name of output histogram to name of input histogram.
char text[TEXT_SIZE]
Definition: elog.cc:72
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
Definition: JException.hh:670
esac print_variable DETECTOR INPUT_FILE OUTPUT_FILE CDF for TYPE in
Definition: JSirene.sh:45
Definition: JRoot.hh:19
void setLimits(TGraph &g1)
Set limits of TGraph.
static const char *const subtract()
Subtract contents with lookup bin in second histogram.
then for HISTOGRAM in h0 h1
Definition: JMatrixNZ.sh:69
Auxiliary class to handle file name, ROOT directory and object name.
static const char *const stdev()
Set contents to standard deviation.
void setLogarithm(TAxis *axis)
Make axis logarithmic (e.g.
bool isTAttLine(const TObject *object)
Get drawing option of TH1.
static const char *const efficiency()
Divide contents and multiply errors with inefficiency.
static const char *const Add()
ROOT TH1::Add.
Lookup table for PMT addresses in optical module.
static const char *const multiply()
Multiply contents with lookup bin in second histogram.
TFile * getFile(const std::string &file_name, const std::string &option="exist")
Get TFile pointer.
static const char *const add()
Add contents with lookup bin in second histogram.
Auxiliary data structure for JOpera1D.cc and JOpera2D.cc applications.
Double_t getResult(const TString &text, TObject *object=NULL)
Get result of given textual formula.
void convertToPDF(TH1 &h1, const std::string &option="NW", const double factor=1.0)
Convert 1D histogram to PDF.
void setAxisLabels(TAxis *axis, const JModuleAddressMap &memo)
initialize axis with PMT address labels
static const char *const Multiply()
ROOT TH1::Multiply.
static const char *const SAME_AS_OPERATION()
Set name of output histogram to name of operation.
void setRange(double &xmin, double &xmax, const bool logx)
Set axis range.
static const char *const divide()
Divide contents with lookup bin in second histogram.
Exception for parsing value.
Definition: JException.hh:180
TDirectory * getDirectory(const JRootObjectID &id)
Get TDirectory pointer.
std::string getFilename(const std::string &file_name)
Get file name part, i.e. part after last JEEP::PATHNAME_SEPARATOR if any.
Definition: JeepToolkit.hh:88
int j
Definition: JPolint.hh:634
Exception for accessing a value in a collection that is outside of its range.
Definition: JException.hh:162
static const char *const TIMESTAMP
Time stamp of earliest UTC time.
then usage $script[input file[working directory[option]]] nWhere option can be N
Definition: JMuonPostfit.sh:37
then set_variable FORMULA *[0] exp(-0.5 *(x-[1])*(x-[1])/([2]*[2]))" set_variable OUTPUT_FILE histogram.root JHistogram1D -o $WORKDIR/$OUTPUT_FILE -F "$FORMULA" -
Double_t g1(const Double_t x)
Function.
Definition: JQuantiles.cc:25