22__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 scale : `float`, optional
40 Scale correction to apply (see ``scaleMaskedImage``).
47 """Scale the specified image or masked image in place.
52 Masked image to scale.
58 """Multiplicative image scaler using interpolation over a grid of points.
60 Contains the x, y positions in tract coordinates
and the scale factors.
63 Currently the only type of
'interpolation' implemented
is CONSTANT which calculates the mean.
67 interpStyle : `Unknown`
68 Interpolation style (`CONSTANT`
is only option).
69 xList : `list` of `int`
70 List of X pixel positions.
71 yList : `list` of `int`
72 List of Y pixel positions.
74 List of multiplicative scale factors at (x,y).
79 Raised
if the lists have different lengths.
82 def __init__(self, interpStyle, xList, yList, scaleList):
83 if len(xList) != len(yList)
or len(xList) != len(scaleList):
85 "len(xList)=%s len(yList)=%s, len(scaleList)=%s but all lists must have the same length" %
86 (len(xList), len(yList), len(scaleList)))
94 """Apply scale correction to the specified masked image.
99 To scale; scale is applied
in place.
105 """Return an image containing the scale correction with same bounding box as supplied.
110 Integer bounding box for image.
115 Raised
if there are no fluxMag0s to interpolate.
117 npoints = len(self._xList)
120 raise RuntimeError(
"Cannot create scaling image. Found no fluxMag0s to interpolate")
122 image = afwImage.ImageF(bbox, numpy.mean(self.
_scaleList))
128 """Config for ScaleZeroPointTask.
131 zeroPoint = pexConfig.Field(
133 doc="desired photometric zero point",
139 selectFluxMag0 = pexConfig.ConfigurableField(
140 doc=
"Task to select data to compute spatially varying photometric zeropoint",
141 target=BaseSelectImagesTask,
144 interpStyle = pexConfig.ChoiceField(
146 doc=
"Algorithm to interpolate the flux scalings;"
147 "Currently only one choice implemented",
150 "CONSTANT":
"Use a single constant value",
156 """Compute scale factor to scale exposures to a desired photometric zero point.
158 This simple version assumes that the zero point is spatially invariant.
161 ConfigClass = ScaleZeroPointConfig
162 _DefaultName = "scaleZeroPoint"
165 pipeBase.Task.__init__(self, *args, **kwargs)
168 fluxMag0 = 10**(0.4 * self.config.zeroPoint)
171 def run(self, exposure, dataRef=None):
172 """Scale the specified exposure to the desired photometric zeropoint.
177 Exposure to scale; masked image is scaled
in place.
179 Data reference
for exposure.
180 Not used, but
in API so that users can switch between spatially variant
185 result : `lsst.pipe.base.Struct`
186 Results
as a struct
with attributes:
189 The image scaling object used to scale exposure.
192 mi = exposure.getMaskedImage()
193 imageScaler.scaleMaskedImage(mi)
194 return pipeBase.Struct(
195 imageScaler=imageScaler,
199 """Compute image scaling object for a given exposure.
204 Exposure for which scaling
is desired.
205 dataRef : `Unknown`, optional
206 Data reference
for exposure.
207 Not used, but
in API so that users can switch between spatially variant
214 """Get desired PhotoCalib.
219 Calibration with ``fluxMag0`` set appropriately
for config.zeroPoint.
224 """Compute the scale for the specified PhotoCalib.
228 result : `lsst.pipe.base.Struct`
229 Results as a struct
with attributes:
233 Scale, such that
if pixelCalib describes the photometric
234 zeropoint of a pixel then the following scales that pixel to
235 the photometric zeropoint specified by config.zeroPoint:
236 ``scale = computeScale(pixelCalib) pixel *= scale``
240 Returns a struct to leave room
for scaleErr
in a future implementation.
242 fluxAtZeroPoint = calib.magnitudeToInstFlux(self.config.zeroPoint)
243 return pipeBase.Struct(
244 scale=1.0 / fluxAtZeroPoint,
248 """Compute the scale for the specified fluxMag0.
250 This is a wrapper around scaleFromPhotoCalib, which see
for more information.
255 Flux at magnitude zero.
259 result : `lsst.pipe.base.Struct`
260 Results
as a struct
with attributes:
264 Scale, such that
if pixelCalib describes the photometric zeropoint
265 of a pixel then the following scales that pixel to the photometric
266 zeropoint specified by config.zeroPoint:
267 ``scale = computeScale(pixelCalib)``
275 """Compute spatially varying scale factor to scale exposures to a desired photometric zero point.
278 ConfigClass = SpatialScaleZeroPointConfig
279 _DefaultName = "scaleZeroPoint"
282 ScaleZeroPointTask.__init__(self, *args, **kwargs)
283 self.makeSubtask(
"selectFluxMag0")
285 def run(self, exposure, dataRef):
286 """Scale the specified exposure to the desired photometric zeropoint.
291 Exposure to scale; masked image is scaled
in place.
293 Data reference
for exposure.
297 result : `lsst.pipe.base.Struct`
298 Results
as a struct
with attributes:
301 The image scaling object used to scale exposure.
304 mi = exposure.getMaskedImage()
305 imageScaler.scaleMaskedImage(mi)
306 return pipeBase.Struct(
307 imageScaler=imageScaler,
311 """Compute image scaling object for a given exposure.
316 Exposure for which scaling
is desired. Only wcs
and bbox are used.
318 Data reference of exposure.
319 dataRef.dataId used to retrieve all applicable fluxMag0
's from a database.
323 result : `SpatialImageScaler`
325 wcs = exposure.getWcs()
327 fluxMagInfoList = self.selectFluxMag0.run(dataRef.dataId).fluxMagInfoList
333 for fluxMagInfo
in fluxMagInfoList:
335 if not fluxMagInfo.coordList:
336 raise RuntimeError(
"no x,y data for fluxMagInfo")
338 for coord
in fluxMagInfo.coordList:
343 xList.append(ctr.getX())
344 yList.append(ctr.getY())
347 self.log.info(
"Found %d flux scales for interpolation: %s",
348 len(scaleList), [f
"{s:%0.4f}" for s
in scaleList])
350 interpStyle=self.config.interpStyle,
A class to contain the data, WCS, and other information needed to describe an image of the sky.
A class to manipulate images, masks, and variance as a single object.
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 __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 __init__(self, *args, **kwargs)
std::shared_ptr< PhotoCalib > makePhotoCalibFromCalibZeroPoint(double instFluxMag0, double instFluxMag0Err)
Construct a PhotoCalib from the deprecated Calib-style instFluxMag0/instFluxMag0Err values.