171def maskVignettedRegion(exposure, polygon, maskPlane="NO_DATA", vignetteValue=None, log=None):
172 """Add mask bit to image pixels according to vignetted polygon region.
173
174 NOTE: this function could be used to mask and replace pixels associated
175 with any polygon in the exposure pixel coordinates.
176
177 Parameters
178 ----------
179 exposure : `lsst.afw.image.Exposure`
180 Image whose mask plane is to be updated.
181 polygon : `lsst.afw.geom.Polygon`
182 Polygon region defining the vignetted region in the pixel coordinates
183 of ``exposure``.
184 maskPlane : `str`, optional
185 Mask plane to assign vignetted pixels to.
186 vignetteValue : `float` or `None`, optional
187 Value to assign to the image array pixels within the ``polygon``
188 region. If `None`, image pixel values are not replaced.
189 log : `logging.Logger`, optional
190 Log object to write to.
191
192 Raises
193 ------
194 RuntimeError
195 Raised if no valid polygon exists.
196 """
197 log = log if log else logging.getLogger(__name__)
198 if not polygon:
199 log.info("No polygon provided. Masking nothing.")
200 return
201
202 fullyIlluminated = True
203 if not all(polygon.contains(exposure.getBBox().getCorners())):
204 fullyIlluminated = False
205 log.info("Exposure is fully illuminated? %s", fullyIlluminated)
206
207 if not fullyIlluminated:
208
209 mask = exposure.getMask()
210 xx, yy = np.meshgrid(np.arange(0, mask.getWidth(), dtype=float),
211 np.arange(0, mask.getHeight(), dtype=float))
212
213 vignMask = ~(polygon.contains(xx, yy))
214
215 bitMask = mask.getPlaneBitMask(maskPlane)
216 maskArray = mask.getArray()
217 maskArray[vignMask] |= bitMask
218 log.info("Exposure contains {} vignetted pixels which are now masked with mask plane {}.".
219 format(np.count_nonzero(vignMask), maskPlane))
220
221 if vignetteValue is not None:
222 imageArray = exposure.getImage().getArray()
223 imageArray[vignMask] = vignetteValue
224 log.info("Vignetted pixels in image array have been replaced with {}.".format(vignetteValue))