| # Gaudi Framework, version v21r6 |

Home |  | Generated: 11 Nov 2009

# HistoUtils.py

Go to the documentation of this file.

    00001 #!/usr/bin/env python
    00002 # =============================================================================
    00003 ##  This module contains set of simple and useful utilities for booking and
    00004 #   manipulations with Gaudi-AIDA histograms, inspired by Thomas' request
    00005 #   @author Vanya BELYAEV ibelyaev@physics.syr.edu
    00006 #   @date 2007-08-03
    00007 # =============================================================================
    00008 """
    00009 This module contains set of simple and useful utilities for booking and
    00010 manipulations with Gaudi-AIDA histograms, inspired by Thomas' request
    00011
    00012 The module contains following public symbols:
    00013
    00014   - book       for booking of various 1D,2D&3D-histograms
    00015   - bookProf   for booking of various 1D&2D-profiles
    00016   - getAsAIDA  for retrieval of histograms/profiles from HTS in AIDA format
    00017   - getAsROOT  for retrieval of histograms/profiles from HTS in ROOT format
    00018   - fill       for smart filling of 1D-histogram (AIDA or ROOT)
    00019   - aida2root  for conversion of AIDA histogram to ROOT
    00020   - HistoStats for many statistical information
    00021   - HistoFile  class for storing histograms to a file
    00022   - histoDump  for dumping of the histogram in text format (a'la HBOOK)
    00023   - dumpHisto  for dumping of the histogram in text format (a'la HBOOK)
    00024
    00025 """
    00026 # =============================================================================
    00027 __author__ = "Vanya BELYAEV ibelyaev@physics.syr.edu"
    00028 # =============================================================================
    00029 __all__    = (
    00030     'book'      , ##                book AIDA histogram using Histogram Service
    00031     'bookProf'  , ##        book AIDA profile histogram using Histogram Service
    00032     'getAsAIDA' , ## get the histogram form Histogram Service as AIDA histogram
    00033     'getAsROOT' , ## get the histogram form Histogram Service as AIDA histogram
    00034     'fill'      , ##              "power-fill" method for filling of histograms
    00035     'aida2root' , ##                                     AIDA -> ROOT converter
    00036     'HistoStats', ##                  statistical information for 1D-histograms
    00037     'HistoFile' , ##                     class for storing histograms to a file
    00038     'histoDump' , ##                     dump histogramintext format a'la HBOOK
    00039     'dumphisto'   ##                     dump histogramintext format a'la HBOOK
    00040     )
    00041 # =============================================================================
    00042 ## import core of Gaudi
    00043 import ROOT
    00044 from   GaudiPython.Bindings import AppMgr
    00045 from   GaudiPython.Bindings import iHistogramSvc
    00046 from   GaudiPython.Bindings import gbl as cpp
    00047 HID = cpp.GaudiAlg.ID
    00048
    00049 # =============================================================================
    00050 ## Helper private auxiliary function to get Application Manager
    00051 def _getAppMgr   ( **kwargs  ) :
    00052     """
    00053     Helper private auxiliary function to get Application Manager
    00054     """
    00055     gaudi = kwargs.get ( 'gaudi' , None )
    00056     if not gaudi : gaudi = AppMgr()
    00057     if not gaudi : raise RuntimeError, 'Unable to get valid ApplicationMgr'
    00058     return gaudi                                               ## RETURN
    00059
    00060 # =============================================================================
    00061 ## Helper private auxiliary function to get iHistogramSvs
    00062 def _getHistoSvc ( **kwargs ) :
    00063     """
    00064     Helper private auxiliary function to get iHistogramSvs
    00065     """
    00066     svc = kwargs.get ( 'service' , None )
    00067     if not svc : svc = kwargs.get ( 'svc' , None )
    00068     else       : return svc                                    ## RETURN
    00069     gaudi = _getAppMgr ( **kwargs )
    00070     return gaudi.histsvc ()                                    ## RETURN
    00071
    00072 # =============================================================================
    00073 ## Helper private auxiliary function to get iDataSvs
    00074 def _getEvtSvc ( **kwargs ) :
    00075     """
    00076     Helper private auxiliary function to get iDataSvs
    00077     """
    00078     svc = kwargs.get ( 'service' , None )
    00079     if not svc : svc = kwargs.get ( 'svc' , None )
    00080     else       : return svc                                    ## RETURN
    00081     gaudi = _getAppMgr ( **kwargs )
    00082     return gaudi.evtsvc()                                      ## RETURN
    00083
    00084 # =============================================================================
    00085 ## The trivial function to book the various 1D,2D&3D-histograms
    00086 def book ( *args , **kwargs ) :
    00087     """
    00088     The trivial function to book the various 1D,2D&3D-histograms
    00089
    00090     (1) book the trivial 1D histogram with full path
    00091
    00092     >>> h1D = book ( 'path/to/my/histo'       , ## path in Histogram Transient Store
    00093                      'cosine of decay angle ' , ## histogram title
    00094                       100                     , ## number of bins
    00095                       -1                      , ## low edge
    00096                       100                     ) ## high edge
    00097
    00098     (2) book the trivial 1D histogram with directory path and string ID :
    00099
    00100     >>> h1D = book ( 'path/to/directory'      , ## the path to directory in HTS
    00101                      'H1'                     , ## string histogram identifier
    00102                      'cosine of decay angle ' , ## histogram title
    00103                       100                     , ## number of bins
    00104                       -1                      , ## low edge
    00105                       100                     ) ## high edge
    00106
    00107     (3) book the trivial 1D histogram with directory path and integer ID :
    00108
    00109     >>> h1D = book ( 'path/to/directory'      , ## the path to directory in HTS
    00110                      124                      , ## integer histogram identifier
    00111                      'cosine of decay angle ' , ## histogram title
    00112                       100                     , ## number of bins
    00113                       -1                      , ## low edge
    00114                       100                     ) ## high edge
    00115
    00116     (4) book the trivial 2D histogram with full path
    00117
    00118     >>> h1D = book ( 'path/to/my/histo'       , ## path in Histogram Transient Store
    00119                      'm12**2 versus m13**2'   , ## histogram title
    00120                       50                      , ## number of X-bins
    00121                       1.0                     , ## low X-edge
    00122                       4.0                     , ## high X-edge
    00123                       50                      , ## number of Y-bins
    00124                       1                       , ## low Y-edge
    00125                       2                       ) ## high Y-edge
    00126
    00127     (5) book the trivial 2D histogram with directory path and literal ID
    00128
    00129     >>> h1D = book ( 'path/to/directory'      , ## path in Histogram Transient Store
    00130                      'Dalitz1'                , ## literal histogram identifier
    00131                      'm12**2 versus m13**2'   , ## histogram title
    00132                       50                      , ## number of X-bins
    00133                       1.0                     , ## low X-edge
    00134                       4.0                     , ## high X-edge
    00135                       50                      , ## number of Y-bins
    00136                       1                       , ## low Y-edge
    00137                       2                       ) ## high Y-edge
    00138
    00139     (6) book the trivial 2D histogram with directory path and integer ID
    00140
    00141     >>> h1D = book ( 'path/to/directory'      , ## path in Histogram Transient Store
    00142                      854                      , ## integer histogram identifier
    00143                      'm12**2 versus m13**2'   , ## histogram title
    00144                       50                      , ## number of X-bins
    00145                       1.0                     , ## low X-edge
    00146                       4.0                     , ## high X-edge
    00147                       50                      , ## number of Y-bins
    00148                       1.0                     , ## low Y-edge
    00149                       4.0                     ) ## high Y-edge
    00150
    00151     (7) book the trivial 3D histogram with full path
    00152
    00153     >>> h1D = book ( 'path/to/my/histo'       , ## path in Histogram Transient Store
    00154                      'x vs y vs z '           , ## histogram title
    00155                       10                      , ## number of X-bins
    00156                       -1.0                    , ## low X-edge
    00157                       1.0                     , ## high X-edge
    00158                       10                      , ## number of Y-bins
    00159                       -1.0                    , ## low Y-edge
    00160                       1.0                     , ## high Y-edge
    00161                       10                      , ## number of Z-bins
    00162                       -1.0                    , ## low Z-edge
    00163                       1.0                     ) ## high Z-edge
    00164
    00165     (8) book the trivial 3D histogram with directory path and literal ID
    00166
    00167     >>> h1D = book ( 'path/to/directory'      , ## path in Histogram Transient Store
    00168                      'xyz'                    , ## literal histogram identifier
    00169                      'x vs y vs z'            , ## histogram title
    00170                       10                      , ## number of X-bins
    00171                       -1.0                    , ## low X-edge
    00172                       1.0                     , ## high X-edge
    00173                       10                      , ## number of Y-bins
    00174                       -1.0                    , ## low Y-edge
    00175                       1.0                     , ## high Y-edge
    00176                       10                      , ## number of Z-bins
    00177                       -1.0                    , ## low Z-edge
    00178                       1.0                     ) ## high Z-edge
    00179
    00180     (9) book the trivial 3D histogram with directory path and integer ID
    00181
    00182     >>> h1D = book ( 'path/to/directory'      , ## path in Histogram Transient Store
    00183                      888                      , ## integer histogram identifier
    00184                      'x vs y vs z'            , ## histogram title
    00185                       10                      , ## number of X-bins
    00186                       -1.0                    , ## low X-edge
    00187                       1.0                     , ## high X-edge
    00188                       10                      , ## number of Y-bins
    00189                       -1.0                    , ## low Y-edge
    00190                       1.0                     , ## high Y-edge
    00191                       10                      , ## number of Z-bins
    00192                       -1.0                    , ## low Z-edge
    00193                       1.0                     ) ## high Z-edge
    00194
    00195     Many other booking methods are available,
    00196     e.g. for the histograms with non-equidistant bins, see IHistogamSvc::book
    00197
    00198     """
    00199     svc = _getHistoSvc ( **kwargs )
    00200     if not svc : raise RuntimeError, 'Unable to get valid HistogramService '
    00201     ## book the histogram using the service
    00202     return svc.book(*args)                                          ## RETURN
    00203
    00204 book.__doc__ += '\n\n' + '\thelp(iHistogramSvc.book) : \n\n' \
    00205                 + iHistogramSvc.book       . __doc__
    00206 book.__doc__ += '\n\n' + '\thelp(IHistogramSvc::book) : \n\n'            \
    00207                 + cpp.IHistogramSvc.book . __doc__
    00208
    00209 # =============================================================================
    00210 ## The trivial function to book 1D&2D profile histograms:
    00211 def bookProf ( *args , **kwargs ) :
    00212     """
    00213
    00214     The trivial function to book 1D&2D profile histograms:
    00215
    00216     (1) book 1D-profile histogram with full path in Histogram Transient Store:
    00217     >>> histo = bookProf ( 'path/to/my/profile'  , ## path in Histogram Transient Store
    00218                            'Energy Correction'   , ## the histogram title
    00219                            100                   , ## number of X-bins
    00220                            0.0                   , ## low X-edge
    00221                            100                   ) ## high X-edge
    00222
    00223     (2) book 1D-profile histogram with directory path and literal ID
    00224     >>> histo = bookProf ( 'path/to/my/profile'  , ## path in Histogram Transient Store
    00225                            'Calibration'         , ## the histogram literal identifier
    00226                            'Energy Correction'   , ## the histogram title
    00227                            100                   , ## number of X-bins
    00228                            0.0                   , ## low X-edge
    00229                            100                   ) ## high X-edge
    00230
    00231     (3) book 1D-profile histogram with directory path and integer  ID
    00232     >>> histo = bookProf ( 'path/to/my/profile'  , ## path in Histogram Transient Store
    00233                            418                   , ## the histogram integer identifier
    00234                            'Energy Correction'   , ## the histogram title
    00235                            100                   , ## number of X-bins
    00236                            0.0                   , ## low X-edge
    00237                            100                   ) ## high X-edge
    00238
    00239     (4) book 2D-profile histogram with full path in Histogram Transient Store:
    00240     >>> histo = bookProf ( 'path/to/my/profile'  , ## path in Histogram Transient Store
    00241                            'Energy Correction'   , ## the histogram title
    00242                            50                    , ## number of X-bins
    00243                            0.0                   , ## low X-edge
    00244                            100                   , ## high X-edge
    00245                            50                    , ## number of Y-bins
    00246                            0.0                   , ## low Y-edge
    00247                            100                   ) ## high Y-edge
    00248
    00249     (5) book 2D-profile histogram with directory path and literal ID
    00250     >>> histo = bookProf ( 'path/to/my/profile'  , ## path in Histogram Transient Store
    00251                            'Calibration'         , ## the histogram literal identifier
    00252                            'Energy Correction'   , ## the histogram title
    00253                            50                    , ## number of X-bins
    00254                            0.0                   , ## low X-edge
    00255                            100                   , ## high X-edge
    00256                            50                    , ## number of Y-bins
    00257                            0.0                   , ## low Y-edge
    00258                            100                   ) ## high Y-edge
    00259
    00260     (6) book 2D-profile histogram with directory path and integer  ID
    00261     >>> histo = bookProf ( 'path/to/my/profile'  , ## path in Histogram Transient Store
    00262                            418                   , ## the histogram integer identifier
    00263                            'Energy Correction'   , ## the histogram title
    00264                            50                    , ## number of X-bins
    00265                            0.0                   , ## low X-edge
    00266                            100                   , ## high X-edge
    00267                            50                    , ## number of Y-bins
    00268                            0.0                   , ## low Y-edge
    00269                            100                   ) ## high Y-edge
    00270
    00271     Many other booking methods are available,
    00272     e.g. for the histograms with non-equidistant bins, see IHistogamSvc::book
    00273
    00274     """
    00275     svc = _getHistoSvc ( **kwargs )
    00276     if not svc : raise RuntimeError, 'Unable to get valid HistogramService '
    00277     ## book the histogram using the service
    00278     return svc.bookProf(*args)                                      ## RETURN
    00279
    00280
    00281 bookProf.__doc__ += '\n\n' + '\thelp(iHistogramSvc.bookProf) : \n\n' \
    00282                     + iHistogramSvc.bookProf . __doc__
    00283 bookProf.__doc__ += '\n\n' + '\thelp(IHistogramSvc::bookProf) : \n\n'             \
    00284                     + cpp.IHistogramSvc.bookProf . __doc__
    00285
    00286 # =============================================================================
    00287 ## The most trivial function to retrieve the histogram from Histogram Transient Store
    00288 def getAsAIDA ( path , **kwargs ) :
    00289     """
    00290
    00291     The most trivial function to retrieve the histogram from Histogram Transient Store
    00292     The histogram is returned by reference to its AIDA-representation (if possible)
    00293
    00294     >>> h = getAsAIDA ( 'some/path/to/my/histogram' )
    00295
    00296     """
    00297     svc = _getHistoSvc ( **kwargs )
    00298     if not svc : raise RuntimeError, 'Unable to get valid HistogramService '
    00299     ## return the histogram
    00300     return svc.getAsAIDA( path )                                   ## RETURN
    00301
    00302 getAsAIDA.__doc__ += '\n\n' + '\thelp(iHistogramSvc.getAsAIDA) : \n\n' \
    00303                      + iHistogramSvc.getAsAIDA . __doc__
    00304 getAsAIDA.__doc__ += '\n\n' + '\thelp(iHistogramSvc.retrieve)  : \n\n' \
    00305                      + iHistogramSvc.retrieve  . __doc__
    00306
    00307 # =============================================================================
    00308 ## The most trivial function to retrieve the histogram from Histogram Transient Store
    00309 def getAsROOT ( path , **kwargs ) :
    00310     """
    00311
    00312     The most trivial function to retrieve the histogram from Histogram Transient Store
    00313     The histogram is returned by reference to its underlying native ROOT-representation (if possible)
    00314
    00315     >>> h = getAsROOT ( 'some/path/to/my/histogram' )
    00316
    00317     """
    00318     svc = _getHistoSvc ( **kwargs )
    00319     if not svc : raise RuntimeError, 'Unable to get valid HistogramService '
    00320     ## return the histogram
    00321     return svc.getAsROOT( path )                                   ## RETURN
    00322
    00323 getAsROOT.__doc__ += '\n\n' + '\thelp(iHistogramSvc.getAsROOT) : \n\n' \
    00324                      + iHistogramSvc.getAsROOT . __doc__
    00325
    00326
    00327 # =============================================================================
    00328 ## The function which allows 'the smart fill' of 1D-histogram
    00329 def fill ( histo                   ,   ## histogram
    00330            data                    ,   ## input data
    00331            fun   = lambda x : x    ,   ## function to be used
    00332            cut   = lambda x : True ,   ## cut to be applied
    00333            **kwargs                ) : ## optional extra arguments
    00334     """
    00335
    00336     The function which allows 'the smart fill' of 1D-histogram
    00337
    00338     >>> histo = ...
    00339
    00340     The most trivial case, fill with the value
    00341     >>> fill ( histo , 1.0 )
    00342
    00343     Fill from any iterable object (sequence)
    00344     >>> fill ( histo , [1,,2,3,4,5,10] )
    00345
    00346     Fill from iterable object and apply the function:
    00347     >>> fill ( histo , [1,2,3,4,5] , math.sin )
    00348
    00349     Use lambda form:
    00350     >>> fill ( histo , [1,2,3,4,5] , lambda x : x*x )
    00351
    00352     The same
    00353     >>> fill ( histo , [1,2,3,4,5] , fun = lambda x : x*x )
    00354
    00355     Use internal attributes:
    00356     >>> tracks = evtSvc['Rec/Track/Best']    ## iterable container of tracks
    00357     >>> fill ( histo , tracks , lambda t : t.pt() )
    00358
    00359     Apply the predicate: fill only even numbers:
    00360     >>> fill ( histo , [1,2,3,4,5,6,7] , lambda x : x , lambda y : y%2 )
    00361
    00362     The same (omit the trivial function) :
    00363     >>> fill ( histo , [1,2,3,4,5,6,7] , cut = lambda y : y%2 )
    00364
    00365     Apply the predicate: fill only pt for positively charged tracks:
    00366     >>> tracks = evtSvc['Rec/Track/Best']
    00367     >>> fill ( histo , tracks , lambda t : t.pt() , lambda t : 0<t.charge() )
    00368
    00369     The same:
    00370     >>> fill ( histo , tracks ,
    00371                fun = lambda t : t.pt()       ,
    00372                cut = lambda t : 0<t.charge() )
    00373
    00374     Ordinary functions are also fine:
    00375     >>> def myfun ( track ) : return sin( track.pt() + track.p() )
    00376     >>> def mycut ( track ) : return track.p() > 100 * GeV
    00377     >>> fill ( histo , tracks , myfun , mycut )
    00378
    00379     The 'data' could be the address in TES, in this case the object
    00380     is retrieved from TES and the method is applied to the objects,
    00381     retrieved from TES:
    00382     >>> fill (  histo             , ## the reference to the histogram
    00383                'Rec/Track/Best'   , ## the location of objects in TES
    00384                 lambda t : t.pt() ) ## function to be used for histogram fill
    00385     >>> fill (  histo             , ## the reference to the histogram
    00386                'Rec/Track/Best'   , ## the address of objects in TES
    00387                 lambda t : t.pt() , ## the function to be used for histogram fill
    00388                 lambda t : t.charge()>0 ) ## the criteria to select tracks
    00389
    00390     The arguments 'fun' and 'cut' could be strings, in this case
    00391     they are evaluated by python before usage.
    00392     This option could be often very useful.
    00393
    00394     """
    00395
    00396     # if value is a string, try to get the objects from TES
    00397     if type ( data ) == str :
    00398         svc  = _getEvtSvc ( **kwargs )
    00399         data = svc[data]
    00400         return fill ( histo , data , fun , cut , **kwargs )
    00401
    00402     # if the function  is a string: evaluate it!
    00403     if type ( fun  ) == str : fun  = eval ( fun  , globals() )
    00404
    00405     # if the criterion is a string: evaluate it!
    00406     if type ( cut  ) == str : cut  = eval ( cut  , globals() )
    00407
    00408     if not hasattr ( data , '__iter__' ) : data = [ data ]
    00409
    00410     if not hasattr ( histo , 'fill' ) and hasattr ( histo , 'Fill' ) :
    00411         setattr ( histo , 'fill' , getattr ( histo , 'Fill' ) )
    00412
    00413     for item in data :
    00414         if not cut ( item )         : continue             ## CONTINUE
    00415         histo.fill ( fun ( item ) )
    00416
    00417     return histo                                           ## RETURN
    00418
    00419 # =============================================================================
    00420 ## AIDA -> ROOT converter
    00421 aida2root = cpp.Gaudi.Utils.Aida2ROOT.aida2root
    00422 # =============================================================================
    00423 ## Convert AIDA to ROOT
    00424 def _to_root_ ( self ) :
    00425     """
    00426     Convert AIDA to ROOT
    00427
    00428     >>> aida = ...            ## get AIDA histogram
    00429     >>> root = aida.toROOT()  ## convert it to ROOT
    00430
    00431     """
    00432     return aida2root ( self )
    00433
    00434 _to_root_ . __doc__  += aida2root . __doc__
    00435
    00436 for t in ( cpp.AIDA.IHistogram3D , cpp.AIDA.IHistogram2D , cpp.AIDA.IHistogram1D ,
    00437            cpp.AIDA.IProfile2D   , cpp.AIDA.IProfile1D   ) :
    00438     if not hasattr ( t , 'Fill' ) and hasattr ( t , 'fill' ) :
    00439         setattr ( t , 'Fill' , getattr ( t , 'fill' ) )
    00440     for attr in ( 'toROOT' , 'toRoot' ,
    00441                   'asROOT' , 'asRoot' ,
    00442                   'AsROOT' , 'AsRoot' ) :
    00443         if not hasattr ( t , attr ) : setattr ( t , attr , _to_root_ )
    00444
    00445 cpp.AIDA.IHistogram3D. __repr__ =  lambda s : cpp.GaudiAlg.Print3D.toString( s , HID( s.title() ) )
    00446 cpp.AIDA.IHistogram3D. __str__  = cpp.AIDA.IHistogram3D. __repr__
    00447
    00448
    00449 HistoStats = cpp.Gaudi.Utils.HistoStats
    00450
    00451 # =============================================================================
    00452 ## Evaluate 'bin-by-bin' momentum of certain order around the value
    00453 def _moment_ ( self , order , value = 0 ) :
    00454     """
    00455     Evaluate 'bin-by-bin' momentum of order 'order' around the value 'value'
    00456     for 1D histogram
    00457
    00458     >>> h1 = ...
    00459     >>> print h1.moment ( 5 )
    00460
    00461     """
    00462     return HistoStats.moment ( self , order , value )
    00463
    00464 # =============================================================================
    00465 ## Evaluate error in 'bin-by-bin' momentum of certain order around the value
    00466 def _momentErr_ ( self , order ) :
    00467     """
    00468     Evaluate error for 'bin-by-bin' momentum of order 'order' around the value 'value'
    00469     for 1D histogram
    00470
    00471     >>> h1 = ...
    00472     >>> print h1.momentErr ( 5 )
    00473
    00474     """
    00475     return HistoStats.momentErr ( self , order )
    00476 # =============================================================================
    00477 ## Evaluate 'bin-by-bin' central momentum (around mean value)
    00478 def _centralMoment_ ( self , order ) :
    00479     """
    00480     Evaluate 'bin-by-bin' central momentum (around mean value)
    00481     for 1D histogram
    00482
    00483     >>> h1 = ...
    00484     >>> print h1.centralMoment ( 5 )
    00485
    00486     """
    00487     return HistoStats.centralMoment ( self , order )
    00488
    00489 # =============================================================================
    00490 ## Evaluate error in 'bin-by-bin' momentum of certain order around the value
    00491 def _centralMomentErr_ ( self , order ) :
    00492     """
    00493     Evaluate error for 'bin-by-bin' central momentum (around mean value)
    00494     for 1D histogram
    00495
    00496     >>> h1 = ...
    00497     >>> print h1.centralMomentErr ( 5 )
    00498
    00499     """
    00500     return HistoStats.centralMomentErr ( self , order )
    00501
    00502 # =============================================================================
    00503 ## Evaluate 'bin-by-bin' skewness for 1D histogram
    00504 def _skewness_ ( self ) :
    00505     """
    00506     Evaluate 'bin-by-bin' skewness for 1D histogram
    00507
    00508     >>> h1 = ...
    00509     >>> print h1.skewness()
    00510
    00511     """
    00512     return HistoStats.skewness ( self )
    00513
    00514 # =============================================================================
    00515 ## Evaluate error for 'bin-by-bin' skewness for 1D histogram
    00516 def _skewnessErr_ ( self ) :
    00517     """
    00518     Evaluate error for 'bin-by-bin' skewness for 1D histogram
    00519
    00520     >>> h1 = ...
    00521     >>> print h1.skewnessErr()
    00522
    00523     """
    00524     return HistoStats.skewnessErr ( self )
    00525
    00526 # =============================================================================
    00527 ## Evaluate 'bin-by-bin' kurtosis for 1D histogram
    00528 def _kurtosis_ ( self ) :
    00529     """
    00530     Evaluate 'bin-by-bin' kurtosis for 1D histogram
    00531
    00532     >>> h1 = ...
    00533     >>> print h1.kurtosis ()
    00534
    00535     """
    00536     return HistoStats.kurtosis ( self )
    00537
    00538 # =============================================================================
    00539 ## Evaluate error for 'bin-by-bin' kurtosis for 1D histogram
    00540 def _kurtosisErr_ ( self ) :
    00541     """
    00542     Evaluate error for 'bin-by-bin' kurtotis for 1D histogram
    00543
    00544     >>> h1 = ...
    00545     >>> print h1.kurtotisErr()
    00546
    00547     """
    00548     return HistoStats.kurtosisErr ( self )
    00549
    00550 # =============================================================================
    00551 def _nEff_    ( self ) :
    00552     """
    00553     Number of equivalent entries
    00554     """
    00555     return HistoStats.nEff ( self )
    00556 # =============================================================================
    00557 def _mean_    ( self ) :
    00558     """
    00559     Evaluate the MEAN value
    00560     """
    00561     return HistoStats.mean ( self )
    00562 # =============================================================================
    00563 def _meanErr_ ( self ) :
    00564     """
    00565     Evaluate the error for MEAN estimate
    00566     """
    00567     return HistoStats.meanErr ( self )
    00568
    00569 # =============================================================================
    00570 def _rms_    ( self ) :
    00571     """
    00572     Evaluate the RMS
    00573     """
    00574     return HistoStats.rms ( self )
    00575 # =============================================================================
    00576 def _rmsErr_ ( self ) :
    00577     """
    00578     Evaluate the error for RMS estimate
    00579     """
    00580     return HistoStats.rmsErr ( self )
    00581
    00582 # =============================================================================
    00583 def _sumBinHeightErr_    ( self ) :
    00584     """
    00585     Get an error in the sum bin height ('in-range integral')
    00586     """
    00587     return HistoStats.sumBinHeightErr ( self )
    00588
    00589 # =============================================================================
    00590 def _sumAllBinHeightErr_ ( self ) :
    00591     """ Get an error in the sum bin height ('in-range integral') """
    00592     return HistoStats.sumAllBinHeightErr ( self )
    00593
    00594 # =============================================================================
    00595 def _overflowEntriesFrac_     ( self ) :
    00596     """
    00597     The fraction of overflow entries  (useful for shape comparison)
    00598     """
    00599     return HistoStats.overflowEntriesFrac     ( self )
    00600 # =============================================================================
    00601 def _overflowEntriesFracErr_  ( self ) :
    00602     """
    00603     The error for fraction of overflow entries  (useful for shape comparison)
    00604     """
    00605     return HistoStats.overflowEntriesFracErr  ( self )
    00606 # =============================================================================
    00607 def _underflowEntriesFrac_    ( self ) :
    00608     """
    00609     The fraction of underflow entries  (useful for shape comparison)
    00610     """
    00611     return HistoStats.underflowEntriesFrac    ( self )
    00612 # =============================================================================
    00613 def _underflowEntriesFracErr_ ( self ) :
    00614     """
    00615     The error for fraction of underflow entries  (useful for shape comparison)
    00616     """
    00617     return HistoStats.underflowEntriesFracErr ( self )
    00618
    00619 # =============================================================================
    00620 def _overflowIntegralFrac_     ( self ) :
    00621     """
    00622     The fraction of overflow integral  (useful for shape comparison)
    00623     """
    00624     return HistoStats.overflowIntegralFrac     ( self )
    00625 # =============================================================================
    00626 def _overflowIntegralFracErr_  ( self ) :
    00627     """
    00628     The error for fraction of overflow integral  (useful for shape comparison)
    00629     """
    00630     return HistoStats.overflowIntegralFracErr  ( self )
    00631 # =============================================================================
    00632 def _underflowIntegralFrac_    ( self ) :
    00633     """
    00634     The fraction of underflow integral  (useful for shape comparison)
    00635     """
    00636     return HistoStats.underflowIntegralFrac    ( self )
    00637 # =============================================================================
    00638 def _underflowIntegralFracErr_ ( self ) :
    00639     """
    00640     The error for fraction of underflow integral (useful for shape comparison)
    00641     """
    00642     return HistoStats.underflowIntegralFracErr ( self )
    00643
    00644 # =============================================================================
    00645 ## get number of entries in histogram up to  the certain bin (not-included)
    00646 #  get number of entries in histogram form the certain
    00647 #  minimal bin up to the certain maximal bin (not-included)
    00648 def _nEntries_ ( self , i1 , i2 = -10000000 ) :
    00649     """
    00650     Get number of entries in histogram up to  the certain bin (not-included)
    00651
    00652     attention: underflow bin is included!
    00653
    00654     >>> h1
    00655     >>> print h1.nEntries ( 10 )
    00656
    00657     Get number of entries in histogram form the certain
    00658     minimal bin up to the certain maximal bin (not-included)
    00659
    00660     >>> h1
    00661     >>> print h1.nEntries ( 10 , 15 )
    00662
    00663     """
    00664     if  i2 < i1 or i2 < 0 : return HistoStats.nEntries ( self , i1 )
    00665     return HistoStats.nEntries ( self , i1 , i2 )
    00666 # =============================================================================
    00667 def _nEntriesFrac_ ( self , i1 , i2 = -10000000 ) :
    00668     """
    00669     Get the fraction of entries in histogram up to  the certain bin (not-included)
    00670
    00671     attention: underflow bin is included!
    00672
    00673     >>> h1
    00674     >>> print h1.nEntriesFrac ( 10 )
    00675
    00676     Get the fraction of entries in histogram form the certain
    00677     minimal bin up to the certain maximal bin (not-included)
    00678
    00679     >>> h1
    00680     >>> print h1.nEntriesFrac ( 10 , 15 )
    00681
    00682     """
    00683     if  i2 < i1 or i2 < 0 : return HistoStats.nEntriesFrac ( self , i1 )
    00684     return HistoStats.nEntriesFrac ( self , i1 , i2 )
    00685 # =============================================================================
    00686 def _nEntriesFracErr_ ( self , i1 , i2 = -10000000 ) :
    00687     """
    00688     Get error for  fraction of entries in histogram up to  the certain bin (not-included)
    00689
    00690     attention: underflow bin is included!
    00691
    00692     >>> h1
    00693     >>> print h1.nEntriesFracErr( 10 )
    00694
    00695     Get error  fraction of entries in histogram form the certain
    00696     minimal bin up to the certain maximal bin (not-included)
    00697
    00698     >>> h1
    00699     >>> print h1.nEntriesFracErr ( 10 , 15 )
    00700
    00701     """
    00702     if  i2 < i1 or i2 < 0 : return HistoStats.nEntriesFracErr ( self , i1 )
    00703     return HistoStats.nEntriesFracErr ( self , i1 , i2 )
    00704
    00705 # =============================================================================
    00706 i1DH = cpp.AIDA.IHistogram1D
    00707
    00708 if not hasattr ( i1DH , 'moment'          ) : i1DH.moment           = _moment_
    00709 if not hasattr ( i1DH , 'momentErr'       ) : i1DH.momentErr        = _momentErr_
    00710 if not hasattr ( i1DH , 'centralMoment'   ) : i1DH.centralMoment    = _centralMoment_
    00711 if not hasattr ( i1DH , 'momentMomentErr' ) : i1DH.centralMomentErr = _centralMomentErr_
    00712 if not hasattr ( i1DH , 'nEff'            ) : i1DH.nEff             = _nEff_
    00713 if not hasattr ( i1DH , 'mean'            ) : i1DH.mean             = _mean_
    00714 if not hasattr ( i1DH , 'meanErr'         ) : i1DH.meanErr          = _meanErr_
    00715 if not hasattr ( i1DH , 'rms'             ) : i1DH.rms              = _rms_
    00716 if not hasattr ( i1DH , 'rmsErr'          ) : i1DH.rmsErr           = _rmsErr_
    00717 if not hasattr ( i1DH , 'skewness'        ) : i1DH.skewness         = _skewness_
    00718 if not hasattr ( i1DH , 'skewnessErr'     ) : i1DH.skewnessErr      = _skewnessErr_
    00719 if not hasattr ( i1DH , 'kurtosis'        ) : i1DH.kurtosis         = _kurtosis_
    00720 if not hasattr ( i1DH , 'kurtosisErr'     ) : i1DH.kurtosisErr      = _kurtosisErr_
    00721
    00722 if not hasattr ( i1DH , 'overflowEntriesFrac'     ) : i1DH.overflowEntriesFrac     = _overflowEntriesFrac_
    00723 if not hasattr ( i1DH , 'overflowEntriesFracErr'  ) : i1DH.overflowEntriesFracErr  = _overflowEntriesFracErr_
    00724 if not hasattr ( i1DH , 'underflowEntriesFrac'    ) : i1DH.underflowEntriesFrac    = _underflowEntriesFrac_
    00725 if not hasattr ( i1DH , 'underflowEntriesFracErr' ) : i1DH.underflowEntriesFracErr = _underflowEntriesFracErr_
    00726
    00727 if not hasattr ( i1DH , 'overflowIntegralFrac'     ) : i1DH.overflowIntegralFrac     = _overflowIntegralFrac_
    00728 if not hasattr ( i1DH , 'overflowIntegralFracErr'  ) : i1DH.overflowIntegralFracErr  = _overflowIntegralFracErr_
    00729 if not hasattr ( i1DH , 'underflowIntegralFrac'    ) : i1DH.underflowIntegralFrac    = _underflowIntegralFrac_
    00730 if not hasattr ( i1DH , 'underflowIntegralFracErr' ) : i1DH.underflowIntegralFracErr = _underflowIntegralFracErr_
    00731
    00732 if not hasattr ( i1DH , 'nEntries'        ) : i1DH.nEntries        = _nEntries_
    00733 if not hasattr ( i1DH , 'nEntriesFrac'    ) : i1DH.nEntriesFrac    = _nEntriesFrac_
    00734 if not hasattr ( i1DH , 'nEntriesFracErr' ) : i1DH.nEntriesFracErr = _nEntriesFracErr_
    00735
    00736 ## ============================================================================
    00737 def _path_ ( self ) :
    00738     """
    00739     Get the path in THS for the given AIDA object:
    00740
    00741     >>> aida =
    00742     >>> print aida.path()
    00743
    00744     """
    00745     return cpp.Gaudi.Utils.Histos.path ( self )
    00746
    00747 iBH = cpp.AIDA.IBaseHistogram
    00748 if not hasattr ( iBH , 'path'     ) : iBH.path     = _path_
    00749 if not hasattr ( iBH , 'TESpath'  ) : iBH.TESpath  = _path_
    00750 if not hasattr ( iBH , 'location' ) : iBH.location = _path_
    00751
    00752
    00753 ## =============================================================================
    00754 def __dumpHisto__ ( histo , *args ) :
    00755     """
    00756
    00757     Dump the histogram/profile in text format (a'la HBOOK)
    00758
    00759     >>> histo
    00760     >>> print dumpHisto ( histo )
    00761
    00762     >>> print histo.dump()
    00763     >>> print histo.dump( 20 , 20 )
    00764     >>> print histo.dump( 20 , 20 , True )
    00765
    00766     Uses:
    00767
    00768     """
    00769     return cpp.Gaudi.Utils.Histos.histoDump ( histo , *args )
    00770
    00771 __dumpHisto__ .__doc__ = '\n'  + cpp.Gaudi.Utils.Histos.histoDump . __doc__
    00772
    00773 # =============================================================================
    00774 ## the actual function for text dump of the histogram
    00775 histoDump = __dumpHisto__
    00776 dumpHisto = __dumpHisto__
    00777
    00778 for t in  ( cpp.AIDA.IHistogram1D ,
    00779             cpp.AIDA.IProfile1D   ,
    00780             ROOT.TH1D             ,
    00781             ROOT.TH1F             ,
    00782             ROOT.TH1              ,
    00783             ROOT.TProfile         ) :
    00784     for method in ( 'dump'       ,
    00785                     'dumpHisto'  ,
    00786                     'dumpAsText' ) :
    00787         if not hasattr ( t , method ) : setattr ( t , method , __dumpHisto__ )
    00788
    00789 # ==============================================================================
    00790 class HistoFile :
    00791     """
    00792     Class to write histograms to a ROOT file.
    00793     hFile = HistoFile("myFile.root")
    00794     myHisto = ...
    00795     hFile.save(myHisto)
    00796     myHisto0 = ...
    00797     myHisto1 = ...
    00798     myHisto2 = ...
    00799     hFile.save(myHisto0, myHisto1, myHisto2)
    00800     histoList = [h0, h1, h2, h3]
    00801     hFile.save(histoList)
    00802     ...
    00803     hWriter.close()
    00804     """
    00805     __author__ = "Juan Palacios juan.palacios@nikhef.nl"
    00806
    00807     def __init__(self, fileName) :
    00808         self.file = TFile(fileName, "RECREATE")
    00809         self.aida2root = gbl.Gaudi.Utils.Aida2ROOT.aida2root
    00810         self.aidaTypes = [gbl.AIDA.IHistogram1D,
    00811                           gbl.AIDA.IHistogram2D,
    00812                           gbl.AIDA.IHistogram3D,
    00813                           gbl.AIDA.IProfile1D,
    00814                           gbl.AIDA.IProfile2D,
    00815                           gbl.AIDA.IHistogram    ]
    00816
    00817     def __convertibleType(self, histo) :
    00818         histoType = type(histo)
    00819         for t in self.aidaTypes :
    00820             if histoType == t : return True
    00821         return False
    00822
    00823     def save(self, *args) :
    00824         """
    00825         This function stores histograms on the file for future saving.
    00826         It takes an arbitrary number of AIDA or ROOT histograms or
    00827         a list of them.
    00828         """
    00829         if args :
    00830             if type(args[0])==list :
    00831                 histoList = args[0]
    00832             else :
    00833                 histoList = args
    00834             for h in histoList :
    00835                 if self.__convertibleType(h) : h = self.aida2root(h)
    00836                 h.Write()
    00837
    00838     def close(self) :
    00839         self.file.Write()
    00840         self.file.Close()
    00841
    00842 # =============================================================================
    00843 if '__main__' == __name__ :
    00844     import sys
    00845     print __doc__
    00846     for o in __all__ :
    00847         print o
    00848         print sys.modules[__name__].__dict__[o].__doc__
    00849
    00850
    00851 # =============================================================================
    00852 # The END
    00853 # =============================================================================