Coverage for pesummary/utils/bounded_interp.py: 96.3%

27 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2024-12-09 22:34 +0000

1# Licensed under an MIT style license -- see LICENSE.md 

2 

3from scipy.interpolate import RectBivariateSpline as _RectBivariateSpline 

4import numpy as np 

5 

6__author__ = [ 

7 "Charlie Hoy <charlie.hoy@ligo.org>", 

8] 

9 

10 

11class RectBivariateSpline(_RectBivariateSpline): 

12 """A modified version of scipy.interpolant.RectBivariateSpline to add 

13 kwargs that were previously available in the deprecated 

14 scipy.interpolant.interp2d. 

15 

16 Parameters 

17 ---------- 

18 x: np.ndarray 

19 data points in the x direction 

20 y: np.ndarray 

21 data points in the y direction 

22 z: np.ndarray 

23 2d array of data points with shape (x.size, y.size) 

24 bounds_error: bool, optional 

25 If True, a ValueError is raised when interpolated values outside of 

26 the range [min(x), max(x)] and [min(y), max(y)] are requested. If False, 

27 fill_value is used when fill_value is not None. Default False 

28 fill_value: float, optional 

29 the value to use when interpolated values outside of the range 

30 [min(x), max(x)] and [min(y), max(y)] are requested. Default None 

31 """ 

32 def __init__(self, x, y, z, bounds_error=False, fill_value=None, **kwargs): 

33 self.x_min = np.min(x) 

34 self.x_max = np.max(x) 

35 self.y_min = np.min(y) 

36 self.y_max = np.max(y) 

37 self.bounds_error = bounds_error 

38 self.fill_value = fill_value 

39 super(RectBivariateSpline, self).__init__(x=x, y=y, z=z, **kwargs) 

40 

41 def __call__(self, x, y, *args, **kwargs): 

42 result = super(RectBivariateSpline, self).__call__(x=x, y=y, *args, **kwargs) 

43 if self.bounds_error or self.fill_value is not None: 

44 out_of_bounds_x = (x < self.x_min) | (x > self.x_max) 

45 out_of_bounds_y = (y < self.y_min) | (y > self.y_max) 

46 any_out_of_bounds_x = np.any(out_of_bounds_x) 

47 any_out_of_bounds_y = np.any(out_of_bounds_y) 

48 if self.bounds_error and (any_out_of_bounds_x or any_out_of_bounds_y): 

49 raise ValueError( 

50 "x and y are out of range. Please ensure that x is in range " 

51 "[{}, {}] and y is in range [{}, {}]".format( 

52 self.x_min, self.x_max, self.y_min, self.y_max 

53 ) 

54 ) 

55 if self.fill_value is not None: 

56 if any_out_of_bounds_x: 

57 result[out_of_bounds_x, :] = self.fill_value 

58 if any_out_of_bounds_y: 

59 result[:, out_of_bounds_y] = self.fill_value 

60 return result