From a403603ee045d3785538fd885ca344df878940cc Mon Sep 17 00:00:00 2001 From: Vanya Belyaev Date: Sun, 4 Aug 2024 15:27:39 +0200 Subject: [PATCH] 1. add `progress` and `report` optioal argumens for (almost) all Frame-related functions --- ReleaseNotes/release_notes.md | 4 +- ostap/frames/frames.py | 598 ++++++++++++++++++----- ostap/frames/tests/test_frames_frames.py | 70 +-- ostap/histos/compare.py | 4 +- ostap/trees/trees.py | 9 +- 5 files changed, 530 insertions(+), 155 deletions(-) diff --git a/ReleaseNotes/release_notes.md b/ReleaseNotes/release_notes.md index c0798a67..a334bb6d 100644 --- a/ReleaseNotes/release_notes.md +++ b/ReleaseNotes/release_notes.md @@ -8,7 +8,9 @@ 1. Add `eff_graph` for 1D historgams for creation of the efficiency graph from the 1D-distribution. 1. Some tweaks for moments & counters - + 1. Activate a new `draw` method (via `tree_draw`) for `ROOT.TTree` + 1. add `progress` and `report` optioal argumens for (almost) all Frame-related functions + ## Backward incompatible 1. `project`(&`draw`) for 2 and 3-dimession now follows the natural order of varibales: diff --git a/ostap/frames/frames.py b/ostap/frames/frames.py index 46230fbf..b6fcf2cc 100644 --- a/ostap/frames/frames.py +++ b/ostap/frames/frames.py @@ -141,24 +141,38 @@ def var_name ( prefix , used_names , *garbage ) : # frame = ... # currnt , vexpr , cexpr, input_string = _fr_helper_ ( frame , 'x*x' , 'z<0' ) # #endcode -def _fr_helper_ ( frame , expressions , cuts = '' ) : +def _fr_helper_ ( frame , expressions , cuts = '' , progress = False ) : """Helper function that defin4es expressions and cuts >>> frame = ... >>> current, vexpr , cexpr = _fr_helper_ ( frame , 'x*x' , 'z<0' ) """ + + if progress and isinstance ( frame , ROOT.TTree ) : progress = len ( frame ) exprs, cuts, input_string = SV.vars_and_cuts ( expressions , cuts ) ## Frame/Tree ? - if isinstance ( frame , ROOT.TTree ) : node = DataFrame ( frame ) + lenght = -1 + + if isinstance ( frame , ROOT.TTree ) : node , length = DataFrame ( frame , progress = progress ) , len ( frame ) elif isinstance ( frame , frame_types ) : node = frame else : node = as_rnode ( frame ) - + ## get the list of currently known names vars = frame_columns ( node ) all_vars = set ( vars ) current = node + + ## progress ? + if progress is False : pass + elif progress is True and 0 < lenght : + current , cnt = frame_progress ( current , length ) + elif isinstance ( progress , integer_types ) and 1 < progress : + current , cnt = frame_progress ( current , progress ) + elif progress : + current , cnt = frame_progress ( current , lenght ) + vnames = ordered_dict() for i , expr in enumerate ( exprs , start = 1 ) : vname = expr @@ -173,7 +187,7 @@ def _fr_helper_ ( frame , expressions , cuts = '' ) : ## Filter frame, if needed! if cuts : ## add named filter - current = current.Filter ( '(bool) (%s)' % cuts, 'FILTER: %s' % cuts ) + current = current.Filter ( '(bool) (%s)' % cuts, 'FILTER/WEIGHT: %s' % cuts ) cname = cuts if cuts and not cuts in all_vars : @@ -188,11 +202,16 @@ def _fr_helper_ ( frame , expressions , cuts = '' ) : # ================================================================================== ## The second helper method to implement various "statistics"-related actions -def _fr_helper2_ ( frame , creator , expressions , cuts = '' , lazy = True ) : +def _fr_helper2_ ( frame , + creator , + expressions , + cuts = '' , + progress = False , + report = False , + lazy = True ) : """The seocnd helper method to implement various statitic-related actions """ - - current, var_names, cut_name, input_string = _fr_helper_ ( frame , expressions , cuts ) + current, var_names, cut_name, input_string = _fr_helper_ ( frame , expressions , cuts , progress = progress ) results = {} for expr, var_name in loop_items ( var_names ) : @@ -202,8 +221,13 @@ def _fr_helper2_ ( frame , creator , expressions , cuts = '' , lazy = True ) : if not lazy : for expr, res in loop_items ( results ) : results [ expr ] = res.GetValue() - rr = results [ expr ] - + rr = results [ expr ] + + if report and not lazy : + report = current.Report() + title = 'DataFrame processing' + logger.info ( '%s\n%s' % ( title , report_print ( report , title = title , prefix = '# ') ) ) + if input_string and 1 == len ( results ) : _ , r = results.popitem() return r @@ -213,23 +237,24 @@ def _fr_helper2_ ( frame , creator , expressions , cuts = '' , lazy = True ) : # ============================================================================== ## modify constructor for RDataFrame to enable/disable Implicit multithreading # @code -# f1 = DataFrame ( ... , enable = True ) ## default -# f2 = DataFrame ( ... , enable = False ) ## default +# f1 = DataFrame ( ... , enable = True , progress = False ) ## default +# f2 = DataFrame ( ... , enable = False , progress = False ) ## default # @endcode # @see ROOT::EnableImplicitMT # @see ROOT::DisableImplicitMT # @see ROOT::IsImplicitMTEnabled -def _fr_new_init_ ( self , name , *args , **kwargs ) : +def _fr_new_init_ ( self , *args , **kwargs ) : """Modify the DataFrame constuctor to allow (semi)automatic manipulations wth ROOT.ROOT.EnableImplicitMT/DisableImplicitMT - see ROOT.ROOT.EnableImplicitMT - see ROOT.ROOT.DisableImplicitMT - see ROOT.ROOT.IsImplicitMTEnabled - >>> f = DataFrame ( .... , enable = True ) ## default - >>> f = DataFrame ( .... , enable = False ) + >>> f = DataFrame ( ... , enable = True , progress = False ) ## default + >>> f = DataFrame ( ... , enable = False , progress = False ) """ - mt = kwargs.pop ( 'enable' , mt_global ) and mt_global + mt = kwargs.pop ( 'enable' , mt_global ) and mt_global + progress = kwargs.pop ( 'progress' , False ) if mt and not ROOT.ROOT.IsImplicitMTEnabled() : ROOT.ROOT.EnableImplicitMT () @@ -238,8 +263,16 @@ def _fr_new_init_ ( self , name , *args , **kwargs ) : ROOT.ROOT.DisableImplicitMT () logger.info ( 'DataFrame:ImplicitMT is %s' % ( 'Enabled' if ROOT.ROOT.IsImplicitMTEnabled() else 'Disabled' ) ) - self._fr_old_init_ ( name , *args , **kwargs ) - + self._fr_old_init_ ( *args , **kwargs ) + + if progress and args : + lenght = -1 + if isinstance ( args [ 0 ] , integer_types ) and 1 < args [ 0 ] : lenght = args [ 0 ] + elif isinstance ( args [ 0 ] , ROOT.TTree ) : lenght = len ( args [ 0 ] ) + elif isinstance ( progress , inetger_types ) and 1 < progress : lenght = progress + _ , _ = frame_progress ( self , lenght ) + + if not hasattr ( DataFrame , '_fr_old_init_' ) : DataFrame._fr_old_init_ = DataFrame.__init__ DataFrame.__init__ = _fr_new_init_ @@ -286,15 +319,15 @@ def frame_columns ( frame ) : # ============================================================================= ## Display the progress bar for the DataFrame: # @code -# f = DataFrame ( ... ) -# p = frame_progress1 ( f , 1000 ) ## number of elements! +# f = DataFrame ( ... ) +# f , c = frame_progress1 ( f , 1000 ) ## number of elements! # .... # @endcode # @attention active only for ROOT < 6.32 def frame_progress1 ( frame , length ) : """ Draw (lazy) progress bar for the DataFrame: - >>> f = DataFrame ( ... ) - >>> p = frame_progress1 ( f , 1000 ) ## number of elements! + >>> f = DataFrame ( ... ) + >>> f , c = frame_progress1 ( f , 1000 ) ## number of elements! >>> .... - active only for ROOT < 6.32 """ @@ -418,9 +451,11 @@ def frame_prescale ( frame , prescale , name = '' ) : raise TypeError ( "Invalid type/value for 'prescale' %s/%s" %( prescale , type ( prescale ) ) ) # ============================================================================== -## Draw the variables for the frame +## Draw the variables for the frame +# - old variant def frame_draw ( frame , *args , **kwargs ) : """Draw the variable (s) for the frames + - old variant """ node = as_rnode ( frame ) from ostap.fitting.dataset import ds_draw as _ds_draw_ @@ -694,7 +729,13 @@ def _p2_model_ ( histo ) : # - anything that can be converted to ROOT::RDF::TH1DModel, # ROOT::RDF::TH2DModel or ROOT::RDF::TH3DModel objects # @attention: variables should be listed in reverse order! -def frame_project ( frame , model , expressions , cuts = '' , lazy = True ) : +def frame_project ( frame , + model , + expressions , + cuts = '' , + progress = False , + report = False , + lazy = True ) : """ Project of the frame into histigram - attention: variables should be listed in reverse order! @@ -732,12 +773,14 @@ def frame_project ( frame , model , expressions , cuts = '' , lazy = True ) : """ + if progress and isinstance ( frame , ROOT.TTree ) : progress = len ( frame ) + if isinstance ( model , _types_nD ) : assert ( 6,25 ) <= root_info, '6.25<=ROOT is required here!' - return _fr_param_ ( frame , model , expression, cuts = cuts , laszy = lazy ) + return _fr_param_ ( frame , model , expression, cuts = cuts , progress = progress , report = report , lazy = lazy ) - ## decode expresisons & cuts - current , items, cname , _ = _fr_helper_ ( frame , expressions , cuts ) + ## decode expressons & cuts + current , items, cname , _ = _fr_helper_ ( frame , expressions , cuts , progress = progress ) ## convert histogram-like objects into 'models' @@ -765,9 +808,17 @@ def frame_project ( frame , model , expressions , cuts = '' , lazy = True ) : ## if true histo is specified, the aciton is NOT lazy! if histo : histo += action.GetValue() - return histo + result = histo + else : + result = action if lazy else action.GetValue() + + if report and not lazy : + report = current.Report() + title = 'DataFrame project' + logger.info ( '%s\n%s' % ( title , report_print ( report , title = title , prefix = '# ') ) ) + + return result - return action if lazy else action.GetValue() # ============================================================================= ## "project/parameterise" frame into polynomial structures (lazy action) @@ -795,7 +846,13 @@ def frame_project ( frame , model , expressions , cuts = '' , lazy = True ) : # bs2 = Ostap.Math.Bernstein2D ( ... ) # res = frame_the_param ( frame , bs2 , ( 'y' , 'x' ) , 'z>0' ) # @endcode -def _fr_param_ ( frame , poly , expressions , cuts = '' , lazy = True ) : +def _fr_param_ ( frame , + poly , + expressions , + cuts = '' , + progress = False , + report = False , + lazy = True ) : """ `project/parameterise` frame into polynomial structures >>> frame = ... @@ -822,12 +879,14 @@ def _fr_param_ ( frame , poly , expressions , cuts = '' , lazy = True ) : >>> res = frame_the_param ( frame , bs2 , 'y,x' , 'z>0' ) """ + if progress and isinstance ( frame , ROOT.TTree ) : progress = len ( frame ) + ## the histogram ? if isinstance ( poly , ROOT.TH1 ) : - return _fr_project_ ( frame , poly , expressions , cuts = cuts , lazy = lazy ) + return _fr_project_ ( frame , poly , expressions , cuts = cuts , progress = progress , report = report , lazy = lazy ) ## - current , items, cname , _ = _fr_helper_ ( frame , expressions , cuts ) + current , items, cname , _ = _fr_helper_ ( frame , expressions , cuts , progress = progress ) nvars = len ( items ) @@ -866,6 +925,11 @@ def _fr_param_ ( frame , poly , expressions , cuts = '' , lazy = True ) : poly *= 0.0 poly += result + if report and not lazy : + report = current.Report() + title = 'DataFrame parameterisation' + logger.info ( '%s\n%s' % ( title , report_print ( report , title = title , prefix = '# ') ) ) + return result @@ -875,14 +939,21 @@ def _fr_param_ ( frame , poly , expressions , cuts = '' , lazy = True ) : # frame = ... # result = frame_draw ( frame , 'x+12/z' , cut = 'z>1' ) ## @endcode -def _fr_draw_ ( frame , expressions , cuts = '' , opts = '' , **kwargs ) : +def _fr_draw_ ( frame , + expressions , + cuts = '' , + opts = '' , + progress = False , + report = False , **kwargs ) : """Draw the variable(s) from the frame >>> frame = ... >>> result = frame_draw ( frame , 'x+12/z' , cut = 'z>1' ) """ - + + if progress and isinstance ( frame , ROOT.TTree ) : progress = len ( frame ) + ## decode expressions & cuts - current , items, cname , _ = _fr_helper_ ( frame , expressions , cuts ) + current , items, cname , _ = _fr_helper_ ( frame , expressions , cuts , progress = progress ) nvars = len ( items ) assert 1 <= nvars <= 3 , 'Invalid expressions: %s' % str ( items ) @@ -890,11 +961,12 @@ def _fr_draw_ ( frame , expressions , cuts = '' , opts = '' , **kwargs ) : cvars = [ v for v in items.values() ] uvars = CNT ( cvars ) if not cname else CNT ( cvars + [ cname ] ) - ## create the - cache = current.Cache ( uvars ) + ## create the cache ... needed ? + ## cache = current.Cache ( uvars ) + cache = current ## get the ranges - ranges = frame_range ( cache , cvars , cname ) + ranges = frame_range ( cache , cvars , cname , report = report ) if not ranges : logger.warning ( 'frame_draw: nothing to draw, return None' ) return None @@ -912,9 +984,16 @@ def _fr_draw_ ( frame , expressions , cuts = '' , opts = '' , **kwargs ) : histo = histo_book ( histos , kw ) ## fill the histogram - histo = frame_project ( cache , histo , cvars , cname , lazy = False ) - ## draw the histogram - histo.draw ( opts , *kw ) + histo = frame_project ( cache , histo , cvars , cname , progress = progress , report = report , lazy = False ) + + ## draw the histogram + histo.draw ( opts , **kw ) + +## if report : +## report = cache.Report() +## title = 'DataFrame draw' +## logger.info ( '%s\n%s' % ( title , report_print ( report , title = title , prefix = '# ') ) ) + return histo # ============================================================================= @@ -1304,7 +1383,12 @@ def frame_deciles ( frame , expression , cuts = '' , exact = True ) : # stat = frame_the_tatVar ( 'pt' , lazy = True ) # stat = frame_the_statVar ( 'pt' , 'eta>0' , lazy = True ) # @endcode -def _fr_the_statVar_ ( frame , expressions , cuts = '' , lazy = True ) : +def _fr_the_statVar_ ( frame , + expressions , + cuts = '' , + progress = False , + report = False , + lazy = True ) : """Get statistics of variable(s) >>> frame = .... >>> stat = frame_the_statVar ( 'pt' , lazy = True ) @@ -1315,7 +1399,13 @@ def screator ( node , var_name , cut_name ) : if cut_name: return node.Book( ROOT.std.move ( Ostap.Actions.WStatVar() ) , CNT ( [ var_name , cut_name ] ) ) else : return node.Book( ROOT.std.move ( Ostap.Actions. StatVar() ) , CNT ( 1 , var_name ) ) - return _fr_helper2_ ( frame , screator , expressions , cuts , lazy = lazy ) + return _fr_helper2_ ( frame , + screator , + expressions , + cuts , + progress = progress , + report = report , + lazy = lazy ) # ================================================================================== @@ -1325,14 +1415,20 @@ def screator ( node , var_name , cut_name ) : # stat = frame_the_statCov ( 'pt1' , 'pt2' , lazy = True ) # stat = frame_the_statCov ( 'pt1' , 'pt2' , 'z<0' , lazy = True ) # @endcode -def _fr_the_statCov_ ( frame , expression1 , expression2 , cuts = '' , lazy = True ) : +def _fr_the_statCov_ ( frame , + expression1 , + expression2 , + cuts = '' , + progress = False , + rreport = False , + lazy = True ) : """Get statistics of variable(s) >>> frame = .... >>> stat = frame_the_statCov ( 'pt1' , 'pt2' , lazy = True ) >>> stat = frame_the_statCov ( 'pt1' , 'pt2' , 'z<0' , lazy = True ) """ - current , exprs1 , cut_name , input_string1 = _fr_helper_ ( frame , expression1 , cuts ) + current , exprs1 , cut_name , input_string1 = _fr_helper_ ( frame , expression1 , cuts , progress = progress ) assert exprs1 and input_string1, 'Invalid expression1: %s' % expression2 current , exprs2 , cut_name , input_string2 = _fr_helper_ ( current , expression2 , cut_name ) @@ -1349,8 +1445,15 @@ def _fr_the_statCov_ ( frame , expression1 , expression2 , cuts = '' , lazy = Tr else : TT = ROOT.Detail.RDF.Stat2Action ( Ostap.Math.Covariance ) action = node.Book( ROOT.std.move ( TT () ) , CNT ( uvars ) ) - - return action if lazy else action.GetValue() + + result = action if lazy else action.GetValue() + + if report and not lazy : + report = current.Report() + title = 'DataFrame processing' + logger.info ( '%s\n%s' % ( title , report_print ( report , title = title , prefix = '# ') ) ) + + return result # ================================================================================== ## get statistics of variable(s) @@ -1359,7 +1462,12 @@ def _fr_the_statCov_ ( frame , expression1 , expression2 , cuts = '' , lazy = Tr # stat = frame.statVar ( 'pt' , lazy = True ) # stat = frame.statVar ( 'pt' , 'eta>0' , lazy = True ) # @endcode -def _fr_the_statVar_ ( frame , expressions , cuts = '' , lazy = True ) : +def _fr_the_statVar_ ( frame , + expressions , + cuts = '' , + progress = False , + report = False , + lazy = True ) : """Get statistics of variable(s) >>> frame = .... >>> stat = frame.statVar ( 'pt' , lazy = True ) @@ -1370,7 +1478,13 @@ def screator ( node , var_name , cut_name ) : if cut_name: return node.Book( ROOT.std.move ( Ostap.Actions.WStatVar() ) , CNT ( [ var_name , cut_name ] ) ) else : return node.Book( ROOT.std.move ( Ostap.Actions. StatVar() ) , CNT ( 1 , var_name ) ) - return _fr_helper2_ ( frame , screator , expressions , cuts , lazy = lazy ) + return _fr_helper2_ ( frame , + screator , + expressions , + cuts = cuts , + progress = progress , + report = report , + lazy = lazy ) # ================================================================================== @@ -1379,12 +1493,21 @@ def screator ( node , var_name , cut_name ) : # frame = ... # nEff = frame_the_nEff ( 'x*x' , 'y>0' ) # @endcode -def _fr_the_nEff_ ( frame , cuts = '' , lazy = False ) : +def _fr_the_nEff_ ( frame , + cuts = '' , + progress = False , + report = False , + lazy = True ) : """Get nEff through action >>> frame = ... >>> nEff = frame_the_nEff ( 'x*x' , 'y>0' ) """ - return _fr_the_statVar_ ( frame , '1.0' , cuts = cuts , lazy = lazy ) + return _fr_the_statVar_ ( frame , + '1.0' , + cuts = cuts , + progress = progress , + report = report , + lazy = lazy ) # ================================================================================== ## get statistics of variable(s) @@ -1395,7 +1518,12 @@ def _fr_the_nEff_ ( frame , cuts = '' , lazy = False ) : # @endcode # @see Ostap::Math::Moment_ # @see Ostap::Math::WMoment_ -def _fr_the_moment_ ( frame , N , expressions , cuts = '' , lazy = True ) : +def _fr_the_moment_ ( frame , N , + expressions , + cuts = '' , + progress = False , + report = False , + lazy = True ) : """Get statistics of variable(s) >>> frame = .... >>> stat = frame_the_moment ( 5 , 'pt' ) @@ -1413,7 +1541,13 @@ def mcreator ( node , var_name , cut_name ) : TT = ROOT.Detail.RDF.Stat1Action ( Ostap.Math.Moment_(N) ) return current.Book ( ROOT.std.move ( TT () ) , CNT ( 1 , var_name ) ) - return _fr_helper2_ ( frame , mcreator , expressions , cuts , lazy = lazy ) + return _fr_helper2_ ( frame , + mcreator , + expressions , + cuts = cuts , + progress = progress , + report = report , + lazy = lazy ) # ============================================================================ ## Get a mean via moment @@ -1422,13 +1556,25 @@ def mcreator ( node , var_name , cut_name ) : # stat = frame.the_mean ( 'x'x' , 'y<0' ) # mean = stat.mean() # @ndcode -def _fr_the_mean_ ( frame , expressions , cuts = '' , errors = True , lazy = True ) : +def _fr_the_mean_ ( frame , + expressions , + cuts = '' , + errors = True , + progress = False , + report = False , + lazy = True ) : """ Get a mean via moment >>> frame = ... >>> stat = frame.the_mean ( 'x'x' , 'y<0' ) >>> mean = stat.mean() """ - return _fr_the_moment_ ( frame , 2 if errors else 1 , expressions , cuts = cuts , lazy = lazy ) + return _fr_the_moment_ ( frame , + 2 if errors else 1 , + expressions , + cuts = cuts , + progress = progress , + report = report , + lazy = lazy ) # ============================================================================ ## Get a rms via moment @@ -1437,13 +1583,25 @@ def _fr_the_mean_ ( frame , expressions , cuts = '' , errors = True , lazy = Tru # stat = frame.the_rms ( 'x'x' , 'y<0' ) # value = stat.rms() # @ndcode -def _fr_the_rms_ ( frame , expressions , cuts = '' , errors = True , lazy = True ) : +def _fr_the_rms_ ( frame , + expressions , + cuts = '' , + errors = True , + progress = False , + report = False , + lazy = True ) : """Get a rms via moment >>> frame = ... >>> stat = frame.the_rms ( 'x'x' , 'y<0' ) >>> value = stat.rms () """ - return _fr_the_moment_ ( frame , 4 if errors else 2 , expressions , cuts = cuts , lazy = lazy ) + return _fr_the_moment_ ( frame , + 4 if errors else 2 , + expressions , + cuts = cuts , + progress = progress , + report = report , + lazy = lazy ) # ============================================================================ ## Get a variance via moment @@ -1452,13 +1610,25 @@ def _fr_the_rms_ ( frame , expressions , cuts = '' , errors = True , lazy = True # stat = frame.the_variance ( 'x'x' , 'y<0' ) # value = stat.variance () # @ndcode -def _fr_the_variance_ ( frame , expressions , cuts = '' , errors = True , lazy = True ) : +def _fr_the_variance_ ( frame , + expressions , + cuts = '' , + errors = True , + progress = False , + report = False , + lazy = True ) : """Get a variance via moment >>> frame = ... >>> stat = frame.the_variance( 'x'x' , 'y<0' ) >>> value = stat.variance () """ - return _fr_the_moment_ ( frame , 4 if errors else 2 , expressions , cuts = cuts , lazy = lazy ) + return _fr_the_moment_ ( frame , + 4 if errors else 2 , + expressions , + cuts = cuts , + progress = progress , + report = report , + lazy = lazy ) # ============================================================================ ## Get a skewness via moment @@ -1467,13 +1637,25 @@ def _fr_the_variance_ ( frame , expressions , cuts = '' , errors = True , lazy = # stat = frame.the_skewness ( 'x'x' , 'y<0' ) # mean = stat.skewness () # @ndcode -def _fr_the_skewness_ ( frame , expressions , cuts = '' , errors = True , lazy = True ) : - """Get a variance via moment +def _fr_the_skewness_ ( frame , + expressions , + cuts = '' , + errors = True , + progress = False , + report = False , + lazy = True ) : + """Get a skewness via moment >>> frame = ... >>> stat = frame.the_skewness ( 'x'x' , 'y<0' ) >>> mean = stat.skreness () """ - return _fr_the_moment_ ( frame , 6 if errors else 3 , expressions , cuts = cuts , lazy = lazy ) + return _fr_the_moment_ ( frame , + 6 if errors else 3 , + expressions , + cuts = cuts , + progress = progress , + report = report , + lazy = lazy ) # ============================================================================ ## Get a kurtosis via moment @@ -1482,13 +1664,25 @@ def _fr_the_skewness_ ( frame , expressions , cuts = '' , errors = True , lazy = # stat = frame.the_kurtosis ( 'x'x' , 'y<0' ) # value = stat.kurtosis () # @ndcode -def _fr_the_kurtosis_ ( frame , expressions , cuts = '' , errors = True , lazy = True ) : +def _fr_the_kurtosis_ ( frame , + expressions , + cuts = '' , + errors = True , + progress = False , + report = False , + lazy = True ) : """Get a kurtosis via moment >>> frame = ... >>> stat = frame.the_kurtosis ( 'x'x' , 'y<0' ) >>> value = stat.kurtosis () """ - return _fr_the_moment_ ( frame , 8 if errors else 4 , expressions , cuts = cuts , lazy = lazy ) + return _fr_the_moment_ ( frame , + 8 if errors else 4 , + expressions , + cuts = cuts , + progress = progress , + report = report , + lazy = lazy ) # ============================================================================ ## Get an arithmetic mean @@ -1497,7 +1691,12 @@ def _fr_the_kurtosis_ ( frame , expressions , cuts = '' , errors = True , lazy = # frame = ... # mean = frame_the_arithmetic_mean ( frame , 'x*x' , '0>> frame = ... >>> mean = frame_the_arithmetic_mean ( frame , 'x*x' , '0>> frame = ... >>> mean = frame_the_geometric_mean ( frame , 'x*x' , '0>> frame = ... >>> mean = frame_the_harmonic_mean ( frame , 'x*x' , '0>> frame = ... >>> mean = frame_the_power_mean ( frame , 5 , 'x*x' , '0>> frame = ... >>> mean = frame_the_lehmer_mean ( frame , 5 , 'x*x' , '0>> frame = ... >>> mean = frame_the_minmax ( frame , 5 , 'x*x' , '00' ) # @endcode - def frame_statVar ( frame , expressions , cuts = '' ) : + def frame_statVar ( frame , expressions , cuts = '' , progress = False , report = False ) : """Get statistics of variable(s) >>> frame = .... >>> stat = frame.statVar ( 'pt' ) >>> stat = frame.statVar ( 'pt' , 'eta>0' ) """ - return frame_the_statVar ( frame , expressions , cuts = cuts , lazy = False ) + return frame_the_statVar ( frame , expressions , cuts = cuts , progress = progress , report = report , lazy = False ) # ================================================================================== ## get covariance for variables via action # @code @@ -1725,13 +1983,24 @@ def frame_statVar ( frame , expressions , cuts = '' ) : # stat = frame_statCov ( 'pt1' , 'pt2' , ) # stat = frame_statCov ( 'pt1' , 'pt2' , 'z<0' ) # @endcode - def frame_statCov ( frame , expression1 , expression2 , cuts = '' ) : + def frame_statCov ( frame , + expression1 , + expression2 , + cuts = '' , + progress = False , + report = False ) : """Get statistics of variables via actions >>> frame = .... >>> stat = frame_statCov ( 'pt1' , 'pt2' , ) >>> stat = frame_statCov ( 'pt1' , 'pt2' , 'z<0' ) """ - return frame_the_statCov ( frame , expression1 , expression2 , cuts = cuts , lazy = False ) + return frame_the_statCov ( frame , + expression1 , + expression2 , + cuts = cuts , + progress = progress , + report = report , + lazy = False ) # ============================================================================= ## Get the effective entries in data frame (via actions) @@ -1739,12 +2008,19 @@ def frame_statCov ( frame , expression1 , expression2 , cuts = '' ) : # data = ... # neff = data.nEff('b1*b1') # @endcode - def frame_nEff ( frame , cuts = '' ) : + def frame_nEff ( frame , + cuts = '' , + progress = False , + report = False ) : """Get the effective entries in data frame >>> data = ... >>> neff = frame_nEff('b1*b1') """ - return frame_the_nEff ( frame , cuts = cuts , lazy = False ).nEff() + return frame_the_nEff ( frame , + cuts = cuts , + progress = progress , + report = report , + lazy = False ).nEff() # ================================================================================== ## get statistics of variable(s) (via actions) # @code @@ -1754,37 +2030,54 @@ def frame_nEff ( frame , cuts = '' ) : # @endcode # @see Ostap::Math::Moment_ # @see Ostap::Math::WMoment_ - def frame_moment ( frame , N , expressions , cuts = '' ) : + def frame_moment ( frame , N , expressions , cuts = '' , progress = False , report = False ) : """Get statistics of variable(s) (via actions) >>> frame = .... >>> stat = frame_moment ( 5 , 'pt' ) >>> stat = frame_moment ( 5 , 'pt' , 'eta>0' ) """ - return frame_the_moment ( frame , N , expressions , cuts = cuts , lazy = False ) + return frame_the_moment ( frame , N , + expressions , + cuts = cuts , + progress = progress , + report = report , + lazy = False ) # ============================================================================ ## Get a mean via moment&action # @code # frame = ... # mean = frame_mean ( 'x'x' , 'y<0' ) # @ndcode - def frame_mean ( frame , expressions , cuts = '' , errors = True ) : + def frame_mean ( frame , expressions , cuts = '' , errors = True , progress = False , report = False ) : """ Get a mean via moment >>> frame = ... >>> mean = frame_mean ( 'x'x' , 'y<0' ) """ - return frame_the_mean ( frame , expressions , cuts = cuts , errors = errors , lazy = False ).mean() + return frame_the_mean ( frame , + expressions , + cuts = cuts , + errors = errors , + progress = progress , + report = report , + lazy = False ).mean() # ============================================================================ ## Get a rms via moment&action # @code # frame = ... # rms = frame_rms ( 'x'x' , 'y<0' ) # @ndcode - def frame_rms ( frame , expressions , cuts = '' , errors = True , lazy = True ) : + def frame_rms ( frame , expressions , cuts = '' , errors = True , progress = False , report = False ) : """Get a rms via moment&action >>> frame = ... >>> rms = frame_rms ( 'x'x' , 'y<0' ) """ - return frame_the_rms ( frame , expressions , cuts = cuts , errors = errors , lazy = False ).rms() + return frame_the_rms ( frame , + expressions , + cuts = cuts , + errors = errors , + progress = progress , + report = report , + lazy = False ).rms() # ============================================================================ ## Get a variance via moment&actions # @code @@ -1792,13 +2085,19 @@ def frame_rms ( frame , expressions , cuts = '' , errors = True , lazy = True ) # variance = frame_variance ( 'x'x' , 'y<0' ) # variance = frame_dispersion ( 'x'x' , 'y<0' ) # @ndcode - def frame_variance ( frame , expressions , cuts = '' , errors = True , lazy = True ) : + def frame_variance ( frame , expressions , cuts = '' , errors = True , progress = False , report = False ) : """Get a variance via moment&action >>> frame = ... >>> variance = frame_variance ( 'x'x' , 'y<0' ) >>> variance = frame_dispersion ( 'x'x' , 'y<0' ) """ - return frame_the_variance ( frame , expressions , cuts = cuts , errors = errors , lazy = False ).variance() + return frame_the_variance ( frame , + expressions , + cuts = cuts , + errors = errors , + progress = progress , + report = report , + lazy = False ).variance() # ============================================================================ ## ditto frame_dispersion = frame_variance @@ -1808,26 +2107,43 @@ def frame_variance ( frame , expressions , cuts = '' , errors = True , lazy = Tr # frame = ... # skew = frame_skewness ( 'x'x' , 'y<0' ) # @ndcode - def frame_skewness ( frame , expressions , cuts = '' , errors = True ) : + def frame_skewness ( frame , expressions , cuts = '' , errors = True , progress = False , report = False ) : """Get a variance via moment >>> frame = ... >>> skew = frame_skewness ( 'x'x' , 'y<0' ) >>> mean = stat.skreness () """ - return frame_the_skewness ( frame , expressions , cuts = cuts , errors = errors , lazy = False ).skewness() + return frame_the_skewness ( frame , + expressions , + cuts = cuts , + errors = errors , + progress = progress , + report = report , + lazy = False ).skewness() # ============================================================================ - ## Get a kurtosis via moment&actgions + ## Get a kurtosis via moment&actions # @code # frame = ... # kurt = frame_kurtosis ( 'x'x' , 'y<0' ) # @ndcode - def frame_kurtosis ( frame , expressions , cuts = '' , errors = True ) : + def frame_kurtosis ( frame , + expressions , + cuts = '' , + errors = True , + progress = False , + report = False ) : """Get a kurtosis via moment >>> frame = ... >>> stat = frame.the_kurtosis ( 'x'x' , 'y<0' ) >>> value = stat.kurtosis () """ - return frame_the_kurtosis ( frame , expressions , cuts = cuts , errors = True , lazy = False ).kurtosis() + return frame_the_kurtosis ( frame , + expressions , + cuts = cuts , + errors = True , + progress = progress , + report = report , + lazy = False ).kurtosis() # ============================================================================ ## Get an arithmetic mean # @see Ostap::Math::ArithmeticMean @@ -1835,13 +2151,22 @@ def frame_kurtosis ( frame , expressions , cuts = '' , errors = True ) : # frame = ... # mean = frame_arithmetic_mean ( frame , 'x*x' , '0>> frame = ... >>> mean = frame_arithmetic_mean ( frame , 'x*x' , '0>> frame = ... >>> mean = frame_geometric_mean ( frame , 'x*x' , '0>> frame = ... >>> mean = frame_harmonic_mean ( frame , 'x*x' , '0>> frame = ... >>> mean = frame_power_mean ( frame , 5 , 'x*x' , '0>> frame = ... >>> mean = frame_lehmer_mean ( frame , 5 , 'x*x' , '00' ) # @endcode - def frame_param ( frame , poly , expressions , cuts = '' ) : + def frame_param ( frame , + poly , + expressions , + cuts = '' , + progress = False , + report = False ) : """ `project/parameterise` frame into polynomial structures >>> frame = ... @@ -1960,8 +2322,12 @@ def frame_param ( frame , poly , expressions , cuts = '' ) : >>> bs2 = Ostap.Math.Bernstein2D ( ... ) >>> res = frame_param ( frame , bs2 , 'y,x' , 'z>0' ) """ - return frame_the_param ( frame , poly , expressions , cuts = cuts , lazy = False ) - + return frame_the_param ( frame , + poly , + expressions , + cuts = cuts , + progress = False , + report = False , lazy = False ) # ============================================================================ ## Get the approproate range for drawing the variables @@ -1970,13 +2336,18 @@ def frame_param ( frame , poly , expressions , cuts = '' ) : # frame = ... # mean = frame_range ( frame , 'x*x' , '0>> frame = ... >>> mean = frame_the_minmax ( frame , 5 , 'x*x' , '0-1)*1.01' ) - rl = frame_param ( frame , ls , 'b5' ) - rc = frame_param ( frame , cs , 'b6' ) - - polc = rc.GetValue() - poll = rl.GetValue() - polb = rb.GetValue() - - with use_canvas ( 'test_frame7: b4,b5,b6 as polynomials' , wait = 2 ) : - poll.draw ( linecolor = 2 ) - polc.draw ( 'same' , linecolor = 4 ) - polb.draw ( 'same' , linecolor = 8 ) - + with timing ( 'param: Bernstein [12]' , logger = logger ) : + rb = frame_param ( frame , bs , 'b4' , '(b4>-1)*1.01' ) + with timing ( 'param: Legendre [15]' , logger = logger ) : + rl = frame_param ( frame , ls , 'b4' , '(b4>-1)*1.01' ) + with timing ( 'param: Chebyshev [18]' , logger = logger ) : + rc = frame_param ( frame , cs , 'b4' , '(b4>-1)*1.01' ) + + with timing ( 'run : Bernstein [12]' , logger = logger ) : polb = rb.GetValue() + with timing ( 'run : Legendre [15]' , logger = logger ) : poll = rl.GetValue() + with timing ( 'run : Chebyshev [18]' , logger = logger ) : polc = rc.GetValue() + + with use_canvas ( 'test_frame7: b4 as polynomials [12/15/18] ' , wait = 2 ) : + polb.draw ( linecolor = 2 , linewidth = 2 ) + poll.draw ( 'same' , linecolor = 4 , linewidth = 2 ) + polc.draw ( 'same' , linecolor = 8 , linewidth = 2 ) # ============================================================================= def test_frame8 () : diff --git a/ostap/histos/compare.py b/ostap/histos/compare.py index cdc4f5a7..f0d4bbd7 100755 --- a/ostap/histos/compare.py +++ b/ostap/histos/compare.py @@ -31,7 +31,7 @@ # ============================================================================= logger.debug ( 'Some specific comparison of histo-objects') # ============================================================================= -## Can 1D-histogram can be considered as ``constant'' ? +## Can 1D-histogram can be considered as `constant' ? # @code # histo = ... # print 'Is constant? %s ' % histo.is_constant( prob = 0.01 ) @@ -1028,8 +1028,6 @@ def _h3_cmp_ddist_ ( h1 , ROOT.TH3F.cmp_ddist = _h3_cmp_ddist_ ROOT.TH3D.cmp_ddist = _h3_cmp_ddist_ - - # ============================================================================= ## compare two histograms and find the largest difference # @code diff --git a/ostap/trees/trees.py b/ostap/trees/trees.py index e0b2856f..ac68fcaf 100755 --- a/ostap/trees/trees.py +++ b/ostap/trees/trees.py @@ -497,6 +497,7 @@ def target_reset ( t ) : ROOT.TChain.project = tree_project # ====================================================================== +## Draw the variables/expressions fom TTree obnjetc def tree_draw ( tree , what , cuts = '' , @@ -562,7 +563,7 @@ def tree_draw ( tree , histo.draw ( opts , **kw ) return histo - ## ROOT nativ eproject (a bit more efficient) + ## ROOT native project (a bit more efficient) if 1 == nvars : varexp = varlst [ 0 ] elif 2 == nvars : varexp = '%s vs %s ' % ( varlst [ 1 ] , varlst [ 0 ] ) @@ -573,7 +574,11 @@ def tree_draw ( tree , ## draw the histogram histo.draw ( opts , **kw ) return histo - + +ROOT.TTree .draw = tree_draw +ROOT.TChain.draw = tree_draw + + # ============================================================================= ## check if object is in tree/chain : # @code