Coverage for python/lsst/ip/isr/isrFunctions.py : 64%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
# # LSST Data Management System # Copyright 2008, 2009, 2010 LSST Corporation. # # This product includes software developed by the # LSST Project (http://www.lsst.org/). # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the LSST License Statement and # the GNU General Public License along with this program. If not, # see <http://www.lsstcorp.org/LegalNotices/>. #
"""Make a double Gaussian PSF
@param[in] fwhm FWHM of double Gaussian smoothing kernel @return measAlg.DoubleGaussianPsf """
"""Make a transposed copy of a masked image
@param[in] maskedImage afw.image.MaskedImage to process @return transposed masked image """ transposed = maskedImage.Factory(afwGeom.Extent2I(maskedImage.getHeight(), maskedImage.getWidth())) transposed.getImage().getArray()[:] = maskedImage.getImage().getArray().T transposed.getMask().getArray()[:] = maskedImage.getMask().getArray().T transposed.getVariance().getArray()[:] = maskedImage.getVariance().getArray().T return transposed
"""Interpolate over defects specified in a defect list
@param[in,out] maskedImage masked image to process @param[in] defectList defect list @param[in] fwhm FWHM of double Gaussian smoothing kernel @param[in] fallbackValue fallback value if an interpolated value cannot be determined; if None then use clipped mean image value """ maskedImage.getMask.addMaskPlane('INTRP')
"""Compute a defect list from a footprint list, optionally growing the footprints
@param[in] fpList footprint list """
"""Make a transposed copy of a defect list
@param[in] defectList a list of defects (afw.meas.algorithms.Defect) @return a defect list with transposed defects """ retDefectList = [] for defect in defectList: bbox = defect.getBBox() nbbox = afwGeom.Box2I(afwGeom.Point2I(bbox.getMinY(), bbox.getMinX()), afwGeom.Extent2I(bbox.getDimensions()[1], bbox.getDimensions()[0])) retDefectList.append(measAlg.Defect(nbbox)) return retDefectList
"""Set mask plane based on a defect list
@param[in,out] maskedImage afw.image.MaskedImage to process; mask plane is updated @param[in] defectList a list of defects (afw.meas.algorithms.Defect) @param[in] maskName mask plane name """ # mask bad pixels
"""Compute a defect list from a specified mask plane
@param[in] maskedImage masked image to process @param[in] maskName mask plane name, or list of names """
"""Mask pixels based on threshold detection
@param[in,out] maskedImage afw.image.MaskedImage to process; the mask is altered @param[in] threshold detection threshold @param[in] growFootprints amount by which to grow footprints of detected regions @param[in] maskName mask plane name @return a list of defects (meas.algrithms.Defect) of regions set in the mask. """ # find saturated regions
fs = afwDetection.FootprintSet(fs, growFootprints)
# set mask
"""Interpolate over defects identified by a particular mask plane
@param[in,out] maskedImage afw.image.MaskedImage to process @param[in] fwhm FWHM of double Gaussian smoothing kernel @param[in] growFootprints amount by which to grow footprints of detected regions @param[in] maskName mask plane name @param[in] fallbackValue value of last resort for interpolation """ # If we are interpolating over an area larger than the original masked region, we need # to expand the original mask bit to the full area to explain why we interpolated there.
fallbackValue=None): """Mark saturated pixels and optionally interpolate over them
@param[in,out] maskedImage afw.image.MaskedImage to process @param[in] saturation saturation level (used as a detection threshold) @param[in] fwhm FWHM of double Gaussian smoothing kernel @param[in] growFootprints amount by which to grow footprints of detected regions @param[in] interpolate interpolate over saturated pixels? @param[in] maskName mask plane name @param[in] fallbackValue value of last resort for interpolation """ defectList = makeThresholdMask( maskedImage=maskedImage, threshold=saturation, growFootprints=growFootprints, maskName=maskName, ) if interpolate: interpolateDefectList(maskedImage, defectList, fwhm, fallbackValue=fallbackValue)
"""Apply bias correction in place
@param[in,out] maskedImage masked image to correct @param[in] biasMaskedImage bias, as a masked image """ raise RuntimeError("maskedImage bbox %s != biasMaskedImage bbox %s" % (maskedImage.getBBox(afwImage.LOCAL), biasMaskedImage.getBBox(afwImage.LOCAL)))
"""Apply dark correction in place
maskedImage -= dark * expScaling / darkScaling
@param[in,out] maskedImage afw.image.MaskedImage to correct @param[in] darkMaskedImage dark afw.image.MaskedImage @param[in] expScale exposure scale @param[in] darkScale dark scale @param[in] invert if True, remove the dark from an already-corrected image """ raise RuntimeError("maskedImage bbox %s != darkMaskedImage bbox %s" % (maskedImage.getBBox(afwImage.LOCAL), darkMaskedImage.getBBox(afwImage.LOCAL)))
else: maskedImage.scaledPlus(scale, darkMaskedImage)
"""Set the variance plane based on the image plane
@param[in,out] maskedImage afw.image.MaskedImage; image plane is read and variance plane is written @param[in] gain amplifier gain (e-/ADU) @param[in] readNoise amplifier read noise (ADU/pixel) """
"""Apply flat correction in place
@param[in,out] maskedImage afw.image.MaskedImage to correct @param[in] flatMaskedImage flat field afw.image.MaskedImage @param[in] scalingType how to compute flat scale; one of 'MEAN', 'MEDIAN' or 'USER' @param[in] userScale scale to use if scalingType is 'USER', else ignored @param[in] invert if True, unflatten an already-flattened image instead. """ raise RuntimeError("maskedImage bbox %s != flatMaskedImage bbox %s" % (maskedImage.getBBox(afwImage.LOCAL), flatMaskedImage.getBBox(afwImage.LOCAL)))
# Figure out scale from the data # Ideally the flats are normalized by the calibration product pipelin, but this allows some flexibility # in the case that the flat is created by some other mechanism. flatScale = afwMath.makeStatistics(flatMaskedImage.getImage(), afwMath.MEAN).getValue(afwMath.MEAN) flatScale = afwMath.makeStatistics(flatMaskedImage.getImage(), afwMath.MEDIAN).getValue(afwMath.MEDIAN) else: raise pexExcept.Exception('%s : %s not implemented' % ("flatCorrection", scalingType))
else: maskedImage.scaledMultiplies(1.0/flatScale, flatMaskedImage)
"""Apply illumination correction in place
@param[in,out] maskedImage afw.image.MaskedImage to correct @param[in] illumMaskedImage illumination correction masked image @param[in] illumScale scale value for illumination correction """ raise RuntimeError("maskedImage bbox %s != illumMaskedImage bbox %s" % (maskedImage.getBBox(afwImage.LOCAL), illumMaskedImage.getBBox(afwImage.LOCAL)))
statControl=None): """Apply overscan correction in-place
The ``ampMaskedImage`` and ``overscanImage`` are modified, with the fit subtracted. Note that the ``overscanImage`` should not be a subimage of the ``ampMaskedImage``, to avoid being subtracted twice.
Parameters ---------- ampMaskedImage : `lsst.afw.image.MaskedImage` Image of amplifier to correct; modified. overscanImage : `lsst.afw.image.Image` or `lsst.afw.image.MaskedImage` Image of overscan; modified. fitType : `str` Type of fit for overscan correction. May be one of:
- ``MEAN``: use mean of overscan. - ``MEDIAN``: use median of overscan. - ``POLY``: fit with ordinary polynomial. - ``CHEB``: fit with Chebyshev polynomial. - ``LEG``: fit with Legendre polynomial. - ``NATURAL_SPLINE``: fit with natural spline. - ``CUBIC_SPLINE``: fit with cubic spline. - ``AKIMA_SPLINE``: fit with Akima spline.
order : `int` Polynomial order or number of spline knots; ignored unless ``fitType`` indicates a polynomial or spline. collapseRej : `float` Rejection threshold (sigma) for collapsing dimension of overscan. statControl : `lsst.afw.math.StatisticsControl` Statistics control object.
Returns ------- result : `lsst.pipe.base.Struct` Result struct with components:
- ``imageFit``: Value(s) removed from image (scalar or `lsst.afw.image.Image`) - ``overscanFit``: Value(s) removed from overscan (scalar or `lsst.afw.image.Image`) """ offImage = afwMath.makeStatistics(overscanImage, afwMath.MEAN, statControl).getValue(afwMath.MEAN) overscanFit = offImage biasArray) else: # Fit along the long axis, so collapse along each short row and fit the resulting array # Convert to some 'standard' representation to make things easier
# Do a single round of clipping to weed out CR hits and signal leaking into the overscan collapsed.data[collapsed.mask] = numpy.mean(biasArray.data[collapsed.mask], axis=1)
# A numpy polynomial "CHEB": (poly.chebyshev.chebfit, poly.chebyshev.chebval), "LEG": (poly.legendre.legfit, poly.legendre.legval), }[fitType]
# An afw interpolation # # numpy.histogram needs a real array for the mask, but numpy.ma "optimises" the case # no-values-are-masked by replacing the mask array by a scalar, numpy.ma.nomask # # Issue DM-415 # except ValueError: # If collapsedMask is an array the test fails [needs .all()] pass
weights=1-collapsedMask.astype(int)) # Binning is just a histogram, with weights equal to the values. # Use a similar trick to get the bin centers (this deals with different numbers per bin). weights=collapsed.data*~collapsedMask)[0]/numPerBin weights=indices*~collapsedMask)[0]/numPerBin values.astype(float)[numPerBin > 0], afwMath.stringToInterpStyle(fitType))
import matplotlib.pyplot as plot figure = plot.figure(1) figure.clear() axes = figure.add_axes((0.1, 0.1, 0.8, 0.8)) axes.plot(indices[~collapsedMask], collapsed[~collapsedMask], 'k+') if collapsedMask.sum() > 0: axes.plot(indices[collapsedMask], collapsed.data[collapsedMask], 'b+') axes.plot(indices, fitBiasArr, 'r-') figure.show() prompt = "Press Enter or c to continue [chp]... " while True: ans = input(prompt).lower() if ans in ("", "c",): break if ans in ("p",): import pdb pdb.set_trace() elif ans in ("h", ): print("h[elp] c[ontinue] p[db]") figure.close()
else:
# We don't trust any extrapolation: mask those pixels as SUSPECT # This will occur when the top and or bottom edges of the overscan # contain saturated values. The values will be extrapolated from # the surrounding pixels, but we cannot entirely trust the value of # the extrapolation, and will mark the image mask plane to flag the # image as such. # There is no mask, so the whole array is fine maskArray[:low, :] |= suspect maskArray[-high:, :] |= suspect
else: raise pexExcept.Exception('%s : %s an invalid overscan type' % ("overscanCorrection", fitType))
sensorTransmission=None, atmosphereTransmission=None): """Attach a TransmissionCurve to an Exposure, given separate curves for different components.
Parameters ---------- exposure : `lsst.afw.image.Exposure` Exposure object to modify by attaching the product of all given ``TransmissionCurves`` in post-assembly trimmed detector coordinates. Must have a valid ``Detector`` attached that matches the detector associated with sensorTransmission. opticsTransmission : `lsst.afw.image.TransmissionCurve` A ``TransmissionCurve`` that represents the throughput of the optics, to be evaluated in focal-plane coordinates. filterTransmission : `lsst.afw.image.TransmissionCurve` A ``TransmissionCurve`` that represents the throughput of the filter itself, to be evaluated in focal-plane coordinates. sensorTransmission : `lsst.afw.image.TransmissionCurve` A ``TransmissionCurve`` that represents the throughput of the sensor itself, to be evaluated in post-assembly trimmed detector coordinates. atmosphereTransmission : `lsst.afw.image.TransmissionCurve` A ``TransmissionCurve`` that represents the throughput of the atmosphere, assumed to be spatially constant.
All ``TransmissionCurve`` arguments are optional; if none are provided, the attached ``TransmissionCurve`` will have unit transmission everywhere.
Returns ------- combined : ``lsst.afw.image.TransmissionCurve`` The TransmissionCurve attached to the exposure. """ combined = afwImage.TransmissionCurve.makeIdentity() if atmosphereTransmission is not None: combined *= atmosphereTransmission if opticsTransmission is not None: combined *= opticsTransmission if filterTransmission is not None: combined *= filterTransmission detector = exposure.getDetector() fpToPix = detector.getTransform(fromSys=camGeom.FOCAL_PLANE, toSys=camGeom.PIXELS) combined = combined.transformedBy(fpToPix) if sensorTransmission is not None: combined *= sensorTransmission exposure.getInfo().setTransmissionCurve(combined) return combined |