23 """Measurement transformations. 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. 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 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. 44 Transformations can be defined in Python or in C++. Python code should inherit 45 from `MeasurementTransform`, following its interface. 47 from builtins
import zip
48 from builtins
import object
50 from lsst.afw.table
import CoordKey
51 from lsst.pex.exceptions
import LengthError
52 from .
import CentroidResultKey
54 __all__ = (
"NullTransform",
"PassThroughTransform",
"SimpleCentroidTransform")
59 Base class for measurement transformations. 61 Create transformations by deriving from this class, implementing 62 `__call__()` and (optionally) augmenting `__init__()`. 69 def __call__(self, inputCatalog, outputCatalog, wcs, calib):
70 raise NotImplementedError()
73 def _checkCatalogSize(cat1, cat2):
74 if len(cat1) != len(cat2):
75 raise LengthError(
"Catalog size mismatch")
80 The null transform transfers no data from input to output. 82 This is intended as the default for measurements for which no other 83 transformation is specified. 86 def __call__(self, inputCatalog, outputCatalog, wcs, calib):
92 Copy all fields named after the measurement plugin from input to output, without transformation. 96 MeasurementTransform.__init__(self, config, name, mapper)
97 for key, field
in mapper.getInputSchema().extract(name +
"*").values():
98 mapper.addMapping(key)
100 def __call__(self, inputCatalog, outputCatalog, wcs, calib):
106 Transform a pixel centroid, excluding uncertainties, to celestial coordinates. 110 MeasurementTransform.__init__(self, config, name, mapper)
111 self.
coordKey = CoordKey.addFields(mapper.editOutputSchema(), name,
"Position from " + name)
113 def __call__(self, inputCatalog, outputCatalog, wcs, calib):
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()))