Coverage for python/lsst/analysis/tools/math.py: 21%

72 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2024-04-23 02:33 -0700

1# This file is part of analysis_tools. 

2# 

3# Developed for the LSST Data Management System. 

4# This product includes software developed by the LSST Project 

5# (https://www.lsst.org). 

6# See the COPYRIGHT file at the top-level directory of this distribution 

7# for details of code ownership. 

8# 

9# This program is free software: you can redistribute it and/or modify 

10# it under the terms of the GNU General Public License as published by 

11# the Free Software Foundation, either version 3 of the License, or 

12# (at your option) any later version. 

13# 

14# This program is distributed in the hope that it will be useful, 

15# but WITHOUT ANY WARRANTY; without even the implied warranty of 

16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

17# GNU General Public License for more details. 

18# 

19# You should have received a copy of the GNU General Public License 

20# along with this program. If not, see <https://www.gnu.org/licenses/>. 

21 

22__all__ = ( 

23 "divide", 

24 "fluxToMag", 

25 "nanMax", 

26 "nanMean", 

27 "nanMin", 

28 "nanMedian", 

29 "nanSigmaMad", 

30 "nanStd", 

31 "sigmaMad", 

32 "sqrt", 

33) 

34 

35import warnings 

36from typing import cast 

37 

38import astropy.units as u 

39import numpy as np 

40import scipy.stats as sps 

41 

42from .interfaces import Scalar, Vector 

43from .warning_control import ( 

44 filterwarnings_action, 

45 numpy_all_nan, 

46 numpy_all_nan_slice, 

47 numpy_divide_zero_divide, 

48 numpy_divide_zero_log, 

49 numpy_divide_zero_log10, 

50 numpy_dof_zero, 

51 numpy_invalid_value_divide, 

52 numpy_invalid_value_log, 

53 numpy_invalid_value_log10, 

54 numpy_invalid_value_sqrt, 

55 numpy_mean_empty, 

56) 

57 

58 

59def divide(dividend: Scalar | Vector, divisor: Scalar | Vector) -> Scalar | Vector: 

60 """Return dividend/divisor.""" 

61 with warnings.catch_warnings(): 

62 warnings.filterwarnings(filterwarnings_action, numpy_divide_zero_divide) 

63 warnings.filterwarnings(filterwarnings_action, numpy_invalid_value_divide) 

64 result = dividend / divisor 

65 return result 

66 

67 

68def fluxToMag( 

69 flux: Scalar | Vector, 

70 flux_unit: u.Unit | str = u.nJy, 

71 return_millimags: bool = False, 

72) -> Scalar | Vector: 

73 """Convert fluxes to magnitudes. 

74 

75 Parameters 

76 ---------- 

77 flux 

78 The flux(es) to convert. 

79 flux_unit 

80 The flux unit, as an object or string. Default astropy.units.nJy. 

81 return_millimags 

82 Whether to return millimags instead of mags. 

83 

84 Returns 

85 ------- 

86 mags 

87 The magnitude(s) converted from the flux(es). 

88 """ 

89 if not isinstance(flux_unit, u.Unit): 

90 flux_unit = u.Unit(flux_unit) 

91 with warnings.catch_warnings(): 

92 warnings.filterwarnings(filterwarnings_action, numpy_divide_zero_log10) 

93 warnings.filterwarnings(filterwarnings_action, numpy_invalid_value_log10) 

94 mag = (np.array(flux) * flux_unit).to(u.ABmag).value # type: ignore 

95 if return_millimags: 

96 mag *= 1000 

97 return mag 

98 

99 

100def log(values: Scalar | Vector) -> Scalar | Vector: 

101 """Return the natural logarithm of values.""" 

102 with warnings.catch_warnings(): 

103 warnings.filterwarnings(filterwarnings_action, numpy_divide_zero_log) 

104 warnings.filterwarnings(filterwarnings_action, numpy_invalid_value_log) 

105 result = np.log(values) 

106 return result 

107 

108 

109def log10(values: Scalar | Vector) -> Scalar | Vector: 

110 """Return the natural logarithm of values.""" 

111 with warnings.catch_warnings(): 

112 warnings.filterwarnings(filterwarnings_action, numpy_divide_zero_log10) 

113 warnings.filterwarnings(filterwarnings_action, numpy_invalid_value_log10) 

114 result = np.log10(values) 

115 return result 

116 

117 

118def nanSigmaMad(vector: Vector) -> Scalar: 

119 """Return the sigma_MAD of a vector.""" 

120 return cast(Scalar, sps.median_abs_deviation(vector, scale="normal", nan_policy="omit")) 

121 

122 

123def nanMax(vector: Vector) -> Scalar: 

124 """Return the max of a vector.""" 

125 with warnings.catch_warnings(): 

126 warnings.filterwarnings(filterwarnings_action, numpy_all_nan) 

127 result = float(np.nanmax(vector)) 

128 return cast(Scalar, result) 

129 

130 

131def nanMean(vector: Vector) -> Scalar: 

132 """Return the mean of a vector.""" 

133 with warnings.catch_warnings(): 

134 warnings.filterwarnings(filterwarnings_action, numpy_all_nan_slice) 

135 warnings.filterwarnings(filterwarnings_action, numpy_mean_empty) 

136 result = float(np.nanmean(vector)) 

137 return cast(Scalar, result) 

138 

139 

140def nanMedian(vector: Vector) -> Scalar: 

141 """Return the median of a vector.""" 

142 with warnings.catch_warnings(): 

143 warnings.filterwarnings(filterwarnings_action, numpy_all_nan_slice) 

144 warnings.filterwarnings(filterwarnings_action, numpy_mean_empty) 

145 result = float(np.nanmedian(vector)) 

146 return cast(Scalar, result) 

147 

148 

149def nanMin(vector: Vector) -> Scalar: 

150 """Return the max of a vector.""" 

151 with warnings.catch_warnings(): 

152 warnings.filterwarnings(filterwarnings_action, numpy_all_nan) 

153 result = float(np.nanmin(vector)) 

154 return cast(Scalar, result) 

155 

156 

157def nanStd(vector: Vector) -> Scalar: 

158 with warnings.catch_warnings(): 

159 warnings.filterwarnings(filterwarnings_action, numpy_dof_zero) 

160 result = float(np.nanstd(vector)) 

161 return cast(Scalar, result) 

162 

163 

164def sigmaMad(vector: Vector) -> Scalar: 

165 return cast(Scalar, sps.median_abs_deviation(vector, scale="normal", nan_policy="propagate")) 

166 

167 

168def sqrt(values: Scalar | Vector) -> Scalar | Vector: 

169 """Return the sqrt of values.""" 

170 with warnings.catch_warnings(): 

171 warnings.filterwarnings(filterwarnings_action, numpy_invalid_value_sqrt) 

172 result = np.sqrt(values) 

173 return result