@@ -399,18 +399,17 @@ def _merge(maskedImages, bbox, wcs):
399399 merged = afwImage .ExposureF (bbox , wcs )
400400 weights = afwImage .ImageF (bbox )
401401 for maskedImage in maskedImages :
402- weight = afwImage .ImageF (maskedImage .variance .array ** (- 0.5 ))
403- bad = np .isnan (maskedImage .image .array ) | ~ np .isfinite (maskedImage .variance .array )
402+ # Catch both zero-value and NaN variance plane pixels
403+ good = maskedImage .variance .array > 0
404+ weight = afwImage .ImageF (maskedImage .getBBox ())
405+ weight .array [good ] = maskedImage .variance .array [good ]** (- 0.5 )
406+ bad = np .isnan (maskedImage .image .array ) | ~ good
404407 # Note that modifying the patch MaskedImage in place is fine;
405408 # we're throwing it away at the end anyway.
406409 maskedImage .image .array [bad ] = 0.0
407410 maskedImage .variance .array [bad ] = 0.0
408411 # Reset mask, too, since these pixels don't contribute to sum.
409412 maskedImage .mask .array [bad ] = 0
410- # Clear the NaNs to ensure that areas missing from this input are
411- # masked with NO_DATA after the loop. Limiting to finite values
412- # can also handle the case where the input variance was zeros.
413- weight .array [~ np .isfinite (weight .array )] = 0
414413 # Cannot use `merged.maskedImage *= weight` because that operator
415414 # multiplies the variance by the weight twice; in this case
416415 # `weight` are the exact values we want to scale by.
@@ -419,14 +418,16 @@ def _merge(maskedImages, bbox, wcs):
419418 merged .maskedImage [maskedImage .getBBox ()] += maskedImage
420419 weights [maskedImage .getBBox ()] += weight
421420
422- bad = np .isnan (weights .array ) | (weights .array == 0 )
423- weights .array [bad ] = np .inf
424- # Cannot use `merged.maskedImage /= weights` because that operator
425- # divides the variance by the weight twice; in this case `weights` are
426- # the exact values we want to scale by.
427- merged .image /= weights
428- merged .variance /= weights
429- merged .mask .array |= merged .mask .getPlaneBitMask ("NO_DATA" ) * bad
421+ inverseWeights = np .zeros_like (weights .array )
422+ good = weights .array > 0
423+ inverseWeights [good ] = 1 / weights .array [good ]
424+
425+ # Cannot use `merged.maskedImage *= inverseWeights` because that
426+ # operator divides the variance by the weight twice; in this case
427+ # `inverseWeights` are the exact values we want to scale by.
428+ merged .image .array *= inverseWeights
429+ merged .variance .array *= inverseWeights
430+ merged .mask .array |= merged .mask .getPlaneBitMask ("NO_DATA" ) * (inverseWeights == 0 )
430431
431432 return merged
432433
0 commit comments