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

70 statements  

« prev     ^ index     » next       coverage.py v7.4.1, created at 2024-01-27 10:59 +0000

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_divide_zero_divide, 

47 numpy_divide_zero_log, 

48 numpy_divide_zero_log10, 

49 numpy_dof_zero, 

50 numpy_invalid_value_divide, 

51 numpy_invalid_value_log, 

52 numpy_invalid_value_log10, 

53 numpy_invalid_value_sqrt, 

54 numpy_mean_empty, 

55) 

56 

57 

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

59 """Return dividend/divisor.""" 

60 with warnings.catch_warnings(): 

61 warnings.filterwarnings(filterwarnings_action, numpy_divide_zero_divide) 

62 warnings.filterwarnings(filterwarnings_action, numpy_invalid_value_divide) 

63 result = dividend / divisor 

64 return result 

65 

66 

67def fluxToMag( 

68 flux: Scalar | Vector, 

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

70 return_millimags: bool = False, 

71) -> Scalar | Vector: 

72 """Convert fluxes to magnitudes. 

73 

74 Parameters 

75 ---------- 

76 flux 

77 The flux(es) to convert. 

78 flux_unit 

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

80 return_millimags 

81 Whether to return millimags instead of mags. 

82 

83 Returns 

84 ------- 

85 mags 

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

87 """ 

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

89 flux_unit = u.Unit(flux_unit) 

90 with warnings.catch_warnings(): 

91 warnings.filterwarnings(filterwarnings_action, numpy_divide_zero_log10) 

92 warnings.filterwarnings(filterwarnings_action, numpy_invalid_value_log10) 

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

94 if return_millimags: 

95 mag *= 1000 

96 return mag 

97 

98 

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

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

101 with warnings.catch_warnings(): 

102 warnings.filterwarnings(filterwarnings_action, numpy_divide_zero_log) 

103 warnings.filterwarnings(filterwarnings_action, numpy_invalid_value_log) 

104 result = np.log(values) 

105 return result 

106 

107 

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

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

110 with warnings.catch_warnings(): 

111 warnings.filterwarnings(filterwarnings_action, numpy_divide_zero_log10) 

112 warnings.filterwarnings(filterwarnings_action, numpy_invalid_value_log10) 

113 result = np.log10(values) 

114 return result 

115 

116 

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

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

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

120 

121 

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

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

124 with warnings.catch_warnings(): 

125 warnings.filterwarnings(filterwarnings_action, numpy_all_nan) 

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

127 return cast(Scalar, result) 

128 

129 

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

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

132 with warnings.catch_warnings(): 

133 warnings.filterwarnings(filterwarnings_action, numpy_mean_empty) 

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

135 return cast(Scalar, result) 

136 

137 

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

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

140 with warnings.catch_warnings(): 

141 warnings.filterwarnings(filterwarnings_action, numpy_mean_empty) 

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

143 return cast(Scalar, result) 

144 

145 

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

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

148 with warnings.catch_warnings(): 

149 warnings.filterwarnings(filterwarnings_action, numpy_all_nan) 

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

151 return cast(Scalar, result) 

152 

153 

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

155 with warnings.catch_warnings(): 

156 warnings.filterwarnings(filterwarnings_action, numpy_dof_zero) 

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

158 return cast(Scalar, result) 

159 

160 

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

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

163 

164 

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

166 """Return the sqrt of values.""" 

167 with warnings.catch_warnings(): 

168 warnings.filterwarnings(filterwarnings_action, numpy_invalid_value_sqrt) 

169 result = np.sqrt(values) 

170 return result