Coverage for install/scipp/utils/comparison.py: 87%

15 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2024-11-17 01:51 +0000

1# SPDX-License-Identifier: BSD-3-Clause 

2# Copyright (c) 2023 Scipp contributors (https://github.com/scipp) 

3# @author Owen Arnold 

4""" 

5Advanced comparisons. 

6""" 

7 

8from ..core import CoordError, DataArray, DType, Variable, all, isclose 

9 

10 

11def isnear( 

12 x: DataArray, 

13 y: DataArray, 

14 rtol: Variable | None = None, 

15 atol: Variable | None = None, 

16 include_attrs: bool = True, 

17 include_data: bool = True, 

18 equal_nan: bool = True, 

19) -> bool: 

20 """ 

21 Similar to scipp.isclose, but intended to compare whole DataArrays. 

22 Coordinates compared element by element with 

23 

24 .. code-block:: python 

25 

26 abs(x - y) <= atol + rtol * abs(y) 

27 

28 Compared coord and attr pairs are only considered equal if all 

29 element-wise comparisons are True. 

30 

31 See scipp.isclose for more details on how the comparisons on each 

32 item will be conducted. 

33 

34 Parameters 

35 ---------- 

36 x: 

37 lhs input 

38 y: 

39 rhs input 

40 rtol: 

41 relative tolerance (to y) 

42 atol: 

43 absolute tolerance 

44 include_data: 

45 Compare data element-wise between x, and y 

46 include_attrs: 

47 Compare all meta (coords and attrs) between x and y, 

48 otherwise only compare coordinates from meta 

49 equal_nan: 

50 If ``True``, consider NaNs or infs to be equal 

51 providing that they match in location and, for infs, 

52 have the same sign 

53 

54 Returns 

55 ------- 

56 : 

57 ``True`` if near 

58 

59 Raises 

60 ------ 

61 Exception: 

62 If `x`, `y` are not going to be logically comparable 

63 for reasons relating to shape, item naming or non-finite elements. 

64 """ 

65 same_data: bool = ( 

66 all(isclose(x.data, y.data, rtol=rtol, atol=atol, equal_nan=equal_nan)).value 

67 if include_data 

68 else True 

69 ) 

70 same_len = ( 

71 len(x.deprecated_meta) == len(y.deprecated_meta) 

72 if include_attrs 

73 else len(x.coords) == len(y.coords) 

74 ) 

75 if not same_len: 

76 return False 

77 for key, val in x.deprecated_meta.items() if include_attrs else x.coords.items(): 

78 a = x.deprecated_meta[key] if include_attrs else x.coords[key] 

79 b = y.deprecated_meta[key] if include_attrs else y.coords[key] 

80 if a.shape != b.shape: 

81 raise CoordError( 

82 f'Coord (or attr) with key {key} have different' 

83 f' shapes. For x, shape is {a.shape}. For y, shape = {b.shape}' 

84 ) 

85 if val.dtype in [DType.float64, DType.float32]: 

86 if not all(isclose(a, b, rtol=rtol, atol=atol, equal_nan=equal_nan)).value: 

87 return False 

88 return same_data