Coverage for python / lsst / analysis / tools / math.py: 24%
94 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-26 09:36 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-26 09:36 +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/>.
22__all__ = (
23 "cos",
24 "divide",
25 "isPercent",
26 "fluxToMag",
27 "nanMax",
28 "nanMean",
29 "nanMin",
30 "nanMedian",
31 "nanSigmaMad",
32 "nanStd",
33 "power",
34 "sigmaMad",
35 "sin",
36 "sqrt",
37)
39import warnings
40from typing import cast
42import astropy.units as u
43import numpy as np
44import scipy.stats as sps
46from .interfaces import Scalar, Vector
47from .warning_control import (
48 filterwarnings_action,
49 numpy_all_nan,
50 numpy_all_nan_slice,
51 numpy_divide_zero_divide,
52 numpy_divide_zero_log,
53 numpy_divide_zero_log10,
54 numpy_dof_zero,
55 numpy_invalid_value_cos,
56 numpy_invalid_value_divide,
57 numpy_invalid_value_log,
58 numpy_invalid_value_log10,
59 numpy_invalid_value_power,
60 numpy_invalid_value_scalar_divide,
61 numpy_invalid_value_sin,
62 numpy_invalid_value_sqrt,
63 numpy_invalid_value_subtract,
64 numpy_mean_empty,
65)
68def cos(values: Scalar | Vector) -> Scalar | Vector:
69 """Return the sqrt of values."""
70 with warnings.catch_warnings():
71 warnings.filterwarnings(filterwarnings_action, numpy_invalid_value_cos)
72 result = np.cos(values)
73 return result
76def divide(dividend: Scalar | Vector, divisor: Scalar | Vector) -> Scalar | Vector:
77 """Return dividend/divisor."""
78 with warnings.catch_warnings():
79 warnings.filterwarnings(filterwarnings_action, numpy_divide_zero_divide)
80 warnings.filterwarnings(filterwarnings_action, numpy_invalid_value_divide)
81 warnings.filterwarnings(filterwarnings_action, numpy_invalid_value_scalar_divide)
82 result = dividend / divisor
83 return result
86def fluxToMag(
87 flux: Scalar | Vector,
88 flux_unit: u.Unit | str = u.nJy,
89 return_millimags: bool = False,
90) -> Scalar | Vector:
91 """Convert fluxes to magnitudes.
93 Parameters
94 ----------
95 flux
96 The flux(es) to convert.
97 flux_unit
98 The flux unit, as an object or string. Default astropy.units.nJy.
99 return_millimags
100 Whether to return millimags instead of mags.
102 Returns
103 -------
104 mags
105 The magnitude(s) converted from the flux(es).
106 """
107 if not isinstance(flux_unit, u.Unit):
108 flux_unit = u.Unit(flux_unit)
109 with warnings.catch_warnings():
110 warnings.filterwarnings(filterwarnings_action, numpy_divide_zero_log10)
111 warnings.filterwarnings(filterwarnings_action, numpy_invalid_value_log10)
112 mag = (np.asarray(flux) * flux_unit).to(u.ABmag).value # type: ignore
113 if return_millimags:
114 mag *= 1000
115 return mag
118def isPercent(value: Scalar) -> bool:
119 """Return true if the value is between 0-100"""
120 result = 0.0 <= value <= 100.0
121 return result
124def log(values: Scalar | Vector) -> Scalar | Vector:
125 """Return the natural logarithm of values."""
126 with warnings.catch_warnings():
127 warnings.filterwarnings(filterwarnings_action, numpy_divide_zero_log)
128 warnings.filterwarnings(filterwarnings_action, numpy_invalid_value_log)
129 result = np.log(values)
130 return result
133def log10(values: Scalar | Vector) -> Scalar | Vector:
134 """Return the natural logarithm of values."""
135 with warnings.catch_warnings():
136 warnings.filterwarnings(filterwarnings_action, numpy_divide_zero_log10)
137 warnings.filterwarnings(filterwarnings_action, numpy_invalid_value_log10)
138 result = np.log10(values)
139 return result
142def nanSigmaMad(vector: Vector) -> Scalar:
143 """Return the sigma_MAD of a vector."""
144 with warnings.catch_warnings():
145 # This is needed to catch inf median in sigma_mad
146 warnings.filterwarnings(filterwarnings_action, numpy_invalid_value_subtract)
147 result = sps.median_abs_deviation(np.asarray(vector), axis=None, scale="normal", nan_policy="omit")
148 return cast(Scalar, result)
151def nanMax(vector: Vector) -> Scalar:
152 """Return the max of a vector."""
153 with warnings.catch_warnings():
154 warnings.filterwarnings(filterwarnings_action, numpy_all_nan)
155 result = float(np.nanmax(np.asarray(vector)))
156 return cast(Scalar, result)
159def nanMean(vector: Vector) -> Scalar:
160 """Return the mean of a vector."""
161 with warnings.catch_warnings():
162 warnings.filterwarnings(filterwarnings_action, numpy_all_nan_slice)
163 warnings.filterwarnings(filterwarnings_action, numpy_mean_empty)
164 result = float(np.nanmean(np.asarray(vector)))
165 return cast(Scalar, result)
168def nanMedian(vector: Vector) -> Scalar:
169 """Return the median of a vector."""
170 with warnings.catch_warnings():
171 warnings.filterwarnings(filterwarnings_action, numpy_all_nan_slice)
172 warnings.filterwarnings(filterwarnings_action, numpy_mean_empty)
173 result = float(np.nanmedian(np.asarray(vector)))
174 return cast(Scalar, result)
177def nanMin(vector: Vector) -> Scalar:
178 """Return the max of a vector."""
179 with warnings.catch_warnings():
180 warnings.filterwarnings(filterwarnings_action, numpy_all_nan)
181 result = float(np.nanmin(np.asarray(vector)))
182 return cast(Scalar, result)
185def nanStd(vector: Vector) -> Scalar:
186 with warnings.catch_warnings():
187 warnings.filterwarnings(filterwarnings_action, numpy_dof_zero)
188 result = float(np.nanstd(np.asarray(vector)))
189 return cast(Scalar, result)
192def power(values: Scalar | Vector, power: float) -> Scalar | Vector:
193 """Return the sqrt of values."""
194 with warnings.catch_warnings():
195 warnings.filterwarnings(filterwarnings_action, numpy_invalid_value_power)
196 result = np.power(values, power)
197 return result
200def sigmaMad(vector: Vector) -> Scalar:
201 return cast(Scalar, sps.median_abs_deviation(np.asarray(vector), scale="normal", nan_policy="propagate"))
204def sin(values: Scalar | Vector) -> Scalar | Vector:
205 """Return the sin of values."""
206 with warnings.catch_warnings():
207 warnings.filterwarnings(filterwarnings_action, numpy_invalid_value_sin)
208 result = np.sin(values)
209 return result
212def sqrt(values: Scalar | Vector) -> Scalar | Vector:
213 """Return the sqrt of values."""
214 with warnings.catch_warnings():
215 warnings.filterwarnings(filterwarnings_action, numpy_invalid_value_sqrt)
216 result = np.sqrt(values)
217 return result