87 """Set the edge fallbackValue for interpolation
91 mi : `lsst.afw.image.MaskedImage`, optional
92 Input maskedImage on which to calculate the statistics
93 Must be provided if fallbackValueType != "USER".
97 fallbackValue : `float`
98 The value set/computed based on the fallbackValueType
99 and negativeFallbackAllowed config parameters.
101 if self.config.fallbackValueType !=
'USER':
102 assert mi,
"No maskedImage provided"
103 if self.config.fallbackValueType ==
'MEAN':
104 fallbackValue = afwMath.makeStatistics(mi, afwMath.MEAN).getValue()
105 elif self.config.fallbackValueType ==
'MEDIAN':
106 fallbackValue = afwMath.makeStatistics(mi, afwMath.MEDIAN).getValue()
107 elif self.config.fallbackValueType ==
'MEANCLIP':
108 fallbackValue = afwMath.makeStatistics(mi, afwMath.MEANCLIP).getValue()
109 elif self.config.fallbackValueType ==
'USER':
110 fallbackValue = self.config.fallbackUserValue
112 raise NotImplementedError(
"%s : %s not implemented" %
113 (
"fallbackValueType", self.config.fallbackValueType))
115 if not self.config.negativeFallbackAllowed
and fallbackValue < 0.0:
116 self.log.warning(
"Negative interpolation edge fallback value computed but "
117 "negativeFallbackAllowed is False: setting fallbackValue to 0.0")
118 fallbackValue = max(fallbackValue, 0.0)
120 self.log.info(
"fallbackValueType %s has been set to %.4f",
121 self.config.fallbackValueType, fallbackValue)
126 def run(self, image, planeName=None, fwhmPixels=None, defects=None):
127 """Interpolate in place over pixels in a maskedImage marked as bad
129 Pixels to be interpolated are set by either a mask planeName provided
130 by the caller OR a defects list of type `~lsst.meas.algorithms.Defects`
131 If both are provided an exception is raised.
133 Note that the interpolation code in meas_algorithms currently doesn't
134 use the input PSF (though it's a required argument), so it's not
135 important to set the input PSF parameters exactly. This PSF is set
136 here as the psf attached to the "image" (i.e if the image passed in
137 is an Exposure). Otherwise, a psf model is created using
138 measAlg.GaussianPsfFactory with the value of fwhmPixels (the value
139 passed in by the caller, or the default defaultFwhm set in
140 measAlg.GaussianPsfFactory if None).
144 image : `lsst.afw.image.MaskedImage` or `lsst.afw.image.exposure.Exposure`
145 MaskedImage OR Exposure to be interpolated.
146 planeName : `str`, optional
147 Name of mask plane over which to interpolate.
148 If None, must provide a defects list.
149 fwhmPixels : `int`, optional
150 FWHM of core star (pixels).
151 If None the default is used, where the default
152 is set to the exposure psf if available.
153 defects : `lsst.meas.algorithms.Defects`, optional
154 List of defects of type ipIsr.Defects
155 over which to interpolate.
158 maskedImage = image.getMaskedImage()
159 except AttributeError:
163 if planeName
is None:
165 raise ValueError(
"No defects or plane name provided")
167 if not isinstance(defects, ipIsr.Defects):
168 defectList = ipIsr.Defects(defects)
171 planeName =
"defects"
173 if defects
is not None:
174 raise ValueError(
"Provide EITHER a planeName OR a list of defects, not both")
175 if planeName
not in maskedImage.getMask().getMaskPlaneDict():
176 raise ValueError(
"maskedImage does not contain mask plane %s" % planeName)
177 defectList = ipIsr.Defects.fromMask(maskedImage, planeName)
182 self.log.info(
"Setting psf for interpolation from image")
183 except AttributeError:
184 self.log.info(
"Creating psf model for interpolation from fwhm(pixels) = %s",
185 str(fwhmPixels)
if fwhmPixels
is not None else
186 (str(self.config.modelPsf.defaultFwhm)) +
" [default]")
187 psf = self.config.modelPsf.apply(fwhm=fwhmPixels)
190 if self.config.useFallbackValueAtEdge:
195 self.log.info(
"Interpolated over %d %s pixels.", len(defectList), planeName)
199 """Context manager to potentially transpose an image
201 This applies the ``transpose`` configuration setting.
203 Transposing the image allows us to interpolate along columns instead
204 of rows, which is useful when the saturation trails are typically
205 oriented along rows on the warped/coadded images, instead of along
206 columns as they typically are in raw CCD images.
210 maskedImage : `lsst.afw.image.MaskedImage`
211 Image on which to perform interpolation.
212 defects : `lsst.meas.algorithms.Defects`
213 List of defects to interpolate over.
217 useImage : `lsst.afw.image.MaskedImage`
218 Image to use for interpolation; it may have been transposed.
219 useDefects : `lsst.meas.algorithms.Defects`
220 List of defects to use for interpolation; they may have been
223 def transposeImage(image):
224 """Transpose an image
230 transposed = image.array.T.copy()
231 return image.Factory(transposed,
False,
lsst.geom.Point2I(*reversed(image.getXY0())))
233 useImage = maskedImage
235 if self.config.transpose:
236 useImage = afwImage.makeMaskedImage(transposeImage(maskedImage.image),
237 transposeImage(maskedImage.mask),
238 transposeImage(maskedImage.variance))
239 useDefects = defects.transpose()
240 yield useImage, useDefects
241 if self.config.transpose:
242 maskedImage.image.array = useImage.image.array.T
243 maskedImage.mask.array = useImage.mask.array.T
244 maskedImage.variance.array = useImage.variance.array.T
247 """Interpolate over defects in an image
251 maskedImage : `lsst.afw.image.MaskedImage`
252 Image on which to perform interpolation.
253 psf : `lsst.afw.detection.Psf`
254 Point-spread function; currently unused.
255 defectList : `lsst.meas.algorithms.Defects`
256 List of defects to interpolate over.
257 fallbackValue : `float`
258 Value to set when interpolation fails.
263 measAlg.interpolateOverDefects(image, psf, defects, fallbackValue,
264 self.config.useFallbackValueAtEdge)