19 This module contains set of simple and useful utilities for booking and 20 manipulations with Gaudi-AIDA histograms, inspired by Thomas' request 22 The module contains following public symbols: 24 - book for booking of various 1D,2D&3D-histograms 25 - bookProf for booking of various 1D&2D-profiles 26 - getAsAIDA for retrieval of histograms/profiles from HTS in AIDA format 27 - getAsROOT for retrieval of histograms/profiles from HTS in ROOT format 28 - fill for smart filling of 1D-histogram (AIDA or ROOT) 29 - aida2root for conversion of AIDA histogram to ROOT 30 - HistoStats for many statistical information 31 - HistoFile class for storing histograms to a file 32 - histoDump for dumping of the histogram in text format (a'la HBOOK) 33 - dumpHisto for dumping of the histogram in text format (a'la HBOOK) 36 from __future__
import print_function
38 __author__ =
"Vanya BELYAEV ibelyaev@physics.syr.edu" 69 Helper private auxiliary function to get Application Manager 71 gaudi = kwargs.get(
'gaudi',
None)
75 raise RuntimeError(
'Unable to get valid ApplicationMgr')
77 state = gaudi._isvc.FSMState()
78 if state < cpp.Gaudi.StateMachine.CONFIGURED:
80 state = gaudi._isvc.FSMState()
81 if state < cpp.Gaudi.StateMachine.INITIALIZED:
93 Helper private auxiliary function to get iHistogramSvs 95 svc = kwargs.get(
'service',
None)
97 svc = kwargs.get(
'svc',
None)
101 return gaudi.histsvc()
110 Helper private auxiliary function to get iDataSvs 112 svc = kwargs.get(
'service',
None)
114 svc = kwargs.get(
'svc',
None)
118 return gaudi.evtsvc()
127 The trivial function to book the various 1D,2D&3D-histograms 129 (1) book the trivial 1D histogram with full path 131 >>> h1D = book ( 'path/to/my/histo' , ## path in Histogram Transient Store 132 'cosine of decay angle ' , ## histogram title 133 100 , ## number of bins 137 (2) book the trivial 1D histogram with directory path and string ID : 139 >>> h1D = book ( 'path/to/directory' , ## the path to directory in HTS 140 'H1' , ## string histogram identifier 141 'cosine of decay angle ' , ## histogram title 142 100 , ## number of bins 146 (3) book the trivial 1D histogram with directory path and integer ID : 148 >>> h1D = book ( 'path/to/directory' , ## the path to directory in HTS 149 124 , ## integer histogram identifier 150 'cosine of decay angle ' , ## histogram title 151 100 , ## number of bins 155 (4) book the trivial 2D histogram with full path 157 >>> h1D = book ( 'path/to/my/histo' , ## path in Histogram Transient Store 158 'm12**2 versus m13**2' , ## histogram title 159 50 , ## number of X-bins 162 50 , ## number of Y-bins 166 (5) book the trivial 2D histogram with directory path and literal ID 168 >>> h1D = book ( 'path/to/directory' , ## path in Histogram Transient Store 169 'Dalitz1' , ## literal histogram identifier 170 'm12**2 versus m13**2' , ## histogram title 171 50 , ## number of X-bins 174 50 , ## number of Y-bins 178 (6) book the trivial 2D histogram with directory path and integer ID 180 >>> h1D = book ( 'path/to/directory' , ## path in Histogram Transient Store 181 854 , ## integer histogram identifier 182 'm12**2 versus m13**2' , ## histogram title 183 50 , ## number of X-bins 186 50 , ## number of Y-bins 190 (7) book the trivial 3D histogram with full path 192 >>> h1D = book ( 'path/to/my/histo' , ## path in Histogram Transient Store 193 'x vs y vs z ' , ## histogram title 194 10 , ## number of X-bins 197 10 , ## number of Y-bins 200 10 , ## number of Z-bins 204 (8) book the trivial 3D histogram with directory path and literal ID 206 >>> h1D = book ( 'path/to/directory' , ## path in Histogram Transient Store 207 'xyz' , ## literal histogram identifier 208 'x vs y vs z' , ## histogram title 209 10 , ## number of X-bins 212 10 , ## number of Y-bins 215 10 , ## number of Z-bins 219 (9) book the trivial 3D histogram with directory path and integer ID 221 >>> h1D = book ( 'path/to/directory' , ## path in Histogram Transient Store 222 888 , ## integer histogram identifier 223 'x vs y vs z' , ## histogram title 224 10 , ## number of X-bins 227 10 , ## number of Y-bins 230 10 , ## number of Z-bins 234 Many other booking methods are available, 235 e.g. for the histograms with non-equidistant bins, see IHistogamSvc::book 238 if useROOT
or kwargs.get(
'useROOT',
239 False)
or not kwargs.get(
'useAIDA',
True):
240 from ROOT
import TH1D
244 if not str
is type(a1):
247 return TH1D(a0 + a1, a2, *args[3:])
249 return TH1D(a0, a1, *args[2:])
253 raise RuntimeError(
'Unable to get valid HistogramService ')
255 return svc.book(*args)
258 book.__doc__ +=
'\n\n' +
'\thelp(iHistogramSvc.book) : \n\n' \
259 + iHistogramSvc.book . __doc__
260 book.__doc__ +=
'\n\n' +
'\thelp(IHistogramSvc::book) : \n\n' \
261 + cpp.IHistogramSvc.book . __doc__
270 The trivial function to book 1D&2D profile histograms: 272 (1) book 1D-profile histogram with full path in Histogram Transient Store: 273 >>> histo = bookProf ( 'path/to/my/profile' , ## path in Histogram Transient Store 274 'Energy Correction' , ## the histogram title 275 100 , ## number of X-bins 279 (2) book 1D-profile histogram with directory path and literal ID 280 >>> histo = bookProf ( 'path/to/my/profile' , ## path in Histogram Transient Store 281 'Calibration' , ## the histogram literal identifier 282 'Energy Correction' , ## the histogram title 283 100 , ## number of X-bins 287 (3) book 1D-profile histogram with directory path and integer ID 288 >>> histo = bookProf ( 'path/to/my/profile' , ## path in Histogram Transient Store 289 418 , ## the histogram integer identifier 290 'Energy Correction' , ## the histogram title 291 100 , ## number of X-bins 295 (4) book 2D-profile histogram with full path in Histogram Transient Store: 296 >>> histo = bookProf ( 'path/to/my/profile' , ## path in Histogram Transient Store 297 'Energy Correction' , ## the histogram title 298 50 , ## number of X-bins 301 50 , ## number of Y-bins 305 (5) book 2D-profile histogram with directory path and literal ID 306 >>> histo = bookProf ( 'path/to/my/profile' , ## path in Histogram Transient Store 307 'Calibration' , ## the histogram literal identifier 308 'Energy Correction' , ## the histogram title 309 50 , ## number of X-bins 312 50 , ## number of Y-bins 316 (6) book 2D-profile histogram with directory path and integer ID 317 >>> histo = bookProf ( 'path/to/my/profile' , ## path in Histogram Transient Store 318 418 , ## the histogram integer identifier 319 'Energy Correction' , ## the histogram title 320 50 , ## number of X-bins 323 50 , ## number of Y-bins 327 Many other booking methods are available, 328 e.g. for the histograms with non-equidistant bins, see IHistogamSvc::book 333 raise RuntimeError(
'Unable to get valid HistogramService ')
335 return svc.bookProf(*args)
338 bookProf.__doc__ +=
'\n\n' +
'\thelp(iHistogramSvc.bookProf) : \n\n' \
339 + iHistogramSvc.bookProf . __doc__
340 bookProf.__doc__ +=
'\n\n' +
'\thelp(IHistogramSvc::bookProf) : \n\n' \
341 + cpp.IHistogramSvc.bookProf . __doc__
350 The most trivial function to retrieve the histogram from Histogram Transient Store 351 The histogram is returned by reference to its AIDA-representation (if possible) 353 >>> h = getAsAIDA ( 'some/path/to/my/histogram' ) 358 raise RuntimeError(
'Unable to get valid HistogramService ')
360 return svc.getAsAIDA(path)
363 getAsAIDA.__doc__ +=
'\n\n' +
'\thelp(iHistogramSvc.getAsAIDA) : \n\n' \
364 + iHistogramSvc.getAsAIDA . __doc__
365 getAsAIDA.__doc__ +=
'\n\n' +
'\thelp(iHistogramSvc.retrieve) : \n\n' \
366 + iHistogramSvc.retrieve . __doc__
375 The most trivial function to retrieve the histogram from Histogram Transient Store 376 The histogram is returned by reference to its underlying native ROOT-representation (if possible) 378 >>> h = getAsROOT ( 'some/path/to/my/histogram' ) 383 raise RuntimeError(
'Unable to get valid HistogramService ')
385 return svc.getAsROOT(path)
388 getAsROOT.__doc__ +=
'\n\n' +
'\thelp(iHistogramSvc.getAsROOT) : \n\n' \
389 + iHistogramSvc.getAsROOT . __doc__
402 The function which allows 'the smart fill' of 1D-histogram 406 The most trivial case, fill with the value 407 >>> fill ( histo , 1.0 ) 409 Fill from any iterable object (sequence) 410 >>> fill ( histo , [1,,2,3,4,5,10] ) 412 Fill from iterable object and apply the function: 413 >>> fill ( histo , [1,2,3,4,5] , math.sin ) 416 >>> fill ( histo , [1,2,3,4,5] , lambda x : x*x ) 419 >>> fill ( histo , [1,2,3,4,5] , fun = lambda x : x*x ) 421 Use internal attributes: 422 >>> tracks = evtSvc['Rec/Track/Best'] ## iterable container of tracks 423 >>> fill ( histo , tracks , lambda t : t.pt() ) 425 Apply the predicate: fill only even numbers: 426 >>> fill ( histo , [1,2,3,4,5,6,7] , lambda x : x , lambda y : y%2 ) 428 The same (omit the trivial function) : 429 >>> fill ( histo , [1,2,3,4,5,6,7] , cut = lambda y : y%2 ) 431 Apply the predicate: fill only pt for positively charged tracks: 432 >>> tracks = evtSvc['Rec/Track/Best'] 433 >>> fill ( histo , tracks , lambda t : t.pt() , lambda t : 0<t.charge() ) 436 >>> fill ( histo , tracks , 437 fun = lambda t : t.pt() , 438 cut = lambda t : 0<t.charge() ) 440 Ordinary functions are also fine: 441 >>> def myfun ( track ) : return sin( track.pt() + track.p() ) 442 >>> def mycut ( track ) : return track.p() > 100 * GeV 443 >>> fill ( histo , tracks , myfun , mycut ) 445 The 'data' could be the address in TES, in this case the object 446 is retrieved from TES and the method is applied to the objects, 448 >>> fill ( histo , ## the reference to the histogram 449 'Rec/Track/Best' , ## the location of objects in TES 450 lambda t : t.pt() ) ## function to be used for histogram fill 451 >>> fill ( histo , ## the reference to the histogram 452 'Rec/Track/Best' , ## the address of objects in TES 453 lambda t : t.pt() , ## the function to be used for histogram fill 454 lambda t : t.charge()>0 ) ## the criteria to select tracks 456 The arguments 'fun' and 'cut' could be strings, in this case 457 they are evaluated by python before usage. 458 This option could be often very useful. 463 if type(data) == str:
466 return fill(histo, data, fun, cut, **kwargs)
470 fun = eval(fun, globals())
474 cut = eval(cut, globals())
476 if not hasattr(data,
'__iter__'):
479 if not hasattr(histo,
'fill')
and hasattr(histo,
'Fill'):
480 setattr(histo,
'fill', getattr(histo,
'Fill'))
485 histo.fill(fun(item))
492 aida2root = cpp.Gaudi.Utils.Aida2ROOT.aida2root
502 >>> aida = ... ## get AIDA histogram 503 >>> root = aida.toROOT() ## convert it to ROOT 509 _to_root_.__doc__ += aida2root.__doc__
511 for t
in (cpp.AIDA.IHistogram3D, cpp.AIDA.IHistogram2D, cpp.AIDA.IHistogram1D,
512 cpp.AIDA.IProfile2D, cpp.AIDA.IProfile1D):
513 if not hasattr(t,
'Fill')
and hasattr(t,
'fill'):
514 setattr(t,
'Fill', getattr(t,
'fill'))
515 for attr
in (
'toROOT',
'toRoot',
'asROOT',
'asRoot',
'AsROOT',
'AsRoot'):
516 if not hasattr(t, attr):
517 setattr(t, attr, _to_root_)
519 cpp.AIDA.IHistogram3D. __repr__ =
lambda s: cpp.GaudiAlg.Print3D.toString(
521 cpp.AIDA.IHistogram3D.__str__ = cpp.AIDA.IHistogram3D.__repr__
523 HistoStats = cpp.Gaudi.Utils.HistoStats
531 Evaluate 'bin-by-bin' momentum of order 'order' around the value 'value' 535 >>> print h1.moment ( 5 ) 538 return HistoStats.moment(self, order, value)
547 Evaluate error for 'bin-by-bin' momentum of order 'order' around the value 'value' 551 >>> print h1.momentErr ( 5 ) 554 return HistoStats.momentErr(self, order)
563 Evaluate 'bin-by-bin' central momentum (around mean value) 567 >>> print h1.centralMoment ( 5 ) 570 return HistoStats.centralMoment(self, order)
579 Evaluate error for 'bin-by-bin' central momentum (around mean value) 583 >>> print h1.centralMomentErr ( 5 ) 586 return HistoStats.centralMomentErr(self, order)
595 Evaluate 'bin-by-bin' skewness for 1D AIDA histogram 598 >>> print h1.skewness() 601 return HistoStats.skewness(self)
610 Evaluate error for 'bin-by-bin' skewness 613 >>> print h1.skewnessErr() 616 return HistoStats.skewnessErr(self)
625 Evaluate 'bin-by-bin' kurtosis 628 >>> print h1.kurtosis () 631 return HistoStats.kurtosis(self)
640 Evaluate error for 'bin-by-bin' kurtotis for 1D AIDA histogram 643 >>> print h1.kurtotisErr() 646 return HistoStats.kurtosisErr(self)
654 Number of equivalent entries 656 return HistoStats.nEff(self)
664 Evaluate the MEAN value 666 return HistoStats.mean(self)
674 Evaluate the error for MEAN estimate 676 return HistoStats.meanErr(self)
684 Evaluate the RMS for AIDA histogram 686 return HistoStats.rms(self)
694 Evaluate the error for RMS estimate 696 return HistoStats.rmsErr(self)
704 Get an error in the sum bin height ('in-range integral') 706 return HistoStats.sumBinHeightErr(self)
713 """ Get an error in the sum bin height ('in-range integral') """ 714 return HistoStats.sumAllBinHeightErr(self)
722 The fraction of overflow entries (useful for shape comparison) 724 return HistoStats.overflowEntriesFrac(self)
732 The error for fraction of overflow entries (useful for shape comparison) 734 return HistoStats.overflowEntriesFracErr(self)
742 The fraction of underflow entries (useful for shape comparison) 744 return HistoStats.underflowEntriesFrac(self)
752 The error for fraction of underflow entries (useful for shape comparison) 754 return HistoStats.underflowEntriesFracErr(self)
762 The fraction of overflow integral (useful for shape comparison) 764 return HistoStats.overflowIntegralFrac(self)
772 The error for fraction of overflow integral (useful for shape comparison) 774 return HistoStats.overflowIntegralFracErr(self)
782 The fraction of underflow integral (useful for shape comparison) 784 return HistoStats.underflowIntegralFrac(self)
792 The error for fraction of underflow integral (useful for shape comparison) 794 return HistoStats.underflowIntegralFracErr(self)
805 Get number of entries in histogram up to the certain bin (not-included) 807 attention: underflow bin is included! 810 >>> print h1.nEntries ( 10 ) 812 Get number of entries in histogram form the certain 813 minimal bin up to the certain maximal bin (not-included) 816 >>> print h1.nEntries ( 10 , 15 ) 819 if i2 < i1
or i2 < 0:
820 return HistoStats.nEntries(self, i1)
821 return HistoStats.nEntries(self, i1, i2)
829 Get the fraction of entries in histogram up to the certain bin (not-included) 831 attention: underflow bin is included! 834 >>> print h1.nEntriesFrac ( 10 ) 836 Get the fraction of entries in histogram form the certain 837 minimal bin up to the certain maximal bin (not-included) 840 >>> print h1.nEntriesFrac ( 10 , 15 ) 843 if i2 < i1
or i2 < 0:
844 return HistoStats.nEntriesFrac(self, i1)
845 return HistoStats.nEntriesFrac(self, i1, i2)
853 Get error for fraction of entries in histogram up to the certain bin (not-included) 855 attention: underflow bin is included! 858 >>> print h1.nEntriesFracErr( 10 ) 860 Get error fraction of entries in histogram form the certain 861 minimal bin up to the certain maximal bin (not-included) 864 >>> print h1.nEntriesFracErr ( 10 , 15 ) 867 if i2 < i1
or i2 < 0:
868 return HistoStats.nEntriesFracErr(self, i1)
869 return HistoStats.nEntriesFracErr(self, i1, i2)
873 i1DH = cpp.AIDA.IHistogram1D
875 if not hasattr(i1DH,
'moment'):
876 i1DH.moment = _moment_
877 if not hasattr(i1DH,
'momentErr'):
878 i1DH.momentErr = _momentErr_
879 if not hasattr(i1DH,
'centralMoment'):
880 i1DH.centralMoment = _centralMoment_
881 if not hasattr(i1DH,
'momentMomentErr'):
882 i1DH.centralMomentErr = _centralMomentErr_
883 if not hasattr(i1DH,
'nEff'):
885 if not hasattr(i1DH,
'mean'):
887 if not hasattr(i1DH,
'meanErr'):
888 i1DH.meanErr = _meanErr_
889 if not hasattr(i1DH,
'rms'):
891 if not hasattr(i1DH,
'rmsErr'):
892 i1DH.rmsErr = _rmsErr_
893 if not hasattr(i1DH,
'skewness'):
894 i1DH.skewness = _skewness_
895 if not hasattr(i1DH,
'skewnessErr'):
896 i1DH.skewnessErr = _skewnessErr_
897 if not hasattr(i1DH,
'kurtosis'):
898 i1DH.kurtosis = _kurtosis_
899 if not hasattr(i1DH,
'kurtosisErr'):
900 i1DH.kurtosisErr = _kurtosisErr_
902 if not hasattr(i1DH,
'overflowEntriesFrac'):
903 i1DH.overflowEntriesFrac = _overflowEntriesFrac_
904 if not hasattr(i1DH,
'overflowEntriesFracErr'):
905 i1DH.overflowEntriesFracErr = _overflowEntriesFracErr_
906 if not hasattr(i1DH,
'underflowEntriesFrac'):
907 i1DH.underflowEntriesFrac = _underflowEntriesFrac_
908 if not hasattr(i1DH,
'underflowEntriesFracErr'):
909 i1DH.underflowEntriesFracErr = _underflowEntriesFracErr_
911 if not hasattr(i1DH,
'overflowIntegralFrac'):
912 i1DH.overflowIntegralFrac = _overflowIntegralFrac_
913 if not hasattr(i1DH,
'overflowIntegralFracErr'):
914 i1DH.overflowIntegralFracErr = _overflowIntegralFracErr_
915 if not hasattr(i1DH,
'underflowIntegralFrac'):
916 i1DH.underflowIntegralFrac = _underflowIntegralFrac_
917 if not hasattr(i1DH,
'underflowIntegralFracErr'):
918 i1DH.underflowIntegralFracErr = _underflowIntegralFracErr_
920 if not hasattr(i1DH,
'nEntries'):
921 i1DH.nEntries = _nEntries_
922 if not hasattr(i1DH,
'nEntriesFrac'):
923 i1DH.nEntriesFrac = _nEntriesFrac_
924 if not hasattr(i1DH,
'nEntriesFracErr'):
925 i1DH.nEntriesFracErr = _nEntriesFracErr_
932 Get the path in THS for the given AIDA object: 935 >>> print aida.path() 938 return cpp.Gaudi.Utils.Histos.path(self)
941 iBH = cpp.AIDA.IBaseHistogram
942 if not hasattr(iBH,
'path'):
944 if not hasattr(iBH,
'TESpath'):
946 if not hasattr(iBH,
'location'):
947 iBH.location = _path_
954 Dump the histogram/profile in text format (a'la HBOOK) 957 >>> print dumpHisto ( histo ) 959 >>> print histo.dump() 960 >>> print histo.dump( 20 , 20 ) 961 >>> print histo.dump( 20 , 20 , True ) 966 return cpp.Gaudi.Utils.Histos.histoDump(histo, *args)
969 __dumpHisto__.__doc__ =
'\n' + cpp.Gaudi.Utils.Histos.histoDump.__doc__
973 histoDump = __dumpHisto__
974 dumpHisto = __dumpHisto__
976 for t
in (cpp.AIDA.IHistogram1D, cpp.AIDA.IProfile1D, ROOT.TH1D, ROOT.TH1F,
977 ROOT.TH1, ROOT.TProfile):
978 for method
in (
'dump',
'dumpHisto',
'dumpAsText'):
979 if not hasattr(t, method):
980 setattr(t, method, __dumpHisto__)
987 Class to write histograms to a ROOT file. 988 hFile = HistoFile("myFile.root") 994 hFile.save(myHisto0, myHisto1, myHisto2) 995 histoList = [h0, h1, h2, h3] 996 hFile.save(histoList) 1000 __author__ =
"Juan Palacios juan.palacios@nikhef.nl" 1003 self.
file = ROOT.TFile(fileName,
"RECREATE")
1004 from GaudiPython
import gbl
1007 gbl.AIDA.IHistogram1D, gbl.AIDA.IHistogram2D,
1008 gbl.AIDA.IHistogram3D, gbl.AIDA.IProfile1D, gbl.AIDA.IProfile2D,
1013 histoType =
type(histo)
1021 This function stores histograms on the file for future saving. 1022 It takes an arbitrary number of AIDA or ROOT histograms or 1026 if type(args[0]) == list:
1041 if '__main__' == __name__:
1046 print(sys.modules[__name__].__dict__[o].__doc__)
def _underflowIntegralFrac_(self)
def _nEntriesFracErr_(self, i1, i2=-10000000)
def _sumBinHeightErr_(self)
def __init__(self, fileName)
def _sumAllBinHeightErr_(self)
def getAsROOT(path, **kwargs)
def _overflowIntegralFracErr_(self)
def _getHistoSvc(**kwargs)
def _overflowEntriesFrac_(self)
def book(*args, **kwargs)
def _moment_(self, order, value=0)
def _nEntriesFrac_(self, i1, i2=-10000000)
def getAsAIDA(path, **kwargs)
def _underflowEntriesFrac_(self)
def _overflowIntegralFrac_(self)
def _overflowEntriesFracErr_(self)
def __dumpHisto__(histo, *args)
def _underflowEntriesFracErr_(self)
def _centralMomentErr_(self, order)
def bookProf(*args, **kwargs)
def _nEntries_(self, i1, i2=-10000000)
def fill(histo, data, fun=lambda x:x, cut=lambda x:True, **kwargs)
def _momentErr_(self, order)
def _centralMoment_(self, order)
def _underflowIntegralFracErr_(self)
def __convertibleType(self, histo)