9 This module contains set of simple and useful utilities for booking and 10 manipulations with Gaudi-AIDA histograms, inspired by Thomas' request 12 The module contains following public symbols: 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) 27 __author__ =
"Vanya BELYAEV ibelyaev@physics.syr.edu" 58 Helper private auxiliary function to get Application Manager 60 gaudi = kwargs.get(
'gaudi',
None)
64 raise RuntimeError,
'Unable to get valid ApplicationMgr' 66 state = gaudi._isvc.FSMState()
67 if state < cpp.Gaudi.StateMachine.CONFIGURED:
69 state = gaudi._isvc.FSMState()
70 if state < cpp.Gaudi.StateMachine.INITIALIZED:
82 Helper private auxiliary function to get iHistogramSvs 84 svc = kwargs.get(
'service',
None)
86 svc = kwargs.get(
'svc',
None)
90 return gaudi.histsvc()
99 Helper private auxiliary function to get iDataSvs 101 svc = kwargs.get(
'service',
None)
103 svc = kwargs.get(
'svc',
None)
107 return gaudi.evtsvc()
116 The trivial function to book the various 1D,2D&3D-histograms 118 (1) book the trivial 1D histogram with full path 120 >>> h1D = book ( 'path/to/my/histo' , ## path in Histogram Transient Store 121 'cosine of decay angle ' , ## histogram title 122 100 , ## number of bins 126 (2) book the trivial 1D histogram with directory path and string ID : 128 >>> h1D = book ( 'path/to/directory' , ## the path to directory in HTS 129 'H1' , ## string histogram identifier 130 'cosine of decay angle ' , ## histogram title 131 100 , ## number of bins 135 (3) book the trivial 1D histogram with directory path and integer ID : 137 >>> h1D = book ( 'path/to/directory' , ## the path to directory in HTS 138 124 , ## integer histogram identifier 139 'cosine of decay angle ' , ## histogram title 140 100 , ## number of bins 144 (4) book the trivial 2D histogram with full path 146 >>> h1D = book ( 'path/to/my/histo' , ## path in Histogram Transient Store 147 'm12**2 versus m13**2' , ## histogram title 148 50 , ## number of X-bins 151 50 , ## number of Y-bins 155 (5) book the trivial 2D histogram with directory path and literal ID 157 >>> h1D = book ( 'path/to/directory' , ## path in Histogram Transient Store 158 'Dalitz1' , ## literal histogram identifier 159 'm12**2 versus m13**2' , ## histogram title 160 50 , ## number of X-bins 163 50 , ## number of Y-bins 167 (6) book the trivial 2D histogram with directory path and integer ID 169 >>> h1D = book ( 'path/to/directory' , ## path in Histogram Transient Store 170 854 , ## integer histogram identifier 171 'm12**2 versus m13**2' , ## histogram title 172 50 , ## number of X-bins 175 50 , ## number of Y-bins 179 (7) book the trivial 3D histogram with full path 181 >>> h1D = book ( 'path/to/my/histo' , ## path in Histogram Transient Store 182 'x vs y vs z ' , ## histogram title 183 10 , ## number of X-bins 186 10 , ## number of Y-bins 189 10 , ## number of Z-bins 193 (8) book the trivial 3D histogram with directory path and literal ID 195 >>> h1D = book ( 'path/to/directory' , ## path in Histogram Transient Store 196 'xyz' , ## literal histogram identifier 197 'x vs y vs z' , ## histogram title 198 10 , ## number of X-bins 201 10 , ## number of Y-bins 204 10 , ## number of Z-bins 208 (9) book the trivial 3D histogram with directory path and integer ID 210 >>> h1D = book ( 'path/to/directory' , ## path in Histogram Transient Store 211 888 , ## integer histogram identifier 212 'x vs y vs z' , ## histogram title 213 10 , ## number of X-bins 216 10 , ## number of Y-bins 219 10 , ## number of Z-bins 223 Many other booking methods are available, 224 e.g. for the histograms with non-equidistant bins, see IHistogamSvc::book 227 if useROOT
or kwargs.get(
'useROOT',
228 False)
or not kwargs.get(
'useAIDA',
True):
229 from ROOT
import TH1D
233 if not str
is type(a1):
236 return TH1D(a0 + a1, a2, *args[3:])
238 return TH1D(a0, a1, *args[2:])
242 raise RuntimeError,
'Unable to get valid HistogramService ' 244 return svc.book(*args)
247 book.__doc__ +=
'\n\n' +
'\thelp(iHistogramSvc.book) : \n\n' \
248 + iHistogramSvc.book . __doc__
249 book.__doc__ +=
'\n\n' +
'\thelp(IHistogramSvc::book) : \n\n' \
250 + cpp.IHistogramSvc.book . __doc__
259 The trivial function to book 1D&2D profile histograms: 261 (1) book 1D-profile histogram with full path in Histogram Transient Store: 262 >>> histo = bookProf ( 'path/to/my/profile' , ## path in Histogram Transient Store 263 'Energy Correction' , ## the histogram title 264 100 , ## number of X-bins 268 (2) book 1D-profile histogram with directory path and literal ID 269 >>> histo = bookProf ( 'path/to/my/profile' , ## path in Histogram Transient Store 270 'Calibration' , ## the histogram literal identifier 271 'Energy Correction' , ## the histogram title 272 100 , ## number of X-bins 276 (3) book 1D-profile histogram with directory path and integer ID 277 >>> histo = bookProf ( 'path/to/my/profile' , ## path in Histogram Transient Store 278 418 , ## the histogram integer identifier 279 'Energy Correction' , ## the histogram title 280 100 , ## number of X-bins 284 (4) book 2D-profile histogram with full path in Histogram Transient Store: 285 >>> histo = bookProf ( 'path/to/my/profile' , ## path in Histogram Transient Store 286 'Energy Correction' , ## the histogram title 287 50 , ## number of X-bins 290 50 , ## number of Y-bins 294 (5) book 2D-profile histogram with directory path and literal ID 295 >>> histo = bookProf ( 'path/to/my/profile' , ## path in Histogram Transient Store 296 'Calibration' , ## the histogram literal identifier 297 'Energy Correction' , ## the histogram title 298 50 , ## number of X-bins 301 50 , ## number of Y-bins 305 (6) book 2D-profile histogram with directory path and integer ID 306 >>> histo = bookProf ( 'path/to/my/profile' , ## path in Histogram Transient Store 307 418 , ## the histogram integer identifier 308 'Energy Correction' , ## the histogram title 309 50 , ## number of X-bins 312 50 , ## number of Y-bins 316 Many other booking methods are available, 317 e.g. for the histograms with non-equidistant bins, see IHistogamSvc::book 322 raise RuntimeError,
'Unable to get valid HistogramService ' 324 return svc.bookProf(*args)
327 bookProf.__doc__ +=
'\n\n' +
'\thelp(iHistogramSvc.bookProf) : \n\n' \
328 + iHistogramSvc.bookProf . __doc__
329 bookProf.__doc__ +=
'\n\n' +
'\thelp(IHistogramSvc::bookProf) : \n\n' \
330 + cpp.IHistogramSvc.bookProf . __doc__
339 The most trivial function to retrieve the histogram from Histogram Transient Store 340 The histogram is returned by reference to its AIDA-representation (if possible) 342 >>> h = getAsAIDA ( 'some/path/to/my/histogram' ) 347 raise RuntimeError,
'Unable to get valid HistogramService ' 349 return svc.getAsAIDA(path)
352 getAsAIDA.__doc__ +=
'\n\n' +
'\thelp(iHistogramSvc.getAsAIDA) : \n\n' \
353 + iHistogramSvc.getAsAIDA . __doc__
354 getAsAIDA.__doc__ +=
'\n\n' +
'\thelp(iHistogramSvc.retrieve) : \n\n' \
355 + iHistogramSvc.retrieve . __doc__
364 The most trivial function to retrieve the histogram from Histogram Transient Store 365 The histogram is returned by reference to its underlying native ROOT-representation (if possible) 367 >>> h = getAsROOT ( 'some/path/to/my/histogram' ) 372 raise RuntimeError,
'Unable to get valid HistogramService ' 374 return svc.getAsROOT(path)
377 getAsROOT.__doc__ +=
'\n\n' +
'\thelp(iHistogramSvc.getAsROOT) : \n\n' \
378 + iHistogramSvc.getAsROOT . __doc__
391 The function which allows 'the smart fill' of 1D-histogram 395 The most trivial case, fill with the value 396 >>> fill ( histo , 1.0 ) 398 Fill from any iterable object (sequence) 399 >>> fill ( histo , [1,,2,3,4,5,10] ) 401 Fill from iterable object and apply the function: 402 >>> fill ( histo , [1,2,3,4,5] , math.sin ) 405 >>> fill ( histo , [1,2,3,4,5] , lambda x : x*x ) 408 >>> fill ( histo , [1,2,3,4,5] , fun = lambda x : x*x ) 410 Use internal attributes: 411 >>> tracks = evtSvc['Rec/Track/Best'] ## iterable container of tracks 412 >>> fill ( histo , tracks , lambda t : t.pt() ) 414 Apply the predicate: fill only even numbers: 415 >>> fill ( histo , [1,2,3,4,5,6,7] , lambda x : x , lambda y : y%2 ) 417 The same (omit the trivial function) : 418 >>> fill ( histo , [1,2,3,4,5,6,7] , cut = lambda y : y%2 ) 420 Apply the predicate: fill only pt for positively charged tracks: 421 >>> tracks = evtSvc['Rec/Track/Best'] 422 >>> fill ( histo , tracks , lambda t : t.pt() , lambda t : 0<t.charge() ) 425 >>> fill ( histo , tracks , 426 fun = lambda t : t.pt() , 427 cut = lambda t : 0<t.charge() ) 429 Ordinary functions are also fine: 430 >>> def myfun ( track ) : return sin( track.pt() + track.p() ) 431 >>> def mycut ( track ) : return track.p() > 100 * GeV 432 >>> fill ( histo , tracks , myfun , mycut ) 434 The 'data' could be the address in TES, in this case the object 435 is retrieved from TES and the method is applied to the objects, 437 >>> fill ( histo , ## the reference to the histogram 438 'Rec/Track/Best' , ## the location of objects in TES 439 lambda t : t.pt() ) ## function to be used for histogram fill 440 >>> fill ( histo , ## the reference to the histogram 441 'Rec/Track/Best' , ## the address of objects in TES 442 lambda t : t.pt() , ## the function to be used for histogram fill 443 lambda t : t.charge()>0 ) ## the criteria to select tracks 445 The arguments 'fun' and 'cut' could be strings, in this case 446 they are evaluated by python before usage. 447 This option could be often very useful. 452 if type(data) == str:
455 return fill(histo, data, fun, cut, **kwargs)
459 fun = eval(fun, globals())
463 cut = eval(cut, globals())
465 if not hasattr(data,
'__iter__'):
468 if not hasattr(histo,
'fill')
and hasattr(histo,
'Fill'):
469 setattr(histo,
'fill', getattr(histo,
'Fill'))
474 histo.fill(
fun(item))
481 aida2root = cpp.Gaudi.Utils.Aida2ROOT.aida2root
491 >>> aida = ... ## get AIDA histogram 492 >>> root = aida.toROOT() ## convert it to ROOT 498 _to_root_.__doc__ += aida2root.__doc__
500 for t
in (cpp.AIDA.IHistogram3D, cpp.AIDA.IHistogram2D, cpp.AIDA.IHistogram1D,
501 cpp.AIDA.IProfile2D, cpp.AIDA.IProfile1D):
502 if not hasattr(t,
'Fill')
and hasattr(t,
'fill'):
503 setattr(t,
'Fill', getattr(t,
'fill'))
504 for attr
in (
'toROOT',
'toRoot',
'asROOT',
'asRoot',
'AsROOT',
'AsRoot'):
505 if not hasattr(t, attr):
506 setattr(t, attr, _to_root_)
508 cpp.AIDA.IHistogram3D. __repr__ =
lambda s: cpp.GaudiAlg.Print3D.toString(
510 cpp.AIDA.IHistogram3D.__str__ = cpp.AIDA.IHistogram3D.__repr__
512 HistoStats = cpp.Gaudi.Utils.HistoStats
520 Evaluate 'bin-by-bin' momentum of order 'order' around the value 'value' 524 >>> print h1.moment ( 5 ) 527 return HistoStats.moment(self, order, value)
536 Evaluate error for 'bin-by-bin' momentum of order 'order' around the value 'value' 540 >>> print h1.momentErr ( 5 ) 543 return HistoStats.momentErr(self, order)
552 Evaluate 'bin-by-bin' central momentum (around mean value) 556 >>> print h1.centralMoment ( 5 ) 559 return HistoStats.centralMoment(self, order)
568 Evaluate error for 'bin-by-bin' central momentum (around mean value) 572 >>> print h1.centralMomentErr ( 5 ) 575 return HistoStats.centralMomentErr(self, order)
584 Evaluate 'bin-by-bin' skewness for 1D AIDA histogram 587 >>> print h1.skewness() 590 return HistoStats.skewness(self)
599 Evaluate error for 'bin-by-bin' skewness 602 >>> print h1.skewnessErr() 605 return HistoStats.skewnessErr(self)
614 Evaluate 'bin-by-bin' kurtosis 617 >>> print h1.kurtosis () 620 return HistoStats.kurtosis(self)
629 Evaluate error for 'bin-by-bin' kurtotis for 1D AIDA histogram 632 >>> print h1.kurtotisErr() 635 return HistoStats.kurtosisErr(self)
643 Number of equivalent entries 645 return HistoStats.nEff(self)
653 Evaluate the MEAN value 655 return HistoStats.mean(self)
663 Evaluate the error for MEAN estimate 665 return HistoStats.meanErr(self)
673 Evaluate the RMS for AIDA histogram 675 return HistoStats.rms(self)
683 Evaluate the error for RMS estimate 685 return HistoStats.rmsErr(self)
693 Get an error in the sum bin height ('in-range integral') 695 return HistoStats.sumBinHeightErr(self)
702 """ Get an error in the sum bin height ('in-range integral') """ 703 return HistoStats.sumAllBinHeightErr(self)
711 The fraction of overflow entries (useful for shape comparison) 713 return HistoStats.overflowEntriesFrac(self)
721 The error for fraction of overflow entries (useful for shape comparison) 723 return HistoStats.overflowEntriesFracErr(self)
731 The fraction of underflow entries (useful for shape comparison) 733 return HistoStats.underflowEntriesFrac(self)
741 The error for fraction of underflow entries (useful for shape comparison) 743 return HistoStats.underflowEntriesFracErr(self)
751 The fraction of overflow integral (useful for shape comparison) 753 return HistoStats.overflowIntegralFrac(self)
761 The error for fraction of overflow integral (useful for shape comparison) 763 return HistoStats.overflowIntegralFracErr(self)
771 The fraction of underflow integral (useful for shape comparison) 773 return HistoStats.underflowIntegralFrac(self)
781 The error for fraction of underflow integral (useful for shape comparison) 783 return HistoStats.underflowIntegralFracErr(self)
794 Get number of entries in histogram up to the certain bin (not-included) 796 attention: underflow bin is included! 799 >>> print h1.nEntries ( 10 ) 801 Get number of entries in histogram form the certain 802 minimal bin up to the certain maximal bin (not-included) 805 >>> print h1.nEntries ( 10 , 15 ) 808 if i2 < i1
or i2 < 0:
809 return HistoStats.nEntries(self, i1)
810 return HistoStats.nEntries(self, i1, i2)
818 Get the fraction of entries in histogram up to the certain bin (not-included) 820 attention: underflow bin is included! 823 >>> print h1.nEntriesFrac ( 10 ) 825 Get the fraction of entries in histogram form the certain 826 minimal bin up to the certain maximal bin (not-included) 829 >>> print h1.nEntriesFrac ( 10 , 15 ) 832 if i2 < i1
or i2 < 0:
833 return HistoStats.nEntriesFrac(self, i1)
834 return HistoStats.nEntriesFrac(self, i1, i2)
842 Get error for fraction of entries in histogram up to the certain bin (not-included) 844 attention: underflow bin is included! 847 >>> print h1.nEntriesFracErr( 10 ) 849 Get error fraction of entries in histogram form the certain 850 minimal bin up to the certain maximal bin (not-included) 853 >>> print h1.nEntriesFracErr ( 10 , 15 ) 856 if i2 < i1
or i2 < 0:
857 return HistoStats.nEntriesFracErr(self, i1)
858 return HistoStats.nEntriesFracErr(self, i1, i2)
862 i1DH = cpp.AIDA.IHistogram1D
864 if not hasattr(i1DH,
'moment'):
865 i1DH.moment = _moment_
866 if not hasattr(i1DH,
'momentErr'):
867 i1DH.momentErr = _momentErr_
868 if not hasattr(i1DH,
'centralMoment'):
869 i1DH.centralMoment = _centralMoment_
870 if not hasattr(i1DH,
'momentMomentErr'):
871 i1DH.centralMomentErr = _centralMomentErr_
872 if not hasattr(i1DH,
'nEff'):
874 if not hasattr(i1DH,
'mean'):
876 if not hasattr(i1DH,
'meanErr'):
877 i1DH.meanErr = _meanErr_
878 if not hasattr(i1DH,
'rms'):
880 if not hasattr(i1DH,
'rmsErr'):
881 i1DH.rmsErr = _rmsErr_
882 if not hasattr(i1DH,
'skewness'):
883 i1DH.skewness = _skewness_
884 if not hasattr(i1DH,
'skewnessErr'):
885 i1DH.skewnessErr = _skewnessErr_
886 if not hasattr(i1DH,
'kurtosis'):
887 i1DH.kurtosis = _kurtosis_
888 if not hasattr(i1DH,
'kurtosisErr'):
889 i1DH.kurtosisErr = _kurtosisErr_
891 if not hasattr(i1DH,
'overflowEntriesFrac'):
892 i1DH.overflowEntriesFrac = _overflowEntriesFrac_
893 if not hasattr(i1DH,
'overflowEntriesFracErr'):
894 i1DH.overflowEntriesFracErr = _overflowEntriesFracErr_
895 if not hasattr(i1DH,
'underflowEntriesFrac'):
896 i1DH.underflowEntriesFrac = _underflowEntriesFrac_
897 if not hasattr(i1DH,
'underflowEntriesFracErr'):
898 i1DH.underflowEntriesFracErr = _underflowEntriesFracErr_
900 if not hasattr(i1DH,
'overflowIntegralFrac'):
901 i1DH.overflowIntegralFrac = _overflowIntegralFrac_
902 if not hasattr(i1DH,
'overflowIntegralFracErr'):
903 i1DH.overflowIntegralFracErr = _overflowIntegralFracErr_
904 if not hasattr(i1DH,
'underflowIntegralFrac'):
905 i1DH.underflowIntegralFrac = _underflowIntegralFrac_
906 if not hasattr(i1DH,
'underflowIntegralFracErr'):
907 i1DH.underflowIntegralFracErr = _underflowIntegralFracErr_
909 if not hasattr(i1DH,
'nEntries'):
910 i1DH.nEntries = _nEntries_
911 if not hasattr(i1DH,
'nEntriesFrac'):
912 i1DH.nEntriesFrac = _nEntriesFrac_
913 if not hasattr(i1DH,
'nEntriesFracErr'):
914 i1DH.nEntriesFracErr = _nEntriesFracErr_
921 Get the path in THS for the given AIDA object: 924 >>> print aida.path() 927 return cpp.Gaudi.Utils.Histos.path(self)
930 iBH = cpp.AIDA.IBaseHistogram
931 if not hasattr(iBH,
'path'):
933 if not hasattr(iBH,
'TESpath'):
935 if not hasattr(iBH,
'location'):
936 iBH.location = _path_
943 Dump the histogram/profile in text format (a'la HBOOK) 946 >>> print dumpHisto ( histo ) 948 >>> print histo.dump() 949 >>> print histo.dump( 20 , 20 ) 950 >>> print histo.dump( 20 , 20 , True ) 955 return cpp.Gaudi.Utils.Histos.histoDump(histo, *args)
958 __dumpHisto__.__doc__ =
'\n' + cpp.Gaudi.Utils.Histos.histoDump.__doc__
962 histoDump = __dumpHisto__
963 dumpHisto = __dumpHisto__
965 for t
in (cpp.AIDA.IHistogram1D, cpp.AIDA.IProfile1D, ROOT.TH1D, ROOT.TH1F,
966 ROOT.TH1, ROOT.TProfile):
967 for method
in (
'dump',
'dumpHisto',
'dumpAsText'):
968 if not hasattr(t, method):
969 setattr(t, method, __dumpHisto__)
976 Class to write histograms to a ROOT file. 977 hFile = HistoFile("myFile.root") 983 hFile.save(myHisto0, myHisto1, myHisto2) 984 histoList = [h0, h1, h2, h3] 985 hFile.save(histoList) 989 __author__ =
"Juan Palacios juan.palacios@nikhef.nl" 992 self.
file = ROOT.TFile(fileName,
"RECREATE")
993 from GaudiPython
import gbl
996 gbl.AIDA.IHistogram1D, gbl.AIDA.IHistogram2D,
997 gbl.AIDA.IHistogram3D, gbl.AIDA.IProfile1D, gbl.AIDA.IProfile2D,
1002 histoType =
type(histo)
1010 This function stores histograms on the file for future saving. 1011 It takes an arbitrary number of AIDA or ROOT histograms or 1015 if type(args[0]) == list:
1030 if '__main__' == __name__:
1035 print sys.modules[__name__].__dict__[o].__doc__
def _underflowIntegralFrac_(self)
def _nEntriesFracErr_(self, i1, i2=-10000000)
def getAsAIDA(path, kwargs)
def _sumBinHeightErr_(self)
def __init__(self, fileName)
def _sumAllBinHeightErr_(self)
def _overflowIntegralFracErr_(self)
def getAsROOT(path, kwargs)
def _overflowEntriesFrac_(self)
def _moment_(self, order, value=0)
def _nEntriesFrac_(self, i1, i2=-10000000)
def _underflowEntriesFrac_(self)
def _overflowIntegralFrac_(self)
def _overflowEntriesFracErr_(self)
def bookProf(args, kwargs)
def _underflowEntriesFracErr_(self)
def _centralMomentErr_(self, order)
double fun(const std::vector< double > &x)
def fill(histo, data, fun=lambda x:x, cut=lambda x:True, kwargs)
def _nEntries_(self, i1, i2=-10000000)
def _momentErr_(self, order)
def _centralMoment_(self, order)
def _underflowIntegralFracErr_(self)
def __dumpHisto__(histo, args)
def __convertibleType(self, histo)