The Gaudi Framework  v32r2 (46d42edc)
HistoUtils.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 # =============================================================================
3 # This module contains set of simple and useful utilities for booking and
4 # manipulations with Gaudi-AIDA histograms, inspired by Thomas' request
5 # @author Vanya BELYAEV ibelyaev@physics.syr.edu
6 # @date 2007-08-03
7 # =============================================================================
8 """
9 This module contains set of simple and useful utilities for booking and
10 manipulations with Gaudi-AIDA histograms, inspired by Thomas' request
11 
12 The module contains following public symbols:
13 
14  - book for booking of various 1D,2D&3D-histograms
15  - bookProf for booking of various 1D&2D-profiles
16  - getAsAIDA for retrieval of histograms/profiles from HTS in AIDA format
17  - getAsROOT for retrieval of histograms/profiles from HTS in ROOT format
18  - fill for smart filling of 1D-histogram (AIDA or ROOT)
19  - aida2root for conversion of AIDA histogram to ROOT
20  - HistoStats for many statistical information
21  - HistoFile class for storing histograms to a file
22  - histoDump for dumping of the histogram in text format (a'la HBOOK)
23  - dumpHisto for dumping of the histogram in text format (a'la HBOOK)
24 
25 """
26 from __future__ import print_function
27 # =============================================================================
28 __author__ = "Vanya BELYAEV ibelyaev@physics.syr.edu"
29 # =============================================================================
30 __all__ = (
31  'book', # book AIDA histogram using Histogram Service
32  'bookProf', # book AIDA profile histogram using Histogram Service
33  'getAsAIDA', # get the histogram form Histogram Service as AIDA histogram
34  'getAsROOT', # get the histogram form Histogram Service as AIDA histogram
35  'fill', # "power-fill" method for filling of histograms
36  'aida2root', # AIDA -> ROOT converter
37  'HistoStats', # statistical information for 1D-histograms
38  'HistoFile', # class for storing histograms to a file
39  'histoDump', # dump histogramintext format a'la HBOOK
40  'dumpHisto' # dump histogramintext format a'la HBOOK
41 )
42 # =============================================================================
43 # import core of Gaudi
44 import ROOT
45 from GaudiPython.Bindings import AppMgr
46 from GaudiPython.Bindings import iHistogramSvc
47 from GaudiPython.Bindings import gbl as cpp
48 HID = cpp.GaudiAlg.ID
49 
50 
51 useROOT = False
52 
53 # =============================================================================
54 # Helper private auxiliary function to get Application Manager
55 
56 
57 def _getAppMgr(**kwargs):
58  """
59  Helper private auxiliary function to get Application Manager
60  """
61  gaudi = kwargs.get('gaudi', None)
62  if not gaudi:
63  gaudi = AppMgr()
64  if not gaudi:
65  raise RuntimeError('Unable to get valid ApplicationMgr')
66 
67  state = gaudi._isvc.FSMState()
68  if state < cpp.Gaudi.StateMachine.CONFIGURED:
69  gaudi.config()
70  state = gaudi._isvc.FSMState()
71  if state < cpp.Gaudi.StateMachine.INITIALIZED:
72  gaudi.initialize()
73 
74  return gaudi # RETURN
75 
76 
77 # =============================================================================
78 # Helper private auxiliary function to get iHistogramSvs
79 
80 
81 def _getHistoSvc(**kwargs):
82  """
83  Helper private auxiliary function to get iHistogramSvs
84  """
85  svc = kwargs.get('service', None)
86  if not svc:
87  svc = kwargs.get('svc', None)
88  else:
89  return svc # RETURN
90  gaudi = _getAppMgr(**kwargs)
91  return gaudi.histsvc() # RETURN
92 
93 
94 # =============================================================================
95 # Helper private auxiliary function to get iDataSvs
96 
97 
98 def _getEvtSvc(**kwargs):
99  """
100  Helper private auxiliary function to get iDataSvs
101  """
102  svc = kwargs.get('service', None)
103  if not svc:
104  svc = kwargs.get('svc', None)
105  else:
106  return svc # RETURN
107  gaudi = _getAppMgr(**kwargs)
108  return gaudi.evtsvc() # RETURN
109 
110 
111 # =============================================================================
112 # The trivial function to book the various 1D,2D&3D-histograms
113 
114 
115 def book(*args, **kwargs):
116  """
117  The trivial function to book the various 1D,2D&3D-histograms
118 
119  (1) book the trivial 1D histogram with full path
120 
121  >>> h1D = book ( 'path/to/my/histo' , ## path in Histogram Transient Store
122  'cosine of decay angle ' , ## histogram title
123  100 , ## number of bins
124  -1 , ## low edge
125  100 ) ## high edge
126 
127  (2) book the trivial 1D histogram with directory path and string ID :
128 
129  >>> h1D = book ( 'path/to/directory' , ## the path to directory in HTS
130  'H1' , ## string histogram identifier
131  'cosine of decay angle ' , ## histogram title
132  100 , ## number of bins
133  -1 , ## low edge
134  100 ) ## high edge
135 
136  (3) book the trivial 1D histogram with directory path and integer ID :
137 
138  >>> h1D = book ( 'path/to/directory' , ## the path to directory in HTS
139  124 , ## integer histogram identifier
140  'cosine of decay angle ' , ## histogram title
141  100 , ## number of bins
142  -1 , ## low edge
143  100 ) ## high edge
144 
145  (4) book the trivial 2D histogram with full path
146 
147  >>> h1D = book ( 'path/to/my/histo' , ## path in Histogram Transient Store
148  'm12**2 versus m13**2' , ## histogram title
149  50 , ## number of X-bins
150  1.0 , ## low X-edge
151  4.0 , ## high X-edge
152  50 , ## number of Y-bins
153  1 , ## low Y-edge
154  2 ) ## high Y-edge
155 
156  (5) book the trivial 2D histogram with directory path and literal ID
157 
158  >>> h1D = book ( 'path/to/directory' , ## path in Histogram Transient Store
159  'Dalitz1' , ## literal histogram identifier
160  'm12**2 versus m13**2' , ## histogram title
161  50 , ## number of X-bins
162  1.0 , ## low X-edge
163  4.0 , ## high X-edge
164  50 , ## number of Y-bins
165  1 , ## low Y-edge
166  2 ) ## high Y-edge
167 
168  (6) book the trivial 2D histogram with directory path and integer ID
169 
170  >>> h1D = book ( 'path/to/directory' , ## path in Histogram Transient Store
171  854 , ## integer histogram identifier
172  'm12**2 versus m13**2' , ## histogram title
173  50 , ## number of X-bins
174  1.0 , ## low X-edge
175  4.0 , ## high X-edge
176  50 , ## number of Y-bins
177  1.0 , ## low Y-edge
178  4.0 ) ## high Y-edge
179 
180  (7) book the trivial 3D histogram with full path
181 
182  >>> h1D = book ( 'path/to/my/histo' , ## path in Histogram Transient Store
183  'x vs y vs z ' , ## histogram title
184  10 , ## number of X-bins
185  -1.0 , ## low X-edge
186  1.0 , ## high X-edge
187  10 , ## number of Y-bins
188  -1.0 , ## low Y-edge
189  1.0 , ## high Y-edge
190  10 , ## number of Z-bins
191  -1.0 , ## low Z-edge
192  1.0 ) ## high Z-edge
193 
194  (8) book the trivial 3D histogram with directory path and literal ID
195 
196  >>> h1D = book ( 'path/to/directory' , ## path in Histogram Transient Store
197  'xyz' , ## literal histogram identifier
198  'x vs y vs z' , ## histogram title
199  10 , ## number of X-bins
200  -1.0 , ## low X-edge
201  1.0 , ## high X-edge
202  10 , ## number of Y-bins
203  -1.0 , ## low Y-edge
204  1.0 , ## high Y-edge
205  10 , ## number of Z-bins
206  -1.0 , ## low Z-edge
207  1.0 ) ## high Z-edge
208 
209  (9) book the trivial 3D histogram with directory path and integer ID
210 
211  >>> h1D = book ( 'path/to/directory' , ## path in Histogram Transient Store
212  888 , ## integer histogram identifier
213  'x vs y vs z' , ## histogram title
214  10 , ## number of X-bins
215  -1.0 , ## low X-edge
216  1.0 , ## high X-edge
217  10 , ## number of Y-bins
218  -1.0 , ## low Y-edge
219  1.0 , ## high Y-edge
220  10 , ## number of Z-bins
221  -1.0 , ## low Z-edge
222  1.0 ) ## high Z-edge
223 
224  Many other booking methods are available,
225  e.g. for the histograms with non-equidistant bins, see IHistogamSvc::book
226 
227  """
228  if useROOT or kwargs.get('useROOT',
229  False) or not kwargs.get('useAIDA', True):
230  from ROOT import TH1D
231  a0 = args[0]
232  a1 = args[1]
233  a2 = args[2]
234  if not str is type(a1):
235  a1 = 'h' + str(a1)
236  if str is type(a2):
237  return TH1D(a0 + a1, a2, *args[3:])
238  else:
239  return TH1D(a0, a1, *args[2:])
240 
241  svc = _getHistoSvc(**kwargs)
242  if not svc:
243  raise RuntimeError('Unable to get valid HistogramService ')
244  # book the histogram using the service
245  return svc.book(*args) # RETURN
246 
247 
248 book.__doc__ += '\n\n' + '\thelp(iHistogramSvc.book) : \n\n' \
249  + iHistogramSvc.book . __doc__
250 book.__doc__ += '\n\n' + '\thelp(IHistogramSvc::book) : \n\n' \
251  + cpp.IHistogramSvc.book . __doc__
252 
253 # =============================================================================
254 # The trivial function to book 1D&2D profile histograms:
255 
256 
257 def bookProf(*args, **kwargs):
258  """
259 
260  The trivial function to book 1D&2D profile histograms:
261 
262  (1) book 1D-profile histogram with full path in Histogram Transient Store:
263  >>> histo = bookProf ( 'path/to/my/profile' , ## path in Histogram Transient Store
264  'Energy Correction' , ## the histogram title
265  100 , ## number of X-bins
266  0.0 , ## low X-edge
267  100 ) ## high X-edge
268 
269  (2) book 1D-profile histogram with directory path and literal ID
270  >>> histo = bookProf ( 'path/to/my/profile' , ## path in Histogram Transient Store
271  'Calibration' , ## the histogram literal identifier
272  'Energy Correction' , ## the histogram title
273  100 , ## number of X-bins
274  0.0 , ## low X-edge
275  100 ) ## high X-edge
276 
277  (3) book 1D-profile histogram with directory path and integer ID
278  >>> histo = bookProf ( 'path/to/my/profile' , ## path in Histogram Transient Store
279  418 , ## the histogram integer identifier
280  'Energy Correction' , ## the histogram title
281  100 , ## number of X-bins
282  0.0 , ## low X-edge
283  100 ) ## high X-edge
284 
285  (4) book 2D-profile histogram with full path in Histogram Transient Store:
286  >>> histo = bookProf ( 'path/to/my/profile' , ## path in Histogram Transient Store
287  'Energy Correction' , ## the histogram title
288  50 , ## number of X-bins
289  0.0 , ## low X-edge
290  100 , ## high X-edge
291  50 , ## number of Y-bins
292  0.0 , ## low Y-edge
293  100 ) ## high Y-edge
294 
295  (5) book 2D-profile histogram with directory path and literal ID
296  >>> histo = bookProf ( 'path/to/my/profile' , ## path in Histogram Transient Store
297  'Calibration' , ## the histogram literal identifier
298  'Energy Correction' , ## the histogram title
299  50 , ## number of X-bins
300  0.0 , ## low X-edge
301  100 , ## high X-edge
302  50 , ## number of Y-bins
303  0.0 , ## low Y-edge
304  100 ) ## high Y-edge
305 
306  (6) book 2D-profile histogram with directory path and integer ID
307  >>> histo = bookProf ( 'path/to/my/profile' , ## path in Histogram Transient Store
308  418 , ## the histogram integer identifier
309  'Energy Correction' , ## the histogram title
310  50 , ## number of X-bins
311  0.0 , ## low X-edge
312  100 , ## high X-edge
313  50 , ## number of Y-bins
314  0.0 , ## low Y-edge
315  100 ) ## high Y-edge
316 
317  Many other booking methods are available,
318  e.g. for the histograms with non-equidistant bins, see IHistogamSvc::book
319 
320  """
321  svc = _getHistoSvc(**kwargs)
322  if not svc:
323  raise RuntimeError('Unable to get valid HistogramService ')
324  # book the histogram using the service
325  return svc.bookProf(*args) # RETURN
326 
327 
328 bookProf.__doc__ += '\n\n' + '\thelp(iHistogramSvc.bookProf) : \n\n' \
329  + iHistogramSvc.bookProf . __doc__
330 bookProf.__doc__ += '\n\n' + '\thelp(IHistogramSvc::bookProf) : \n\n' \
331  + cpp.IHistogramSvc.bookProf . __doc__
332 
333 # =============================================================================
334 # The most trivial function to retrieve the histogram from Histogram Transient Store
335 
336 
337 def getAsAIDA(path, **kwargs):
338  """
339 
340  The most trivial function to retrieve the histogram from Histogram Transient Store
341  The histogram is returned by reference to its AIDA-representation (if possible)
342 
343  >>> h = getAsAIDA ( 'some/path/to/my/histogram' )
344 
345  """
346  svc = _getHistoSvc(**kwargs)
347  if not svc:
348  raise RuntimeError('Unable to get valid HistogramService ')
349  # return the histogram
350  return svc.getAsAIDA(path) # RETURN
351 
352 
353 getAsAIDA.__doc__ += '\n\n' + '\thelp(iHistogramSvc.getAsAIDA) : \n\n' \
354  + iHistogramSvc.getAsAIDA . __doc__
355 getAsAIDA.__doc__ += '\n\n' + '\thelp(iHistogramSvc.retrieve) : \n\n' \
356  + iHistogramSvc.retrieve . __doc__
357 
358 # =============================================================================
359 # The most trivial function to retrieve the histogram from Histogram Transient Store
360 
361 
362 def getAsROOT(path, **kwargs):
363  """
364 
365  The most trivial function to retrieve the histogram from Histogram Transient Store
366  The histogram is returned by reference to its underlying native ROOT-representation (if possible)
367 
368  >>> h = getAsROOT ( 'some/path/to/my/histogram' )
369 
370  """
371  svc = _getHistoSvc(**kwargs)
372  if not svc:
373  raise RuntimeError('Unable to get valid HistogramService ')
374  # return the histogram
375  return svc.getAsROOT(path) # RETURN
376 
377 
378 getAsROOT.__doc__ += '\n\n' + '\thelp(iHistogramSvc.getAsROOT) : \n\n' \
379  + iHistogramSvc.getAsROOT . __doc__
380 
381 
382 # =============================================================================
383 # The function which allows 'the smart fill' of 1D-histogram
384 def fill(
385  histo, # histogram
386  data, # input data
387  fun=lambda x: x, # function to be used
388  cut=lambda x: True, # cut to be applied
389  **kwargs): # optional extra arguments
390  """
391 
392  The function which allows 'the smart fill' of 1D-histogram
393 
394  >>> histo = ...
395 
396  The most trivial case, fill with the value
397  >>> fill ( histo , 1.0 )
398 
399  Fill from any iterable object (sequence)
400  >>> fill ( histo , [1,,2,3,4,5,10] )
401 
402  Fill from iterable object and apply the function:
403  >>> fill ( histo , [1,2,3,4,5] , math.sin )
404 
405  Use lambda form:
406  >>> fill ( histo , [1,2,3,4,5] , lambda x : x*x )
407 
408  The same
409  >>> fill ( histo , [1,2,3,4,5] , fun = lambda x : x*x )
410 
411  Use internal attributes:
412  >>> tracks = evtSvc['Rec/Track/Best'] ## iterable container of tracks
413  >>> fill ( histo , tracks , lambda t : t.pt() )
414 
415  Apply the predicate: fill only even numbers:
416  >>> fill ( histo , [1,2,3,4,5,6,7] , lambda x : x , lambda y : y%2 )
417 
418  The same (omit the trivial function) :
419  >>> fill ( histo , [1,2,3,4,5,6,7] , cut = lambda y : y%2 )
420 
421  Apply the predicate: fill only pt for positively charged tracks:
422  >>> tracks = evtSvc['Rec/Track/Best']
423  >>> fill ( histo , tracks , lambda t : t.pt() , lambda t : 0<t.charge() )
424 
425  The same:
426  >>> fill ( histo , tracks ,
427  fun = lambda t : t.pt() ,
428  cut = lambda t : 0<t.charge() )
429 
430  Ordinary functions are also fine:
431  >>> def myfun ( track ) : return sin( track.pt() + track.p() )
432  >>> def mycut ( track ) : return track.p() > 100 * GeV
433  >>> fill ( histo , tracks , myfun , mycut )
434 
435  The 'data' could be the address in TES, in this case the object
436  is retrieved from TES and the method is applied to the objects,
437  retrieved from TES:
438  >>> fill ( histo , ## the reference to the histogram
439  'Rec/Track/Best' , ## the location of objects in TES
440  lambda t : t.pt() ) ## function to be used for histogram fill
441  >>> fill ( histo , ## the reference to the histogram
442  'Rec/Track/Best' , ## the address of objects in TES
443  lambda t : t.pt() , ## the function to be used for histogram fill
444  lambda t : t.charge()>0 ) ## the criteria to select tracks
445 
446  The arguments 'fun' and 'cut' could be strings, in this case
447  they are evaluated by python before usage.
448  This option could be often very useful.
449 
450  """
451 
452  # if value is a string, try to get the objects from TES
453  if type(data) == str:
454  svc = _getEvtSvc(**kwargs)
455  data = svc[data]
456  return fill(histo, data, fun, cut, **kwargs)
457 
458  # if the function is a string: evaluate it!
459  if type(fun) == str:
460  fun = eval(fun, globals())
461 
462  # if the criterion is a string: evaluate it!
463  if type(cut) == str:
464  cut = eval(cut, globals())
465 
466  if not hasattr(data, '__iter__'):
467  data = [data]
468 
469  if not hasattr(histo, 'fill') and hasattr(histo, 'Fill'):
470  setattr(histo, 'fill', getattr(histo, 'Fill'))
471 
472  for item in data:
473  if not cut(item):
474  continue # CONTINUE
475  histo.fill(fun(item))
476 
477  return histo # RETURN
478 
479 
480 # =============================================================================
481 # AIDA -> ROOT converter
482 aida2root = cpp.Gaudi.Utils.Aida2ROOT.aida2root
483 
484 # =============================================================================
485 # Convert AIDA to ROOT
486 
487 
488 def _to_root_(self):
489  """
490  Convert AIDA to ROOT
491 
492  >>> aida = ... ## get AIDA histogram
493  >>> root = aida.toROOT() ## convert it to ROOT
494 
495  """
496  return aida2root(self)
497 
498 
499 _to_root_.__doc__ += aida2root.__doc__
500 
501 for t in (cpp.AIDA.IHistogram3D, cpp.AIDA.IHistogram2D, cpp.AIDA.IHistogram1D,
502  cpp.AIDA.IProfile2D, cpp.AIDA.IProfile1D):
503  if not hasattr(t, 'Fill') and hasattr(t, 'fill'):
504  setattr(t, 'Fill', getattr(t, 'fill'))
505  for attr in ('toROOT', 'toRoot', 'asROOT', 'asRoot', 'AsROOT', 'AsRoot'):
506  if not hasattr(t, attr):
507  setattr(t, attr, _to_root_)
508 
509 cpp.AIDA.IHistogram3D. __repr__ = lambda s: cpp.GaudiAlg.Print3D.toString(
510  s, HID(s.title()))
511 cpp.AIDA.IHistogram3D.__str__ = cpp.AIDA.IHistogram3D.__repr__
512 
513 HistoStats = cpp.Gaudi.Utils.HistoStats
514 
515 # =============================================================================
516 # Evaluate 'bin-by-bin' momentum of certain order around the value
517 
518 
519 def _moment_(self, order, value=0):
520  """
521  Evaluate 'bin-by-bin' momentum of order 'order' around the value 'value'
522  for 1D histogram
523 
524  >>> h1 = ...
525  >>> print h1.moment ( 5 )
526 
527  """
528  return HistoStats.moment(self, order, value)
529 
530 
531 # =============================================================================
532 # Evaluate error in 'bin-by-bin' momentum of certain order around the value
533 
534 
535 def _momentErr_(self, order):
536  """
537  Evaluate error for 'bin-by-bin' momentum of order 'order' around the value 'value'
538  for 1D histogram
539 
540  >>> h1 = ...
541  >>> print h1.momentErr ( 5 )
542 
543  """
544  return HistoStats.momentErr(self, order)
545 
546 
547 # =============================================================================
548 # Evaluate 'bin-by-bin' central momentum (around mean value)
549 
550 
551 def _centralMoment_(self, order):
552  """
553  Evaluate 'bin-by-bin' central momentum (around mean value)
554  for 1D histogram
555 
556  >>> h1 = ...
557  >>> print h1.centralMoment ( 5 )
558 
559  """
560  return HistoStats.centralMoment(self, order)
561 
562 
563 # =============================================================================
564 # Evaluate error in 'bin-by-bin' momentum of certain order around the value
565 
566 
567 def _centralMomentErr_(self, order):
568  """
569  Evaluate error for 'bin-by-bin' central momentum (around mean value)
570  for 1D histogram
571 
572  >>> h1 = ...
573  >>> print h1.centralMomentErr ( 5 )
574 
575  """
576  return HistoStats.centralMomentErr(self, order)
577 
578 
579 # =============================================================================
580 # Evaluate 'bin-by-bin' skewness for 1D histogram
581 
582 
583 def _skewness_(self):
584  """
585  Evaluate 'bin-by-bin' skewness for 1D AIDA histogram
586 
587  >>> h1 = ...
588  >>> print h1.skewness()
589 
590  """
591  return HistoStats.skewness(self)
592 
593 
594 # =============================================================================
595 # Evaluate error for 'bin-by-bin' skewness for 1D histogram
596 
597 
598 def _skewnessErr_(self):
599  """
600  Evaluate error for 'bin-by-bin' skewness
601 
602  >>> h1 = ...
603  >>> print h1.skewnessErr()
604 
605  """
606  return HistoStats.skewnessErr(self)
607 
608 
609 # =============================================================================
610 # Evaluate 'bin-by-bin' kurtosis for 1D histogram
611 
612 
613 def _kurtosis_(self):
614  """
615  Evaluate 'bin-by-bin' kurtosis
616 
617  >>> h1 = ...
618  >>> print h1.kurtosis ()
619 
620  """
621  return HistoStats.kurtosis(self)
622 
623 
624 # =============================================================================
625 # Evaluate error for 'bin-by-bin' kurtosis for 1D histogram
626 
627 
628 def _kurtosisErr_(self):
629  """
630  Evaluate error for 'bin-by-bin' kurtotis for 1D AIDA histogram
631 
632  >>> h1 = ...
633  >>> print h1.kurtotisErr()
634 
635  """
636  return HistoStats.kurtosisErr(self)
637 
638 
639 # =============================================================================
640 
641 
642 def _nEff_(self):
643  """
644  Number of equivalent entries
645  """
646  return HistoStats.nEff(self)
647 
648 
649 # =============================================================================
650 
651 
652 def _mean_(self):
653  """
654  Evaluate the MEAN value
655  """
656  return HistoStats.mean(self)
657 
658 
659 # =============================================================================
660 
661 
662 def _meanErr_(self):
663  """
664  Evaluate the error for MEAN estimate
665  """
666  return HistoStats.meanErr(self)
667 
668 
669 # =============================================================================
670 
671 
672 def _rms_(self):
673  """
674  Evaluate the RMS for AIDA histogram
675  """
676  return HistoStats.rms(self)
677 
678 
679 # =============================================================================
680 
681 
682 def _rmsErr_(self):
683  """
684  Evaluate the error for RMS estimate
685  """
686  return HistoStats.rmsErr(self)
687 
688 
689 # =============================================================================
690 
691 
693  """
694  Get an error in the sum bin height ('in-range integral')
695  """
696  return HistoStats.sumBinHeightErr(self)
697 
698 
699 # =============================================================================
700 
701 
703  """ Get an error in the sum bin height ('in-range integral') """
704  return HistoStats.sumAllBinHeightErr(self)
705 
706 
707 # =============================================================================
708 
709 
711  """
712  The fraction of overflow entries (useful for shape comparison)
713  """
714  return HistoStats.overflowEntriesFrac(self)
715 
716 
717 # =============================================================================
718 
719 
721  """
722  The error for fraction of overflow entries (useful for shape comparison)
723  """
724  return HistoStats.overflowEntriesFracErr(self)
725 
726 
727 # =============================================================================
728 
729 
731  """
732  The fraction of underflow entries (useful for shape comparison)
733  """
734  return HistoStats.underflowEntriesFrac(self)
735 
736 
737 # =============================================================================
738 
739 
741  """
742  The error for fraction of underflow entries (useful for shape comparison)
743  """
744  return HistoStats.underflowEntriesFracErr(self)
745 
746 
747 # =============================================================================
748 
749 
751  """
752  The fraction of overflow integral (useful for shape comparison)
753  """
754  return HistoStats.overflowIntegralFrac(self)
755 
756 
757 # =============================================================================
758 
759 
761  """
762  The error for fraction of overflow integral (useful for shape comparison)
763  """
764  return HistoStats.overflowIntegralFracErr(self)
765 
766 
767 # =============================================================================
768 
769 
771  """
772  The fraction of underflow integral (useful for shape comparison)
773  """
774  return HistoStats.underflowIntegralFrac(self)
775 
776 
777 # =============================================================================
778 
779 
781  """
782  The error for fraction of underflow integral (useful for shape comparison)
783  """
784  return HistoStats.underflowIntegralFracErr(self)
785 
786 
787 # =============================================================================
788 # get number of entries in histogram up to the certain bin (not-included)
789 # get number of entries in histogram form the certain
790 # minimal bin up to the certain maximal bin (not-included)
791 
792 
793 def _nEntries_(self, i1, i2=-10000000):
794  """
795  Get number of entries in histogram up to the certain bin (not-included)
796 
797  attention: underflow bin is included!
798 
799  >>> h1
800  >>> print h1.nEntries ( 10 )
801 
802  Get number of entries in histogram form the certain
803  minimal bin up to the certain maximal bin (not-included)
804 
805  >>> h1
806  >>> print h1.nEntries ( 10 , 15 )
807 
808  """
809  if i2 < i1 or i2 < 0:
810  return HistoStats.nEntries(self, i1)
811  return HistoStats.nEntries(self, i1, i2)
812 
813 
814 # =============================================================================
815 
816 
817 def _nEntriesFrac_(self, i1, i2=-10000000):
818  """
819  Get the fraction of entries in histogram up to the certain bin (not-included)
820 
821  attention: underflow bin is included!
822 
823  >>> h1
824  >>> print h1.nEntriesFrac ( 10 )
825 
826  Get the fraction of entries in histogram form the certain
827  minimal bin up to the certain maximal bin (not-included)
828 
829  >>> h1
830  >>> print h1.nEntriesFrac ( 10 , 15 )
831 
832  """
833  if i2 < i1 or i2 < 0:
834  return HistoStats.nEntriesFrac(self, i1)
835  return HistoStats.nEntriesFrac(self, i1, i2)
836 
837 
838 # =============================================================================
839 
840 
841 def _nEntriesFracErr_(self, i1, i2=-10000000):
842  """
843  Get error for fraction of entries in histogram up to the certain bin (not-included)
844 
845  attention: underflow bin is included!
846 
847  >>> h1
848  >>> print h1.nEntriesFracErr( 10 )
849 
850  Get error fraction of entries in histogram form the certain
851  minimal bin up to the certain maximal bin (not-included)
852 
853  >>> h1
854  >>> print h1.nEntriesFracErr ( 10 , 15 )
855 
856  """
857  if i2 < i1 or i2 < 0:
858  return HistoStats.nEntriesFracErr(self, i1)
859  return HistoStats.nEntriesFracErr(self, i1, i2)
860 
861 
862 # =============================================================================
863 i1DH = cpp.AIDA.IHistogram1D
864 
865 if not hasattr(i1DH, 'moment'):
866  i1DH.moment = _moment_
867 if not hasattr(i1DH, 'momentErr'):
868  i1DH.momentErr = _momentErr_
869 if not hasattr(i1DH, 'centralMoment'):
870  i1DH.centralMoment = _centralMoment_
871 if not hasattr(i1DH, 'momentMomentErr'):
872  i1DH.centralMomentErr = _centralMomentErr_
873 if not hasattr(i1DH, 'nEff'):
874  i1DH.nEff = _nEff_
875 if not hasattr(i1DH, 'mean'):
876  i1DH.mean = _mean_
877 if not hasattr(i1DH, 'meanErr'):
878  i1DH.meanErr = _meanErr_
879 if not hasattr(i1DH, 'rms'):
880  i1DH.rms = _rms_
881 if not hasattr(i1DH, 'rmsErr'):
882  i1DH.rmsErr = _rmsErr_
883 if not hasattr(i1DH, 'skewness'):
884  i1DH.skewness = _skewness_
885 if not hasattr(i1DH, 'skewnessErr'):
886  i1DH.skewnessErr = _skewnessErr_
887 if not hasattr(i1DH, 'kurtosis'):
888  i1DH.kurtosis = _kurtosis_
889 if not hasattr(i1DH, 'kurtosisErr'):
890  i1DH.kurtosisErr = _kurtosisErr_
891 
892 if not hasattr(i1DH, 'overflowEntriesFrac'):
893  i1DH.overflowEntriesFrac = _overflowEntriesFrac_
894 if not hasattr(i1DH, 'overflowEntriesFracErr'):
895  i1DH.overflowEntriesFracErr = _overflowEntriesFracErr_
896 if not hasattr(i1DH, 'underflowEntriesFrac'):
897  i1DH.underflowEntriesFrac = _underflowEntriesFrac_
898 if not hasattr(i1DH, 'underflowEntriesFracErr'):
899  i1DH.underflowEntriesFracErr = _underflowEntriesFracErr_
900 
901 if not hasattr(i1DH, 'overflowIntegralFrac'):
902  i1DH.overflowIntegralFrac = _overflowIntegralFrac_
903 if not hasattr(i1DH, 'overflowIntegralFracErr'):
904  i1DH.overflowIntegralFracErr = _overflowIntegralFracErr_
905 if not hasattr(i1DH, 'underflowIntegralFrac'):
906  i1DH.underflowIntegralFrac = _underflowIntegralFrac_
907 if not hasattr(i1DH, 'underflowIntegralFracErr'):
908  i1DH.underflowIntegralFracErr = _underflowIntegralFracErr_
909 
910 if not hasattr(i1DH, 'nEntries'):
911  i1DH.nEntries = _nEntries_
912 if not hasattr(i1DH, 'nEntriesFrac'):
913  i1DH.nEntriesFrac = _nEntriesFrac_
914 if not hasattr(i1DH, 'nEntriesFracErr'):
915  i1DH.nEntriesFracErr = _nEntriesFracErr_
916 
917 # ============================================================================
918 
919 
920 def _path_(self):
921  """
922  Get the path in THS for the given AIDA object:
923 
924  >>> aida =
925  >>> print aida.path()
926 
927  """
928  return cpp.Gaudi.Utils.Histos.path(self)
929 
930 
931 iBH = cpp.AIDA.IBaseHistogram
932 if not hasattr(iBH, 'path'):
933  iBH.path = _path_
934 if not hasattr(iBH, 'TESpath'):
935  iBH.TESpath = _path_
936 if not hasattr(iBH, 'location'):
937  iBH.location = _path_
938 
939 
940 # =============================================================================
941 def __dumpHisto__(histo, *args):
942  """
943 
944  Dump the histogram/profile in text format (a'la HBOOK)
945 
946  >>> histo
947  >>> print dumpHisto ( histo )
948 
949  >>> print histo.dump()
950  >>> print histo.dump( 20 , 20 )
951  >>> print histo.dump( 20 , 20 , True )
952 
953  Uses:
954 
955  """
956  return cpp.Gaudi.Utils.Histos.histoDump(histo, *args)
957 
958 
959 __dumpHisto__.__doc__ = '\n' + cpp.Gaudi.Utils.Histos.histoDump.__doc__
960 
961 # =============================================================================
962 # the actual function for text dump of the histogram
963 histoDump = __dumpHisto__
964 dumpHisto = __dumpHisto__
965 
966 for t in (cpp.AIDA.IHistogram1D, cpp.AIDA.IProfile1D, ROOT.TH1D, ROOT.TH1F,
967  ROOT.TH1, ROOT.TProfile):
968  for method in ('dump', 'dumpHisto', 'dumpAsText'):
969  if not hasattr(t, method):
970  setattr(t, method, __dumpHisto__)
971 
972 # ==============================================================================
973 
974 
975 class HistoFile:
976  """
977  Class to write histograms to a ROOT file.
978  hFile = HistoFile("myFile.root")
979  myHisto = ...
980  hFile.save(myHisto)
981  myHisto0 = ...
982  myHisto1 = ...
983  myHisto2 = ...
984  hFile.save(myHisto0, myHisto1, myHisto2)
985  histoList = [h0, h1, h2, h3]
986  hFile.save(histoList)
987  ...
988  hWriter.close()
989  """
990  __author__ = "Juan Palacios juan.palacios@nikhef.nl"
991 
992  def __init__(self, fileName):
993  self.file = ROOT.TFile(fileName, "RECREATE")
994  from GaudiPython import gbl
995  self.aida2root = gbl.Gaudi.Utils.Aida2ROOT.aida2root
996  self.aidaTypes = [
997  gbl.AIDA.IHistogram1D, gbl.AIDA.IHistogram2D,
998  gbl.AIDA.IHistogram3D, gbl.AIDA.IProfile1D, gbl.AIDA.IProfile2D,
999  gbl.AIDA.IHistogram
1000  ]
1001 
1002  def __convertibleType(self, histo):
1003  histoType = type(histo)
1004  for t in self.aidaTypes:
1005  if histoType == t:
1006  return True
1007  return False
1008 
1009  def save(self, *args):
1010  """
1011  This function stores histograms on the file for future saving.
1012  It takes an arbitrary number of AIDA or ROOT histograms or
1013  a list of them.
1014  """
1015  if args:
1016  if type(args[0]) == list:
1017  histoList = args[0]
1018  else:
1019  histoList = args
1020  for h in histoList:
1021  if self.__convertibleType(h):
1022  h = self.aida2root(h)
1023  h.Write()
1024 
1025  def close(self):
1026  self.file.Write()
1027  self.file.Close()
1028 
1029 
1030 # =============================================================================
1031 if '__main__' == __name__:
1032  import sys
1033  print(__doc__)
1034  for o in __all__:
1035  print(o)
1036  print(sys.modules[__name__].__dict__[o].__doc__)
1037 
1038 # =============================================================================
1039 # The END
1040 # =============================================================================
def _underflowIntegralFrac_(self)
Definition: HistoUtils.py:770
def _nEntriesFracErr_(self, i1, i2=-10000000)
Definition: HistoUtils.py:841
def _getAppMgr(**kwargs)
Definition: HistoUtils.py:57
def _sumBinHeightErr_(self)
Definition: HistoUtils.py:692
def __init__(self, fileName)
Definition: HistoUtils.py:992
def _sumAllBinHeightErr_(self)
Definition: HistoUtils.py:702
def getAsROOT(path, **kwargs)
Definition: HistoUtils.py:362
def _overflowIntegralFracErr_(self)
Definition: HistoUtils.py:760
def _getHistoSvc(**kwargs)
Definition: HistoUtils.py:81
def _overflowEntriesFrac_(self)
Definition: HistoUtils.py:710
def book(*args, **kwargs)
Definition: HistoUtils.py:115
def _moment_(self, order, value=0)
Definition: HistoUtils.py:519
def _nEntriesFrac_(self, i1, i2=-10000000)
Definition: HistoUtils.py:817
def getAsAIDA(path, **kwargs)
Definition: HistoUtils.py:337
def _underflowEntriesFrac_(self)
Definition: HistoUtils.py:730
def _overflowIntegralFrac_(self)
Definition: HistoUtils.py:750
def _overflowEntriesFracErr_(self)
Definition: HistoUtils.py:720
def __dumpHisto__(histo, *args)
Definition: HistoUtils.py:941
def _underflowEntriesFracErr_(self)
Definition: HistoUtils.py:740
def _centralMomentErr_(self, order)
Definition: HistoUtils.py:567
def bookProf(*args, **kwargs)
Definition: HistoUtils.py:257
def _nEntries_(self, i1, i2=-10000000)
Definition: HistoUtils.py:793
def fill(histo, data, fun=lambda x:x, cut=lambda x:True, **kwargs)
Definition: HistoUtils.py:384
def _getEvtSvc(**kwargs)
Definition: HistoUtils.py:98
def _momentErr_(self, order)
Definition: HistoUtils.py:535
def _centralMoment_(self, order)
Definition: HistoUtils.py:551
def _underflowIntegralFracErr_(self)
Definition: HistoUtils.py:780
def __convertibleType(self, histo)
Definition: HistoUtils.py:1002