From 643b344cec485cdb7ea77f9d541fce3ca980fe75 Mon Sep 17 00:00:00 2001 From: Vanya Belyaev Date: Mon, 5 Aug 2024 14:10:53 +0200 Subject: [PATCH] imporove determinationfo ranges --- .aux/test_with_lcg | 2 +- ostap/core/core.py | 100 +++++++++++++++++++++++++-------------- ostap/fitting/dataset.py | 4 +- ostap/frames/frames.py | 21 ++++---- ostap/math/base.py | 87 ++++++++++++++++++++++++---------- ostap/trees/trees.py | 2 +- 6 files changed, 140 insertions(+), 76 deletions(-) diff --git a/.aux/test_with_lcg b/.aux/test_with_lcg index 8a1ae1fe..4f43dd1e 100755 --- a/.aux/test_with_lcg +++ b/.aux/test_with_lcg @@ -4,5 +4,5 @@ CMTCONFIG=$2 source /cvmfs/sft.cern.ch/lcg/views/${LCG}/${CMTCONFIG}/setup.sh source build/INSTALL/thisostap.sh cd build -ctest -N && cmake .. -DCMAKE_INSTALL_PREFIX=./INSTALL/ && ctest -R roc -j8 --output-on-failure +ctest -N && cmake .. -DCMAKE_INSTALL_PREFIX=./INSTALL/ && ctest -R '(roc|runnit)' -j8 --output-on-failure diff --git a/ostap/core/core.py b/ostap/core/core.py index 500b01d6..a9fe9ea1 100644 --- a/ostap/core/core.py +++ b/ostap/core/core.py @@ -433,6 +433,21 @@ def _TO_draw_ ( obj , option = '', *args , **kwargs ) : >>> obj.draw ( minimal = -1 ) >>> obj.draw ( max = 100 ) + + - Combined FillStyle/FillColor optoios + + >> obj.draw ( fill = 29 ) ## Color if 0 < fill < 1000 + >> obj.draw ( fill = 2045 ) ## Style if 1000 < fill + + - LogX/logY options : + + >>> obj.draw ( logx = True ) + >>> obj.draw ( logy = True ) + + - Opacity/Opaque for TAttFill + + >>> obg.draw ( opacity = 0.45 ) + >>> obg.draw ( opaque = 0.45 ) """ @@ -450,42 +465,48 @@ def _TO_draw_ ( obj , option = '', *args , **kwargs ) : obj.SetFillColor ( color ) ## Line - - if 'LineColor' in kw and hasattr ( obj , 'SetLineColor' ) : - color = check_color ( kw.pop('LineColor' ) ) - obj.SetLineColor ( color ) - if 'LineStyle' in kw and hasattr ( obj , 'SetLineStyle' ) : - obj.SetLineStyle ( kw.pop('LineStyle' ) ) - if 'LineWidth' in kw and hasattr ( obj , 'SetLineWidth' ) : - obj.SetLineWidth ( kw.pop('LineWidth' ) ) - + if isinstance ( obj , ROOT.TAttLine ) : + if 'LineColor' in kw : obj.SetLineColor ( check_color ( kw.pop('LineColor' ) ) ) + if 'LineStyle' in kw : obj.SetLineStyle ( kw.pop('LineStyle' ) ) + if 'LineWidth' in kw : obj.SetLineWidth ( kw.pop('LineWidth' ) ) + ## Marker - - if 'MarkerColor' in kw and hasattr ( obj , 'SetMarkerColor' ) : - color = check_color ( kw.pop('MarkerColor' ) ) - obj.SetMarkerColor ( color ) - if 'MarkerStyle' in kw and hasattr ( obj , 'SetMarkerStyle' ) : - obj.SetMarkerStyle ( kw.pop('MarkerStyle' ) ) - if 'MarkerSize' in kw and hasattr ( obj , 'SetMarkerSize' ) : - obj.SetMarkerSize ( kw.pop('MarkerSize' ) ) + if isinstance ( obj , ROOT.TAttMarker ) : + if 'MarkerColor' in kw : obj.SetMarkerColor ( check_color ( kw.pop('MarkerColor' ) ) ) + if 'MarkerStyle' in kw : obj.SetMarkerStyle ( kw.pop('MarkerStyle' ) ) + if 'MarkerSize' in kw : obj.SetMarkerSize ( kw.pop('MarkerSize' ) ) ## Area + if isinstance ( obj , ROOT.TAttFill ) : + fcolor = False + fstyle = False + if 'FillColor' in kw : + fcolor = True + obj.SetFillColor ( check_color ( kw.pop('FillColor' ) ) ) + if 'FillStyle' in kw : + fstyle = True + obj.SetFillStyle ( kw.pop('FillStyle' ) ) + + if 'Fill' in kw : + + fill = kw.pop ( 'Fill' ) - if 'FillColor' in kw and hasattr ( obj , 'SetFillColor' ) : - color = check_color ( kw.pop('FillColor' ) ) - obj.SetFillColor ( color ) - if 'FillStyle' in kw and hasattr ( obj , 'SetFillStyle' ) : - obj.SetFillStyle ( kw.pop('FillStyle' ) ) + if fill is True and ( not fstyle ) and has_style : obj.SetFillStyle ( 1001 ) + elif fill is False and ( not fstyle ) and has_style : obj.SetFillStyle ( 0 ) + elif isinstance ( fill , integer_types ) : + if 0 < fill < 1000 and not fcolor : + obj.SetFillColor ( fill ) + if not fstyle : obj.SetFillStyle ( 1001 ) + elif 1000 < fill and not fstyle : + obj.SetFillStyle ( fill ) - if 'Opacity' in kw and \ - hasattr ( obj , 'SetFillColorAlpha' ) and \ - hasattr ( obj , 'GetFillStyle' ) : - fs = obj.GetFillStyle() - if 1001 == fs and hasattr ( obj , 'GetFillColor' ) : + if ( ( 'Opacity' in kw ) or ( 'Opaque' in kw ) ) and 1001 == obj.GetFillStyle () : fc = obj.GetFillColor() - if fc : obj.SetFillColorAlpha ( fc , kw.pop ('Opacity' ) ) - + if fc : + if 'Opacity' in kw : obj.SetFillColorAlpha ( fc , kw.pop ('Opacity' ) ) + elif 'Opaque' in kw : obj.SetFillColorAlpha ( fc , kw.pop ('Opaque' ) ) + ## Min/max values if 'Minimum' in kw and hasattr ( obj , 'SetMinimum' ) : @@ -548,18 +569,27 @@ def _TO_draw_ ( obj , option = '', *args , **kwargs ) : za = obj.GetZaxis() if za : za.SetLabelOffset ( kw.pop ( 'ZaxisLabelOffset' ) ) - ## - copy = kw.pop ( 'copy' , False ) + ## + + copy = kw.pop ( 'copy' , False ) + + + groot = ROOT.ROOT.GetROOT () + pad = groot.GetSelectedPad() + if not pad : pad = ROOT.gPad + if pad : + if 'LogX' in kw : pad.SetLogx ( kw.pop ( 'LogX' ) ) + if 'LogY' in kw : pad.SetLogy ( kw.pop ( 'LogY' ) ) + if kw : logger.warning('draw: unknown attributes: %s' % kw.keys() ) with rootWarning() , rooSilent ( 2 ) : if copy and hasattr ( obj , 'DrawCopy' ): result = obj.DrawCopy ( option , *args ) else : result = obj.Draw ( option , *args ) - - groot = ROOT.ROOT.GetROOT () - pad = groot.GetSelectedPad() - if pad and not ROOT.gPad : + + + if pad and not ROOT.gPad : c = pad.GetCanvas() if c : c.Update() elif ROOT.gPad : diff --git a/ostap/fitting/dataset.py b/ostap/fitting/dataset.py index da984a37..d4b3c62c 100644 --- a/ostap/fitting/dataset.py +++ b/ostap/fitting/dataset.py @@ -982,7 +982,7 @@ def ds_draw ( dataset , cut_range = '' , first = 0 , last = LAST_ENTRY , - delta = 0.05 , **kwargs ) : + delta = 0.01 , **kwargs ) : """Helper draw method for drawing of RooDataSet >>> dataset.draw ( 'm', 'chi2<10' ) ## cuts & weight @@ -1023,8 +1023,6 @@ def ds_draw ( dataset , assert len ( ranges ) == nvars , 'Invalid ranges: %s' % str ( ranges ) - print ('RANGES' , ranges ) - from ostap.utils.cidict import cidict kw = cidict ( transform = cidict_fun , **kwargs ) diff --git a/ostap/frames/frames.py b/ostap/frames/frames.py index b6fcf2cc..f0e1f8cc 100644 --- a/ostap/frames/frames.py +++ b/ostap/frames/frames.py @@ -154,7 +154,7 @@ def _fr_helper_ ( frame , expressions , cuts = '' , progress = False ) : ## Frame/Tree ? lenght = -1 - if isinstance ( frame , ROOT.TTree ) : node , length = DataFrame ( frame , progress = progress ) , len ( frame ) + if isinstance ( frame , ROOT.TTree ) : node , length = DataFrame ( frame ) , len ( frame ) elif isinstance ( frame , frame_types ) : node = frame else : node = as_rnode ( frame ) @@ -211,6 +211,7 @@ def _fr_helper2_ ( frame , lazy = True ) : """The seocnd helper method to implement various statitic-related actions """ + current, var_names, cut_name, input_string = _fr_helper_ ( frame , expressions , cuts , progress = progress ) results = {} @@ -222,7 +223,7 @@ def _fr_helper2_ ( frame , for expr, res in loop_items ( results ) : results [ expr ] = res.GetValue() rr = results [ expr ] - + if report and not lazy : report = current.Report() title = 'DataFrame processing' @@ -943,6 +944,7 @@ def _fr_draw_ ( frame , expressions , cuts = '' , opts = '' , + delta = 0.01 , progress = False , report = False , **kwargs ) : """Draw the variable(s) from the frame @@ -964,9 +966,9 @@ def _fr_draw_ ( frame , ## create the cache ... needed ? ## cache = current.Cache ( uvars ) cache = current - + ## get the ranges - ranges = frame_range ( cache , cvars , cname , report = report ) + ranges = frame_range ( cache , cvars , cname , delta = delta , report = report ) if not ranges : logger.warning ( 'frame_draw: nothing to draw, return None' ) return None @@ -979,21 +981,16 @@ def _fr_draw_ ( frame , mn , mx = ranges [ var ] item = key , ( mn , mx ) histos.append ( item ) - + ## book the histogram histo = histo_book ( histos , kw ) ## fill the histogram 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 # ============================================================================= @@ -2339,7 +2336,7 @@ def frame_param ( frame , def frame_range ( frame , expressions , cuts = '' , - delta = 0.05 , + delta = 0.01 , progress = False , report = False ) : """Get the approproavte range values for variables diff --git a/ostap/math/base.py b/ostap/math/base.py index 61fdc14f..3abda84e 100755 --- a/ostap/math/base.py +++ b/ostap/math/base.py @@ -859,58 +859,97 @@ def frexp10 ( value ) : return ( xv , q ) if ( 0 <= value ) else ( -xv , q ) +# ============================================================================= +## Define some "range" for the given value: +# @code +# value = ... +# mn, mx = num_range ( value ) +# @endcode +def num_range ( value , N = 1 ) : + """ Define some "range" for the given value: + >>> value = ... + >>> mn, mx = num_range ( value ) + """ + + if iszero ( value ) : return ( -0.5 , 0.5 ) + + a , b = frexp10 ( value ) + b -= N + + NN = 10 ** N + + af = math.floor ( a * 2 * NN ) + ac = math.ceil ( a * 2 * NN ) + + if isequal ( af , ac ) : + af, ac = af - 0.5 , ac + 0.5 + + xmin = af * ( 10 ** b ) * 0.5 + xmax = ac * ( 10 ** b ) * 0.5 + + return xmin , xmax + + # ============================================================================= ## Find suitable range for histogram axis -def axis_range ( xmin , xmax , delta = 0.05 , log = False ) : +def axis_range ( xmin , xmax , delta = 0.02 , log = False ) : """Find suitable range for histogram axis """ xmn = min ( xmin , xmax ) xmx = max ( xmin , xmax ) - import math - ## 1) special case - if isequal ( xmn , xmx ) : - return math.floor ( xmn - 0.1 ) , math.ceil ( xmx + 0.1 ) + if iszero ( xmn ) and iszero ( xmn ) : return ( -1.0 , 1.0 ) + + ## 2) special case + if isequal ( xmn , xmx ) : return num_range ( 0.5 * ( xmn + xmx ) ) + - ## 2) special case - if islong ( xmn - 0.5 ) and islong ( xmn + 0.5 ) : + ## 3) special case + if islong ( xmn - 0.5 ) and islong ( xmx + 0.5 ) : return math.floor ( xmn - 0.1 ) , math.ceil ( xmx + 0.1 ) + d = xmx - xmn + + delta = abs ( delta ) + fr = min ( delta , 0.9 ) - if 0 <= xmn < xmx : - - xmin = max ( 0 , xmn - delta * d ) - xmax = xmx + delta * d + if iszero ( xmn ) and xmn < xmx : - elif xmn < xmx <= 0 : + xmin = 0 + xmax = xmx + delta * d + + elif iszero ( xmx ) and xmn < xmx : - xmin = xmn - delta * d - xmax = max ( 0 , xmx + delta * d ) + xmin = xmn - delta * d + xmax = 0 elif xmn < 0 < xmx : xmin = ( 1 + delta ) * xmn xmax = ( 1 + delta ) * xmx + elif 0 < xmn < xmx : + + xmin = max ( xmn * ( 1 - fr ) , xmn - delta * d ) + xmax = xmx + delta * d + + elif xmn < xmx < 0 : + + xmin = xmn - delta * d + xmax = min ( xmx * ( 1 - fr ) , xmx + delta * d ) + else : xmin = xmn - delta * d xmax = xmx + delta * d - N = 3 - - a1 , b1 = frexp10 ( xmin ) - a2 , b2 = frexp10 ( xmax ) - b1 -= N - b2 -= N + xmin , _ = num_range ( xmin ) + _ , xmax = num_range ( xmax ) - xmin = math.floor ( a1 * ( 10**N ) ) * ( 10 ** b1 ) - xmax = math.ceil ( a2 * ( 10**N ) ) * ( 10 ** b2 ) - - return xmin , xmax + return xmin, xmax # ============================================================================= if (3,9) <= sys.version_info : diff --git a/ostap/trees/trees.py b/ostap/trees/trees.py index ac68fcaf..911ad3da 100755 --- a/ostap/trees/trees.py +++ b/ostap/trees/trees.py @@ -505,7 +505,7 @@ def tree_draw ( tree , first = 0 , last = LAST_ENTRY , use_frame = False , - delta = 0.05 , + delta = 0.01 , native = False , **kwargs ) : ## use DataFrame ?