| # Gaudi Framework, version v21r11 |

Home |  | Generated: 30 Sep 2010

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