25 import lsst.pex.config
as pexConfig
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 (geom.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)
149 def run(self, exposure, dataRef=None):
150 """Scale the specified exposure to the desired photometric zeropoint 152 @param[in,out] exposure: exposure to scale; masked image is scaled in place 153 @param[in] dataRef: dataRef for exposure. 154 Not used, but in API so that users can switch between spatially variant 156 @return a pipeBase.Struct containing: 157 - imageScaler: the image scaling object used to scale exposure 160 mi = exposure.getMaskedImage()
161 imageScaler.scaleMaskedImage(mi)
162 return pipeBase.Struct(
163 imageScaler=imageScaler,
167 """Compute image scaling object for a given exposure. 169 @param[in] exposure: exposure for which scaling is desired 170 @param[in] dataRef: dataRef for exposure. 171 Not used, but in API so that users can switch between spatially variant 178 """Get desired PhotoCalib 180 @return calibration (lsst.afw.image.PhotoCalib) with fluxMag0 set appropriately for config.zeroPoint 185 """Compute the scale for the specified PhotoCalib 187 Compute scale, such that if pixelCalib describes the photometric zeropoint of a pixel 188 then the following scales that pixel to the photometric zeropoint specified by config.zeroPoint: 189 scale = computeScale(pixelCalib) 192 @return a pipeBase.Struct containing: 193 - scale, as described above. 195 @note: returns a struct to leave room for scaleErr in a future implementation. 197 fluxAtZeroPoint = calib.magnitudeToInstFlux(self.config.zeroPoint)
198 return pipeBase.Struct(
199 scale=1.0 / fluxAtZeroPoint,
203 """Compute the scale for the specified fluxMag0 205 This is a wrapper around scaleFromPhotoCalib, which see for more information 208 @return a pipeBase.Struct containing: 209 - scale, as described in scaleFromPhotoCalib. 216 """Compute spatially varying scale factor to scale exposures to a desired photometric zero point 218 ConfigClass = SpatialScaleZeroPointConfig
219 _DefaultName =
"scaleZeroPoint" 222 ScaleZeroPointTask.__init__(self, *args, **kwargs)
223 self.makeSubtask(
"selectFluxMag0")
225 def run(self, exposure, dataRef):
226 """Scale the specified exposure to the desired photometric zeropoint 228 @param[in,out] exposure: exposure to scale; masked image is scaled in place 229 @param[in] dataRef: dataRef for exposure 231 @return a pipeBase.Struct containing: 232 - imageScaler: the image scaling object used to scale exposure 235 mi = exposure.getMaskedImage()
236 imageScaler.scaleMaskedImage(mi)
237 return pipeBase.Struct(
238 imageScaler=imageScaler,
242 """Compute image scaling object for a given exposure. 244 @param[in] exposure: exposure for which scaling is desired. Only wcs and bbox are used. 245 @param[in] dataRef: dataRef of exposure 246 dataRef.dataId used to retrieve all applicable fluxMag0's from a database. 247 @return a SpatialImageScaler 250 wcs = exposure.getWcs()
252 fluxMagInfoList = self.selectFluxMag0.
run(dataRef.dataId).fluxMagInfoList
258 for fluxMagInfo
in fluxMagInfoList:
260 if not fluxMagInfo.coordList:
261 raise RuntimeError(
"no x,y data for fluxMagInfo")
263 for coord
in fluxMagInfo.coordList:
268 xList.append(ctr.getX())
269 yList.append(ctr.getY())
272 self.log.
info(
"Found %d flux scales for interpolation: %s" % (len(scaleList),
273 [
"%0.4f"%(s)
for s
in scaleList]))
275 interpStyle=self.config.interpStyle,
std::shared_ptr< PhotoCalib > makePhotoCalibFromCalibZeroPoint(double instFluxMag0, double instFluxMag0Err)
Construct a PhotoCalib from the deprecated Calib-style instFluxMag0/instFluxMag0Err values...
def computeImageScaler(self, exposure, dataRef=None)
def getInterpImage(self, bbox)
def scaleMaskedImage(self, maskedImage)
def scaleFromPhotoCalib(self, calib)
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)
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects...
def __init__(self, args, kwargs)
def scaleFromFluxMag0(self, fluxMag0)
def __init__(self, interpStyle, xList, yList, scaleList)