lsst.pipe.tasks
g2c8cee2ce7+1ac6cedd78
Toggle main menu visibility
Loading...
Searching...
No Matches
python
lsst
pipe
tasks
scaleZeroPoint.py
Go to the documentation of this file.
1
# This file is part of pipe_tasks.
2
#
3
# Developed for the LSST Data Management System.
4
# This product includes software developed by the LSST Project
5
# (https://www.lsst.org).
6
# See the COPYRIGHT file at the top-level directory of this distribution
7
# for details of code ownership.
8
#
9
# This program is free software: you can redistribute it and/or modify
10
# it under the terms of the GNU General Public License as published by
11
# the Free Software Foundation, either version 3 of the License, or
12
# (at your option) any later version.
13
#
14
# This program is distributed in the hope that it will be useful,
15
# but WITHOUT ANY WARRANTY; without even the implied warranty of
16
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
# GNU General Public License for more details.
18
#
19
# You should have received a copy of the GNU General Public License
20
# along with this program. If not, see <https://www.gnu.org/licenses/>.
21
22
23
from
__future__
import
annotations
24
25
__all__ = [
"ImageScaler"
,
"SpatialImageScaler"
,
"ScaleZeroPointTask"
]
26
27
import
numpy
28
import
lsst.geom
as
geom
29
import
lsst.afw.image
as
afwImage
30
import
lsst.pex.config
as
pexConfig
31
import
lsst.pipe.base
as
pipeBase
32
from
lsst.pipe.tasks.selectImages
import
BaseSelectImagesTask
33
from
deprecated.sphinx
import
deprecated
34
35
36
class
ImageScaler
:
37
"""A class that scales an image.
38
39
This version uses a single scalar. Fancier versions may use a spatially varying scale.
40
41
Parameters
42
----------
43
scale : `float`, optional
44
Scale correction to apply (see ``scaleMaskedImage``).
45
"""
46
47
def
__init__
(self, scale=1.0):
48
self.
_scale
= scale
49
50
# TODO: Remove this property in DM-49402.
51
@property
52
@deprecated("This property will be removed after v30.", version="v30", category=FutureWarning)
53
def
scale
(self) -> float:
54
"""Scale that it applies to a specified image."""
55
return
self.
_scale
56
57
def
scaleMaskedImage
(self, maskedImage):
58
"""Scale the specified image or masked image in place.
59
60
Parameters
61
----------
62
maskedImage : `lsst.afw.image.MaskedImage`
63
Masked image to scale.
64
"""
65
maskedImage *= self.
_scale
66
67
68
class
SpatialImageScaler
(
ImageScaler
):
69
"""Multiplicative image scaler using interpolation over a grid of points.
70
71
Contains the x, y positions in tract coordinates and the scale factors.
72
Interpolates only when scaleMaskedImage() or getInterpImage() is called.
73
74
Currently the only type of 'interpolation' implemented is CONSTANT which calculates the mean.
75
76
Parameters
77
----------
78
interpStyle : `Unknown`
79
Interpolation style (`CONSTANT` is only option).
80
xList : `list` of `int`
81
List of X pixel positions.
82
yList : `list` of `int`
83
List of Y pixel positions.
84
scaleList : `Unknown`
85
List of multiplicative scale factors at (x,y).
86
87
Raises
88
------
89
RuntimeError
90
Raised if the lists have different lengths.
91
"""
92
93
def
__init__
(self, interpStyle, xList, yList, scaleList):
94
if
len(xList) != len(yList)
or
len(xList) != len(scaleList):
95
raise
RuntimeError(
96
"len(xList)=%s len(yList)=%s, len(scaleList)=%s but all lists must have the same length"
%
97
(len(xList), len(yList), len(scaleList)))
98
99
# Eventually want this do be: self.interpStyle = getattr(afwMath.Interpolate2D, interpStyle)
100
self.
_xList
= xList
101
self.
_yList
= yList
102
self.
_scaleList
= scaleList
103
104
# TODO: Remove this property in DM-49402.
105
@property
106
@deprecated("This property will be removed after v30.", version="v30", category=FutureWarning)
107
def
scale
(self) -> float:
108
"""Mean scale that it applies to a specified image."""
109
return
numpy.mean(self.
_scaleList
)
110
111
def
scaleMaskedImage
(self, maskedImage):
112
"""Apply scale correction to the specified masked image.
113
114
Parameters
115
----------
116
maskedImage : `lsst.afw.image.MaskedImage`
117
Masked image to scale; scale is applied in place.
118
"""
119
scale = self.
getInterpImage
(maskedImage.getBBox())
120
maskedImage *= scale
121
122
def
getInterpImage
(self, bbox):
123
"""Return an image containing the scale correction with same bounding box as supplied.
124
125
Parameters
126
----------
127
bbox : `lsst.geom.Box2I`
128
Integer bounding box for image.
129
130
Raises
131
------
132
RuntimeError
133
Raised if there are no fluxMag0s to interpolate.
134
"""
135
npoints = len(self.
_xList
)
136
137
if
npoints < 1:
138
raise
RuntimeError(
"Cannot create scaling image. Found no fluxMag0s to interpolate"
)
139
140
image = afwImage.ImageF(bbox, numpy.mean(self.
_scaleList
))
141
142
return
image
143
144
145
class
ScaleZeroPointConfig
(pexConfig.Config):
146
"""Config for ScaleZeroPointTask.
147
"""
148
149
zeroPoint = pexConfig.Field(
150
dtype=float,
151
doc=
"desired photometric zero point"
,
152
default=27.0,
153
)
154
155
156
class
SpatialScaleZeroPointConfig
(
ScaleZeroPointConfig
):
157
selectFluxMag0 = pexConfig.ConfigurableField(
158
doc=
"Task to select data to compute spatially varying photometric zeropoint"
,
159
target=BaseSelectImagesTask,
160
)
161
162
interpStyle = pexConfig.ChoiceField(
163
dtype=str,
164
doc=
"Algorithm to interpolate the flux scalings;"
165
"Currently only one choice implemented"
,
166
default=
"CONSTANT"
,
167
allowed={
168
"CONSTANT"
:
"Use a single constant value"
,
169
}
170
)
171
172
173
class
ScaleZeroPointTask
(pipeBase.Task):
174
"""Compute scale factor to scale exposures to a desired photometric zero point.
175
176
This simple version assumes that the zero point is spatially invariant.
177
"""
178
179
ConfigClass = ScaleZeroPointConfig
180
_DefaultName =
"scaleZeroPoint"
181
182
def
__init__
(self, *args, **kwargs):
183
pipeBase.Task.__init__(self, *args, **kwargs)
184
185
# flux at mag=0 is 10^(zeroPoint/2.5) because m = -2.5*log10(F/F0)
186
fluxMag0 = 10**(0.4 * self.config.zeroPoint)
187
self.
_photoCalib
= afwImage.makePhotoCalibFromCalibZeroPoint(fluxMag0, 0.0)
188
189
def
run
(self, exposure, dataRef=None):
190
"""Scale the specified exposure to the desired photometric zeropoint.
191
192
Parameters
193
----------
194
exposure : `lsst.afw.image.Exposure`
195
Exposure to scale; masked image is scaled in place.
196
dataRef : `Unknown`, optional
197
Data reference for exposure.
198
Not used, but in API so that users can switch between spatially variant
199
and invariant tasks.
200
201
Returns
202
-------
203
result : `~lsst.pipe.base.Struct`
204
Results as a struct with attributes:
205
206
``imageScaler``
207
The image scaling object used to scale exposure.
208
"""
209
imageScaler = self.
computeImageScaler
(exposure=exposure, dataRef=dataRef)
210
mi = exposure.getMaskedImage()
211
imageScaler.scaleMaskedImage(mi)
212
return
pipeBase.Struct(
213
imageScaler=imageScaler,
214
)
215
216
def
computeImageScaler
(self, exposure, dataRef=None):
217
"""Compute image scaling object for a given exposure.
218
219
Parameters
220
----------
221
exposure : `lsst.afw.image.Exposure`
222
Exposure for which scaling is desired.
223
dataRef : `Unknown`, optional
224
Data reference for exposure.
225
Not used, but in API so that users can switch between spatially variant
226
and invariant tasks.
227
"""
228
scale = self.
scaleFromPhotoCalib
(exposure.getPhotoCalib()).scale
229
return
ImageScaler
(scale)
230
231
def
getPhotoCalib
(self):
232
"""Get desired PhotoCalib.
233
234
Returns
235
-------
236
calibration : `lsst.afw.image.PhotoCalib`
237
Calibration with ``fluxMag0`` set appropriately for config.zeroPoint.
238
"""
239
return
self.
_photoCalib
240
241
def
scaleFromPhotoCalib
(self, calib):
242
"""Compute the scale for the specified PhotoCalib.
243
244
Parameter
245
---------
246
calib : `lsst.afw.image.PhotoCalib`
247
PhotoCalib object to compute the scale from.
248
249
Returns
250
-------
251
result : `lsst.pipe.base.Struct`
252
Results as a struct with attributes:
253
254
`scale`
255
256
Scale, such that if pixelCalib describes the photometric
257
zeropoint of a pixel then the following scales that pixel to
258
the photometric zeropoint specified by config.zeroPoint:
259
``scale = computeScale(pixelCalib) pixel *= scale``
260
261
Notes
262
-----
263
Returns a struct to leave room for scaleErr in a future implementation.
264
"""
265
fluxAtZeroPoint = calib.magnitudeToInstFlux(self.config.zeroPoint)
266
return
pipeBase.Struct(
267
scale=1.0 / fluxAtZeroPoint,
268
)
269
270
def
scaleFromFluxMag0
(self, fluxMag0):
271
"""Compute the scale for the specified fluxMag0.
272
273
This is a wrapper around scaleFromPhotoCalib, which see for more information.
274
275
Parameters
276
----------
277
fluxMag0 : `float`
278
Flux at magnitude zero.
279
280
Returns
281
-------
282
result : `lsst.pipe.base.Struct`
283
Results as a struct with attributes:
284
285
`scale`
286
287
Scale, such that if pixelCalib describes the photometric zeropoint
288
of a pixel then the following scales that pixel to the photometric
289
zeropoint specified by config.zeroPoint:
290
``scale = computeScale(pixelCalib)``
291
``pixel *= scale``
292
"""
293
calib = afwImage.makePhotoCalibFromCalibZeroPoint(fluxMag0, 0.0)
294
return
self.
scaleFromPhotoCalib
(calib)
295
296
297
class
SpatialScaleZeroPointTask
(
ScaleZeroPointTask
):
298
"""Compute spatially varying scale factor to scale exposures to a desired photometric zero point.
299
"""
300
301
ConfigClass = SpatialScaleZeroPointConfig
302
_DefaultName =
"scaleZeroPoint"
303
304
def
__init__
(self, *args, **kwargs):
305
ScaleZeroPointTask.__init__(self, *args, **kwargs)
306
self.makeSubtask(
"selectFluxMag0"
)
307
308
def
run
(self, exposure, dataRef):
309
"""Scale the specified exposure to the desired photometric zeropoint.
310
311
Parameters
312
----------
313
exposure : `lsst.afw.image.Exposure`
314
Exposure to scale; masked image is scaled in place.
315
dataRef : `Unknown`
316
Data reference for exposure.
317
318
Returns
319
-------
320
result : `lsst.pipe.base.Struct`
321
Results as a struct with attributes:
322
323
``imageScaler``
324
The image scaling object used to scale exposure.
325
"""
326
imageScaler = self.
computeImageScaler
(exposure=exposure, dataRef=dataRef)
327
mi = exposure.getMaskedImage()
328
imageScaler.scaleMaskedImage(mi)
329
return
pipeBase.Struct(
330
imageScaler=imageScaler,
331
)
332
333
def
computeImageScaler
(self, exposure, dataRef):
334
"""Compute image scaling object for a given exposure.
335
336
Parameters
337
----------
338
exposure : `lsst.afw.image.Exposure`
339
Exposure for which scaling is desired. Only wcs and bbox are used.
340
dataRef : `Unknown`
341
Data reference of exposure.
342
dataRef.dataId used to retrieve all applicable fluxMag0's from a database.
343
344
Returns
345
-------
346
result : `SpatialImageScaler`
347
"""
348
wcs = exposure.getWcs()
349
350
fluxMagInfoList = self.selectFluxMag0.run(dataRef.dataId).fluxMagInfoList
351
352
xList = []
353
yList = []
354
scaleList = []
355
356
for
fluxMagInfo
in
fluxMagInfoList:
357
# find center of field in tract coordinates
358
if
not
fluxMagInfo.coordList:
359
raise
RuntimeError(
"no x,y data for fluxMagInfo"
)
360
ctr =
geom.Extent2D
()
361
for
coord
in
fluxMagInfo.coordList:
362
# accumulate x, y
363
ctr +=
geom.Extent2D
(wcs.skyToPixel(coord))
364
# and find average x, y as the center of the chip
365
ctr =
geom.Point2D
(ctr / len(fluxMagInfo.coordList))
366
xList.append(ctr.getX())
367
yList.append(ctr.getY())
368
scaleList.append(self.
scaleFromFluxMag0
(fluxMagInfo.fluxMag0).scale)
369
370
self.log.info(
"Found %d flux scales for interpolation: %s"
,
371
len(scaleList), [f
"{s:%0.4f}"
for
s
in
scaleList])
372
return
SpatialImageScaler
(
373
interpStyle=self.config.interpStyle,
374
xList=xList,
375
yList=yList,
376
scaleList=scaleList,
377
)
lsst::geom::Extent< double, 2 >
lsst::geom::Point< double, 2 >
lsst.pipe.tasks.scaleZeroPoint.ImageScaler
Definition
scaleZeroPoint.py:36
lsst.pipe.tasks.scaleZeroPoint.ImageScaler.scaleMaskedImage
scaleMaskedImage(self, maskedImage)
Definition
scaleZeroPoint.py:57
lsst.pipe.tasks.scaleZeroPoint.ImageScaler.scale
float scale(self)
Definition
scaleZeroPoint.py:53
lsst.pipe.tasks.scaleZeroPoint.ImageScaler.__init__
__init__(self, scale=1.0)
Definition
scaleZeroPoint.py:47
lsst.pipe.tasks.scaleZeroPoint.ImageScaler._scale
float _scale
Definition
scaleZeroPoint.py:48
lsst.pipe.tasks.scaleZeroPoint.ScaleZeroPointConfig
Definition
scaleZeroPoint.py:145
lsst.pipe.tasks.scaleZeroPoint.ScaleZeroPointTask
Definition
scaleZeroPoint.py:173
lsst.pipe.tasks.scaleZeroPoint.ScaleZeroPointTask.scaleFromFluxMag0
scaleFromFluxMag0(self, fluxMag0)
Definition
scaleZeroPoint.py:270
lsst.pipe.tasks.scaleZeroPoint.ScaleZeroPointTask.run
run(self, exposure, dataRef=None)
Definition
scaleZeroPoint.py:189
lsst.pipe.tasks.scaleZeroPoint.ScaleZeroPointTask.computeImageScaler
computeImageScaler(self, exposure, dataRef=None)
Definition
scaleZeroPoint.py:216
lsst.pipe.tasks.scaleZeroPoint.ScaleZeroPointTask.getPhotoCalib
getPhotoCalib(self)
Definition
scaleZeroPoint.py:231
lsst.pipe.tasks.scaleZeroPoint.ScaleZeroPointTask.scaleFromPhotoCalib
scaleFromPhotoCalib(self, calib)
Definition
scaleZeroPoint.py:241
lsst.pipe.tasks.scaleZeroPoint.ScaleZeroPointTask.__init__
__init__(self, *args, **kwargs)
Definition
scaleZeroPoint.py:182
lsst.pipe.tasks.scaleZeroPoint.ScaleZeroPointTask._photoCalib
_photoCalib
Definition
scaleZeroPoint.py:187
lsst.pipe.tasks.scaleZeroPoint.SpatialImageScaler
Definition
scaleZeroPoint.py:68
lsst.pipe.tasks.scaleZeroPoint.SpatialImageScaler.scaleMaskedImage
scaleMaskedImage(self, maskedImage)
Definition
scaleZeroPoint.py:111
lsst.pipe.tasks.scaleZeroPoint.SpatialImageScaler.__init__
__init__(self, interpStyle, xList, yList, scaleList)
Definition
scaleZeroPoint.py:93
lsst.pipe.tasks.scaleZeroPoint.SpatialImageScaler.scale
float scale(self)
Definition
scaleZeroPoint.py:107
lsst.pipe.tasks.scaleZeroPoint.SpatialImageScaler.getInterpImage
getInterpImage(self, bbox)
Definition
scaleZeroPoint.py:122
lsst.pipe.tasks.scaleZeroPoint.SpatialImageScaler._yList
_yList
Definition
scaleZeroPoint.py:101
lsst.pipe.tasks.scaleZeroPoint.SpatialImageScaler._scaleList
_scaleList
Definition
scaleZeroPoint.py:102
lsst.pipe.tasks.scaleZeroPoint.SpatialImageScaler._xList
_xList
Definition
scaleZeroPoint.py:100
lsst.pipe.tasks.scaleZeroPoint.SpatialScaleZeroPointConfig
Definition
scaleZeroPoint.py:156
lsst.pipe.tasks.scaleZeroPoint.SpatialScaleZeroPointTask
Definition
scaleZeroPoint.py:297
lsst.pipe.tasks.scaleZeroPoint.SpatialScaleZeroPointTask.run
run(self, exposure, dataRef)
Definition
scaleZeroPoint.py:308
lsst.pipe.tasks.scaleZeroPoint.SpatialScaleZeroPointTask.__init__
__init__(self, *args, **kwargs)
Definition
scaleZeroPoint.py:304
lsst.pipe.tasks.scaleZeroPoint.SpatialScaleZeroPointTask.computeImageScaler
computeImageScaler(self, exposure, dataRef)
Definition
scaleZeroPoint.py:333
lsst::afw::image
lsst::geom
lsst::pex::config
lsst.pipe.tasks.selectImages
Definition
selectImages.py:1
Generated on
for lsst.pipe.tasks by
1.17.0