From 7d5d630292ac4daab5e341134cccbadf2e4f167d Mon Sep 17 00:00:00 2001 From: Vanya Belyaev Date: Thu, 5 Sep 2024 13:11:27 +0200 Subject: [PATCH] prepare v1.13.2.0 --- .aux/test_with_lcg | 2 +- CMakeLists.txt | 6 +-- ReleaseNotes/release_notes.md | 29 +++++++------ ostap/histos/histos.py | 58 +++++++++++++++++++------- ostap/math/tests/test_math_linalgt.py | 60 +++++++++++++-------------- 5 files changed, 92 insertions(+), 63 deletions(-) diff --git a/.aux/test_with_lcg b/.aux/test_with_lcg index 9a769045..8923cec5 100755 --- a/.aux/test_with_lcg +++ b/.aux/test_with_lcg @@ -4,4 +4,4 @@ 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 -j4 -R linalg --output-on-failure --test-output-size-failed=5000000 +ctest -N && cmake .. -DCMAKE_INSTALL_PREFIX=./INSTALL/ && ctest -j4 --output-on-failure --test-output-size-failed=5000000 diff --git a/CMakeLists.txt b/CMakeLists.txt index f8df4be1..ab6afc67 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,12 +18,10 @@ endif() project(ostap LANGUAGES CXX) include(CTest) - - set(OSTAP_VERSION_MAJOR 1) set(OSTAP_VERSION_MINOR 13) -set(OSTAP_VERSION_PATCH 1) -set(OSTAP_VERSION_TWEAK 1) +set(OSTAP_VERSION_PATCH 2) +set(OSTAP_VERSION_TWEAK 0) set(OSTAP_VERSION ${OSTAP_VERSION_MAJOR}.${OSTAP_VERSION_MINOR}.${OSTAP_VERSION_PATCH}.${OSTAP_VERSION_TWEAK}) diff --git a/ReleaseNotes/release_notes.md b/ReleaseNotes/release_notes.md index 02e480d5..f839462c 100644 --- a/ReleaseNotes/release_notes.md +++ b/ReleaseNotes/release_notes.md @@ -1,22 +1,25 @@ +# v1.13.2.0 + ## New features - 1. further improvemets for nice printout of linear algebra objects - 1. add `lnorm` and `mnorm` methods for matrices to get L-norm and max-norm - 1. add `gdiagonal` method to get diagonal matrice - 1. add `abs` method for `SVectors` - 1. improve Linear Algebra tests - 1. improve the machinery for eigenvalues and eigenvectors - 1. add possibility to avodi coloring of the header row in the tables - 1. add protection for double cpoulmn (`::`) for the expression strings - 1. resurrect and improve `ostap.stats.corr2d` module with simple 2D-decorrelation utility - 1. make use of `terminaltables3` instead of `terminaltables` where/when possible - + 1. Further improvemets for nice printout of linear algebra objects + 1. Add `lnorm` and `mnorm` methods for matrices to get L-norm and max-norm + 1. Add `gdiagonal` method to get diagonal matrice + 1. Add `abs` method for `SVectors` + 1. Improve Linear Algebra tests + 1. Improve the machinery for eigenvalues and eigenvectors + 1. Add possibility to avoid coloring of the header row in the tables + 1. Add protection for double cpoulmn (`::`) for the expression strings + 1. Resurrect and improve `ostap.stats.corr2d` module with simple 2D-decorrelation utility + 1. Make use of `terminaltables3` instead of `terminaltables` where/when possible + 1. Add new method `TH1.min_positive` to get minimal positive entry (or negative infinity). + ## Backward incompatible ## Bug fixes - 1. fix tiny bug in `histo_book` - 1. fix tiny bug in printout of linear algebra objects + 1. Fix tiny bug in `histo_book` + 1. Fix tiny bug in printout of linear algebra objects # v1.13.1.0 diff --git a/ostap/histos/histos.py b/ostap/histos/histos.py index 26b1ab2a..e2c079c4 100755 --- a/ostap/histos/histos.py +++ b/ostap/histos/histos.py @@ -2971,7 +2971,7 @@ def _h1_CL_interval_ ( self , # ============================================================================= ## get the minumum value for the histogram def _h_minv_ ( self ) : - """Get the minimum value for the histogram + """ Get the minimum value for the histogram >>> h = ... >>> mv = h.minv () """ @@ -2984,7 +2984,7 @@ def _h_minv_ ( self ) : # ============================================================================= ## get the maximum value for the histogram def _h_maxv_ ( self ) : - """Get the maximum value for the histogram + """ Get the maximum value for the histogram >>> h = ... >>> mv = h.maxv () """ @@ -2995,9 +2995,9 @@ def _h_maxv_ ( self ) : return mv # ============================================================================= -## get the minmaximum values for the histogram +## get the minmax values for the histogram def _h_minmax_ ( self ) : - """Get the minmax pair for the histogram + """ Get the minmax pair for the histogram >>> h = ... >>> mn,mx = h.minmax () """ @@ -3007,10 +3007,35 @@ def _h_minmax_ ( self ) : ROOT.TH1 . maxv = _h_maxv_ ROOT.TH1 . minmax = _h_minmax_ +# ============================================================================ +## Get the minimal positive entry in the historgam +# - It is useful e.g. to define the proper scale for drawing, especially for log-scale +# @code +# histo = ... +# minpos = histo.min_positive() +# @endcode +# @return minimal positive entry or negative infinity if no positive entries +def _h_minpos_ ( histo ) : + """ Get the minimal positive entry in the histogram + - It is useful e.g. to define the proper scale for drawing, especially for log-scale + - return minimal positive entry or negative infinity if no positive entries + >>> histo = ... + >>> minpos = histo.min_positive() + """ + result = inf_neg + for items in histo.items() : + v = items [ -1 ] . value() + if 0 < v : + result = min ( v , result ) if 0 < result else v + return result + +ROOT.TH1.minpos = _h_minpos_ +ROOT.TH1.min_positive = _h_minpos_ + # ============================================================================ ## get the first bin with the minimum content def _h1_minimum_bin_ ( h1 ) : - """Get the first bin with the minimum content + """ Get the first bin with the minimum content """ value = None bin = 0 @@ -3024,7 +3049,7 @@ def _h1_minimum_bin_ ( h1 ) : # ============================================================================ ## get the first bin with the maximal content def _h1_maximum_bin_ ( h1 ) : - """Get the first bin with the maximal content + """ Get the first bin with the maximal content """ value = None bin = 0 @@ -3038,7 +3063,7 @@ def _h1_maximum_bin_ ( h1 ) : # ============================================================================= ## get the first bin with the minimum content def _h2_minimum_bin_ ( h2 ) : - """Get the first bin with the minimum content + """ Get the first bin with the minimum content """ value = None bin = 0,0 @@ -3052,7 +3077,7 @@ def _h2_minimum_bin_ ( h2 ) : # ============================================================================= ## get the first bin with the maximal content def _h2_maximum_bin_ ( h2 ) : - """Get the first bin with the maximal content + """ Get the first bin with the maximal content """ value = None bin = 0,0 @@ -3066,7 +3091,7 @@ def _h2_maximum_bin_ ( h2 ) : # ============================================================================= ## get the first bin with the minimum content def _h3_minimum_bin_ ( h3 ) : - """Get the first bin with the minimum content + """ Get the first bin with the minimum content """ value = None bin = 0,0 @@ -3080,7 +3105,7 @@ def _h3_minimum_bin_ ( h3 ) : # ============================================================================= ## get the first bin with the maximal content def _h3_maximum_bin_ ( h3 ) : - """Get the first bin with the maximal content + """ Get the first bin with the maximal content """ value = None bin = 0,0 @@ -3101,7 +3126,7 @@ def _h3_maximum_bin_ ( h3 ) : # ============================================================================ ## get the minimum value for X-axis def _ax_min_ ( self ) : - """Get the minimum value for X-axis + """ Get the minimum value for X-axis >>> xmin = h.xmin() """ ax = self.GetXaxis () @@ -3109,7 +3134,7 @@ def _ax_min_ ( self ) : # ============================================================================ ## get the minimum value for y-axis def _ay_min_ ( self ) : - """Get the minimum value for Y-axis + """ Get the minimum value for Y-axis >>> ymin = h.ymin() """ ay = self.GetYaxis () @@ -3117,7 +3142,7 @@ def _ay_min_ ( self ) : # ============================================================================ ## get the minimum value for z-axis def _az_min_ ( self ) : - """Get the minimum value for Z-axis + """ Get the minimum value for Z-axis >>> zmin = h.zmin() """ az = self.GetZaxis () @@ -3126,7 +3151,7 @@ def _az_min_ ( self ) : # ============================================================================ ## get the maximum value for X-axis def _ax_max_ ( self ) : - """Get the maximum value for X-axis + """ Get the maximum value for X-axis >>> xmax = h.xmax() """ ax = self.GetXaxis () @@ -3134,7 +3159,7 @@ def _ax_max_ ( self ) : # ============================================================================ ## get the maximum value for y-axis def _ay_max_ ( self ) : - """Get the maximum value for Y-axis + """ Get the maximum value for Y-axis >>> ymax = h.ymax() """ ay = self.GetYaxis () @@ -8754,6 +8779,9 @@ def _h1_roc_ ( h1 , h2 ) : ROOT.TH3 . yminmax , ROOT.TH3 . zminmax , # + ROOT.TH1 . min_positive , + ROOT.TH1 . minpos , + # ROOT.TH2F.random , ROOT.TH2D.random , # diff --git a/ostap/math/tests/test_math_linalgt.py b/ostap/math/tests/test_math_linalgt.py index 28a1d390..fa6eb30a 100755 --- a/ostap/math/tests/test_math_linalgt.py +++ b/ostap/math/tests/test_math_linalgt.py @@ -14,7 +14,7 @@ from ostap.math.base import typename from ostap.math.linalg import checkops from ostap.core.core import Ostap -from ostap.core.meta_info import root_version_int +from ostap.core.meta_info import root_info import ostap.logger.table as T import ROOT, array, random # ============================================================================= @@ -367,7 +367,6 @@ def test_linalgt_mtrx () : row3 = n1 , '*' , n2 , typename ( r_mult ) rows.append ( row3 ) - ## pow for matrices for m1 in matrices22 : @@ -418,7 +417,7 @@ def test_linalgt_mtrx () : # ============================================================================= ## The main function to test linear algebra def test_linalgt_old () : - """The main function to test linear algebra + """ The main function to test linear algebra """ logger = getLogger( 'test_linangt_old') @@ -433,19 +432,19 @@ def test_linalgt_old () : l1[0],l1[1],l1[2] = 0,1,2 l2[0],l2[1],l2[2] = 3,4,5 - logger.info ( 'l1 , l2 : %s %s ' % ( l1 , l2 ) ) - logger.info ( 'l1 + l2 : %s ' % ( l1 + l2 ) ) + logger.info ( 'l1 , l2 : \n%s \n%s ' % ( l1 , l2 ) ) + logger.info ( 'l1 + l2 : \n%s ' % ( l1 + l2 ) ) - logger.info ( 'l1 - l2 : %s ' % ( l1 - l2 ) ) - logger.info ( 'l1 * l2 : %s ' % ( l1 * l2 ) ) - logger.info ( 'l1 * 2 : %s ' % ( l1 * 2 ) ) - logger.info ( ' 2 * l2 : %s ' % ( 2 * l2 ) ) - logger.info ( 'l1 / 2 : %s ' % ( l1 / 2 ) ) + logger.info ( 'l1 - l2 : \n%s ' % ( l1 - l2 ) ) + logger.info ( 'l1 * l2 : \n%s ' % ( l1 * l2 ) ) + logger.info ( 'l1 * 2 : \n%s ' % ( l1 * 2 ) ) + logger.info ( ' 2 * l2 : \n%s ' % ( 2 * l2 ) ) + logger.info ( 'l1 / 2 : \n%s ' % ( l1 / 2 ) ) l1 /= 2 - logger.info ( 'l1 /= 2 : %s ' % l1 ) + logger.info ( 'l1 /= 2 : \n%s ' % l1 ) l1 *= 2 - logger.info ( 'l1 *= 2 : %s ' % l1 ) + logger.info ( 'l1 *= 2 : \n%s ' % l1 ) ## if ( 3 , 5 ) <= python_version : @@ -470,7 +469,7 @@ def test_linalgt_old () : l3[1] = 2 l3[1] = 3 - logger.info ( 'l2 , l3 : %s %s ' % ( l2 , l3 ) ) + logger.info ( 'l2 , l3 : \n%s \n%s ' % ( l2 , l3 ) ) ## if ( 3 , 5 ) <= python_version : @@ -502,11 +501,11 @@ def test_linalgt_old () : logger.info ( 'm22**3\n%s' % m22**3 ) logger.info ( 's22**4\n%s' % s22**4 ) - logger.info ( 'm22 * m23 :\n%s' % ( m22 * m23 ) ) - logger.info ( 'm22 * l2 : %s ' % ( m22 * l2 ) ) - logger.info ( 'l2 * m22 : %s ' % ( l2 * m22 ) ) - logger.info ( 'm23 * l3 : %s ' % ( m23 * l3 ) ) - logger.info ( 'l2 * m23 : %s ' % ( l2 * m23 ) ) + logger.info ( 'm22 * m23 : \n%s' % ( m22 * m23 ) ) + logger.info ( 'm22 * l2 : \n%s ' % ( m22 * l2 ) ) + logger.info ( 'l2 * m22 : \n%s ' % ( l2 * m22 ) ) + logger.info ( 'm23 * l3 : \n%s ' % ( m23 * l3 ) ) + logger.info ( 'l2 * m23 : \n%s ' % ( l2 * m23 ) ) logger.info ( 'm22 * s22 + 2 * m22 :\n%s ' % ( m22*s22 + 2*m22 ) ) logger.info ( 'm22 == m22*1.0 : %s ' % ( m22 == m22 * 1.0 ) ) @@ -552,20 +551,21 @@ def test_linalgt_old () : v2 = np.array ( [1.0,2.0] ) v3 = np.array ( [1.0,2.0,3.0 ] ) - logger.info ( 'v2 * l2 : %s' % ( v2 * l2 ) ) - logger.info ( 'l3 * v3 : %s' % ( l3 * v3 ) ) - logger.info ( 's22 * v2 : %s' % ( s22 * v2 ) ) - logger.info ( 'm22 * v2 : %s' % ( m22 * v2 ) ) - logger.info ( 'm23 * v3 : %s' % ( m23 * v3 ) ) + logger.info ( 'v2 * l2 : \n%s' % ( v2 * l2 ) ) + logger.info ( 'l3 * v3 : \n%s' % ( l3 * v3 ) ) + logger.info ( 's22 * v2 : \n%s' % ( s22 * v2 ) ) + logger.info ( 'm22 * v2 : \n%s' % ( m22 * v2 ) ) + logger.info ( 'm23 * v3 : \n%s' % ( m23 * v3 ) ) n22_m = m22.to_numpy () n22_s = s22.to_numpy () n23 = m23.to_numpy () - if 62006 <= root_version_int : - logger.warning ("Tests with numpy are broken for ROOT %s" % root_version_int ) - else : + if ( 6 , 20 ) <= root_info < ( 6 ,33 ) : + logger.warning ("Tests with numpy are broken for ROOT %s" % str ( root_info ) ) + else : + logger.info ( 'm22 * m22(np) :\n%s' % ( m22 * m22.to_numpy() ) ) logger.info ( 's22 * s22(np) :\n%s' % ( s22 * s22.to_numpy() ) ) logger.info ( 's22 * m23(np) :\n%s' % ( s22 * m23.to_numpy() ) ) @@ -576,7 +576,7 @@ def test_linalgt_old () : # ============================================================================== ## test to check TMatrix <-> array interplay def test_linalgt_arr () : - """Test to check TMatrix <-> array interplay""" + """ Test to check TMatrix <-> array interplay""" logger = getLogger( 'test_linangt_2') @@ -629,10 +629,10 @@ def test_linalgt_arr () : if '__main__' == __name__ : - ## test_linalgt_vct () + test_linalgt_vct () test_linalgt_mtrx () - ## test_linalgt_old () - ## test_linalgt_arr () + test_linalgt_old () + test_linalgt_arr () # =============================================================================