lsst.meas.algorithms
g4a7591d645+fa9daf83c6
Toggle main menu visibility
Loading...
Searching...
No Matches
python
lsst
meas
algorithms
variance_plane.py
Go to the documentation of this file.
1
# This file is part of meas_algorithms.
2
#
3
# LSST Data Management System
4
# This product includes software developed by the
5
# LSST Project (http://www.lsst.org/).
6
# See COPYRIGHT file at the top of the source tree.
7
#
8
# This program is free software: you can redistribute it and/or modify
9
# it under the terms of the GNU General Public License as published by
10
# the Free Software Foundation, either version 3 of the License, or
11
# (at your option) any later version.
12
#
13
# This program is distributed in the hope that it will be useful,
14
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
# GNU General Public License for more details.
17
#
18
# You should have received a copy of the LSST License Statement and
19
# the GNU General Public License along with this program. If not,
20
# see <https://www.lsstcorp.org/LegalNotices/>.
21
#
22
"""Utility functions related to the variance plane of Exposure objects. Tested
23
in `ip_isr/tests/test_variance_plane.py` to avoid circular dependencies.
24
"""
25
26
import
numpy
as
np
27
28
__all__ = [
"remove_signal_from_variance"
]
29
30
31
def
remove_signal_from_variance
(exposure, gain=None, gains=None, average_across_amps=False, in_place=False):
32
"""
33
Removes the Poisson contribution from actual sources in the variance plane
34
of an Exposure.
35
36
If neither gain nor gains are provided, the function estimates the gain(s).
37
If ``average_across_amps`` is True, a single gain value for the entire
38
image is estimated. If False, individual gain values for each amplifier are
39
estimated. The estimation involves a linear fit of variance versus image
40
plane.
41
42
Parameters
43
----------
44
exposure : `~lsst.afw.image.Exposure`
45
The background-subtracted exposure containing a variance plane to be
46
corrected for source contributions.
47
gain : `float`, optional
48
The gain value for the entire image. This parameter is used if
49
``gains`` is not provided. If both ``gain`` and ``gains`` are None, and
50
``average_across_amps`` is True, ``gain`` is estimated from the image
51
and variance planes.
52
gains : dict[`str`, `float`], optional
53
A dictionary mapping amplifier ID (as a string) to gain value. This
54
parameter is used if ``gain`` is not provided. If both ``gain`` and
55
``gains`` are None, and ``average_across_amps`` is False, ``gains`` are
56
estimated from the image and variance planes.
57
average_across_amps : `bool`, optional
58
Determines the gain estimation strategy. If True, the gain for the
59
entire image is estimated at once. If False, individual gains for each
60
amplifier are estimated. This parameter is ignored if either ``gain``
61
or ``gains`` is specified.
62
in_place : `bool`, optional
63
If True, the variance plane of the input Exposure is modified in place.
64
A modified copy of the variance plane is always returned irrespective
65
of this.
66
67
Returns
68
-------
69
variance_plane : `~lsst.afw.image.Image`
70
The corrected variance plane, with the signal contribution removed.
71
72
Raises
73
------
74
AttributeError
75
If amplifiers cannot be retrieved from the exposure.
76
ValueError
77
If both ``gain`` and ``gains`` are provided, or if the number of
78
provided ``gains`` does not match the number of amplifiers.
79
"""
80
variance_plane = exposure.variance
if
in_place
else
exposure.variance.clone()
81
if
gain
is
None
and
gains
is
None
:
82
if
average_across_amps:
83
amp_bboxes = [exposure.getBBox()]
84
else
:
85
try
:
86
amps = exposure.getDetector().getAmplifiers()
87
amp_bboxes = [amp.getBBox()
for
amp
in
amps]
88
except
AttributeError:
89
raise
AttributeError(
90
"Could not retrieve amplifiers from exposure. To compute a simple gain value across the "
91
"entire image, use average_across_amps=True."
92
)
93
# Fit a straight line to variance vs (sky-subtracted) signal. Then
94
# evaluate that line at zero signal to get an estimate of the
95
# signal-free variance.
96
for
amp_bbox
in
amp_bboxes:
97
amp_im_arr = exposure[amp_bbox].image.array
98
amp_var_arr = variance_plane[amp_bbox].array
99
good = (amp_var_arr != 0) & np.isfinite(amp_var_arr) & np.isfinite(amp_im_arr)
100
fit = np.polyfit(amp_im_arr[good], amp_var_arr[good], deg=1)
101
# Fit is [1/gain, sky_var].
102
amp_gain = 1.0 / fit[0]
103
variance_plane[amp_bbox].array[good] -= amp_im_arr[good] / amp_gain
104
elif
gain
is
None
and
gains
is
not
None
:
105
amps = exposure.getDetector().getAmplifiers()
106
namps = len(amps)
107
if
len(gains) != namps:
108
raise
ValueError(
109
f
"Incorrect number of gains provided: {len(gains)} values for {namps} amplifiers."
110
)
111
for
amp
in
amps:
112
amp_bbox = amp.getBBox()
113
amp_gain = gains[amp.getName()]
114
im_arr = exposure[amp_bbox].image.array
115
variance_plane[amp_bbox].array -= im_arr / amp_gain
116
elif
gain
is
not
None
and
gains
is
None
:
117
im_arr = exposure.image.array
118
variance_plane.array -= im_arr / gain
119
elif
gain
is
not
None
and
gains
is
not
None
:
120
raise
ValueError(
121
"Both 'gain' and 'gains' are provided. Please provide only one of them or none at "
122
"all in case of automatic gain estimation from the image and variance planes."
123
)
124
# Check that the variance plane has no negative values.
125
if
np.any(variance_plane.array < 0):
126
raise
ValueError(
"Corrected variance plane has negative values."
)
127
return
variance_plane
lsst::meas::algorithms.variance_plane.remove_signal_from_variance
remove_signal_from_variance(exposure, gain=None, gains=None, average_across_amps=False, in_place=False)
Definition
variance_plane.py:31
Generated on
for lsst.meas.algorithms by
1.17.0