Skip to content

Commit

Permalink
Refactor code organization; Move test to ip_isr
Browse files Browse the repository at this point in the history
  • Loading branch information
enourbakhsh committed Apr 8, 2024
1 parent a24ea2b commit 586771c
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 1,004 deletions.
63 changes: 34 additions & 29 deletions python/lsst/meas/algorithms/variance_plane.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@
# the GNU General Public License along with this program. If not,
# see <https://www.lsstcorp.org/LegalNotices/>.
#
"""Utility functions related to the variance plane of Exposure objects.
"""Utility functions related to the variance plane of Exposure objects. Tested
in `ip_isr/tests/test_variance_plane.py` to avoid circular dependencies.
"""

import numpy as np


__all__ = ["remove_signal_from_variance"]


Expand All @@ -34,49 +34,49 @@ def remove_signal_from_variance(exposure, gain=None, gains=None, average_across_
of an Exposure.
If neither gain nor gains are provided, the function estimates the gain(s).
If 'average_across_amps' is True, a single gain value for the entire image
is estimated. If False, individual gain values for each amplifier are
If ``average_across_amps`` is True, a single gain value for the entire
image is estimated. If False, individual gain values for each amplifier are
estimated. The estimation involves a linear fit of variance versus image
plane.
Parameters
----------
exposure : `~lsst.afw.image.Exposure`
The exposure containing a variance plane to be corrected for
source contributions.
The background-subtracted exposure containing a variance plane to be
corrected for source contributions.
gain : `float`, optional
The gain value for the entire image. This parameter is used if 'gains'
is not provided. If both 'gain' and 'gains' are None, and
'average_across_amps' is True, 'gain' is estimated from the image and
variance planes.
gains : `list` of `float`, optional
A list of gain values for each amplifier. This parameter is used if
'gain' is not provided. If both 'gain' and 'gains' are None, and
'average_across_amps' is False, 'gains' are estimated from the image
and variance planes.
The gain value for the entire image. This parameter is used if
``gains`` is not provided. If both ``gain`` and ``gains`` are None, and
``average_across_amps`` is True, ``gain`` is estimated from the image
and variance planes.
gains : dict[`str`, `float`], optional
A dictionary mapping amplifier ID (as a string) to gain value. This
parameter is used if ``gain`` is not provided. If both ``gain`` and
``gains`` are None, and ``average_across_amps`` is False, ``gains`` are
estimated from the image and variance planes.
average_across_amps : `bool`, optional
Determines the gain estimation strategy. If True, the gain for the
entire image is estimated at once. If False, individual gains for each
amplifier are estimated. This parameter is ignored if either 'gain' or
'gains' is specified.
amplifier are estimated. This parameter is ignored if either ``gain``
or ``gains`` is specified.
in_place : `bool`, optional
If True, the variance plane of the input Exposure is modified in place.
If False (default), a modified copy of the variance plane is returned.
A modified copy of the variance plane is always returned irrespective
of this.
Returns
-------
variance_plane : `~lsst.afw.image.MaskedImage`, optional
variance_plane : `~lsst.afw.image.Image`
The corrected variance plane, with the signal contribution removed.
This is only returned if 'in_place' is False.
Raises
------
AttributeError
If amplifiers cannot be retrieved from the exposure without providing
'average_across_amps=True'.
``average_across_amps==True``.
ValueError
If both 'gain' and 'gains' are provided, or if the number of provided
'gains' does not match the number of amplifiers.
If both ``gain`` and ``gains`` are provided, or if the number of
provided ``gains`` does not match the number of amplifiers.
"""
variance_plane = exposure.variance if in_place else exposure.variance.clone()
if gain is None and gains is None:
Expand Down Expand Up @@ -104,20 +104,25 @@ def remove_signal_from_variance(exposure, gain=None, gains=None, average_across_
variance_plane[amp_bbox].array[good] -= amp_im_arr[good] / amp_gain
elif gain is None and gains is not None:
amps = exposure.getDetector().getAmplifiers()
amp_bboxes = [amp.getBBox() for amp in amps]
namps = len(amps)
if len(gains) != namps:
raise ValueError(
f"Incorrect number of gains provided: {len(gains)} values for {namps} amplifiers."
)
for amp_bbox, amp_gain in zip(amp_bboxes, gains):
for amp in amps:
amp_bbox = amp.getBBox()
amp_gain = gains[amp.getName()]
im_arr = exposure[amp_bbox].image.array
variance_plane[amp_bbox].array -= im_arr / amp_gain
elif gain is not None and gains is None:
im_arr = exposure.image.array
variance_plane.array -= im_arr / gain
elif gain is not None and gains is not None:
raise ValueError("Both gain and gains are provided. Please provide only one of them or none at all "
"in case of automatic gain estimation from the image and variance planes.")
if not in_place:
return variance_plane
raise ValueError(
"Both 'gain' and 'gains' are provided. Please provide only one of them or none at "
"all in case of automatic gain estimation from the image and variance planes."
)
# Check that the variance plane has no negative values.
if np.any(variance_plane.array < 0):
raise ValueError("Corrected variance plane has negative values")
return variance_plane

0 comments on commit 586771c

Please sign in to comment.