Hide keyboard shortcuts

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/>. 

21 

22from lsst.pipe.base import (Struct, PipelineTask, PipelineTaskConfig, PipelineTaskConnections) 

23import lsst.pipe.base.connectionTypes as cT 

24 

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 

29 

30import lsst.afw.image as afwImage 

31import lsst.afw.table as afwTable 

32 

33__all__ = ("DeblendCoaddSourcesSingleConfig", "DeblendCoaddSourcesSingleTask", 

34 "DeblendCoaddSourcesMultiConfig", "DeblendCoaddSourcesMultiTask") 

35 

36 

37deblendBaseTemplates = {"inputCoaddName": "deep", "outputCoaddName": "deep"} 

38 

39 

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 ) 

76 

77 def setDefaults(self): 

78 super().setDefaults() 

79 self.singleBandDeblend.propagateAllPeaks = True 

80 

81 

82class DeblendCoaddSourcesSingleConfig(PipelineTaskConfig, 

83 pipelineConnections=DeblendCoaddSourceSingleConnections): 

84 singleBandDeblend = ConfigurableField( 

85 target=SourceDeblendTask, 

86 doc="Task to deblend an image in one band" 

87 ) 

88 

89 

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 ) 

128 

129 

130class DeblendCoaddSourcesMultiConfig(PipelineTaskConfig, 

131 pipelineConnections=DeblendCoaddSourcesMultiConnections): 

132 multibandDeblend = ConfigurableField( 

133 target=ScarletDeblendTask, 

134 doc="Task to deblend an images in multiple bands" 

135 ) 

136 

137 

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() 

146 

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) 

155 

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 

161 

162 

163class DeblendCoaddSourcesSingleTask(DeblendCoaddSourcesBaseTask): 

164 ConfigClass = DeblendCoaddSourcesSingleConfig 

165 _DefaultName = "deblendCoaddSourcesSingle" 

166 

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) 

171 

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) 

178 

179 

180class DeblendCoaddSourcesMultiTask(DeblendCoaddSourcesBaseTask): 

181 ConfigClass = DeblendCoaddSourcesMultiConfig 

182 _DefaultName = "deblendCoaddSourcesMulti" 

183 

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) 

188 

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) 

201 

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