lsst.pipe.tasks  13.0-66-gfbf2f2ce+5
transformMeasurement.py
Go to the documentation of this file.
1 #
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 """
23 Tasks for transforming raw measurement outputs to calibrated quantities.
24 """
25 from __future__ import absolute_import, division, print_function
26 import lsst.afw.table as afwTable
27 import lsst.pex.config as pexConfig
28 import lsst.pipe.base as pipeBase
29 
30 
31 def makeContiguous(catalog):
32  """!Return a version of the input catalog which is contiguous in memory."""
33  if not catalog.isContiguous():
34  return catalog.copy(deep=True)
35  else:
36  return catalog
37 
38 
39 class TransformConfig(pexConfig.Config):
40  """!Configuration for TransformTask."""
41  copyFields = pexConfig.ListField(
42  dtype=str,
43  doc="Fields to copy from input to output catalog without transformation",
44  default=('id', 'coord_ra', 'coord_dec')
45  )
46 
47 
53 
54 
55 class TransformTask(pipeBase.Task):
56  """!
57  \anchor TransformTask_
58 
59  \brief Transform a SourceCatalog containing raw measurements to calibrated form.
60 
61  \section pipe_tasks_transform_Contents Contents
62 
63  - \ref pipe_tasks_transform_purpose
64  - \ref pipe_tasks_transform_initialize
65  - \ref pipe_tasks_transform_invoke
66 
67  \section pipe_tasks_transform_purpose Description
68 
69  Given a set of measurement algorithms with their associated configuration,
70  the table of source measurements they have produced, and information about
71  an associated WCS and calibration, transform the raw measurement output to
72  a calibrated form.
73 
74  Transformations are defined on a per-measurement-plugin basis. In
75  addition, a configurable set of fields may be simply copied from the input
76  to the output catalog.
77 
78  This task operates on an input SourceCatalog and returns a BaseCatalog
79  containing the transformed results. It requires that the caller supply
80  information on the configuration of the measurement task which produced
81  the input data as well as the world coordinate system and calibration
82  under which the transformation will take place. It provides no
83  functionality for reading or writing data from a Butler: rather,
84  per-dataset-type command line tasks are provided to obtain the appropriate
85  information from a Butler (or elsewhere) and then delegate to this task.
86 
87  \section pipe_tasks_transform_initialize Task initialization
88 
89  \copydoc \_\_init\_\_
90 
91  \section pipe_tasks_transform_invoke Task invocation
92 
93  \copydoc run
94  """
95  ConfigClass = TransformConfig
96  _DefaultName = "transform"
97 
98  def __init__(self, measConfig, inputSchema, outputDataset, *args, **kwargs):
99  """!Initialize TransformTask.
100 
101  @param[in] measConfig Configuration for the measurement task which
102  produced the measurments being transformed.
103  @param[in] inputSchema The schema of the input catalog.
104  @param[in] outputDataset The butler dataset type of the output catalog.
105  @param[in] *args Passed through to pipeBase.Task.__init__()
106  @param[in] *kwargs Passed through to pipeBase.Task.__init__()
107  """
108  pipeBase.Task.__init__(self, *args, **kwargs)
109 
110  # This task can be used to generate multiple different output dataset types. We
111  # need to be able to specify the output type together with its schema.
112  self.outputDataset = outputDataset
113 
114  # Define a mapper and add the basic fields to be copied.
115  self.mapper = afwTable.SchemaMapper(inputSchema)
116  for field in self.config.copyFields:
117  self.mapper.addMapping(inputSchema.find(field).key)
118 
119  # Build a list of all transforms that will be applied to the input. We
120  # will iterate over this in run().
121  self.transforms = []
122  for name in measConfig.plugins.names:
123  config = measConfig.plugins.get(name)
124  transformClass = measConfig.plugins.registry.get(name).PluginClass.getTransformClass()
125  self.transforms.append(transformClass(config, name, self.mapper))
126 
127  def getSchemaCatalogs(self):
128  """!Return a dict containing an empty catalog representative of this task's output."""
129  transformedSrc = afwTable.BaseCatalog(self.mapper.getOutputSchema())
130  return {self.outputDataset: transformedSrc}
131 
132  def run(self, inputCat, wcs, calib):
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] calib 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, calib)
151  return outputCat
152 
153 
154 class 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 
166 class RunTransformTaskBase(pipeBase.CmdLineTask):
167  """!
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
210  def inputSchemaType(self):
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
230  def measurementConfig(self):
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 run(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  # TODO: pybind11 remove `immediate=True` once DM-9112 is resolved
259  inputCat = dataRef.get(self.sourceType, immediate=True)
260  wcs = dataRef.get(self.calexpType).getWcs()
261  calib = dataRef.get(self.calexpType).getCalib()
262  outputCat = self.transform.run(inputCat, wcs, calib)
263  dataRef.put(outputCat, self.outputDataset)
264  return outputCat
265 
266 
267 
273 
275  """!
276  \anchor SrcTransformTask_
277 
278  \brief Transform ``src`` measuremenents to calibrated form.
279 
280  This is a specialization of \ref RunTransformTaskBase_ "RunTransformTaskBase" which
281  operates on ``src`` measurements. Refer to the parent documentation for details.
282  """
283  _DefaultName = "transformSrcMeasurement"
284  sourceType = 'src'
285  calexpType = 'calexp'
286 
287  @property
288  def measurementConfig(self):
289  return self.butler.get(self.config.inputConfigType).calibrate.measurement.value
290 
291 
292 
298 
300  """!
301  \anchor ForcedSrcTransformTask_
302 
303  \brief Transform ``forced_src`` measuremenents to calibrated form.
304 
305  This is a specialization of \ref RunTransformTaskBase_ "RunTransformTaskBase" which
306  operates on ``forced_src`` measurements. Refer to the parent documentation for details.
307  """
308  _DefaultName = "transformForcedSrcMeasurement"
309  sourceType = 'forced_src'
310  calexpType = 'calexp'
311 
312 
313 
319 
321  """!
322  \anchor CoaddSrcTransformTask_
323 
324  \brief Transform measuremenents made on coadds to calibrated form.
325 
326  This is a specialization of \ref RunTransformTaskBase_ "RunTransformTaskBase" which
327  operates on measurements made on coadds. Refer to the parent documentation for details.
328  """
329  _DefaultName = "transformCoaddSrcMeasurement"
330 
331  @property
332  def coaddName(self):
333  return self.butler.get(self.config.inputConfigType).coaddName
334 
335  @property
336  def sourceType(self):
337  return self.coaddName + "Coadd_meas"
338 
339  @property
340  def calexpType(self):
341  return self.coaddName + "Coadd_calexp"
342 
343  def _getConfigName(self):
344  return "%s_transformCoaddSrcMeasurement_config" % (self.coaddName,)
345 
346  def _getMetaDataName(self):
347  return "%s_transformCoaddSrcMeasurement_metadata" % (self.coaddName,)
Transform a SourceCatalog containing raw measurements to calibrated form.
def getSchemaCatalogs(self)
Return a dict containing an empty catalog representative of this task&#39;s output.
Transform src measuremenents to calibrated form.
def run(self, inputCat, wcs, calib)
Transform raw source measurements to calibrated quantities.
def run(self, dataRef)
Transform the source catalog referred to by dataRef.
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 __init__(self, measConfig, inputSchema, outputDataset, args, kwargs)
Initialize TransformTask.
def makeContiguous(catalog)
Return a version of the input catalog which is contiguous in memory.
Transform forced_src measuremenents to calibrated form.
Configuration for RunTransformTaskBase derivatives.
Transform measuremenents made on coadds to calibrated form.
def outputDataset(self)
The Butler dataset type for the schema of the output catalog.