22 from lsst.pipe.base import (Struct, PipelineTask, PipelineTaskConfig, PipelineTaskConnections)
25 from lsst.pex.config
import ConfigurableField
27 from lsst.meas.extensions.scarlet.deblend
import ScarletDeblendTask
32 __all__ = (
"DeblendCoaddSourcesSingleConfig",
"DeblendCoaddSourcesSingleTask",
33 "DeblendCoaddSourcesMultiConfig",
"DeblendCoaddSourcesMultiTask")
36 deblendBaseTemplates = {
"inputCoaddName":
"deep",
"outputCoaddName":
"deep"}
40 dimensions=(
"tract",
"patch",
"abstract_filter",
"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",
"abstract_filter",
"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",
"abstract_filter",
"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",
"abstract_filter",
"skymap")
115 outputSchema = cT.InitOutput(
116 doc=
"Output of the schema used in deblending task",
117 name=
"{outputCoaddName}Coadd_deblendedModel_schema",
118 storageClass=
"SourceCatalog"
120 fluxCatalogs = cT.Output(
121 doc=
"Flux catalogs produced by multiband deblending, not written "
122 "if conserve flux is turned off",
123 name=
"{outputCoaddName}Coadd_deblendedFlux",
124 storageClass=
"SourceCatalog",
125 dimensions=(
"tract",
"patch",
"abstract_filter",
"skymap")
127 templateCatalogs = cT.Output(
128 doc=
"Template catalogs produced by multiband deblending",
129 name=
"{outputCoaddName}Coadd_deblendedModel",
130 storageClass=
"SourceCatalog",
131 dimensions=(
"tract",
"patch",
"abstract_filter",
"skymap")
136 if not config.multibandDeblend.conserveFlux:
141 pipelineConnections=DeblendCoaddSourcesMultiConnections):
142 multibandDeblend = ConfigurableField(
143 target=ScarletDeblendTask,
144 doc=
"Task to deblend an images in multiple bands"
150 super().
__init__(initInputs=initInputs, **kwargs)
151 schema = initInputs[
"inputSchema"].schema
158 inputs = butlerQC.get(inputRefs)
159 packedId, maxBits = butlerQC.quantum.dataId.pack(
"tract_patch", returnMaxBits=
True)
160 inputs[
"idFactory"] = afwTable.IdFactory.makeSource(packedId, 64 - maxBits)
161 outputs = self.
run(**inputs)
162 butlerQC.put(outputs, outputRefs)
164 def _makeSourceCatalog(self, mergedDetections, idFactory):
165 table = afwTable.SourceTable.make(self.
schema, idFactory)
172 ConfigClass = DeblendCoaddSourcesSingleConfig
173 _DefaultName =
"deblendCoaddSourcesSingle"
176 super().
__init__(initInputs=initInputs, **kwargs)
180 def run(self, coadd, mergedDetections, idFactory):
182 self.singleBandDeblend.
run(coadd, sources)
183 if not sources.isContiguous():
184 sources = sources.copy(deep=
True)
185 return Struct(measureCatalog=sources)
189 ConfigClass = DeblendCoaddSourcesMultiConfig
190 _DefaultName =
"deblendCoaddSourcesMulti"
193 super().
__init__(initInputs=initInputs, **kwargs)
198 inputs = butlerQC.get(inputRefs)
199 packedId, maxBits = butlerQC.quantum.dataId.pack(
"tract_patch", returnMaxBits=
True)
200 inputs[
"idFactory"] = afwTable.IdFactory.makeSource(packedId, 64 - maxBits)
201 inputs[
"filters"] = [dRef.dataId[
"abstract_filter"]
for dRef
in inputRefs.coadds]
202 outputs = self.
run(**inputs)
203 butlerQC.put(outputs, outputRefs)
205 def run(self, coadds, filters, mergedDetections, idFactory):
207 multiExposure = afwImage.MultibandExposure.fromExposures(filters, coadds)
208 fluxCatalogs, templateCatalogs = self.multibandDeblend.
run(multiExposure, sources)
209 retStruct =
Struct(templateCatalogs)
210 if self.
config.multibandDeblend.conserveFlux:
211 retStruct.fluxCatalogs = fluxCatalogs