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

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
29import lsst.afw.image as afwImage
30import lsst.afw.table as afwTable
32__all__ = ("DeblendCoaddSourcesSingleConfig", "DeblendCoaddSourcesSingleTask",
33 "DeblendCoaddSourcesMultiConfig", "DeblendCoaddSourcesMultiTask")
36deblendBaseTemplates = {"inputCoaddName": "deep", "outputCoaddName": "deep"}
39class DeblendCoaddSourceSingleConnections(PipelineTaskConnections,
40 dimensions=("tract", "patch", "band", "skymap"),
41 defaultTemplates=deblendBaseTemplates):
42 inputSchema = cT.InitInput(
43 doc="Input schema to use in the deblend catalog",
44 name="{inputCoaddName}Coadd_mergeDet_schema",
45 storageClass="SourceCatalog"
46 )
47 peakSchema = cT.InitInput(
48 doc="Schema of the footprint peak catalogs",
49 name="{inputCoaddName}Coadd_peak_schema",
50 storageClass="PeakCatalog"
51 )
52 mergedDetections = cT.Input(
53 doc="Detection catalog merged across bands",
54 name="{inputCoaddName}Coadd_mergeDet",
55 storageClass="SourceCatalog",
56 dimensions=("tract", "patch", "skymap")
57 )
58 coadd = cT.Input(
59 doc="Exposure on which to run deblending",
60 name="{inputCoaddName}Coadd_calexp",
61 storageClass="ExposureF",
62 dimensions=("tract", "patch", "band", "skymap")
63 )
64 measureCatalog = cT.Output(
65 doc="The output measurement catalog of deblended sources",
66 name="{outputCoaddName}Coadd_deblendedFlux",
67 storageClass="SourceCatalog",
68 dimensions=("tract", "patch", "band", "skymap")
69 )
70 outputSchema = cT.InitOutput(
71 doc="Output of the schema used in deblending task",
72 name="{outputCoaddName}Coadd_deblendedFlux_schema",
73 storageClass="SourceCatalog"
74 )
76 def setDefaults(self):
77 super().setDefaults()
78 self.singleBandDeblend.propagateAllPeaks = True
81class DeblendCoaddSourcesSingleConfig(PipelineTaskConfig,
82 pipelineConnections=DeblendCoaddSourceSingleConnections):
83 singleBandDeblend = ConfigurableField(
84 target=SourceDeblendTask,
85 doc="Task to deblend an image in one band"
86 )
89class DeblendCoaddSourcesMultiConnections(PipelineTaskConnections,
90 dimensions=("tract", "patch", "skymap"),
91 defaultTemplates=deblendBaseTemplates):
92 inputSchema = cT.InitInput(
93 doc="Input schema to use in the deblend catalog",
94 name="{inputCoaddName}Coadd_mergeDet_schema",
95 storageClass="SourceCatalog"
96 )
97 peakSchema = cT.InitInput(
98 doc="Schema of the footprint peak catalogs",
99 name="{inputCoaddName}Coadd_peak_schema",
100 storageClass="PeakCatalog"
101 )
102 mergedDetections = cT.Input(
103 doc="Detection catalog merged across bands",
104 name="{inputCoaddName}Coadd_mergeDet",
105 storageClass="SourceCatalog",
106 dimensions=("tract", "patch", "skymap")
107 )
108 coadds = cT.Input(
109 doc="Exposure on which to run deblending",
110 name="{inputCoaddName}Coadd_calexp",
111 storageClass="ExposureF",
112 multiple=True,
113 dimensions=("tract", "patch", "band", "skymap")
114 )
115 outputSchema = cT.InitOutput(
116 doc="Output of the schema used in deblending task",
117 name="{outputCoaddName}Coadd_deblendedFlux_schema",
118 storageClass="SourceCatalog"
119 )
120 templateCatalogs = cT.Output(
121 doc="Template catalogs produced by multiband deblending",
122 name="{outputCoaddName}Coadd_deblendedFlux",
123 storageClass="SourceCatalog",
124 dimensions=("tract", "patch", "band", "skymap"),
125 multiple=True
126 )
129class DeblendCoaddSourcesMultiConfig(PipelineTaskConfig,
130 pipelineConnections=DeblendCoaddSourcesMultiConnections):
131 multibandDeblend = ConfigurableField(
132 target=ScarletDeblendTask,
133 doc="Task to deblend an images in multiple bands"
134 )
137class DeblendCoaddSourcesBaseTask(PipelineTask):
138 def __init__(self, initInputs, **kwargs):
139 super().__init__(initInputs=initInputs, **kwargs)
140 schema = initInputs["inputSchema"].schema
141 self.peakSchema = initInputs["peakSchema"].schema
142 self.schemaMapper = afwTable.SchemaMapper(schema)
143 self.schemaMapper.addMinimalSchema(schema)
144 self.schema = self.schemaMapper.getOutputSchema()
146 def runQuantum(self, butlerQC, inputRefs, outputRefs):
147 inputs = butlerQC.get(inputRefs)
148 packedId, maxBits = butlerQC.quantum.dataId.pack("tract_patch", returnMaxBits=True)
149 inputs["idFactory"] = afwTable.IdFactory.makeSource(packedId, 64 - maxBits)
150 outputs = self.run(**inputs)
151 butlerQC.put(outputs, outputRefs)
153 def _makeSourceCatalog(self, mergedDetections, idFactory):
154 table = afwTable.SourceTable.make(self.schema, idFactory)
155 sources = afwTable.SourceCatalog(table)
156 sources.extend(mergedDetections, self.schemaMapper)
157 return sources
160class DeblendCoaddSourcesSingleTask(DeblendCoaddSourcesBaseTask):
161 ConfigClass = DeblendCoaddSourcesSingleConfig
162 _DefaultName = "deblendCoaddSourcesSingle"
164 def __init__(self, initInputs, **kwargs):
165 super().__init__(initInputs=initInputs, **kwargs)
166 self.makeSubtask("singleBandDeblend", schema=self.schema, peakSchema=self.peakSchema)
167 self.outputSchema = afwTable.SourceCatalog(self.schema)
169 def run(self, coadd, mergedDetections, idFactory):
170 sources = self._makeSourceCatalog(mergedDetections, idFactory)
171 self.singleBandDeblend.run(coadd, sources)
172 if not sources.isContiguous():
173 sources = sources.copy(deep=True)
174 return Struct(measureCatalog=sources)
177class DeblendCoaddSourcesMultiTask(DeblendCoaddSourcesBaseTask):
178 ConfigClass = DeblendCoaddSourcesMultiConfig
179 _DefaultName = "deblendCoaddSourcesMulti"
181 def __init__(self, initInputs, **kwargs):
182 super().__init__(initInputs=initInputs, **kwargs)
183 self.makeSubtask("multibandDeblend", schema=self.schema, peakSchema=self.peakSchema)
184 self.outputSchema = afwTable.SourceCatalog(self.schema)
186 def runQuantum(self, butlerQC, inputRefs, outputRefs):
187 inputs = butlerQC.get(inputRefs)
188 packedId, maxBits = butlerQC.quantum.dataId.pack("tract_patch", returnMaxBits=True)
189 inputs["idFactory"] = afwTable.IdFactory.makeSource(packedId, 64 - maxBits)
190 inputs["filters"] = [dRef.dataId["band"] for dRef in inputRefs.coadds]
191 outputs = self.run(**inputs)
192 sortedTemplateCatalogs = []
193 for outRef in outputRefs.templateCatalogs:
194 band = outRef.dataId['band']
195 sortedTemplateCatalogs.append(outputs.templateCatalogs[band])
196 outputs.templateCatalogs = sortedTemplateCatalogs
197 butlerQC.put(outputs, outputRefs)
199 def run(self, coadds, filters, mergedDetections, idFactory):
200 sources = self._makeSourceCatalog(mergedDetections, idFactory)
201 multiExposure = afwImage.MultibandExposure.fromExposures(filters, coadds)
202 templateCatalogs = self.multibandDeblend.run(multiExposure, sources)
203 retStruct = Struct(templateCatalogs=templateCatalogs)
204 return retStruct