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
50 maskedImage *= self._scale_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.
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)
95 npoints = len(self._xList_xList)
98 raise RuntimeError(
"Cannot create scaling image. Found no fluxMag0s to interpolate")
100 image = afwImage.ImageF(bbox, numpy.mean(self.
_scaleList_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
159 imageScaler = self.computeImageScalercomputeImageScaler(exposure=exposure, dataRef=dataRef)
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
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())
270 scaleList.append(self.
scaleFromFluxMag0scaleFromFluxMag0(fluxMagInfo.fluxMag0).scale)
272 self.log.
info(
"Found %d flux scales for interpolation: %s",
273 len(scaleList), [f
"{s:%0.4f}" for s
in scaleList])
275 interpStyle=self.config.interpStyle,
The photometric calibration of an exposure.
An integer coordinate rectangle.
def scaleMaskedImage(self, maskedImage)
def __init__(self, scale=1.0)
def scaleFromPhotoCalib(self, calib)
def scaleFromFluxMag0(self, fluxMag0)
def run(self, exposure, dataRef=None)
def __init__(self, *args, **kwargs)
def computeImageScaler(self, exposure, dataRef=None)
def scaleMaskedImage(self, maskedImage)
def __init__(self, interpStyle, xList, yList, scaleList)
def getInterpImage(self, bbox)
def computeImageScaler(self, exposure, dataRef)
def run(self, exposure, dataRef)
def __init__(self, *args, **kwargs)
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
std::shared_ptr< PhotoCalib > makePhotoCalibFromCalibZeroPoint(double instFluxMag0, double instFluxMag0Err)
Construct a PhotoCalib from the deprecated Calib-style instFluxMag0/instFluxMag0Err values.