00001
00002
00003
00004
00005
00006
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
00028 import GaudiPython as gaudimodule
00029
00030
00031
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
00039
00040
00041
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
00047 gaudi = _getAppMgr ( **kwargs )
00048 return gaudi.histsvc ()
00049
00050
00051
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
00057 gaudi = _getAppMgr ( **kwargs )
00058 return gaudi.evtsvc()
00059
00060
00061
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
00178 return svc.book(*args)
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
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
00254 return svc.bookProf(*args)
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
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
00276 return svc.getAsAIDA( path )
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
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
00297 return svc.getAsROOT( path )
00298
00299 getAsROOT.__doc__ += '\n\n' + '\thelp(gaudimodule.iHistogramSvc.getAsROOT) : \n\n' \
00300 + gaudimodule.iHistogramSvc.getAsROOT . __doc__
00301
00302
00303
00304
00305 def fill ( histo ,
00306 data ,
00307 fun = lambda x : x ,
00308 cut = lambda x : True ,
00309 **kwargs ) :
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
00373 if type ( data ) == str :
00374 svc = _getEvtSvc ( **kwargs )
00375 data = svc[data]
00376 return fill ( histo , data , fun , cut , **kwargs )
00377
00378
00379 if type ( fun ) == str : fun = eval ( fun , globals() )
00380
00381
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
00391 histo.fill ( fun ( item ) )
00392
00393 return histo
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
00407