lsst.pipe.tasks g4a6547c0d5+6fab381471
transformMeasurement.py
Go to the documentation of this file.
2# LSST Data Management System
3# Copyright 2008-2015 AURA/LSST.
4#
5# This product includes software developed by the
6# LSST Project (http://www.lsst.org/).
7#
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation, either version 3 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the LSST License Statement and
19# the GNU General Public License along with this program. If not,
20# see <http://www.lsstcorp.org/LegalNotices/>.
21#
22"""
23Tasks for transforming raw measurement outputs to calibrated quantities.
24"""
25import lsst.afw.table as afwTable
26import lsst.pex.config as pexConfig
27import lsst.pipe.base as pipeBase
28
29
30def makeContiguous(catalog):
31 """!Return a version of the input catalog which is contiguous in memory."""
32 if not catalog.isContiguous():
33 return catalog.copy(deep=True)
34 else:
35 return catalog
36
37
38class TransformConfig(pexConfig.Config):
39 """!Configuration for TransformTask."""
40 copyFields = pexConfig.ListField(
41 dtype=str,
42 doc="Fields to copy from input to output catalog without transformation",
43 default=('id', 'coord_ra', 'coord_dec')
44 )
45
46
52
53
54class TransformTask(pipeBase.Task):
55 r"""!
56 \anchor TransformTask_
57
58 \brief Transform a SourceCatalog containing raw measurements to calibrated form.
59
60 \section pipe_tasks_transform_Contents Contents
61
62 - \ref pipe_tasks_transform_purpose
63 - \ref pipe_tasks_transform_initialize
64 - \ref pipe_tasks_transform_invoke
65
66 \section pipe_tasks_transform_purpose Description
67
68 Given a set of measurement algorithms with their associated configuration,
69 the table of source measurements they have produced, and information about
70 an associated WCS and calibration, transform the raw measurement output to
71 a calibrated form.
72
73 Transformations are defined on a per-measurement-plugin basis. In
74 addition, a configurable set of fields may be simply copied from the input
75 to the output catalog.
76
77 This task operates on an input SourceCatalog and returns a BaseCatalog
78 containing the transformed results. It requires that the caller supply
79 information on the configuration of the measurement task which produced
80 the input data as well as the world coordinate system and calibration
81 under which the transformation will take place. It provides no
82 functionality for reading or writing data from a Butler: rather,
83 per-dataset-type command line tasks are provided to obtain the appropriate
84 information from a Butler (or elsewhere) and then delegate to this task.
85
86 \section pipe_tasks_transform_initialize Task initialization
87
88 \copydoc \_\_init\_\_
89
90 \section pipe_tasks_transform_invoke Task invocation
91
92 \copydoc run
93 """
94 ConfigClass = TransformConfig
95 _DefaultName = "transform"
96
97 def __init__(self, measConfig, inputSchema, outputDataset, *args, **kwargs):
98 """!Initialize TransformTask.
99
100 @param[in] measConfig Configuration for the measurement task which
101 produced the measurments being transformed.
102 @param[in] inputSchema The schema of the input catalog.
103 @param[in] outputDataset The butler dataset type of the output catalog.
104 @param[in] *args Passed through to pipeBase.Task.__init__()
105 @param[in] *kwargs Passed through to pipeBase.Task.__init__()
106 """
107 pipeBase.Task.__init__(self, *args, **kwargs)
108
109 # This task can be used to generate multiple different output dataset types. We
110 # need to be able to specify the output type together with its schema.
111 self.outputDataset = outputDataset
112
113 # Define a mapper and add the basic fields to be copied.
114 self.mapper = afwTable.SchemaMapper(inputSchema)
115 for field in self.config.copyFields:
116 self.mapper.addMapping(inputSchema.find(field).key)
117
118 # Build a list of all transforms that will be applied to the input. We
119 # will iterate over this in run().
120 self.transforms = []
121 for name in measConfig.plugins.names:
122 config = measConfig.plugins.get(name)
123 transformClass = measConfig.plugins.registry.get(name).PluginClass.getTransformClass()
124 self.transforms.append(transformClass(config, name, self.mapper))
125
127 """!Return a dict containing an empty catalog representative of this task's output."""
128 transformedSrc = afwTable.BaseCatalog(self.mapper.getOutputSchema())
129 return {self.outputDataset: transformedSrc}
130
131 @pipeBase.timeMethod
132 def run(self, inputCat, wcs, photoCalib):
133 """!Transform raw source measurements to calibrated quantities.
134
135 @param[in] inputCat SourceCatalog of sources to transform.
136 @param[in] wcs The world coordinate system under which transformations will take place.
137 @param[in] photoCalib The calibration under which transformations will take place.
138
139 @return A BaseCatalog containing the transformed measurements.
140 """
141 outputCat = afwTable.BaseCatalog(self.mapper.getOutputSchema())
142 outputCat.extend(inputCat, mapper=self.mapper)
143
144 # Transforms may use a ColumnView on the input and output catalogs,
145 # which requires that the data be contiguous in memory.
146 inputCat = makeContiguous(inputCat)
147 outputCat = makeContiguous(outputCat)
148
149 for transform in self.transforms:
150 transform(inputCat, outputCat, wcs, photoCalib)
151 return outputCat
152
153
154class RunTransformConfig(pexConfig.Config):
155 """!Configuration for RunTransformTaskBase derivatives."""
156 transform = pexConfig.ConfigurableField(
157 doc="Subtask which performs transformations",
158 target=TransformTask
159 )
160 inputConfigType = pexConfig.Field(
161 dtype=str,
162 doc="Dataset type of measurement operation configuration",
163 )
164
165
166class RunTransformTaskBase(pipeBase.CmdLineTask):
167 r"""!
168 \anchor RunTransformTaskBase_
169
170 \brief Command line interface for TransformTask.
171
172 \section pipe_tasks_transform_Contents Contents
173
174 - \ref pipe_tasks_runtransform_purpose
175 - \ref pipe_tasks_runtransform_invoke
176
177 \section pipe_tasks_runtransform_purpose Description
178
179 Provides a command-line task which can be used to run TransformTask.
180
181 - Loads a plugin registry based on configuration;
182 - Loads configuration for the measurement task which was applied from a repository;
183 - Loads the SourceCatalog input schema from a repository;
184 - For each input dataRef, reads the SourceCatalog, WCS and calibration from the
185 repository and executes TransformTask.
186
187 This is not a fully-fledged command line task: it requires specialization to a particular
188 source type by defining the variables indicated below.
189
190 \section pipe_tasks_runtransform_invoke Task invocation
191
192 \copydoc run
193 """
194 RunnerClass = pipeBase.ButlerInitializedTaskRunner
195 ConfigClass = RunTransformConfig
196
197 # Subclasses should provide definitions for the attributes named below.
198 # Properties can be used if appropriate.
199 #
200 # Standard CmdLineTask attributes:
201 _DefaultName = None
202
203 # Butler dataset type of the source type to be transformed ("src", "forced_src", etc):
204 sourceType = None
205
206 # Butler dataset type of the calibration exposure to use when transforming ("calexp", etc):
207 calexpType = None
208
209 @property
211 """!
212 The Butler dataset type for the schema of the input source catalog.
213
214 By default, we append `_schema` to the input source type. Subclasses may customize
215 if required.
216 """
217 return self.sourceType + "_schema"
218
219 @property
220 def outputDataset(self):
221 """!
222 The Butler dataset type for the schema of the output catalog.
223
224 By default, we prepend `transformed_` to the input source type. Subclasses may
225 customize if required.
226 """
227 return 'transformed_' + self.sourceType
228
229 @property
231 """!
232 The configuration of the measurement operation used to generate the input catalog.
233
234 By default we look for `measurement` under the root configuration of the
235 generating task. Subclasses may customize this (e.g. to `calibrate.measurement`)
236 if required.
237 """
238 return self.butler.get(self.config.inputConfigType).measurement.value
239
240 def __init__(self, *args, **kwargs):
241 pipeBase.CmdLineTask.__init__(self, *args, config=kwargs['config'], log=kwargs['log'])
242 self.butler = kwargs['butler']
243 self.makeSubtask('transform', measConfig=self.measurementConfig,
244 inputSchema=self.butler.get(self.inputSchemaType).schema,
245 outputDataset=self.outputDataset)
246
247 @pipeBase.timeMethod
248 def runDataRef(self, dataRef):
249 """!Transform the source catalog referred to by dataRef.
250
251 The result is both returned and written as dataset type "transformed_" + the input
252 source dataset type to the provided dataRef.
253
254 @param[in] dataRef Data reference for source catalog & calibrated exposure.
255
256 @returns A BaseCatalog containing the transformed measurements.
257 """
258 inputCat = dataRef.get(self.sourceType)
259 wcs = dataRef.get(self.calexpType).getWcs()
260 photoCalib = dataRef.get(self.calexpType).getPhotoCalib()
261 outputCat = self.transform.run(inputCat, wcs, photoCalib)
262 dataRef.put(outputCat, self.outputDataset)
263 return outputCat
264
265
266
272
274 """!
275 \anchor SrcTransformTask_
276
277 \brief Transform ``src`` measuremenents to calibrated form.
278
279 This is a specialization of \ref RunTransformTaskBase_ "RunTransformTaskBase" which
280 operates on ``src`` measurements. Refer to the parent documentation for details.
281 """
282 _DefaultName = "transformSrcMeasurement"
283 sourceType = 'src'
284 calexpType = 'calexp'
285
286 @property
288 return self.butler.get(self.config.inputConfigType).calibrate.measurement.value
289
290
291
297
299 """!
300 \anchor ForcedSrcTransformTask_
301
302 \brief Transform ``forced_src`` measuremenents to calibrated form.
303
304 This is a specialization of \ref RunTransformTaskBase_ "RunTransformTaskBase" which
305 operates on ``forced_src`` measurements. Refer to the parent documentation for details.
306 """
307 _DefaultName = "transformForcedSrcMeasurement"
308 sourceType = 'forced_src'
309 calexpType = 'calexp'
310
311
312
318
320 """!
321 \anchor CoaddSrcTransformTask_
322
323 \brief Transform measuremenents made on coadds to calibrated form.
324
325 This is a specialization of \ref RunTransformTaskBase_ "RunTransformTaskBase" which
326 operates on measurements made on coadds. Refer to the parent documentation for details.
327 """
328 _DefaultName = "transformCoaddSrcMeasurement"
329
330 @property
331 def coaddName(self):
332 return self.butler.get(self.config.inputConfigType).coaddName
333
334 @property
335 def sourceType(self):
336 return self.coaddName + "Coadd_meas"
337
338 @property
339 def calexpType(self):
340 return self.coaddName + "Coadd_calexp"
341
342 def _getConfigName(self):
343 return "%s_transformCoaddSrcMeasurement_config" % (self.coaddName,)
344
345 def _getMetaDataName(self):
346 return "%s_transformCoaddSrcMeasurement_metadata" % (self.coaddName,)
Configuration for RunTransformTaskBase derivatives.
def inputSchemaType(self)
The Butler dataset type for the schema of the input source catalog.
def measurementConfig(self)
The configuration of the measurement operation used to generate the input catalog.
def outputDataset(self)
The Butler dataset type for the schema of the output catalog.
def runDataRef(self, dataRef)
Transform the source catalog referred to by dataRef.
def measurementConfig(self)
The configuration of the measurement operation used to generate the input catalog.
def run(self, inputCat, wcs, photoCalib)
Transform raw source measurements to calibrated quantities.
def __init__(self, measConfig, inputSchema, outputDataset, *args, **kwargs)
Initialize TransformTask.
def getSchemaCatalogs(self)
Return a dict containing an empty catalog representative of this task's output.
def makeContiguous(catalog)
Return a version of the input catalog which is contiguous in memory.