| # Gaudi Framework, version v20r4
Generated: 8 Jan 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 utilitied for booking and
    00004 #   manipulations with Gaudi-AIDA histograms, inspired by Thomas' requiest
    00005 #   @author Vanya BELYAEV ibelyaev@physics.syr.edu
    00006 #   @date 2007-08-03
    00007 # =============================================================================
    00008 """
    00009 This module contains set of simple and useful utilitied for booking and
    00010 manipulations with Gaudi-AIDA histograms, inspired by Thomas' requiest
    00011
    00012 The module contais 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 retrival of histigrams/profiles from HTS in AIDA format
    00017   - getAsROOT  for retrival of histograms/profiles from HTS in ROOT format
    00018   - fill       for smart filling of 1D-histogram (AIDA or ROOT)
    00019
    00020 """
    00021 # =============================================================================
    00022 __author__ = "Vanya BELYAEV ibelyaev@physics.syr.edu"
    00023 # =============================================================================
    00024 __all__    = ( 'book' , 'bookProf' , 'getAsAIDA' , 'getAsROOT' , 'fill' )
    00025 # =============================================================================
    00026
    00027 # import core of Gaudi
    00028 import GaudiPython as gaudimodule
    00029
    00030 # =============================================================================
    00031 ## Helper private auxillary function to get Aplication Manager
    00032 def _getAppMgr   ( **kwars  ) :
    00033     """ Helper private auxillary function to get Aplication Manager """
    00034     gaudi = kwargs.get ( 'gaudi' , None )
    00035     if not gaudi : gaudi = gaudimodule.gaudi
    00036     if not gaudi : gaudi = gaudimodule.AppMgr()
    00037     if not gaudi : raise RuntimeError, 'Unable to get valid ApplicationMgr'
    00038     return gaudi                                               ## RETURN
    00039
    00040 # =============================================================================
    00041 ## Helper private auxillary function to get iHistogramSvs
    00042 def _getHistoSvc ( **kwargs ) :
    00043     """ Helper private auxillary function to get iHistogramSvs """
    00044     svc = kwargs.get ( 'service' , None )
    00045     if not svc : svc = kwargs.get ( 'svc' , None )
    00046     else       : return svc                                    ## RETURN
    00047     gaudi = _getAppMgr ( **kwargs )
    00048     return gaudi.histsvc ()                                    ## RETURN
    00049
    00050 # =============================================================================
    00051 ## Helper private auxillary function to get iDataSvs
    00052 def _getEvtSvc ( **kwargs ) :
    00053     """ Helper private auxillary function to get iDataSvs """
    00054     svc = kwargs.get ( 'service' , None )
    00055     if not svc : svc = kwargs.get ( 'svc' , None )
    00056     else       : return svc                                    ## RETURN
    00057     gaudi = _getAppMgr ( **kwargs )
    00058     return gaudi.evtsvc()                                      ## RETURN
    00059
    00060 # =============================================================================
    00061 ## The trivial function to book the various 1D,2D&3D-histograms
    00062 def book ( *args , **kwargs ) :
    00063     """
    00064     The trivial function to book the various 1D,2D&3D-histograms
    00065
    00066     (1) book the trivial 1D histogram with full path
    00067
    00068     >>> h1D = book ( 'path/to/my/histo'       , ## path in Histogram Transient Store
    00069                      'cosine of decay angle ' , ## histogram title
    00070                       100                     , ## number of bins
    00071                       -1                      , ## low edge
    00072                       100                     ) ## high edge
    00073
    00074     (2) book the trivial 1D histogram with directory path and string ID :
    00075
    00076     >>> h1D = book ( 'path/to/directory'      , ## the path to directory in HTS
    00077                      'H1'                     , ## string histogrsm identifier
    00078                      'cosine of decay angle ' , ## histogram title
    00079                       100                     , ## number of bins
    00080                       -1                      , ## low edge
    00081                       100                     ) ## high edge
    00082
    00083     (3) book the trivial 1D histogram with directoty path and integer ID :
    00084
    00085     >>> h1D = book ( 'path/to/directory'      , ## the path to directory in HTS
    00086                      124                      , ## integer histogrsm identifier
    00087                      'cosine of decay angle ' , ## histogram title
    00088                       100                     , ## number of bins
    00089                       -1                      , ## low edge
    00090                       100                     ) ## high edge
    00091
    00092     (4) book the trivial 2D histogram with full path
    00093
    00094     >>> h1D = book ( 'path/to/my/histo'       , ## path in Histogram Transient Store
    00095                      'm12**2 versus m13**2'   , ## histogram title
    00096                       50                      , ## number of X-bins
    00097                       1.0                     , ## low X-edge
    00098                       4.0                     , ## high X-edge
    00099                       50                      , ## number of Y-bins
    00100                       1                       , ## low Y-edge
    00101                       2                       ) ## high Y-edge
    00102
    00103     (5) book the trivial 2D histogram with directory path and literal ID
    00104
    00105     >>> h1D = book ( 'path/to/directory'      , ## path in Histogram Transient Store
    00106                      'Dalitz1'                , ## literal histogram identifier
    00107                      'm12**2 versus m13**2'   , ## histogram title
    00108                       50                      , ## number of X-bins
    00109                       1.0                     , ## low X-edge
    00110                       4.0                     , ## high X-edge
    00111                       50                      , ## number of Y-bins
    00112                       1                       , ## low Y-edge
    00113                       2                       ) ## high Y-edge
    00114
    00115     (6) book the trivial 2D histogram with directory path and integer ID
    00116
    00117     >>> h1D = book ( 'path/to/directory'      , ## path in Histogram Transient Store
    00118                      854                      , ## integer histogram identifier
    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.0                     , ## low Y-edge
    00125                       4.0                     ) ## high Y-edge
    00126
    00127     (7) book the trivial 3D histogram with full path
    00128
    00129     >>> h1D = book ( 'path/to/my/histo'       , ## path in Histogram Transient Store
    00130                      'x vs y vs z '           , ## histogram title
    00131                       10                      , ## number of X-bins
    00132                       -1.0                    , ## low X-edge
    00133                       1.0                     , ## high X-edge
    00134                       10                      , ## number of Y-bins
    00135                       -1.0                    , ## low Y-edge
    00136                       1.0                     , ## high Y-edge
    00137                       10                      , ## number of Z-bins
    00138                       -1.0                    , ## low Z-edge
    00139                       1.0                     ) ## high Z-edge
    00140
    00141     (8) book the trivial 3D histogram with directory path and literal ID
    00142
    00143     >>> h1D = book ( 'path/to/directory'      , ## path in Histogram Transient Store
    00144                      'xyz'                    , ## literal histogram identifier
    00145                      'x vs y vs z'            , ## histogram title
    00146                       10                      , ## number of X-bins
    00147                       -1.0                    , ## low X-edge
    00148                       1.0                     , ## high X-edge
    00149                       10                      , ## number of Y-bins
    00150                       -1.0                    , ## low Y-edge
    00151                       1.0                     , ## high Y-edge
    00152                       10                      , ## number of Z-bins
    00153                       -1.0                    , ## low Z-edge
    00154                       1.0                     ) ## high Z-edge
    00155
    00156     (9) book the trivial 3D histogram with directory path and integer ID
    00157
    00158     >>> h1D = book ( 'path/to/directory'      , ## path in Histogram Transient Store
    00159                      888                      , ## integer histogram identifier
    00160                      'x vs y vs z'            , ## histogram title
    00161                       10                      , ## number of X-bins
    00162                       -1.0                    , ## low X-edge
    00163                       1.0                     , ## high X-edge
    00164                       10                      , ## number of Y-bins
    00165                       -1.0                    , ## low Y-edge
    00166                       1.0                     , ## high Y-edge
    00167                       10                      , ## number of Z-bins
    00168                       -1.0                    , ## low Z-edge
    00169                       1.0                     ) ## high Z-edge
    00170
    00171     Many other booking methods are avilable,
    00172     e.g. for the histograms with non-equidistant bins, see IHistogamSvc::book
    00173
    00174     """
    00175     svc = _getHistoSvc ( **kwargs )
    00176     if not svc : raise RuntimeError, 'Unable to get valid HistogramService '
    00177     ## book the histogram using the service
    00178     return svc.book(*args)                                          ## RETURN
    00179
    00180 book.__doc__ += '\n\n' + '\thelp(gaudimodule.iHistogramSvc.book) : \n\n' \
    00181                 + gaudimodule.iHistogramSvc.book       . __doc__
    00182 book.__doc__ += '\n\n' + '\thelp(IHistogramSvc::book) : \n\n'            \
    00183                 + gaudimodule.gbl.IHistogramSvc.book . __doc__
    00184
    00185 # =============================================================================
    00186 ## The trivial function to book 1D&2D profile histograms:
    00187 def bookProf ( *args , **kwargs ) :
    00188     """
    00189
    00190     The trivial function to book 1D&2D profile histograms:
    00191
    00192     (1) book 1D-profile histogram with full path in Historam Transient Store:
    00193     >>> histo = bookProf ( 'path/to/my/profile'  , ## path in Histogram Transient Store
    00194                            'Energy Correction'   , ## the histogram title
    00195                            100                   , ## number of X-bins
    00196                            0.0                   , ## low X-edge
    00197                            100                   ) ## high X-edge
    00198
    00199     (2) book 1D-profile histogram with directory path and literal ID
    00200     >>> histo = bookProf ( 'path/to/my/profile'  , ## path in Histogram Transient Store
    00201                            'Calibration'         , ## the histogram literal identifier
    00202                            'Energy Correction'   , ## the histogram title
    00203                            100                   , ## number of X-bins
    00204                            0.0                   , ## low X-edge
    00205                            100                   ) ## high X-edge
    00206
    00207     (3) book 1D-profile histogram with directory path and integer  ID
    00208     >>> histo = bookProf ( 'path/to/my/profile'  , ## path in Histogram Transient Store
    00209                            418                   , ## the histogram integer identifier
    00210                            'Energy Correction'   , ## the histogram title
    00211                            100                   , ## number of X-bins
    00212                            0.0                   , ## low X-edge
    00213                            100                   ) ## high X-edge
    00214
    00215     (4) book 2D-profile histogram with full path in Historam Transient Store:
    00216     >>> histo = bookProf ( 'path/to/my/profile'  , ## path in Histogram Transient Store
    00217                            'Energy Correction'   , ## the histogram title
    00218                            50                    , ## number of X-bins
    00219                            0.0                   , ## low X-edge
    00220                            100                   , ## high X-edge
    00221                            50                    , ## number of Y-bins
    00222                            0.0                   , ## low Y-edge
    00223                            100                   ) ## high Y-edge
    00224
    00225     (5) book 2D-profile histogram with directory path and literal ID
    00226     >>> histo = bookProf ( 'path/to/my/profile'  , ## path in Histogram Transient Store
    00227                            'Calibration'         , ## the histogram literal identifier
    00228                            'Energy Correction'   , ## the histogram title
    00229                            50                    , ## number of X-bins
    00230                            0.0                   , ## low X-edge
    00231                            100                   , ## high X-edge
    00232                            50                    , ## number of Y-bins
    00233                            0.0                   , ## low Y-edge
    00234                            100                   ) ## high Y-edge
    00235
    00236     (6) book 2D-profile histogram with directory path and integer  ID
    00237     >>> histo = bookProf ( 'path/to/my/profile'  , ## path in Histogram Transient Store
    00238                            418                   , ## the histogram integer identifier
    00239                            'Energy Correction'   , ## the histogram title
    00240                            50                    , ## number of X-bins
    00241                            0.0                   , ## low X-edge
    00242                            100                   , ## high X-edge
    00243                            50                    , ## number of Y-bins
    00244                            0.0                   , ## low Y-edge
    00245                            100                   ) ## high Y-edge
    00246
    00247     Many other booking methods are avilable,
    00248     e.g. for the histograms with non-equidistant bins, see IHistogamSvc::book
    00249
    00250     """
    00251     svc = _getHistoSvc ( **kwargs )
    00252     if not svc : raise RuntimeError, 'Unable to get valid HistogramService '
    00253     ## book the histogram using the service
    00254     return svc.bookProf(*args)                                      ## RETURN
    00255
    00256
    00257 bookProf.__doc__ += '\n\n' + '\thelp(gaudimodule.iHistogramSvc.bookProf) : \n\n' \
    00258                     + gaudimodule.iHistogramSvc.bookProf . __doc__
    00259 bookProf.__doc__ += '\n\n' + '\thelp(IHistogramSvc::bookProf) : \n\n'             \
    00260                     + gaudimodule.gbl.IHistogramSvc.bookProf . __doc__
    00261
    00262 # =============================================================================
    00263 ## The most trivial function to retrieve the histogram from Histogram Transient Store
    00264 def getAsAIDA ( path , **kwargs ) :
    00265     """
    00266
    00267     The most trivial function to retrieve the histogram from Histogram Transient Store
    00268     The historgam is returned by reference to its AIDA-representation (if possible)
    00269
    00270     >>> h = getAsAIDA ( 'some/path/to/my/histogram' )
    00271
    00272     """
    00273     svc = _getHistoSvc ( **kwargs )
    00274     if not svc : raise RuntimeError, 'Unable to get valid HistogramService '
    00275     ## return the histogram
    00276     return svc.getAsAIDA( path )                                   ## RETURN
    00277
    00278 getAsAIDA.__doc__ += '\n\n' + '\thelp(gaudimodule.iHistogramSvc.getAsAIDA) : \n\n' \
    00279                      + gaudimodule.iHistogramSvc.getAsAIDA . __doc__
    00280 getAsAIDA.__doc__ += '\n\n' + '\thelp(gaudimodule.iHistogramSvc.retrieve)  : \n\n' \
    00281                      + gaudimodule.iHistogramSvc.retrieve  . __doc__
    00282
    00283 # =============================================================================
    00284 ## The most trivial function to retrieve the histogram from Histogram Transient Store
    00285 def getAsROOT ( path , **kwargs ) :
    00286     """
    00287
    00288     The most trivial function to retrieve the histogram from Histogram Transient Store
    00289     The historgam is returned by reference to its underlying native ROOT-representation (if possible)
    00290
    00291     >>> h = getAsROOT ( 'some/path/to/my/histogram' )
    00292
    00293     """
    00294     svc = _getHistoSvc ( **kwargs )
    00295     if not svc : raise RuntimeError, 'Unable to get valid HistogramService '
    00296     ## return the histogram
    00297     return svc.getAsROOT( path )                                   ## RETURN
    00298
    00299 getAsROOT.__doc__ += '\n\n' + '\thelp(gaudimodule.iHistogramSvc.getAsROOT) : \n\n' \
    00300                      + gaudimodule.iHistogramSvc.getAsROOT . __doc__
    00301
    00302
    00303 # =============================================================================
    00304 ## The function which allows 'the smart fill' of 1D-histogram
    00305 def fill ( histo                   ,   ## histogram
    00306            data                    ,   ## input data
    00307            fun   = lambda x : x    ,   ## function to be used
    00308            cut   = lambda x : True ,   ## cut to be applied
    00309            **kwargs                ) : ## optional extra arguments
    00310     """
    00311
    00312     The function which allows 'the smart fill' of 1D-histogram
    00313
    00314     >>> histo = ...
    00315
    00316     The most trivial case, fill with the value
    00317     >>> fill ( histo , 1.0 )
    00318
    00319     Fill from any iterable object (sequence)
    00320     >>> fill ( histo , [1,,2,3,4,5,10] )
    00321
    00322     Fill from iterable object and apply the function:
    00323     >>> fill ( histo , [1,2,3,4,5] , math.sin )
    00324
    00325     Use lambda form:
    00326     >>> fill ( histo , [1,2,3,4,5] , lambda x : x*x )
    00327
    00328     The same
    00329     >>> fill ( histo , [1,2,3,4,5] , fun = lambda x : x*x )
    00330
    00331     Use internal attributes:
    00332     >>> tracks = evtSvc['Rec/Track/Best']    ## iterable container of tracks
    00333     >>> fill ( histo , tracks , lambda t : t.pt() )
    00334
    00335     Apply the predicate: fill only even numbers:
    00336     >>> fill ( histo , [1,2,3,4,5,6,7] , lambda x : x , lambda y : y%2 )
    00337
    00338     The same (omit the trivial function) :
    00339     >>> fill ( histo , [1,2,3,4,5,6,7] , cut = lambda y : y%2 )
    00340
    00341     Apply the predicate: fill only pt for positively charged tracks:
    00342     >>> tracks = evtSvc['Rec/Track/Best']
    00343     >>> fill ( histo , tracks , lambda t : t.pt() , lambda t : 0<t.charge() )
    00344
    00345     The same:
    00346     >>> fill ( histo , tracks ,
    00347                fun = lambda t : t.pt()       ,
    00348                cut = lambda t : 0<t.charge() )
    00349
    00350     Ordinary functions are also fine:
    00351     >>> def myfun ( track ) : return sin( track.pt() + track.p() )
    00352     >>> def mycut ( track ) : return track.p() > 100 * GeV
    00353     >>> fill ( histo , tracks , myfun , mycut )
    00354
    00355     The 'data' could be the address in TES, in this case the object
    00356     is retrieevd from TES and the method is applied to the objects,
    00357     retrieved from TES:
    00358     >>> fill (  histo             , ## the reference to the histogram
    00359                'Rec/Track/Best'   , ## the location of objects in TES
    00360                 lambda t : t.pt() ) ## function to be used for histogram fill
    00361     >>> fill (  histo             , ## the reference to the histogram
    00362                'Rec/Track/Best'   , ## the address of objects in TES
    00363                 lambda t : t.pt() , ## the functuon to be used for histogram fill
    00364                 lambda t : t.charge()>0 ) ## the criteria to select tracks
    00365
    00366     The arguments 'fun' and 'cut' could be strings, in this case
    00367     they are evaluated by python before usage.
    00368     This option could be often very useful.
    00369
    00370     """
    00371
    00372     # if value is a string, try to get the objects from TES
    00373     if type ( data ) == str :
    00374         svc  = _getEvtSvc ( **kwargs )
    00375         data = svc[data]
    00376         return fill ( histo , data , fun , cut , **kwargs )
    00377
    00378     # if the function  is a string: evaluate it!
    00379     if type ( fun  ) == str : fun  = eval ( fun  , globals() )
    00380
    00381     # if the criterion is a string: evaluate it!
    00382     if type ( cut  ) == str : cut  = eval ( cut  , globals() )
    00383
    00384     if not hasattr ( data , '__iter__' ) : data = [ data ]
    00385
    00386     if not hassattr ( histo , 'fill' ) and hasattr ( histo , 'Fill' ) :
    00387         setattr ( histo , 'fill' , getattr ( histo , 'Fill' ) )
    00388
    00389     for item in data :
    00390         if not cut ( item )         : continue             ## CONTINUE
    00391         histo.fill ( fun ( item ) )
    00392
    00393     return histo                                           ## RETURN
    00394
    00395
    00396 # ==================================================:===========================
    00397 if '__main__' == __name__ :
    00398     import sys
    00399     print __doc__
    00400     for o in __all__ :
    00401         print o
    00402         print sys.modules[__name__].__dict__[o].__doc__
    00403
    00404
    00405 # =============================================================================
    00406 # The END
    00407 # =============================================================================