Skip to content

Commit

Permalink
Add tests for AccumulatorMeanStack with weight arrays.
Browse files Browse the repository at this point in the history
  • Loading branch information
erykoff committed Jul 9, 2024
1 parent 07d0863 commit 1adeb2a
Showing 1 changed file with 156 additions and 135 deletions.
291 changes: 156 additions & 135 deletions tests/test_accumulator_mean_stack.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,147 +97,168 @@ def make_mask_map(self, stats_ctrl):

def test_online_coadd_input_variance_true(self):
"""Test online coaddition with calcErrorFromInputVariance=True."""
exposures, weights = self.make_test_images_to_coadd()
coadd_exposure = self.make_coadd_exposure(exposures[0])
stats_ctrl = self.make_stats_ctrl()
stats_ctrl.setCalcErrorFromInputVariance(True)
mask_map = self.make_mask_map(stats_ctrl)

stats_flags = afwMath.stringToStatisticsProperty("MEAN")
clipped = afwImage.Mask.getPlaneBitMask("CLIPPED")

masked_image_list = [exp.maskedImage for exp in exposures]

afw_masked_image = afwMath.statisticsStack(masked_image_list,
stats_flags,
stats_ctrl,
weights,
clipped,
mask_map)

mask_threshold_dict = AccumulatorMeanStack.stats_ctrl_to_threshold_dict(stats_ctrl)

# Make the stack with the online accumulator
stacker = AccumulatorMeanStack(
coadd_exposure.image.array.shape,
stats_ctrl.getAndMask(),
mask_threshold_dict=mask_threshold_dict,
mask_map=mask_map,
no_good_pixels_mask=stats_ctrl.getNoGoodPixelsMask(),
calc_error_from_input_variance=stats_ctrl.getCalcErrorFromInputVariance(),
compute_n_image=True)

for exposure, weight in zip(exposures, weights):
stacker.add_masked_image(exposure.maskedImage, weight=weight)

stacker.fill_stacked_masked_image(coadd_exposure.maskedImage)

online_masked_image = coadd_exposure.maskedImage

# The coadds match at the <1e-5 level.
testing.assert_array_almost_equal(online_masked_image.image.array,
afw_masked_image.image.array, decimal=5)
testing.assert_array_almost_equal(online_masked_image.variance.array,
afw_masked_image.variance.array)
testing.assert_array_equal(online_masked_image.mask.array,
afw_masked_image.mask.array)
for use_weight_arrays in [False, True]:
exposures, weights = self.make_test_images_to_coadd()
coadd_exposure = self.make_coadd_exposure(exposures[0])
stats_ctrl = self.make_stats_ctrl()
stats_ctrl.setCalcErrorFromInputVariance(True)
mask_map = self.make_mask_map(stats_ctrl)

stats_flags = afwMath.stringToStatisticsProperty("MEAN")
clipped = afwImage.Mask.getPlaneBitMask("CLIPPED")

masked_image_list = [exp.maskedImage for exp in exposures]

afw_masked_image = afwMath.statisticsStack(masked_image_list,
stats_flags,
stats_ctrl,
weights,
clipped,
mask_map)

mask_threshold_dict = AccumulatorMeanStack.stats_ctrl_to_threshold_dict(stats_ctrl)

# Make the stack with the online accumulator
stacker = AccumulatorMeanStack(
coadd_exposure.image.array.shape,
stats_ctrl.getAndMask(),
mask_threshold_dict=mask_threshold_dict,
mask_map=mask_map,
no_good_pixels_mask=stats_ctrl.getNoGoodPixelsMask(),
calc_error_from_input_variance=stats_ctrl.getCalcErrorFromInputVariance(),
compute_n_image=True)

for exposure, weight in zip(exposures, weights):
if use_weight_arrays:
stacker.add_masked_image(
exposure.maskedImage,
weight=np.full(exposure.image.array.shape, weight),
)
else:
stacker.add_masked_image(exposure.maskedImage, weight=weight)

stacker.fill_stacked_masked_image(coadd_exposure.maskedImage)

online_masked_image = coadd_exposure.maskedImage

# The coadds match at the <1e-5 level.
testing.assert_array_almost_equal(online_masked_image.image.array,
afw_masked_image.image.array, decimal=5)
testing.assert_array_almost_equal(online_masked_image.variance.array,
afw_masked_image.variance.array)
testing.assert_array_equal(online_masked_image.mask.array,
afw_masked_image.mask.array)

def test_online_coadd_input_variance_false(self):
"""Test online coaddition with calcErrorFromInputVariance=False."""
exposures, weights = self.make_test_images_to_coadd()
coadd_exposure = self.make_coadd_exposure(exposures[0])
stats_ctrl = self.make_stats_ctrl()
stats_ctrl.setCalcErrorFromInputVariance(False)
mask_map = self.make_mask_map(stats_ctrl)

stats_flags = afwMath.stringToStatisticsProperty("MEAN")
clipped = afwImage.Mask.getPlaneBitMask("CLIPPED")

masked_image_list = [exp.maskedImage for exp in exposures]

afw_masked_image = afwMath.statisticsStack(masked_image_list,
stats_flags,
stats_ctrl,
weights,
clipped,
mask_map)

mask_threshold_dict = AccumulatorMeanStack.stats_ctrl_to_threshold_dict(stats_ctrl)

# Make the stack with the online accumulator

# By setting no_good_pixels=None we have the same behavior
# as the default from stats_ctrl.getNoGoodPixelsMask(), but
# covers the alternate code path.
stacker = AccumulatorMeanStack(
coadd_exposure.image.array.shape,
stats_ctrl.getAndMask(),
mask_threshold_dict=mask_threshold_dict,
mask_map=mask_map,
no_good_pixels_mask=None,
calc_error_from_input_variance=stats_ctrl.getCalcErrorFromInputVariance(),
compute_n_image=True)

for exposure, weight in zip(exposures, weights):
stacker.add_masked_image(exposure.maskedImage, weight=weight)

stacker.fill_stacked_masked_image(coadd_exposure.maskedImage)

online_masked_image = coadd_exposure.maskedImage

# The coadds match at the <1e-5 level.
testing.assert_array_almost_equal(online_masked_image.image.array,
afw_masked_image.image.array, decimal=5)
# The computed variances match at the <1e-4 level.
testing.assert_array_almost_equal(online_masked_image.variance.array,
afw_masked_image.variance.array, decimal=4)
testing.assert_array_equal(online_masked_image.mask.array,
afw_masked_image.mask.array)
for use_weight_arrays in [False, True]:
exposures, weights = self.make_test_images_to_coadd()
coadd_exposure = self.make_coadd_exposure(exposures[0])
stats_ctrl = self.make_stats_ctrl()
stats_ctrl.setCalcErrorFromInputVariance(False)
mask_map = self.make_mask_map(stats_ctrl)

stats_flags = afwMath.stringToStatisticsProperty("MEAN")
clipped = afwImage.Mask.getPlaneBitMask("CLIPPED")

masked_image_list = [exp.maskedImage for exp in exposures]

afw_masked_image = afwMath.statisticsStack(masked_image_list,
stats_flags,
stats_ctrl,
weights,
clipped,
mask_map)

mask_threshold_dict = AccumulatorMeanStack.stats_ctrl_to_threshold_dict(stats_ctrl)

# Make the stack with the online accumulator

# By setting no_good_pixels=None we have the same behavior
# as the default from stats_ctrl.getNoGoodPixelsMask(), but
# covers the alternate code path.
stacker = AccumulatorMeanStack(
coadd_exposure.image.array.shape,
stats_ctrl.getAndMask(),
mask_threshold_dict=mask_threshold_dict,
mask_map=mask_map,
no_good_pixels_mask=None,
calc_error_from_input_variance=stats_ctrl.getCalcErrorFromInputVariance(),
compute_n_image=True)

for exposure, weight in zip(exposures, weights):
if use_weight_arrays:
stacker.add_masked_image(
exposure.maskedImage,
weight=np.full(exposure.image.array.shape, weight),
)
else:
stacker.add_masked_image(exposure.maskedImage, weight=weight)

stacker.fill_stacked_masked_image(coadd_exposure.maskedImage)

online_masked_image = coadd_exposure.maskedImage

# The coadds match at the <1e-5 level.
testing.assert_array_almost_equal(online_masked_image.image.array,
afw_masked_image.image.array, decimal=5)
# The computed variances match at the <1e-4 level.
testing.assert_array_almost_equal(online_masked_image.variance.array,
afw_masked_image.variance.array, decimal=4)
testing.assert_array_equal(online_masked_image.mask.array,
afw_masked_image.mask.array)

def test_online_coadd_image(self):
"""Test online coaddition with regular non-masked images."""
exposures, weights = self.make_test_images_to_coadd()
coadd_exposure = self.make_coadd_exposure(exposures[0])
stats_ctrl = self.make_stats_ctrl()
stats_ctrl.setAndMask(0)
stats_ctrl.setCalcErrorFromInputVariance(True)
mask_map = self.make_mask_map(stats_ctrl)

stats_flags = afwMath.stringToStatisticsProperty("MEAN")
clipped = afwImage.Mask.getPlaneBitMask("CLIPPED")

masked_image_list = [exp.maskedImage for exp in exposures]

afw_masked_image = afwMath.statisticsStack(masked_image_list,
stats_flags,
stats_ctrl,
weights,
clipped,
mask_map)

# Make the stack with the online accumulator
stacker = AccumulatorMeanStack(
coadd_exposure.image.array.shape,
stats_ctrl.getAndMask(),
mask_map=mask_map,
no_good_pixels_mask=stats_ctrl.getNoGoodPixelsMask(),
calc_error_from_input_variance=stats_ctrl.getCalcErrorFromInputVariance(),
compute_n_image=True)

for exposure, weight in zip(exposures, weights):
stacker.add_image(exposure.image, weight=weight)

stacker.fill_stacked_image(coadd_exposure.image)

online_image = coadd_exposure.image

# The unmasked coadd good pixels should match at the <1e-5 level
# The masked pixels will not be correct for straight image stacking.
good_pixels = np.where(afw_masked_image.mask.array == 0)

testing.assert_array_almost_equal(online_image.array[good_pixels],
afw_masked_image.image.array[good_pixels],
decimal=5)
for use_weight_arrays in [False, True]:
exposures, weights = self.make_test_images_to_coadd()
coadd_exposure = self.make_coadd_exposure(exposures[0])
stats_ctrl = self.make_stats_ctrl()
stats_ctrl.setAndMask(0)
stats_ctrl.setCalcErrorFromInputVariance(True)
mask_map = self.make_mask_map(stats_ctrl)

stats_flags = afwMath.stringToStatisticsProperty("MEAN")
clipped = afwImage.Mask.getPlaneBitMask("CLIPPED")

masked_image_list = [exp.maskedImage for exp in exposures]

afw_masked_image = afwMath.statisticsStack(masked_image_list,
stats_flags,
stats_ctrl,
weights,
clipped,
mask_map)

# Make the stack with the online accumulator
stacker = AccumulatorMeanStack(
coadd_exposure.image.array.shape,
stats_ctrl.getAndMask(),
mask_map=mask_map,
no_good_pixels_mask=stats_ctrl.getNoGoodPixelsMask(),
calc_error_from_input_variance=stats_ctrl.getCalcErrorFromInputVariance(),
compute_n_image=True)

for exposure, weight in zip(exposures, weights):
if use_weight_arrays:
stacker.add_image(
exposure.image,
weight=np.full(exposure.image.array.shape, weight),
)
else:
stacker.add_image(exposure.image, weight=weight)

stacker.fill_stacked_image(coadd_exposure.image)

online_image = coadd_exposure.image

# The unmasked coadd good pixels should match at the <1e-5 level
# The masked pixels will not be correct for straight image stacking.
good_pixels = np.where(afw_masked_image.mask.array == 0)

testing.assert_array_almost_equal(online_image.array[good_pixels],
afw_masked_image.image.array[good_pixels],
decimal=5)


class TestMemory(lsst.utils.tests.MemoryTestCase):
Expand Down

0 comments on commit 1adeb2a

Please sign in to comment.