34 """Make a double Gaussian PSF
36 @param[in] fwhm FWHM of double Gaussian smoothing kernel
37 @return measAlg.DoubleGaussianPsf
39 ksize = 4*int(fwhm) + 1
43 """Calculate effective gain
45 @param[in] maskedImage afw.image.MaskedImage to process
46 @return (median gain, mean gain) in e-/ADU
48 im = afwImage.ImageF(maskedImage.getImage(),
True)
49 var = maskedImage.getVariance()
53 return medgain, meangain
56 """Make a transposed copy of a masked image
58 @param[in] maskedImage afw.image.MaskedImage to process
59 @return transposed masked image
61 imarr = maskedImage.getImage().getArray().T.__copy__()
62 vararr = maskedImage.getVariance().getArray().T.__copy__()
63 maskarr = maskedImage.getMask().getArray().T.__copy__()
67 """Interpolate over defects specified in a defect list
69 @param[in,out] maskedImage masked image to process
70 @param[in] defectList defect list
71 @param[in] fwhm FWHM of double Gaussian smoothing kernel
72 @param[in] fallbackValue fallback value if an interpolated value cannot be determined;
73 if None then use clipped mean image value
76 if fallbackValue
is None:
78 if 'INTRP' not in maskedImage.getMask().getMaskPlaneDict().keys():
79 maskedImage.getMask.addMaskPlane(
'INTRP')
83 """Compute a defect list from a footprint list, optionally growing the footprints
85 @param[in] fpList footprint list
86 @param[in] growFootprints amount by which to grow footprints of detected regions
87 @return meas.algorithms.DefectListT
89 defectList = measAlg.DefectListT()
91 if growFootprints > 0:
99 defectList.push_back(defect)
103 """Make a transposed copy of a defect list
105 @param[in] defectList defect list
106 @return meas.algorithms.DefectListT with transposed defects
108 retDefectList = measAlg.DefectListT()
109 for defect
in defectList:
110 bbox = defect.getBBox()
117 """Set mask plane based on a defect list
119 @param[in,out] maskedImage afw.image.MaskedImage to process; mask plane is updated
120 @param[in] defectList meas.algorithms.DefectListT
121 @param[in] maskName mask plane name
124 mask = maskedImage.getMask()
125 bitmask = mask.getPlaneBitMask(maskName)
126 for defect
in defectList:
127 bbox = defect.getBBox()
131 """Compute a defect list from a specified mask plane
133 @param[in] maskedImage masked image to process
134 @param[in] maskName mask plane name
135 @param[in] growFootprints amount by which to grow footprints of detected regions
136 @return meas.algrithms.DefectListT of regions in mask
138 mask = maskedImage.getMask()
139 workmask = afwImage.MaskU(mask,
True)
140 workmask &= mask.getPlaneBitMask(maskName)
142 maskimg = afwImage.ImageU(workmask.getBBox())
145 fpList = ds.getFootprints()
149 """Mask pixels based on threshold detection
151 @param[in,out] maskedImage afw.image.MaskedImage to process; the mask is altered
152 @param[in] threshold detection threshold
153 @param[in] growFootprints amount by which to grow footprints of detected regions
154 @param[in] maskName mask plane name
155 @return meas.algorihtms.DefectListT of regions set in the mask.
161 if growFootprints > 0:
164 fpList = fs.getFootprints()
166 mask = maskedImage.getMask()
167 bitmask = mask.getPlaneBitMask(maskName)
173 """Interpolate over defects identified by a particular mask plane
175 @param[in,out] maskedImage afw.image.MaskedImage to process
176 @param[in] fwhm FWHM of double Gaussian smoothing kernel
177 @param[in] growFootprints amount by which to grow footprints of detected regions
178 @param[in] maskName mask plane name
179 @param[in] fallbackValue value of last resort for interpolation
184 def saturationCorrection(maskedImage, saturation, fwhm, growFootprints=1, interpolate=True, maskName='SAT',
186 """Mark saturated pixels and optionally interpolate over them
188 @param[in,out] maskedImage afw.image.MaskedImage to process
189 @param[in] saturation saturation level (used as a detection threshold)
190 @param[in] fwhm FWHM of double Gaussian smoothing kernel
191 @param[in] growFootprints amount by which to grow footprints of detected regions
192 @param[in] interpolate interpolate over saturated pixels?
193 @param[in] maskName mask plane name
194 @param[in] fallbackValue value of last resort for interpolation
197 maskedImage = maskedImage,
198 threshold = saturation,
199 growFootprints = growFootprints,
206 """Apply bias correction in place
208 @param[in,out] maskedImage masked image to correct
209 @param[in] biasMaskedImage bias, as a masked image
211 maskedImage -= biasMaskedImage
214 """Apply dark correction in place
216 maskedImage -= dark * expScaling / darkScaling
218 @param[in,out] maskedImage afw.image.MaskedImage to correct
219 @param[in] darkMaskedImage dark afw.image.MaskedImage
220 @param[in] expScale exposure scale
221 @param[in] darkScale dark scale
223 if maskedImage.getBBox(afwImage.LOCAL) != darkMaskedImage.getBBox(afwImage.LOCAL):
224 raise RuntimeError(
"maskedImage bbox %s != darkMaskedImage bbox %s" % \
225 (maskedImage.getBBox(afwImage.LOCAL), darkMaskedImage.getBBox(afwImage.LOCAL)))
227 scale = expScale / darkScale
228 maskedImage.scaledMinus(scale, darkMaskedImage)
231 """Set the variance plane based on the image plane
233 @param[in,out] maskedImage afw.image.MaskedImage; image plane is read and variance plane is written
234 @param[in] gain amplifier gain (e-/ADU)
235 @param[in] readNoise amplifier read noise (ADU/pixel)
237 var = maskedImage.getVariance()
238 var <<= maskedImage.getImage()
243 """Apply flat correction in place
245 @param[in,out] maskedImage afw.image.MaskedImage to correct
246 @param[in] flatMaskedImage flat field afw.image.MaskedImage
247 @param[in] scalingType how to compute flat scale; one of 'MEAN', 'MEDIAN' or 'USER'
248 @param[in] userScale scale to use if scalingType is 'USER', else ignored
250 if maskedImage.getBBox(afwImage.LOCAL) != flatMaskedImage.getBBox(afwImage.LOCAL):
251 raise RuntimeError(
"maskedImage bbox %s != flatMaskedImage bbox %s" % \
252 (maskedImage.getBBox(afwImage.LOCAL), flatMaskedImage.getBBox(afwImage.LOCAL)))
257 if scalingType ==
'MEAN':
259 elif scalingType ==
'MEDIAN':
261 elif scalingType ==
'USER':
262 flatScale = userScale
266 maskedImage.scaledDivides(1.0/flatScale, flatMaskedImage)
269 """Apply illumination correction in place
271 @param[in,out] maskedImage afw.image.MaskedImage to correct
272 @param[in] illumMaskedImage illumination correction masked image
273 @param[in] illumScale scale value for illumination correction
275 if maskedImage.getBBox(afwImage.LOCAL) != illumMaskedImage.getBBox(afwImage.LOCAL):
276 raise RuntimeError(
"maskedImage bbox %s != illumMaskedImage bbox %s" % \
277 (maskedImage.getBBox(afwImage.LOCAL), illumMaskedImage.getBBox(afwImage.LOCAL)))
279 maskedImage.scaledDivides(1./illumScale, illumMaskedImage)
282 """Apply overscan correction in place
284 @param[in,out] ampMaskedImage masked image to correct
285 @param[in] overscanImage overscan data as an afw.image.IMage
286 @param[in] fitType type of fit for overscan correction; one of:
289 - 'POLY' (ordinary polynomial)
290 - 'CHEB' (Chebyshev polynomial)
291 - 'LEG' (Legendre polynomial)
292 - 'NATURAL_SPLINE', 'CUBIC_SPLINE', 'AKIMA_SPLINE' (splines)
293 @param[in] order polynomial order or spline knots (ignored unless fitType
294 indicates a polynomial or spline)
295 @param[in] collapseRej Rejection threshold (sigma) for collapsing dimension of overscan
297 ampImage = ampMaskedImage.getImage()
298 if fitType ==
'MEAN':
300 elif fitType ==
'MEDIAN':
302 elif fitType
in (
'POLY',
'CHEB',
'LEG',
'NATURAL_SPLINE',
'CUBIC_SPLINE',
'AKIMA_SPLINE'):
303 biasArray = overscanImage.getArray()
305 shortInd = numpy.argmin(biasArray.shape)
308 biasArray = numpy.transpose(biasArray)
311 percentiles = numpy.percentile(biasArray, [25.0, 50.0, 75.0], axis=1)
312 medianBiasArr = percentiles[1]
313 stdevBiasArr = 0.74*(percentiles[2] - percentiles[0])
314 diff = numpy.abs(biasArray - medianBiasArr[:,numpy.newaxis])
315 biasMaskedArr = numpy.ma.masked_where(diff > collapseRej*stdevBiasArr[:,numpy.newaxis], biasArray)
316 collapsed = numpy.mean(biasMaskedArr, axis=1)
317 del biasArray, percentiles, stdevBiasArr, diff, biasMaskedArr
320 collapsed = numpy.transpose(collapsed)
323 indices = 2.0*numpy.arange(num)/float(num) - 1.0
325 if fitType
in (
'POLY',
'CHEB',
'LEG'):
327 poly = numpy.polynomial
328 fitter, evaler = {
"POLY": (poly.polynomial.polyfit, poly.polynomial.polyval),
329 "CHEB": (poly.chebyshev.chebfit, poly.chebyshev.chebval),
330 "LEG": (poly.legendre.legfit, poly.legendre.legval),
333 coeffs = fitter(indices, collapsed, order)
334 fitBiasArr = evaler(indices, coeffs)
335 elif 'SPLINE' in fitType:
338 numPerBin, binEdges = numpy.histogram(indices, bins=numBins, weights=numpy.ones_like(collapsed))
341 values = numpy.histogram(indices, bins=numBins, weights=collapsed)[0]/numPerBin
342 binCenters = numpy.histogram(indices, bins=numBins, weights=indices)[0]/numPerBin
345 tuple(values.astype(float)),
347 fitBiasArr = numpy.array([interp.interpolate(i)
for i
in indices])
351 import matplotlib.pyplot
as plot
352 figure = plot.figure(1)
354 axes = figure.add_axes((0.1, 0.1, 0.8, 0.8))
355 axes.plot(indices, collapsed,
'k+')
356 axes.plot(indices, fitBiasArr,
'r-')
358 prompt =
"Press Enter or c to continue [chp]... "
360 ans = raw_input(prompt).lower()
361 if ans
in (
"",
"c",):
364 import pdb; pdb.set_trace()
366 print "h[elp] c[ontinue] p[db]"
369 offImage = ampImage.Factory(ampImage.getDimensions())
370 offArray = offImage.getArray()
372 offArray[:,:] = fitBiasArr[:,numpy.newaxis]
374 offArray[:,:] = fitBiasArr[numpy.newaxis,:]
377 (
"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.
boost::shared_ptr< Interpolate > makeInterpolate(std::vector< double > const &x, std::vector< double > const &y, Interpolate::Style const style=Interpolate::AKIMA_SPLINE)
A Threshold is used to pass a threshold value to detection algorithms.
void interpolateOverDefects(MaskedImageT &mimage, lsst::afw::detection::Psf const &, std::vector< Defect::Ptr > &_badList, double fallbackValue)
Process a set of known bad pixels in an image.
An integer coordinate rectangle.
def maskPixelsFromDefectList
Represent a Psf as a circularly symmetrical double Gaussian.
def interpolateDefectList
def illuminationCorrection
def getDefectListFromMask
std::vector< lsst::afw::geom::Box2I > footprintToBBoxList(Footprint const &foot)
def makeMaskedImageFromArrays
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.
Encapsulate information about a bad portion of a detector.
def defectListFromFootprintList