@@ -375,7 +375,8 @@ def _makeExposureCatalog(self, exposures, dataIds):
375
375
376
376
return images , catalog , totalBox
377
377
378
- def _merge (self , maskedImages , bbox , wcs ):
378
+ @staticmethod
379
+ def _merge (maskedImages , bbox , wcs ):
379
380
"""Merge the images that came from one tract into one larger image,
380
381
ignoring NaN pixels and non-finite variance pixels from individual
381
382
exposures.
@@ -398,8 +399,11 @@ def _merge(self, maskedImages, bbox, wcs):
398
399
merged = afwImage .ExposureF (bbox , wcs )
399
400
weights = afwImage .ImageF (bbox )
400
401
for maskedImage in maskedImages :
401
- weight = afwImage .ImageF (maskedImage .variance .array ** (- 0.5 ))
402
- 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
403
407
# Note that modifying the patch MaskedImage in place is fine;
404
408
# we're throwing it away at the end anyway.
405
409
maskedImage .image .array [bad ] = 0.0
@@ -412,16 +416,18 @@ def _merge(self, maskedImages, bbox, wcs):
412
416
maskedImage .image *= weight
413
417
maskedImage .variance *= weight
414
418
merged .maskedImage [maskedImage .getBBox ()] += maskedImage
415
- # Clear the NaNs to ensure that areas missing from this input are
416
- # masked with NO_DATA after the loop.
417
- weight .array [np .isnan (weight .array )] = 0
418
419
weights [maskedImage .getBBox ()] += weight
419
- # Cannot use `merged.maskedImage /= weights` because that operator
420
- # divides the variance by the weight twice; in this case `weights` are
421
- # the exact values we want to scale by.
422
- merged .image /= weights
423
- merged .variance /= weights
424
- merged .mask .array |= merged .mask .getPlaneBitMask ("NO_DATA" ) * (weights .array == 0 )
420
+
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 )
425
431
426
432
return merged
427
433
0 commit comments