lsst.meas.base  14.0-17-g4f4ea82
transforms.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 #
3 # LSST Data Management System
4 # Copyright 2008-2015 AURA/LSST.
5 #
6 # This product includes software developed by the
7 # LSST Project (http://www.lsst.org/).
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 LSST License Statement and
20 # the GNU General Public License along with this program. If not,
21 # see <http://www.lsstcorp.org/LegalNotices/>.
22 #
23 """Measurement transformations.
24 
25 When a measurement plugin is run, it provides raw, uncalibrated outputs such
26 as pixel positions. A transformation may be run as a post-processing step to
27 convert those outputs to calibrated quantities, such as celestial coordinates.
28 
29 At construction, the transformation is passed the configuration and name of
30 the plugin whose outputs it will be transformaing (all fields in the input
31 table produced by that plugin will have their field names prefixed by the
32 plugin name) and a `SchemaMapper` which holds the schemata for the input and
33 output catalogs and which may be used to directly map fields between the
34 catalogs.
35 
36 When a transformer is called, it is handed a `SourceCatalog` containing the
37 measurements to be transformed, a `BaseCatalog` in which to store results, and
38 information about the WCS and calibration of the data. It may be safely
39 assumed that both are contiguous in memory, thus a ColumnView may be used for
40 efficient processing. If the transformation is not possible, it should be
41 aborted by throwing an exception; if this happens, the caller should
42 assume that the contents of the output catalog are inconsistent.
43 
44 Transformations can be defined in Python or in C++. Python code should inherit
45 from `MeasurementTransform`, following its interface.
46 """
47 from builtins import zip
48 from builtins import object
49 
50 from lsst.afw.table import CoordKey
51 from lsst.pex.exceptions import LengthError
52 from . import CentroidResultKey
53 
54 __all__ = ("NullTransform", "PassThroughTransform", "SimpleCentroidTransform")
55 
56 
57 class MeasurementTransform(object):
58  """!
59  Base class for measurement transformations.
60 
61  Create transformations by deriving from this class, implementing
62  `__call__()` and (optionally) augmenting `__init__()`.
63  """
64 
65  def __init__(self, config, name, mapper):
66  self.name = name
67  self.config = config
68 
69  def __call__(self, inputCatalog, outputCatalog, wcs, calib):
70  raise NotImplementedError()
71 
72  @staticmethod
73  def _checkCatalogSize(cat1, cat2):
74  if len(cat1) != len(cat2):
75  raise LengthError("Catalog size mismatch")
76 
77 
79  """!
80  The null transform transfers no data from input to output.
81 
82  This is intended as the default for measurements for which no other
83  transformation is specified.
84  """
85 
86  def __call__(self, inputCatalog, outputCatalog, wcs, calib):
87  self._checkCatalogSize(inputCatalog, outputCatalog)
88 
89 
91  """!
92  Copy all fields named after the measurement plugin from input to output, without transformation.
93  """
94 
95  def __init__(self, config, name, mapper):
96  MeasurementTransform.__init__(self, config, name, mapper)
97  for key, field in mapper.getInputSchema().extract(name + "*").values():
98  mapper.addMapping(key)
99 
100  def __call__(self, inputCatalog, outputCatalog, wcs, calib):
101  self._checkCatalogSize(inputCatalog, outputCatalog)
102 
103 
105  """!
106  Transform a pixel centroid, excluding uncertainties, to celestial coordinates.
107  """
108 
109  def __init__(self, config, name, mapper):
110  MeasurementTransform.__init__(self, config, name, mapper)
111  self.coordKey = CoordKey.addFields(mapper.editOutputSchema(), name, "Position from " + name)
112 
113  def __call__(self, inputCatalog, outputCatalog, wcs, calib):
114  self._checkCatalogSize(inputCatalog, outputCatalog)
115  centroidResultKey = CentroidResultKey(inputCatalog.schema[self.name])
116  for inSrc, outSrc in zip(inputCatalog, outputCatalog):
117  self.coordKey.set(outSrc, wcs.pixelToSky(centroidResultKey.get(inSrc).getCentroid()))
def __call__(self, inputCatalog, outputCatalog, wcs, calib)
Definition: transforms.py:86
Copy all fields named after the measurement plugin from input to output, without transformation.
Definition: transforms.py:90
def __call__(self, inputCatalog, outputCatalog, wcs, calib)
Definition: transforms.py:69
The null transform transfers no data from input to output.
Definition: transforms.py:78
def __init__(self, config, name, mapper)
Definition: transforms.py:95
def __call__(self, inputCatalog, outputCatalog, wcs, calib)
Definition: transforms.py:113
def __init__(self, config, name, mapper)
Definition: transforms.py:65
Base class for measurement transformations.
Definition: transforms.py:57
def __init__(self, config, name, mapper)
Definition: transforms.py:109
Transform a pixel centroid, excluding uncertainties, to celestial coordinates.
Definition: transforms.py:104
def __call__(self, inputCatalog, outputCatalog, wcs, calib)
Definition: transforms.py:100