1 from __future__
import print_function
2 from builtins
import input
3 from builtins
import range
38 """Make a double Gaussian PSF
40 @param[in] fwhm FWHM of double Gaussian smoothing kernel
41 @return measAlg.DoubleGaussianPsf
43 ksize = 4*int(fwhm) + 1
48 """Calculate effective gain
50 @param[in] maskedImage afw.image.MaskedImage to process
51 @return (median gain, mean gain) in e-/ADU
53 im = afwImage.ImageF(maskedImage.getImage(),
True)
54 var = maskedImage.getVariance()
58 return medgain, meangain
62 """Make a transposed copy of a masked image
64 @param[in] maskedImage afw.image.MaskedImage to process
65 @return transposed masked image
67 transposed = maskedImage.Factory(
afwGeom.Extent2I(maskedImage.getHeight(), maskedImage.getWidth()))
68 transposed.getImage().getArray()[:] = maskedImage.getImage().getArray().T
69 transposed.getMask().getArray()[:] = maskedImage.getMask().getArray().T
70 transposed.getVariance().getArray()[:] = maskedImage.getVariance().getArray().T
75 """Interpolate over defects specified in a defect list
77 @param[in,out] maskedImage masked image to process
78 @param[in] defectList defect list
79 @param[in] fwhm FWHM of double Gaussian smoothing kernel
80 @param[in] fallbackValue fallback value if an interpolated value cannot be determined;
81 if None then use clipped mean image value
84 if fallbackValue
is None:
86 if 'INTRP' not in maskedImage.getMask().getMaskPlaneDict():
87 maskedImage.getMask.addMaskPlane(
'INTRP')
92 """Compute a defect list from a footprint list, optionally growing the footprints
94 @param[in] fpList footprint list
95 @param[in] growFootprints amount by which to grow footprints of detected regions
96 @return meas.algorithms.DefectListT
98 defectList = measAlg.DefectListT()
100 if growFootprints > 0:
108 defectList.push_back(defect)
113 """Make a transposed copy of a defect list
115 @param[in] defectList defect list
116 @return meas.algorithms.DefectListT with transposed defects
118 retDefectList = measAlg.DefectListT()
119 for defect
in defectList:
120 bbox = defect.getBBox()
128 """Set mask plane based on a defect list
130 @param[in,out] maskedImage afw.image.MaskedImage to process; mask plane is updated
131 @param[in] defectList meas.algorithms.DefectListT
132 @param[in] maskName mask plane name
135 mask = maskedImage.getMask()
136 bitmask = mask.getPlaneBitMask(maskName)
137 for defect
in defectList:
138 bbox = defect.getBBox()
143 """Compute a defect list from a specified mask plane
145 @param[in] maskedImage masked image to process
146 @param[in] maskName mask plane name, or list of names
147 @param[in] growFootprints amount by which to grow footprints of detected regions
148 @return meas.algrithms.DefectListT of regions in mask
150 mask = maskedImage.getMask()
157 """Mask pixels based on threshold detection
159 @param[in,out] maskedImage afw.image.MaskedImage to process; the mask is altered
160 @param[in] threshold detection threshold
161 @param[in] growFootprints amount by which to grow footprints of detected regions
162 @param[in] maskName mask plane name
163 @return meas.algorihtms.DefectListT of regions set in the mask.
169 if growFootprints > 0:
172 fpList = fs.getFootprints()
174 mask = maskedImage.getMask()
175 bitmask = mask.getPlaneBitMask(maskName)
182 """Interpolate over defects identified by a particular mask plane
184 @param[in,out] maskedImage afw.image.MaskedImage to process
185 @param[in] fwhm FWHM of double Gaussian smoothing kernel
186 @param[in] growFootprints amount by which to grow footprints of detected regions
187 @param[in] maskName mask plane name
188 @param[in] fallbackValue value of last resort for interpolation
194 def saturationCorrection(maskedImage, saturation, fwhm, growFootprints=1, interpolate=True, maskName='SAT',
196 """Mark saturated pixels and optionally interpolate over them
198 @param[in,out] maskedImage afw.image.MaskedImage to process
199 @param[in] saturation saturation level (used as a detection threshold)
200 @param[in] fwhm FWHM of double Gaussian smoothing kernel
201 @param[in] growFootprints amount by which to grow footprints of detected regions
202 @param[in] interpolate interpolate over saturated pixels?
203 @param[in] maskName mask plane name
204 @param[in] fallbackValue value of last resort for interpolation
207 maskedImage=maskedImage,
208 threshold=saturation,
209 growFootprints=growFootprints,
217 """Apply bias correction in place
219 @param[in,out] maskedImage masked image to correct
220 @param[in] biasMaskedImage bias, as a masked image
222 if maskedImage.getBBox(afwImage.LOCAL) != biasMaskedImage.getBBox(afwImage.LOCAL):
223 raise RuntimeError(
"maskedImage bbox %s != biasMaskedImage bbox %s" %
224 (maskedImage.getBBox(afwImage.LOCAL), biasMaskedImage.getBBox(afwImage.LOCAL)))
225 maskedImage -= biasMaskedImage
229 """Apply dark correction in place
231 maskedImage -= dark * expScaling / darkScaling
233 @param[in,out] maskedImage afw.image.MaskedImage to correct
234 @param[in] darkMaskedImage dark afw.image.MaskedImage
235 @param[in] expScale exposure scale
236 @param[in] darkScale dark scale
238 if maskedImage.getBBox(afwImage.LOCAL) != darkMaskedImage.getBBox(afwImage.LOCAL):
239 raise RuntimeError(
"maskedImage bbox %s != darkMaskedImage bbox %s" %
240 (maskedImage.getBBox(afwImage.LOCAL), darkMaskedImage.getBBox(afwImage.LOCAL)))
242 scale = expScale / darkScale
243 maskedImage.scaledMinus(scale, darkMaskedImage)
247 """Set the variance plane based on the image plane
249 @param[in,out] maskedImage afw.image.MaskedImage; image plane is read and variance plane is written
250 @param[in] gain amplifier gain (e-/ADU)
251 @param[in] readNoise amplifier read noise (ADU/pixel)
253 var = maskedImage.getVariance()
254 var[:] = maskedImage.getImage()
260 """Apply flat correction in place
262 @param[in,out] maskedImage afw.image.MaskedImage to correct
263 @param[in] flatMaskedImage flat field afw.image.MaskedImage
264 @param[in] scalingType how to compute flat scale; one of 'MEAN', 'MEDIAN' or 'USER'
265 @param[in] userScale scale to use if scalingType is 'USER', else ignored
267 if maskedImage.getBBox(afwImage.LOCAL) != flatMaskedImage.getBBox(afwImage.LOCAL):
268 raise RuntimeError(
"maskedImage bbox %s != flatMaskedImage bbox %s" %
269 (maskedImage.getBBox(afwImage.LOCAL), flatMaskedImage.getBBox(afwImage.LOCAL)))
274 if scalingType ==
'MEAN':
276 elif scalingType ==
'MEDIAN':
278 afwMath.MEDIAN).getValue(afwMath.MEDIAN)
279 elif scalingType ==
'USER':
280 flatScale = userScale
284 maskedImage.scaledDivides(1.0/flatScale, flatMaskedImage)
288 """Apply illumination correction in place
290 @param[in,out] maskedImage afw.image.MaskedImage to correct
291 @param[in] illumMaskedImage illumination correction masked image
292 @param[in] illumScale scale value for illumination correction
294 if maskedImage.getBBox(afwImage.LOCAL) != illumMaskedImage.getBBox(afwImage.LOCAL):
295 raise RuntimeError(
"maskedImage bbox %s != illumMaskedImage bbox %s" %
296 (maskedImage.getBBox(afwImage.LOCAL), illumMaskedImage.getBBox(afwImage.LOCAL)))
298 maskedImage.scaledDivides(1./illumScale, illumMaskedImage)
301 def overscanCorrection(ampMaskedImage, overscanImage, fitType='MEDIAN', order=1, collapseRej=3.0,
303 """Apply overscan correction in place
305 @param[in,out] ampMaskedImage masked image to correct
306 @param[in] overscanImage overscan data as an afw.image.Image or afw.image.MaskedImage.
307 If a masked image is passed in the mask plane will be used
308 to constrain the fit of the bias level.
309 @param[in] fitType type of fit for overscan correction; one of:
312 - 'POLY' (ordinary polynomial)
313 - 'CHEB' (Chebyshev polynomial)
314 - 'LEG' (Legendre polynomial)
315 - 'NATURAL_SPLINE', 'CUBIC_SPLINE', 'AKIMA_SPLINE' (splines)
316 @param[in] order polynomial order or spline knots (ignored unless fitType
317 indicates a polynomial or spline)
318 @param[in] collapseRej Rejection threshold (sigma) for collapsing dimension of overscan
319 @param[in] statControl Statistics control object
321 ampImage = ampMaskedImage.getImage()
322 if statControl
is None:
324 if fitType ==
'MEAN':
326 elif fitType ==
'MEDIAN':
328 elif fitType
in (
'POLY',
'CHEB',
'LEG',
'NATURAL_SPLINE',
'CUBIC_SPLINE',
'AKIMA_SPLINE'):
329 if hasattr(overscanImage,
"getImage"):
330 biasArray = overscanImage.getImage().getArray()
331 biasArray = numpy.ma.masked_where(overscanImage.getMask().getArray() & statControl.getAndMask(),
334 biasArray = overscanImage.getArray()
336 shortInd = numpy.argmin(biasArray.shape)
339 biasArray = numpy.transpose(biasArray)
342 percentiles = numpy.percentile(biasArray, [25.0, 50.0, 75.0], axis=1)
343 medianBiasArr = percentiles[1]
344 stdevBiasArr = 0.74*(percentiles[2] - percentiles[0])
345 diff = numpy.abs(biasArray - medianBiasArr[:, numpy.newaxis])
346 biasMaskedArr = numpy.ma.masked_where(diff > collapseRej*stdevBiasArr[:, numpy.newaxis], biasArray)
347 collapsed = numpy.mean(biasMaskedArr, axis=1)
348 if collapsed.mask.sum() > 0:
349 collapsed.data[collapsed.mask] = numpy.mean(biasArray.data[collapsed.mask], axis=1)
350 del biasArray, percentiles, stdevBiasArr, diff, biasMaskedArr
353 collapsed = numpy.transpose(collapsed)
356 indices = 2.0*numpy.arange(num)/float(num) - 1.0
358 if fitType
in (
'POLY',
'CHEB',
'LEG'):
360 poly = numpy.polynomial
361 fitter, evaler = {
"POLY": (poly.polynomial.polyfit, poly.polynomial.polyval),
362 "CHEB": (poly.chebyshev.chebfit, poly.chebyshev.chebval),
363 "LEG": (poly.legendre.legfit, poly.legendre.legval),
366 coeffs = fitter(indices, collapsed, order)
367 fitBiasArr = evaler(indices, coeffs)
368 elif 'SPLINE' in fitType:
377 collapsedMask = collapsed.mask
379 if collapsedMask == numpy.ma.nomask:
380 collapsedMask = numpy.array(len(collapsed)*[numpy.ma.nomask])
384 numPerBin, binEdges = numpy.histogram(indices, bins=numBins,
385 weights=1-collapsedMask.astype(int))
388 values = numpy.histogram(indices, bins=numBins,
389 weights=collapsed.data*~collapsedMask)[0]/numPerBin
390 binCenters = numpy.histogram(indices, bins=numBins,
391 weights=indices*~collapsedMask)[0]/numPerBin
393 values.astype(float)[numPerBin > 0],
395 fitBiasArr = numpy.array([interp.interpolate(i)
for i
in indices])
399 import matplotlib.pyplot
as plot
400 figure = plot.figure(1)
402 axes = figure.add_axes((0.1, 0.1, 0.8, 0.8))
403 axes.plot(indices[~collapsedMask], collapsed[~collapsedMask],
'k+')
404 if collapsedMask.sum() > 0:
405 axes.plot(indices[collapsedMask], collapsed.data[collapsedMask],
'b+')
406 axes.plot(indices, fitBiasArr,
'r-')
408 prompt =
"Press Enter or c to continue [chp]... "
410 ans =
input(prompt).lower()
411 if ans
in (
"",
"c",):
417 print(
"h[elp] c[ontinue] p[db]")
420 offImage = ampImage.Factory(ampImage.getDimensions())
421 offArray = offImage.getArray()
423 offArray[:, :] = fitBiasArr[:, numpy.newaxis]
425 offArray[:, :] = fitBiasArr[numpy.newaxis, :]
433 mask = ampMaskedImage.getMask()
434 maskArray = mask.getArray()
if shortInd == 1
else mask.getArray().transpose()
435 suspect = mask.getPlaneBitMask(
"SUSPECT")
437 if collapsed.mask == numpy.ma.nomask:
441 for low
in range(num):
442 if not collapsed.mask[low]:
445 maskArray[:low, :] |= suspect
446 for high
in range(1, num):
447 if not collapsed.mask[-high]:
450 maskArray[-high:, :] |= suspect
454 (
"overscanCorrection", fitType))
Interpolate::Style stringToInterpStyle(std::string const &style)
Conversion function to switch a string to an Interpolate::Style.
boost::shared_ptr< Footprint > growFootprint(Footprint const &foot, int nGrow, bool left, bool right, bool up, bool down)
Grow a Footprint in at least one of the cardinal directions, returning a new Footprint.
A Threshold is used to pass a threshold value to detection algorithms.
Fit spatial kernel using approximate fluxes for candidates, and solving a linear system of equations...
boost::shared_ptr< Interpolate > makeInterpolate(ndarray::Array< double const, 1 > const &x, ndarray::Array< double const, 1 > const &y, Interpolate::Style const style)
An integer coordinate rectangle.
def maskPixelsFromDefectList
Represent a Psf as a circularly symmetrical double Gaussian.
def interpolateDefectList
Pass parameters to a Statistics objectA class to pass parameters which control how the stats are calc...
def illuminationCorrection
def getDefectListFromMask
std::vector< lsst::afw::geom::Box2I > footprintToBBoxList(Footprint const &foot)
Return a list of BBoxs, whose union contains exactly the pixels in foot, neither more nor less...
MaskT setMaskFromFootprint(lsst::afw::image::Mask< MaskT > *mask, Footprint const &footprint, MaskT const bitmask)
OR bitmask into all the Mask's pixels that are in the Footprint.
Statistics makeStatistics(afwImage::Mask< afwImage::MaskPixel > const &msk, int const flags, StatisticsControl const &sctrl)
Specialization to handle Masks.
MaskT setMaskFromFootprintList(lsst::afw::image::Mask< MaskT > *mask, boost::shared_ptr< std::vector< boost::shared_ptr< Footprint >> const > const &footprints, MaskT const bitmask)
OR bitmask into all the Mask's pixels which are in the set of Footprints.
void interpolateOverDefects(MaskedImageT &mimage, lsst::afw::detection::Psf const &, std::vector< Defect::Ptr > &_badList, double fallbackValue, bool useFallbackValueAtEdge)
Process a set of known bad pixels in an image.
Encapsulate information about a bad portion of a detector.
def defectListFromFootprintList