LSST Applications g0f08755f38+82efc23009,g12f32b3c4e+e7bdf1200e,g1653933729+a8ce1bb630,g1a0ca8cf93+50eff2b06f,g28da252d5a+52db39f6a5,g2bbee38e9b+37c5a29d61,g2bc492864f+37c5a29d61,g2cdde0e794+c05ff076ad,g3156d2b45e+41e33cbcdc,g347aa1857d+37c5a29d61,g35bb328faa+a8ce1bb630,g3a166c0a6a+37c5a29d61,g3e281a1b8c+fb992f5633,g414038480c+7f03dfc1b0,g41af890bb2+11b950c980,g5fbc88fb19+17cd334064,g6b1c1869cb+12dd639c9a,g781aacb6e4+a8ce1bb630,g80478fca09+72e9651da0,g82479be7b0+04c31367b4,g858d7b2824+82efc23009,g9125e01d80+a8ce1bb630,g9726552aa6+8047e3811d,ga5288a1d22+e532dc0a0b,gae0086650b+a8ce1bb630,gb58c049af0+d64f4d3760,gc28159a63d+37c5a29d61,gcf0d15dbbd+2acd6d4d48,gd7358e8bfb+778a810b6e,gda3e153d99+82efc23009,gda6a2b7d83+2acd6d4d48,gdaeeff99f8+1711a396fd,ge2409df99d+6b12de1076,ge79ae78c31+37c5a29d61,gf0baf85859+d0a5978c5a,gf3967379c6+4954f8c433,gfb92a5be7c+82efc23009,gfec2e1e490+2aaed99252,w.2024.46
LSST Data Management Base Package
Loading...
Searching...
No Matches
deblendCoaddSourcesPipeline.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__ = ["DeblendCoaddSourcesSingleConfig", "DeblendCoaddSourcesSingleTask",
23 "DeblendCoaddSourcesMultiConfig", "DeblendCoaddSourcesMultiTask"]
24
25import numpy as np
26
27from lsst.pipe.base import (Struct, PipelineTask, PipelineTaskConfig, PipelineTaskConnections)
28import lsst.pipe.base.connectionTypes as cT
29
30from lsst.pex.config import ConfigurableField
31from lsst.meas.base import SkyMapIdGeneratorConfig
32from lsst.meas.deblender import SourceDeblendTask
33from lsst.meas.extensions.scarlet import ScarletDeblendTask
34
35import lsst.afw.image as afwImage
36import lsst.afw.table as afwTable
37
38from .makeWarp import reorderRefs
39
40
41deblendBaseTemplates = {"inputCoaddName": "deep", "outputCoaddName": "deep"}
42
43
44class DeblendCoaddSourceSingleConnections(PipelineTaskConnections,
45 dimensions=("tract", "patch", "band", "skymap"),
46 defaultTemplates=deblendBaseTemplates):
47 inputSchema = cT.InitInput(
48 doc="Input schema to use in the deblend catalog",
49 name="{inputCoaddName}Coadd_mergeDet_schema",
50 storageClass="SourceCatalog"
51 )
52 peakSchema = cT.InitInput(
53 doc="Schema of the footprint peak catalogs",
54 name="{inputCoaddName}Coadd_peak_schema",
55 storageClass="PeakCatalog"
56 )
57 mergedDetections = cT.Input(
58 doc="Detection catalog merged across bands",
59 name="{inputCoaddName}Coadd_mergeDet",
60 storageClass="SourceCatalog",
61 dimensions=("tract", "patch", "skymap")
62 )
63 coadd = cT.Input(
64 doc="Exposure on which to run deblending",
65 name="{inputCoaddName}Coadd_calexp",
66 storageClass="ExposureF",
67 dimensions=("tract", "patch", "band", "skymap")
68 )
69 measureCatalog = cT.Output(
70 doc="The output measurement catalog of deblended sources",
71 name="{outputCoaddName}Coadd_deblendedFlux",
72 storageClass="SourceCatalog",
73 dimensions=("tract", "patch", "band", "skymap")
74 )
75 outputSchema = cT.InitOutput(
76 doc="Output of the schema used in deblending task",
77 name="{outputCoaddName}Coadd_deblendedFlux_schema",
78 storageClass="SourceCatalog"
79 )
80
81
82class DeblendCoaddSourcesSingleConfig(PipelineTaskConfig,
83 pipelineConnections=DeblendCoaddSourceSingleConnections):
84 singleBandDeblend = ConfigurableField(
85 target=SourceDeblendTask,
86 doc="Task to deblend an image in one band"
87 )
88 idGenerator = SkyMapIdGeneratorConfig.make_field()
89
90 def setDefaults(self):
91 super().setDefaults()
92 self.singleBandDeblend.propagateAllPeaks = True
93
94
95class DeblendCoaddSourcesMultiConnections(PipelineTaskConnections,
96 dimensions=("tract", "patch", "skymap"),
97 defaultTemplates=deblendBaseTemplates):
98 inputSchema = cT.InitInput(
99 doc="Input schema to use in the deblend catalog",
100 name="{inputCoaddName}Coadd_mergeDet_schema",
101 storageClass="SourceCatalog"
102 )
103 peakSchema = cT.InitInput(
104 doc="Schema of the footprint peak catalogs",
105 name="{inputCoaddName}Coadd_peak_schema",
106 storageClass="PeakCatalog"
107 )
108 mergedDetections = cT.Input(
109 doc="Detection catalog merged across bands",
110 name="{inputCoaddName}Coadd_mergeDet",
111 storageClass="SourceCatalog",
112 dimensions=("tract", "patch", "skymap")
113 )
114 coadds = cT.Input(
115 doc="Exposure on which to run deblending",
116 name="{inputCoaddName}Coadd_calexp",
117 storageClass="ExposureF",
118 multiple=True,
119 dimensions=("tract", "patch", "band", "skymap")
120 )
121 outputSchema = cT.InitOutput(
122 doc="Output of the schema used in deblending task",
123 name="{outputCoaddName}Coadd_deblendedFlux_schema",
124 storageClass="SourceCatalog"
125 )
126 # TODO[DM-47405]: remove this deprecated connection.
127 fluxCatalogs = cT.Output(
128 doc="Flux weighted catalogs produced by multiband deblending",
129 name="{outputCoaddName}Coadd_deblendedFlux",
130 storageClass="SourceCatalog",
131 dimensions=("tract", "patch", "band", "skymap"),
132 multiple=True,
133 deprecated="Deprecated and unused; will be removed after v29."
134 )
135 # TODO[DM-47405]: remove this deprecated connection.
136 templateCatalogs = cT.Output(
137 doc="Template catalogs produced by multiband deblending",
138 name="{outputCoaddName}Coadd_deblendedModel",
139 storageClass="SourceCatalog",
140 dimensions=("tract", "patch", "band", "skymap"),
141 multiple=True,
142 deprecated="Deprecated and unused; will be removed after v29."
143 )
144 deblendedCatalog = cT.Output(
145 doc="Catalogs produced by multiband deblending",
146 name="{outputCoaddName}Coadd_deblendedCatalog",
147 storageClass="SourceCatalog",
148 dimensions=("tract", "patch", "skymap"),
149 )
150 scarletModelData = cT.Output(
151 doc="Multiband scarlet models produced by the deblender",
152 name="{outputCoaddName}Coadd_scarletModelData",
153 storageClass="ScarletModelData",
154 dimensions=("tract", "patch", "skymap"),
155 )
156
157 def __init__(self, *, config=None):
158 super().__init__(config=config)
159 del self.fluxCatalogs
160 del self.templateCatalogs
161
162
163class DeblendCoaddSourcesMultiConfig(PipelineTaskConfig,
164 pipelineConnections=DeblendCoaddSourcesMultiConnections):
165 multibandDeblend = ConfigurableField(
166 target=ScarletDeblendTask,
167 doc="Task to deblend an images in multiple bands"
168 )
169 idGenerator = SkyMapIdGeneratorConfig.make_field()
170
171
172class DeblendCoaddSourcesBaseTask(PipelineTask):
173 def __init__(self, initInputs, **kwargs):
174 super().__init__(initInputs=initInputs, **kwargs)
175 schema = initInputs["inputSchema"].schema
176 self.peakSchema = initInputs["peakSchema"].schema
178 self.schemaMapper.addMinimalSchema(schema)
179 self.schema = self.schemaMapper.getOutputSchema()
180
181 def runQuantum(self, butlerQC, inputRefs, outputRefs):
182 inputs = butlerQC.get(inputRefs)
183 inputs["idFactory"] = self.config.idGenerator.apply(butlerQC.quantum.dataId).make_table_id_factory()
184 outputs = self.run(**inputs)
185 butlerQC.put(outputs, outputRefs)
186
187 def _makeSourceCatalog(self, mergedDetections, idFactory):
188 # There may be gaps in the mergeDet catalog, which will cause the
189 # source ids to be inconsistent. So we update the id factory
190 # with the largest id already in the catalog.
191 maxId = np.max(mergedDetections["id"])
192 idFactory.notify(maxId)
193 table = afwTable.SourceTable.make(self.schema, idFactory)
194 sources = afwTable.SourceCatalog(table)
195 sources.extend(mergedDetections, self.schemaMapper)
196 return sources
197
198
200 ConfigClass = DeblendCoaddSourcesSingleConfig
201 _DefaultName = "deblendCoaddSourcesSingle"
202
203 def __init__(self, initInputs, **kwargs):
204 super().__init__(initInputs=initInputs, **kwargs)
205 self.makeSubtask("singleBandDeblend", schema=self.schema, peakSchema=self.peakSchema)
207
208 def run(self, coadd, mergedDetections, idFactory):
209 sources = self._makeSourceCatalog(mergedDetections, idFactory)
210 self.singleBandDeblend.run(coadd, sources)
211 if not sources.isContiguous():
212 sources = sources.copy(deep=True)
213 return Struct(measureCatalog=sources)
214
215
217 ConfigClass = DeblendCoaddSourcesMultiConfig
218 _DefaultName = "deblendCoaddSourcesMulti"
219
220 def __init__(self, initInputs, **kwargs):
221 super().__init__(initInputs=initInputs, **kwargs)
222 self.makeSubtask("multibandDeblend", schema=self.schema, peakSchema=self.peakSchema)
224
225 def runQuantum(self, butlerQC, inputRefs, outputRefs):
226 # Obtain the list of bands, sort them (alphabetically), then reorder
227 # all input lists to match this band order.
228 bandOrder = [dRef.dataId["band"] for dRef in inputRefs.coadds]
229 bandOrder.sort()
230 inputRefs = reorderRefs(inputRefs, bandOrder, dataIdKey="band")
231 inputs = butlerQC.get(inputRefs)
232 inputs["idFactory"] = self.config.idGenerator.apply(butlerQC.quantum.dataId).make_table_id_factory()
233 inputs["filters"] = [dRef.dataId["band"] for dRef in inputRefs.coadds]
234 outputs = self.run(**inputs)
235 butlerQC.put(outputs, outputRefs)
236
237 def run(self, coadds, filters, mergedDetections, idFactory):
238 sources = self._makeSourceCatalog(mergedDetections, idFactory)
239 multiExposure = afwImage.MultibandExposure.fromExposures(filters, coadds)
240 catalog, modelData = self.multibandDeblend.run(multiExposure, sources)
241 retStruct = Struct(deblendedCatalog=catalog, scarletModelData=modelData)
242 return retStruct
A mapping between the keys of two Schemas, used to copy data between them.