Coverage for python/lsst/pipe/tasks/deblendCoaddSourcesPipeline.py : 47%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
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/>.
22from lsst.pipe.base import (Struct, PipelineTask, PipelineTaskConfig, PipelineTaskConnections)
23import lsst.pipe.base.connectionTypes as cT
25from lsst.pex.config import ConfigurableField
26from lsst.meas.deblender import SourceDeblendTask
27from lsst.meas.extensions.scarlet import ScarletDeblendTask
28from lsst.obs.base import ExposureIdInfo
30import lsst.afw.image as afwImage
31import lsst.afw.table as afwTable
33__all__ = ("DeblendCoaddSourcesSingleConfig", "DeblendCoaddSourcesSingleTask",
34 "DeblendCoaddSourcesMultiConfig", "DeblendCoaddSourcesMultiTask")
37deblendBaseTemplates = {"inputCoaddName": "deep", "outputCoaddName": "deep"}
40class DeblendCoaddSourceSingleConnections(PipelineTaskConnections,
41 dimensions=("tract", "patch", "band", "skymap"),
42 defaultTemplates=deblendBaseTemplates):
43 inputSchema = cT.InitInput(
44 doc="Input schema to use in the deblend catalog",
45 name="{inputCoaddName}Coadd_mergeDet_schema",
46 storageClass="SourceCatalog"
47 )
48 peakSchema = cT.InitInput(
49 doc="Schema of the footprint peak catalogs",
50 name="{inputCoaddName}Coadd_peak_schema",
51 storageClass="PeakCatalog"
52 )
53 mergedDetections = cT.Input(
54 doc="Detection catalog merged across bands",
55 name="{inputCoaddName}Coadd_mergeDet",
56 storageClass="SourceCatalog",
57 dimensions=("tract", "patch", "skymap")
58 )
59 coadd = cT.Input(
60 doc="Exposure on which to run deblending",
61 name="{inputCoaddName}Coadd_calexp",
62 storageClass="ExposureF",
63 dimensions=("tract", "patch", "band", "skymap")
64 )
65 measureCatalog = cT.Output(
66 doc="The output measurement catalog of deblended sources",
67 name="{outputCoaddName}Coadd_deblendedFlux",
68 storageClass="SourceCatalog",
69 dimensions=("tract", "patch", "band", "skymap")
70 )
71 outputSchema = cT.InitOutput(
72 doc="Output of the schema used in deblending task",
73 name="{outputCoaddName}Coadd_deblendedFlux_schema",
74 storageClass="SourceCatalog"
75 )
77 def setDefaults(self):
78 super().setDefaults()
79 self.singleBandDeblend.propagateAllPeaks = True
82class DeblendCoaddSourcesSingleConfig(PipelineTaskConfig,
83 pipelineConnections=DeblendCoaddSourceSingleConnections):
84 singleBandDeblend = ConfigurableField(
85 target=SourceDeblendTask,
86 doc="Task to deblend an image in one band"
87 )
90class DeblendCoaddSourcesMultiConnections(PipelineTaskConnections,
91 dimensions=("tract", "patch", "skymap"),
92 defaultTemplates=deblendBaseTemplates):
93 inputSchema = cT.InitInput(
94 doc="Input schema to use in the deblend catalog",
95 name="{inputCoaddName}Coadd_mergeDet_schema",
96 storageClass="SourceCatalog"
97 )
98 peakSchema = cT.InitInput(
99 doc="Schema of the footprint peak catalogs",
100 name="{inputCoaddName}Coadd_peak_schema",
101 storageClass="PeakCatalog"
102 )
103 mergedDetections = cT.Input(
104 doc="Detection catalog merged across bands",
105 name="{inputCoaddName}Coadd_mergeDet",
106 storageClass="SourceCatalog",
107 dimensions=("tract", "patch", "skymap")
108 )
109 coadds = cT.Input(
110 doc="Exposure on which to run deblending",
111 name="{inputCoaddName}Coadd_calexp",
112 storageClass="ExposureF",
113 multiple=True,
114 dimensions=("tract", "patch", "band", "skymap")
115 )
116 outputSchema = cT.InitOutput(
117 doc="Output of the schema used in deblending task",
118 name="{outputCoaddName}Coadd_deblendedFlux_schema",
119 storageClass="SourceCatalog"
120 )
121 templateCatalogs = cT.Output(
122 doc="Template catalogs produced by multiband deblending",
123 name="{outputCoaddName}Coadd_deblendedFlux",
124 storageClass="SourceCatalog",
125 dimensions=("tract", "patch", "band", "skymap"),
126 multiple=True
127 )
130class DeblendCoaddSourcesMultiConfig(PipelineTaskConfig,
131 pipelineConnections=DeblendCoaddSourcesMultiConnections):
132 multibandDeblend = ConfigurableField(
133 target=ScarletDeblendTask,
134 doc="Task to deblend an images in multiple bands"
135 )
138class DeblendCoaddSourcesBaseTask(PipelineTask):
139 def __init__(self, initInputs, **kwargs):
140 super().__init__(initInputs=initInputs, **kwargs)
141 schema = initInputs["inputSchema"].schema
142 self.peakSchema = initInputs["peakSchema"].schema
143 self.schemaMapper = afwTable.SchemaMapper(schema)
144 self.schemaMapper.addMinimalSchema(schema)
145 self.schema = self.schemaMapper.getOutputSchema()
147 def runQuantum(self, butlerQC, inputRefs, outputRefs):
148 inputs = butlerQC.get(inputRefs)
149 inputs["idFactory"] = ExposureIdInfo.fromDataId(
150 butlerQC.quantum.dataId,
151 "tract_patch"
152 ).makeSourceIdFactory()
153 outputs = self.run(**inputs)
154 butlerQC.put(outputs, outputRefs)
156 def _makeSourceCatalog(self, mergedDetections, idFactory):
157 table = afwTable.SourceTable.make(self.schema, idFactory)
158 sources = afwTable.SourceCatalog(table)
159 sources.extend(mergedDetections, self.schemaMapper)
160 return sources
163class DeblendCoaddSourcesSingleTask(DeblendCoaddSourcesBaseTask):
164 ConfigClass = DeblendCoaddSourcesSingleConfig
165 _DefaultName = "deblendCoaddSourcesSingle"
167 def __init__(self, initInputs, **kwargs):
168 super().__init__(initInputs=initInputs, **kwargs)
169 self.makeSubtask("singleBandDeblend", schema=self.schema, peakSchema=self.peakSchema)
170 self.outputSchema = afwTable.SourceCatalog(self.schema)
172 def run(self, coadd, mergedDetections, idFactory):
173 sources = self._makeSourceCatalog(mergedDetections, idFactory)
174 self.singleBandDeblend.run(coadd, sources)
175 if not sources.isContiguous():
176 sources = sources.copy(deep=True)
177 return Struct(measureCatalog=sources)
180class DeblendCoaddSourcesMultiTask(DeblendCoaddSourcesBaseTask):
181 ConfigClass = DeblendCoaddSourcesMultiConfig
182 _DefaultName = "deblendCoaddSourcesMulti"
184 def __init__(self, initInputs, **kwargs):
185 super().__init__(initInputs=initInputs, **kwargs)
186 self.makeSubtask("multibandDeblend", schema=self.schema, peakSchema=self.peakSchema)
187 self.outputSchema = afwTable.SourceCatalog(self.schema)
189 def runQuantum(self, butlerQC, inputRefs, outputRefs):
190 inputs = butlerQC.get(inputRefs)
191 exposureIdInfo = ExposureIdInfo.fromDataId(butlerQC.quantum.dataId, "tract_patch")
192 inputs["idFactory"] = exposureIdInfo.makeSourceIdFactory()
193 inputs["filters"] = [dRef.dataId["band"] for dRef in inputRefs.coadds]
194 outputs = self.run(**inputs)
195 sortedTemplateCatalogs = []
196 for outRef in outputRefs.templateCatalogs:
197 band = outRef.dataId['band']
198 sortedTemplateCatalogs.append(outputs.templateCatalogs[band])
199 outputs.templateCatalogs = sortedTemplateCatalogs
200 butlerQC.put(outputs, outputRefs)
202 def run(self, coadds, filters, mergedDetections, idFactory):
203 sources = self._makeSourceCatalog(mergedDetections, idFactory)
204 multiExposure = afwImage.MultibandExposure.fromExposures(filters, coadds)
205 templateCatalogs = self.multibandDeblend.run(multiExposure, sources)
206 retStruct = Struct(templateCatalogs=templateCatalogs)
207 return retStruct