22 from lsst.pipe.base import (Struct, PipelineTask, PipelineTaskConfig, PipelineTaskConnections)
27 from lsst.meas.extensions.scarlet
import ScarletDeblendTask
32 __all__ = (
"DeblendCoaddSourcesSingleConfig",
"DeblendCoaddSourcesSingleTask",
33 "DeblendCoaddSourcesMultiConfig",
"DeblendCoaddSourcesMultiTask")
36 deblendBaseTemplates = {
"inputCoaddName":
"deep",
"outputCoaddName":
"deep"}
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"
47 peakSchema = cT.InitInput(
48 doc=
"Schema of the footprint peak catalogs",
49 name=
"{inputCoaddName}Coadd_peak_schema",
50 storageClass=
"PeakCatalog"
52 mergedDetections = cT.Input(
53 doc=
"Detection catalog merged across bands",
54 name=
"{inputCoaddName}Coadd_mergeDet",
55 storageClass=
"SourceCatalog",
56 dimensions=(
"tract",
"patch",
"skymap")
59 doc=
"Exposure on which to run deblending",
60 name=
"{inputCoaddName}Coadd_calexp",
61 storageClass=
"ExposureF",
62 dimensions=(
"tract",
"patch",
"band",
"skymap")
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")
70 outputSchema = cT.InitOutput(
71 doc=
"Output of the schema used in deblending task",
72 name=
"{outputCoaddName}Coadd_deblendedFlux_schema",
73 storageClass=
"SourceCatalog"
78 self.singleBandDeblend.propagateAllPeaks =
True
82 pipelineConnections=DeblendCoaddSourceSingleConnections):
83 singleBandDeblend = ConfigurableField(
84 target=SourceDeblendTask,
85 doc=
"Task to deblend an image in one band"
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"
97 peakSchema = cT.InitInput(
98 doc=
"Schema of the footprint peak catalogs",
99 name=
"{inputCoaddName}Coadd_peak_schema",
100 storageClass=
"PeakCatalog"
102 mergedDetections = cT.Input(
103 doc=
"Detection catalog merged across bands",
104 name=
"{inputCoaddName}Coadd_mergeDet",
105 storageClass=
"SourceCatalog",
106 dimensions=(
"tract",
"patch",
"skymap")
109 doc=
"Exposure on which to run deblending",
110 name=
"{inputCoaddName}Coadd_calexp",
111 storageClass=
"ExposureF",
113 dimensions=(
"tract",
"patch",
"band",
"skymap")
115 outputSchema = cT.InitOutput(
116 doc=
"Output of the schema used in deblending task",
117 name=
"{outputCoaddName}Coadd_deblendedFlux_schema",
118 storageClass=
"SourceCatalog"
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"),
130 pipelineConnections=DeblendCoaddSourcesMultiConnections):
131 multibandDeblend = ConfigurableField(
132 target=ScarletDeblendTask,
133 doc=
"Task to deblend an images in multiple bands"
139 super().
__init__(initInputs=initInputs, **kwargs)
140 schema = initInputs[
"inputSchema"].schema
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)
161 ConfigClass = DeblendCoaddSourcesSingleConfig
162 _DefaultName =
"deblendCoaddSourcesSingle"
165 super().
__init__(initInputs=initInputs, **kwargs)
166 self.makeSubtask(
"singleBandDeblend", schema=self.
schema, peakSchema=self.
peakSchema)
169 def run(self, coadd, mergedDetections, idFactory):
171 self.singleBandDeblend.
run(coadd, sources)
172 if not sources.isContiguous():
173 sources = sources.copy(deep=
True)
174 return Struct(measureCatalog=sources)
178 ConfigClass = DeblendCoaddSourcesMultiConfig
179 _DefaultName =
"deblendCoaddSourcesMulti"
182 super().
__init__(initInputs=initInputs, **kwargs)
183 self.makeSubtask(
"multibandDeblend", schema=self.
schema, peakSchema=self.
peakSchema)
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):
201 multiExposure = afwImage.MultibandExposure.fromExposures(filters, coadds)
202 templateCatalogs = self.multibandDeblend.
run(multiExposure, sources)
203 retStruct = Struct(templateCatalogs=templateCatalogs)