29 __all__ = [
"ImageScaler",
"SpatialImageScaler",
"ScaleZeroPointTask"]
33 """A class that scales an image 35 This version uses a single scalar. Fancier versions may use a spatially varying scale. 39 """Construct an ImageScaler 41 @param[in] scale: scale correction to apply (see scaleMaskedImage); 46 """Scale the specified image or masked image in place. 48 @param[in,out] maskedImage: masked image to scale 54 """Multiplicative image scaler using interpolation over a grid of points. 56 Contains the x, y positions in tract coordinates and the scale factors. 57 Interpolates only when scaleMaskedImage() or getInterpImage() is called. 59 Currently the only type of 'interpolation' implemented is CONSTANT which calculates the mean. 62 def __init__(self, interpStyle, xList, yList, scaleList):
65 @param[in] interpStyle: interpolation style (CONSTANT is only option) 66 @param[in] xList: list of X pixel positions 67 @param[in] yList: list of Y pixel positions 68 @param[in] scaleList: list of multiplicative scale factors at (x,y) 70 @raise RuntimeError if the lists have different lengths 72 if len(xList) != len(yList)
or len(xList) != len(scaleList):
74 "len(xList)=%s len(yList)=%s, len(scaleList)=%s but all lists must have the same length" %
75 (len(xList), len(yList), len(scaleList)))
83 """Apply scale correction to the specified masked image 85 @param[in,out] image to scale; scale is applied in place 91 """Return an image containing the scale correction with same bounding box as supplied. 93 @param[in] bbox: integer bounding box for image (afwGeom.Box2I) 98 raise RuntimeError(
"Cannot create scaling image. Found no fluxMag0s to interpolate")
100 image = afwImage.ImageF(bbox, numpy.mean(self.
_scaleList))
106 """Config for ScaleZeroPointTask 108 zeroPoint = pexConfig.Field(
110 doc=
"desired photometric zero point",
116 selectFluxMag0 = pexConfig.ConfigurableField(
117 doc=
"Task to select data to compute spatially varying photometric zeropoint",
118 target=BaseSelectImagesTask,
121 interpStyle = pexConfig.ChoiceField(
123 doc=
"Algorithm to interpolate the flux scalings;" 124 "Currently only one choice implemented",
127 "CONSTANT":
"Use a single constant value",
133 """Compute scale factor to scale exposures to a desired photometric zero point 135 This simple version assumes that the zero point is spatially invariant. 137 ConfigClass = ScaleZeroPointConfig
138 _DefaultName =
"scaleZeroPoint" 141 """Construct a ScaleZeroPointTask 143 pipeBase.Task.__init__(self, *args, **kwargs)
146 fluxMag0 = 10**(0.4 * self.config.zeroPoint)
147 self.
_calib = afwImage.Calib()
148 self.
_calib.setFluxMag0(fluxMag0)
150 def run(self, exposure, dataRef=None):
151 """Scale the specified exposure to the desired photometric zeropoint 153 @param[in,out] exposure: exposure to scale; masked image is scaled in place 154 @param[in] dataRef: dataRef for exposure. 155 Not used, but in API so that users can switch between spatially variant 157 @return a pipeBase.Struct containing: 158 - imageScaler: the image scaling object used to scale exposure 161 mi = exposure.getMaskedImage()
162 imageScaler.scaleMaskedImage(mi)
163 return pipeBase.Struct(
164 imageScaler=imageScaler,
168 """Compute image scaling object for a given exposure. 170 @param[in] exposure: exposure for which scaling is desired 171 @param[in] dataRef: dataRef for exposure. 172 Not used, but in API so that users can switch between spatially variant 181 @return calibration (lsst.afw.image.Calib) with fluxMag0 set appropriately for config.zeroPoint 186 """Compute the scale for the specified Calib 188 Compute scale, such that if pixelCalib describes the photometric zeropoint of a pixel 189 then the following scales that pixel to the photometric zeropoint specified by config.zeroPoint: 190 scale = computeScale(pixelCalib) 193 @return a pipeBase.Struct containing: 194 - scale, as described above. 196 @note: returns a struct to leave room for scaleErr in a future implementation. 198 fluxAtZeroPoint = calib.getFlux(self.config.zeroPoint)
199 return pipeBase.Struct(
200 scale=1.0 / fluxAtZeroPoint,
204 """Compute the scale for the specified fluxMag0 206 This is a wrapper around scaleFromCalib, which see for more information 209 @return a pipeBase.Struct containing: 210 - scale, as described in scaleFromCalib. 212 calib = afwImage.Calib()
213 calib.setFluxMag0(fluxMag0)
218 """Compute spatially varying scale factor to scale exposures to a desired photometric zero point 220 ConfigClass = SpatialScaleZeroPointConfig
221 _DefaultName =
"scaleZeroPoint" 224 ScaleZeroPointTask.__init__(self, *args, **kwargs)
225 self.makeSubtask(
"selectFluxMag0")
227 def run(self, exposure, dataRef):
228 """Scale the specified exposure to the desired photometric zeropoint 230 @param[in,out] exposure: exposure to scale; masked image is scaled in place 231 @param[in] dataRef: dataRef for exposure 233 @return a pipeBase.Struct containing: 234 - imageScaler: the image scaling object used to scale exposure 237 mi = exposure.getMaskedImage()
238 imageScaler.scaleMaskedImage(mi)
239 return pipeBase.Struct(
240 imageScaler=imageScaler,
244 """Compute image scaling object for a given exposure. 246 @param[in] exposure: exposure for which scaling is desired. Only wcs and bbox are used. 247 @param[in] dataRef: dataRef of exposure 248 dataRef.dataId used to retrieve all applicable fluxMag0's from a database. 249 @return a SpatialImageScaler 252 wcs = exposure.getWcs()
254 fluxMagInfoList = self.selectFluxMag0.
run(dataRef.dataId).fluxMagInfoList
260 for fluxMagInfo
in fluxMagInfoList:
262 if not fluxMagInfo.coordList:
263 raise RuntimeError(
"no x,y data for fluxMagInfo")
264 ctr = afwGeom.Extent2D()
265 for coord
in fluxMagInfo.coordList:
267 ctr += afwGeom.Extent2D(wcs.skyToPixel(coord))
269 ctr = afwGeom.Point2D(ctr / len(fluxMagInfo.coordList))
270 xList.append(ctr.getX())
271 yList.append(ctr.getY())
274 self.log.info(
"Found %d flux scales for interpolation: %s" % (len(scaleList),
275 [
"%0.4f"%(s)
for s
in scaleList]))
277 interpStyle=self.config.interpStyle,
def computeImageScaler(self, exposure, dataRef=None)
def getInterpImage(self, bbox)
def scaleMaskedImage(self, maskedImage)
def run(self, exposure, dataRef=None)
def __init__(self, args, kwargs)
def scaleMaskedImage(self, maskedImage)
def run(self, exposure, dataRef)
def __init__(self, scale=1.0)
def computeImageScaler(self, exposure, dataRef)
def __init__(self, args, kwargs)
def scaleFromCalib(self, calib)
def scaleFromFluxMag0(self, fluxMag0)
def __init__(self, interpStyle, xList, yList, scaleList)