Coverage for python/lsst/analysis/tools/math.py: 21%
72 statements
« prev ^ index » next coverage.py v7.5.0, created at 2024-05-04 03:35 -0700
« prev ^ index » next coverage.py v7.5.0, created at 2024-05-04 03:35 -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/>.
22__all__ = (
23 "divide",
24 "fluxToMag",
25 "nanMax",
26 "nanMean",
27 "nanMin",
28 "nanMedian",
29 "nanSigmaMad",
30 "nanStd",
31 "sigmaMad",
32 "sqrt",
33)
35import warnings
36from typing import cast
38import astropy.units as u
39import numpy as np
40import scipy.stats as sps
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)
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
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.
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.
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
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
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
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"))
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)
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)
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)
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)
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)
164def sigmaMad(vector: Vector) -> Scalar:
165 return cast(Scalar, sps.median_abs_deviation(vector, scale="normal", nan_policy="propagate"))
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