lsst.pipe.tasks
g11fb74eaa6+dcef186389
Toggle main menu visibility
Loading...
Searching...
No Matches
python
lsst
pipe
tasks
fit_coadd_psf.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
__all__ = [
23
"CatalogExposurePsf"
,
"CoaddPsfFitConfig"
,
"CoaddPsfFitConnections"
,
24
"CoaddPsfFitSubConfig"
,
"CoaddPsfFitSubTask"
,
"CoaddPsfFitTask"
,
25
]
26
27
from
.fit_multiband
import
CatalogExposure, CatalogExposureConfig
28
from
lsst.geom
import
Point2D
29
from
lsst.meas.base
import
SkyMapIdGeneratorConfig
30
import
lsst.pex.config
as
pexConfig
31
import
lsst.pipe.base
as
pipeBase
32
import
lsst.pipe.base.connectionTypes
as
cT
33
34
import
dataclasses
35
from
abc
import
ABC, abstractmethod
36
from
pydantic.dataclasses
import
dataclass
37
38
39
@dataclass(frozen=True, kw_only=True, config=CatalogExposureConfig)
40
class
CatalogExposurePsf
(
CatalogExposure
):
41
def
get_catalog
(self):
42
return
self.
catalog
43
44
def
get_psf_image
(self, source):
45
"""Return the PSF image for this object."""
46
center =
Point2D
(round(source.getX()), round(source.getY()))
47
return
self.
exposure
.getPsf().computeKernelImage(center).array
48
49
50
CoaddPsfFitBaseTemplates = {
51
"name_coadd"
:
"deep"
,
52
"name_output_method"
:
"multiprofit"
,
53
}
54
55
56
class
CoaddPsfFitConnections
(
57
pipeBase.PipelineTaskConnections,
58
dimensions=(
"tract"
,
"patch"
,
"band"
,
"skymap"
),
59
defaultTemplates=CoaddPsfFitBaseTemplates,
60
):
61
coadd = cT.Input(
62
doc=
"Coadd image to fit a PSF model to"
,
63
name=
"{name_coadd}Coadd_calexp"
,
64
storageClass=
"ExposureF"
,
65
dimensions=(
"tract"
,
"patch"
,
"band"
,
"skymap"
),
66
)
67
coadd_cell = cT.Input(
68
doc=
"Cell-coadd image to fit a PSF model to"
,
69
name=
"{name_coadd}CoaddCell"
,
70
storageClass=
"MultipleCellCoadd"
,
71
dimensions=(
"tract"
,
"patch"
,
"band"
,
"skymap"
),
72
)
73
background = cT.Input(
74
doc=
"Background model to subtract from the coadd_cell"
,
75
name=
"{name_coadd}Coadd_calexp_background"
,
76
storageClass=
"Background"
,
77
dimensions=(
"tract"
,
"patch"
,
"band"
,
"skymap"
),
78
)
79
cat_meas = cT.Input(
80
doc=
"Deblended single-band source catalog"
,
81
name=
"{name_coadd}Coadd_meas"
,
82
storageClass=
"SourceCatalog"
,
83
dimensions=(
"tract"
,
"patch"
,
"band"
,
"skymap"
),
84
)
85
cat_output = cT.Output(
86
doc=
"Output PSF fit parameter catalog"
,
87
name=
"{name_coadd}Coadd_psfs_{name_output_method}"
,
88
storageClass=
"ArrowTable"
,
89
dimensions=(
"tract"
,
"patch"
,
"band"
,
"skymap"
),
90
)
91
92
def
__init__
(self, *, config=None):
93
super().
__init__
(config=config)
94
if
config
is
None
:
95
return
96
97
if
config.image_type ==
"future"
:
98
self.
coadd
= dataclasses.replace(self.
coadd
, storageClass=
"CellCoadd"
)
99
del self.
coadd_cell
100
del self.
background
101
elif
config.use_cell_coadds:
102
del self.
coadd
103
else
:
104
del self.
coadd_cell
105
del self.
background
106
107
108
class
CoaddPsfFitSubConfig
(pexConfig.Config):
109
"""Base config class for the CoaddPsfFitTask.
110
111
Implementing classes may add any necessary attributes.
112
"""
113
114
115
class
CoaddPsfFitSubTask(pipeBase.Task, ABC):
116
"""Interface for CoaddPsfFitTask subtasks to fit PSFs.
117
118
Parameters
119
----------
120
**kwargs
121
Additional arguments to be passed to the `lsst.pipe.base.Task`
122
constructor.
123
"""
124
ConfigClass = CoaddPsfFitSubConfig
125
126
def
__init__
(self, **kwargs):
127
super().
__init__
(**kwargs)
128
129
@abstractmethod
130
def
run
(
131
self, catexp: CatalogExposurePsf
132
) -> pipeBase.Struct:
133
"""Fit PSF images at locations of sources in a single exposure.
134
135
Parameters
136
----------
137
catexp : `CatalogExposurePsf`
138
An exposure to fit a model PSF at the position of all
139
sources in the corresponding catalog.
140
141
Returns
142
-------
143
retStruct : `lsst.pipe.base.Struct`
144
A struct with a cat_output attribute containing the output
145
measurement catalog.
146
147
Notes
148
-----
149
Subclasses may have further requirements on the input parameters,
150
including:
151
- Passing only one catexp per band;
152
- Catalogs containing HeavyFootprints with deblended images;
153
- Fitting only a subset of the sources.
154
If any requirements are not met, the subtask should fail as soon as
155
possible.
156
"""
157
raise
NotImplementedError()
158
159
160
class
CoaddPsfFitConfig
(
161
pipeBase.PipelineTaskConfig,
162
pipelineConnections=CoaddPsfFitConnections,
163
):
164
"""Configure a CoaddPsfFitTask, including a configurable fitting subtask.
165
"""
166
use_cell_coadds = pexConfig.Field(
167
dtype=bool,
168
default=
False
,
169
doc=
"Use cell coadd images for PSF fitting"
,
170
)
171
fit_coadd_psf = pexConfig.ConfigurableField(
172
target=CoaddPsfFitSubTask,
173
doc=
"Task to fit PSF models for a single coadd"
,
174
)
175
idGenerator = SkyMapIdGeneratorConfig.make_field()
176
image_type = pexConfig.ChoiceField(
177
"Which image type to expect for the input coadd. "
178
"This option only directly affects connection storage classes and hence 'runQuantum'; the 'run' "
179
"method behavior is determined by which type is actually passed in."
,
180
allowed={
181
"legacy"
: (
182
"Read a lsst.cell_coadds.MultipleCellCoadd via 'coadd_cell` and restore 'background' "
183
"(if use_cell_coadd) or lsst.afw.image.Exposure via `coadd` (if not use_cell_coadd)."
184
),
185
"future"
: (
186
"Read lsst.images.cells.CellCoadd via the 'coadd' connection. use_cell_coadd is ignored."
187
),
188
},
189
dtype=str,
190
optional=
False
,
191
default=
"legacy"
,
192
)
193
194
195
class
CoaddPsfFitTask
(pipeBase.PipelineTask):
196
"""Fit a PSF model at the location of sources in a coadd.
197
198
This task is intended to fit only a single PSF model at the
199
centroid of all of the sources in a single coadd exposure.
200
Subtasks may choose to filter which sources they fit,
201
and may output whatever columns they desire in addition to
202
the minimum of 'id'.
203
"""
204
ConfigClass = CoaddPsfFitConfig
205
_DefaultName =
"CoaddPsfFit"
206
207
def
__init__
(self, initInputs, **kwargs):
208
super().
__init__
(initInputs=initInputs, **kwargs)
209
self.makeSubtask(
"fit_coadd_psf"
)
210
211
def
runQuantum
(self, butlerQC, inputRefs, outputRefs):
212
inputs = butlerQC.get(inputRefs)
213
id_tp = self.config.idGenerator.apply(butlerQC.quantum.dataId).catalog_id
214
dataId = inputRefs.cat_meas.dataId
215
216
if
self.config.image_type ==
"future"
:
217
coaddDataRef = inputRefs.coadd
218
exposure = inputs.pop(
'coadd'
).to_legacy()
219
elif
self.config.use_cell_coadds:
220
coaddDataRef = inputRefs.coadd_cell
221
multiple_cell_coadd = inputs.pop(
'coadd_cell'
)
222
background = inputs.pop(
'background'
)
223
exposure = multiple_cell_coadd.stitch().asExposure()
224
exposure.image -= background.getImage()
225
else
:
226
coaddDataRef = inputRefs.coadd
227
exposure = inputs.pop(
'coadd'
)
228
229
for
dataRef
in
(coaddDataRef,):
230
if
dataRef.dataId != dataId:
231
raise
RuntimeError(f
'{dataRef=}.dataId != {inputRefs.cat_meas.dataId=}'
)
232
233
catalog = inputs.pop(
'cat_meas'
)
234
catexp =
CatalogExposurePsf
(
235
catalog=catalog, exposure=exposure, dataId=dataId, id_tract_patch=id_tp,
236
)
237
assert
not
inputs,
"runQuantum got more inputs than expected"
238
outputs = self.
run
(catexp=catexp)
239
butlerQC.put(outputs, outputRefs)
240
241
def
run
(self, catexp: CatalogExposurePsf) -> pipeBase.Struct:
242
"""Fit a PSF model at the location of sources in a coadd.
243
244
Parameters
245
----------
246
catexp : `typing.List [CatalogExposurePsf]`
247
A list of catalog-exposure pairs in a given band.
248
249
Returns
250
-------
251
retStruct : `lsst.pipe.base.Struct`
252
A struct with a cat_output attribute containing the output
253
measurement catalog.
254
255
Notes
256
-----
257
Subtasks may have further requirements; see `CoaddPsfFitSubTask.run`.
258
"""
259
cat_output = self.fit_coadd_psf.run(catexp).output
260
retStruct = pipeBase.Struct(cat_output=cat_output)
261
return
retStruct
lsst::geom::Point< double, 2 >
lsst.pipe.tasks.fit_coadd_psf.CatalogExposurePsf
Definition
fit_coadd_psf.py:40
lsst.pipe.tasks.fit_coadd_psf.CatalogExposurePsf.get_catalog
get_catalog(self)
Definition
fit_coadd_psf.py:41
lsst.pipe.tasks.fit_coadd_psf.CatalogExposurePsf.get_psf_image
get_psf_image(self, source)
Definition
fit_coadd_psf.py:44
lsst.pipe.tasks.fit_coadd_psf.CoaddPsfFitConfig
Definition
fit_coadd_psf.py:163
lsst.pipe.tasks.fit_coadd_psf.CoaddPsfFitConnections
Definition
fit_coadd_psf.py:60
lsst.pipe.tasks.fit_coadd_psf.CoaddPsfFitConnections.coadd_cell
coadd_cell
Definition
fit_coadd_psf.py:67
lsst.pipe.tasks.fit_coadd_psf.CoaddPsfFitConnections.__init__
__init__(self, *, config=None)
Definition
fit_coadd_psf.py:92
lsst.pipe.tasks.fit_coadd_psf.CoaddPsfFitConnections.background
background
Definition
fit_coadd_psf.py:73
lsst.pipe.tasks.fit_coadd_psf.CoaddPsfFitConnections.coadd
coadd
Definition
fit_coadd_psf.py:61
lsst.pipe.tasks.fit_coadd_psf.CoaddPsfFitSubConfig
Definition
fit_coadd_psf.py:108
lsst.pipe.tasks.fit_coadd_psf.CoaddPsfFitSubTask.__init__
__init__(self, **kwargs)
Definition
fit_coadd_psf.py:126
lsst.pipe.tasks.fit_coadd_psf.CoaddPsfFitSubTask.run
pipeBase.Struct run(self, CatalogExposurePsf catexp)
Definition
fit_coadd_psf.py:132
lsst.pipe.tasks.fit_coadd_psf.CoaddPsfFitTask
Definition
fit_coadd_psf.py:195
lsst.pipe.tasks.fit_coadd_psf.CoaddPsfFitTask.run
pipeBase.Struct run(self, CatalogExposurePsf catexp)
Definition
fit_coadd_psf.py:241
lsst.pipe.tasks.fit_coadd_psf.CoaddPsfFitTask.__init__
__init__(self, initInputs, **kwargs)
Definition
fit_coadd_psf.py:207
lsst.pipe.tasks.fit_coadd_psf.CoaddPsfFitTask.runQuantum
runQuantum(self, butlerQC, inputRefs, outputRefs)
Definition
fit_coadd_psf.py:211
lsst.pipe.tasks.fit_multiband.CatalogExposure
Definition
fit_multiband.py:37
lsst.pipe.tasks.fit_multiband.CatalogExposure.exposure
afwImage exposure
Definition
fit_multiband.py:55
lsst.pipe.tasks.fit_multiband.CatalogExposure.catalog
afwTable catalog
Definition
fit_multiband.py:54
lsst::geom
lsst::meas::base
lsst::pex::config
Generated on
for lsst.pipe.tasks by
1.17.0