LSSTApplications  18.0.0+106,18.0.0+50,19.0.0,19.0.0+1,19.0.0+10,19.0.0+11,19.0.0+13,19.0.0+17,19.0.0+2,19.0.0-1-g20d9b18+6,19.0.0-1-g425ff20,19.0.0-1-g5549ca4,19.0.0-1-g580fafe+6,19.0.0-1-g6fe20d0+1,19.0.0-1-g7011481+9,19.0.0-1-g8c57eb9+6,19.0.0-1-gb5175dc+11,19.0.0-1-gdc0e4a7+9,19.0.0-1-ge272bc4+6,19.0.0-1-ge3aa853,19.0.0-10-g448f008b,19.0.0-12-g6990b2c,19.0.0-2-g0d9f9cd+11,19.0.0-2-g3d9e4fb2+11,19.0.0-2-g5037de4,19.0.0-2-gb96a1c4+3,19.0.0-2-gd955cfd+15,19.0.0-3-g2d13df8,19.0.0-3-g6f3c7dc,19.0.0-4-g725f80e+11,19.0.0-4-ga671dab3b+1,19.0.0-4-gad373c5+3,19.0.0-5-ga2acb9c+2,19.0.0-5-gfe96e6c+2,w.2020.01
LSSTDataManagementBasePackage
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 from lsst.pipe.base import (Struct, PipelineTask, PipelineTaskConfig, PipelineTaskConnections)
24 
25 from lsst.pex.config import ConfigurableField
26 from lsst.meas.deblender import SourceDeblendTask, MultibandDeblendTask
27 
28 import lsst.afw.image as afwImage
29 import lsst.afw.table as afwTable
30 
31 __all__ = ("DeblendCoaddSourcesSingleConfig", "DeblendCoaddSourcesSingleTask",
32  "DeblendCoaddSourcesMultiConfig", "DeblendCoaddSourcesMultiTask")
33 
34 
35 deblendBaseTemplates = {"inputCoaddName": "deep", "outputCoaddName": "deep"}
36 
37 
38 class DeblendCoaddSourceSingleConnections(PipelineTaskConnections,
39  dimensions=("tract", "patch", "abstract_filter", "skymap"),
40  defaultTemplates=deblendBaseTemplates):
41  inputSchema = cT.InitInput(
42  doc="Input schema to use in the deblend catalog",
43  name="{inputCoaddName}Coadd_mergeDet_schema",
44  storageClass="SourceCatalog"
45  )
46  peakSchema = cT.InitInput(
47  doc="Schema of the footprint peak catalogs",
48  name="{inputCoaddName}Coadd_peak_schema",
49  storageClass="PeakCatalog"
50  )
51  mergedDetections = cT.Input(
52  doc="Detection catalog merged across bands",
53  name="{inputCoaddName}Coadd_mergeDet",
54  storageClass="SourceCatalog",
55  dimensions=("tract", "patch", "skymap")
56  )
57  coadd = cT.Input(
58  doc="Exposure on which to run deblending",
59  name="{inputCoaddName}Coadd_calexp",
60  storageClass="ExposureF",
61  dimensions=("tract", "patch", "abstract_filter", "skymap")
62  )
63  measureCatalog = cT.Output(
64  doc="The output measurement catalog of deblended sources",
65  name="{outputCoaddName}Coadd_deblendedFlux",
66  storageClass="SourceCatalog",
67  dimensions=("tract", "patch", "abstract_filter", "skymap")
68  )
69  outputSchema = cT.InitOutput(
70  doc="Output of the schema used in deblending task",
71  name="{outputCoaddName}Coadd_deblendedFlux_schema",
72  storageClass="SourceCatalog"
73  )
74 
75  def setDefaults(self):
76  super().setDefaults()
77  self.singleBandDeblend.propagateAllPeaks = True
78 
79 
80 class DeblendCoaddSourcesSingleConfig(PipelineTaskConfig,
81  pipelineConnections=DeblendCoaddSourceSingleConnections):
82  singleBandDeblend = ConfigurableField(
83  target=SourceDeblendTask,
84  doc="Task to deblend an image in one band"
85  )
86 
87 
88 class DeblendCoaddSourcesMultiConnections(PipelineTaskConnections,
89  dimensions=("tract", "patch", "skymap"),
90  defaultTemplates=deblendBaseTemplates):
91  inputSchema = cT.InitInput(
92  doc="Input schema to use in the deblend catalog",
93  name="{inputCoaddName}Coadd_mergeDet_schema",
94  storageClass="SourceCatalog"
95  )
96  peakSchema = cT.InitInput(
97  doc="Schema of the footprint peak catalogs",
98  name="{inputCoaddName}Coadd_peak_schema",
99  storageClass="PeakCatalog"
100  )
101  mergedDetections = cT.Input(
102  doc="Detection catalog merged across bands",
103  name="{inputCoaddName}Coadd_mergeDet",
104  storageClass="SourceCatalog",
105  dimensions=("tract", "patch", "skymap")
106  )
107  coadds = cT.Input(
108  doc="Exposure on which to run deblending",
109  name="{inputCoaddName}Coadd_calexp",
110  storageClass="ExposureF",
111  multiple=True,
112  dimensions=("tract", "patch", "abstract_filter", "skymap")
113  )
114  outputSchema = cT.InitOutput(
115  doc="Output of the schema used in deblending task",
116  name="{outputCoaddName}Coadd_deblendedModel_schema",
117  storageClass="SourceCatalog"
118  )
119  fluxCatalogs = cT.Output(
120  doc="Flux catalogs produced by multiband deblending, not written "
121  "if conserve flux is turned off",
122  name="{outputCoaddName}Coadd_deblendedFlux",
123  storageClass="SourceCatalog",
124  dimensions=("tract", "patch", "abstract_filter", "skymap")
125  )
126  templateCatalogs = cT.Output(
127  doc="Template catalogs produced by multiband deblending",
128  name="{outputCoaddName}Coadd_deblendedModel",
129  storageClass="SourceCatalog",
130  dimensions=("tract", "patch", "abstract_filter", "skymap")
131  )
132 
133  def __init__(self, *, config=None):
134  super().__init__(config=config)
135  if not config.multibandDeblend.conserveFlux:
136  self.outputs -= set(("fluxCatalogs",))
137 
138 
139 class DeblendCoaddSourcesMultiConfig(PipelineTaskConfig,
140  pipelineConnections=DeblendCoaddSourcesMultiConnections):
141  multibandDeblend = ConfigurableField(
142  target=MultibandDeblendTask,
143  doc="Task to deblend an images in multiple bands"
144  )
145 
146 
147 class DeblendCoaddSourcesBaseTask(PipelineTask):
148  def __init__(self, initInputs, **kwargs):
149  super().__init__(initInputs=initInputs, **kwargs)
150  schema = initInputs["inputSchema"].schema
151  self.peakSchema = initInputs["peakSchema"].schema
153  self.schemaMapper.addMinimalSchema(schema)
154  self.schema = self.schemaMapper.getOutputSchema()
155 
156  def runQuantum(self, butlerQC, inputRefs, outputRefs):
157  inputs = butlerQC.get(inputRefs)
158  packedId, maxBits = butlerQC.quantum.dataId.pack("tract_patch", returnMaxBits=True)
159  inputs["idFactory"] = afwTable.IdFactory.makeSource(packedId, 64 - maxBits)
160  outputs = self.run(**inputs)
161  butlerQC.put(outputs, outputRefs)
162 
163  def _makeSourceCatalog(self, mergedDetections, idFactory):
164  table = afwTable.SourceTable.make(self.schema, idFactory)
165  sources = afwTable.SourceCatalog(table)
166  sources.extend(mergedDetections, self.schemaMapper)
167  return sources
168 
169 
171  ConfigClass = DeblendCoaddSourcesSingleConfig
172  _DefaultName = "deblendCoaddSourcesSingle"
173 
174  def __init__(self, initInputs, **kwargs):
175  super().__init__(initInputs=initInputs, **kwargs)
176  self.makeSubtask("singleBandDeblend", schema=self.schema, peakSchema=self.peakSchema)
178 
179  def run(self, coadd, mergedDetections, idFactory):
180  sources = self._makeSourceCatalog(mergedDetections, idFactory)
181  self.singleBandDeblend.run(coadd, sources)
182  if not sources.isContiguous():
183  sources = sources.copy(deep=True)
184  return Struct(measureCatalog=sources)
185 
186 
188  ConfigClass = DeblendCoaddSourcesMultiConfig
189  _DefaultName = "deblendCoaddSourcesMulti"
190 
191  def __init__(self, initInputs, **kwargs):
192  super().__init__(initInputs=initInputs, **kwargs)
193  self.makeSubtask("multibandDeblend", schema=self.schema, peakSchema=self.peakSchema)
195 
196  def runQuantum(self, butlerQC, inputRefs, outputRefs):
197  inputs = butlerQC.get(inputRefs)
198  packedId, maxBits = butlerQC.quantum.dataId.pack("tract_patch", returnMaxBits=True)
199  inputs["idFactory"] = afwTable.IdFactory.makeSource(packedId, 64 - maxBits)
200  inputs["filters"] = [dRef.dataId["abstract_filter"] for dRef in inputRefs.coadds]
201  outputs = self.run(**inputs)
202  butlerQC.put(outputs, outputRefs)
203 
204  def run(self, coadds, filters, mergedDetections, idFactory):
205  sources = self._makeSourceCatalog(mergedDetections, idFactory)
206  multiExposure = afwImage.MultibandExposure.fromExposures(filters, coadds)
207  fluxCatalogs, templateCatalogs = self.multibandDeblend.run(multiExposure, sources)
208  retStruct = Struct(templateCatalogs)
209  if self.config.multibandDeblend.conserveFlux:
210  retStruct.fluxCatalogs = fluxCatalogs
211  return retStruct
A mapping between the keys of two Schemas, used to copy data between them.
Definition: SchemaMapper.h:21
daf::base::PropertySet * set
Definition: fits.cc:902
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects...