22"""Definition of measurement plugins.
24This module defines and registers a series of pure-Python measurement plugins
25which have trivial implementations. It also wraps measurement algorithms
26defined in C++ to expose them to the measurement framework.
36from ._measBaseLib
import (ApertureFluxControl, ApertureFluxTransform,
37 BaseTransform, BlendednessAlgorithm,
38 BlendednessControl, CircularApertureFluxAlgorithm,
39 GaussianFluxAlgorithm, GaussianFluxControl,
40 GaussianFluxTransform, LocalBackgroundAlgorithm,
41 LocalBackgroundControl, LocalBackgroundTransform,
42 MeasurementError, NaiveCentroidAlgorithm,
43 NaiveCentroidControl, NaiveCentroidTransform,
44 PeakLikelihoodFluxAlgorithm,
45 PeakLikelihoodFluxControl,
46 PeakLikelihoodFluxTransform, PixelFlagsAlgorithm,
47 PixelFlagsControl, PsfFluxAlgorithm, PsfFluxControl,
48 PsfFluxTransform, ScaledApertureFluxAlgorithm,
49 ScaledApertureFluxControl,
50 ScaledApertureFluxTransform, SdssCentroidAlgorithm,
51 SdssCentroidControl, SdssCentroidTransform,
52 SdssShapeAlgorithm, SdssShapeControl,
54from .baseMeasurement
import BaseMeasurementPluginConfig
55from .forcedMeasurement
import ForcedPlugin, ForcedPluginConfig
56from .pluginRegistry
import register
57from .pluginsBase
import BasePlugin
58from .sfm
import SingleFramePlugin, SingleFramePluginConfig
59from .transforms
import SimpleCentroidTransform
60from .wrappers
import GenericPlugin, wrapSimpleAlgorithm, wrapTransform
63 "SingleFrameFPPositionConfig",
"SingleFrameFPPositionPlugin",
64 "SingleFrameJacobianConfig",
"SingleFrameJacobianPlugin",
65 "VarianceConfig",
"SingleFrameVariancePlugin",
"ForcedVariancePlugin",
66 "InputCountConfig",
"SingleFrameInputCountPlugin",
"ForcedInputCountPlugin",
67 "SingleFramePeakCentroidConfig",
"SingleFramePeakCentroidPlugin",
68 "SingleFrameSkyCoordConfig",
"SingleFrameSkyCoordPlugin",
69 "SingleFrameMomentsClassifierConfig",
"SingleFrameMomentsClassifierPlugin",
70 "ForcedPeakCentroidConfig",
"ForcedPeakCentroidPlugin",
71 "ForcedTransformedCentroidConfig",
"ForcedTransformedCentroidPlugin",
72 "ForcedTransformedCentroidFromCoordConfig",
73 "ForcedTransformedCentroidFromCoordPlugin",
74 "ForcedTransformedShapeConfig",
"ForcedTransformedShapePlugin",
75 "EvaluateLocalPhotoCalibPlugin",
"EvaluateLocalPhotoCalibPluginConfig",
76 "EvaluateLocalWcsPlugin",
"EvaluateLocalWcsPluginConfig",
80wrapSimpleAlgorithm(PsfFluxAlgorithm, Control=PsfFluxControl,
81 TransformClass=PsfFluxTransform, executionOrder=BasePlugin.FLUX_ORDER,
82 shouldApCorr=
True, hasLogName=
True)
83wrapSimpleAlgorithm(PeakLikelihoodFluxAlgorithm, Control=PeakLikelihoodFluxControl,
84 TransformClass=PeakLikelihoodFluxTransform, executionOrder=BasePlugin.FLUX_ORDER)
85wrapSimpleAlgorithm(GaussianFluxAlgorithm, Control=GaussianFluxControl,
86 TransformClass=GaussianFluxTransform, executionOrder=BasePlugin.FLUX_ORDER,
88wrapSimpleAlgorithm(NaiveCentroidAlgorithm, Control=NaiveCentroidControl,
89 TransformClass=NaiveCentroidTransform, executionOrder=BasePlugin.CENTROID_ORDER)
90wrapSimpleAlgorithm(SdssCentroidAlgorithm, Control=SdssCentroidControl,
91 TransformClass=SdssCentroidTransform, executionOrder=BasePlugin.CENTROID_ORDER)
92wrapSimpleAlgorithm(PixelFlagsAlgorithm, Control=PixelFlagsControl,
93 executionOrder=BasePlugin.FLUX_ORDER)
94wrapSimpleAlgorithm(SdssShapeAlgorithm, Control=SdssShapeControl,
95 TransformClass=SdssShapeTransform, executionOrder=BasePlugin.SHAPE_ORDER)
96wrapSimpleAlgorithm(ScaledApertureFluxAlgorithm, Control=ScaledApertureFluxControl,
97 TransformClass=ScaledApertureFluxTransform, executionOrder=BasePlugin.FLUX_ORDER)
99wrapSimpleAlgorithm(CircularApertureFluxAlgorithm, needsMetadata=
True, Control=ApertureFluxControl,
100 TransformClass=ApertureFluxTransform, executionOrder=BasePlugin.FLUX_ORDER)
101wrapSimpleAlgorithm(BlendednessAlgorithm, Control=BlendednessControl,
102 TransformClass=BaseTransform, executionOrder=BasePlugin.SHAPE_ORDER)
104wrapSimpleAlgorithm(LocalBackgroundAlgorithm, Control=LocalBackgroundControl,
105 TransformClass=LocalBackgroundTransform, executionOrder=BasePlugin.FLUX_ORDER)
107wrapTransform(PsfFluxTransform)
108wrapTransform(PeakLikelihoodFluxTransform)
109wrapTransform(GaussianFluxTransform)
110wrapTransform(NaiveCentroidTransform)
111wrapTransform(SdssCentroidTransform)
112wrapTransform(SdssShapeTransform)
113wrapTransform(ScaledApertureFluxTransform)
114wrapTransform(ApertureFluxTransform)
115wrapTransform(LocalBackgroundTransform)
119 """Configuration for the focal plane position measurment algorithm.
123@register(
"base_FPPosition")
125 """Algorithm to calculate the position of a centroid on the focal plane.
129 config : `SingleFrameFPPositionConfig`
133 schema : `lsst.afw.table.Schema`
134 The schema for the measurement output catalog. New fields will be
135 added to hold measurements produced by this plugin.
136 metadata : `lsst.daf.base.PropertySet`
137 Plugin metadata that will be attached to the output catalog
140 ConfigClass = SingleFrameFPPositionConfig
146 def __init__(self, config, name, schema, metadata):
147 SingleFramePlugin.__init__(self, config, name, schema, metadata)
148 self.
focalValue = lsst.afw.table.Point2DKey.addFields(schema, name,
"Position on the focal plane",
150 self.
focalFlag = schema.addField(name +
"_flag", type=
"Flag", doc=
"Set to True for any fatal failure")
151 self.
detectorFlag = schema.addField(name +
"_missingDetector_flag", type=
"Flag",
152 doc=
"Set to True if detector object is missing")
155 det = exposure.getDetector()
160 center = measRecord.getCentroid()
161 fp = det.transform(center, lsst.afw.cameraGeom.PIXELS, lsst.afw.cameraGeom.FOCAL_PLANE)
164 def fail(self, measRecord, error=None):
169 """Configuration for the Jacobian calculation plugin.
175@register("base_Jacobian")
177 """Compute the Jacobian and its ratio with a nominal pixel area.
179 This enables one to compare relative, rather than absolute, pixel areas.
183 config : `SingleFrameJacobianConfig`
187 schema : `lsst.afw.table.Schema`
188 The schema for the measurement output catalog. New fields will be
189 added to hold measurements produced by this plugin.
190 metadata : `lsst.daf.base.PropertySet`
191 Plugin metadata that will be attached to the output catalog
194 ConfigClass = SingleFrameJacobianConfig
200 def __init__(self, config, name, schema, metadata):
201 SingleFramePlugin.__init__(self, config, name, schema, metadata)
202 self.
jacValue = schema.addField(name +
'_value', type=
"D", doc=
"Jacobian correction")
203 self.
jacFlag = schema.addField(name +
'_flag', type=
"Flag", doc=
"Set to 1 for any fatal failure")
208 center = measRecord.getCentroid()
211 result = np.abs(self.
scale*exposure.getWcs().linearizePixelToSky(
213 lsst.geom.arcseconds).getLinear().computeDeterminant())
214 measRecord.set(self.
jacValue, result)
216 def fail(self, measRecord, error=None):
217 measRecord.set(self.
jacFlag,
True)
221 """Configuration for the variance calculation plugin.
224 doc=
"Scale factor to apply to shape for aperture")
226 default=[
"DETECTED",
"DETECTED_NEGATIVE",
"BAD",
"SAT"])
230 """Compute the median variance corresponding to a footprint.
232 The aim here is to measure the background variance, rather than that of
233 the object itself. In order to achieve this, the variance is calculated
234 over an area scaled up from the shape of the input footprint.
238 config : `VarianceConfig`
242 schema : `lsst.afw.table.Schema`
243 The schema for the measurement output catalog. New fields will be
244 added to hold measurements produced by this plugin.
245 metadata : `lsst.daf.base.PropertySet`
246 Plugin metadata that will be attached to the output catalog
249 ConfigClass = VarianceConfig
251 FAILURE_BAD_CENTROID = 1
252 """Denotes failures due to bad centroiding (`int`).
255 FAILURE_EMPTY_FOOTPRINT = 2
256 """Denotes failures due to a lack of usable pixels (`int`).
261 return BasePlugin.FLUX_ORDER
263 def __init__(self, config, name, schema, metadata):
264 GenericPlugin.__init__(self, config, name, schema, metadata)
265 self.
varValue = schema.addField(name +
'_value', type=
"D", doc=
"Variance at object position")
267 doc=
"Set to True when the footprint has no usable pixels")
272 schema.getAliasMap().
set(name +
'_flag_badCentroid', schema.getAliasMap().apply(
"slot_Centroid_flag"))
274 def measure(self, measRecord, exposure, center):
278 if not np.all(np.isfinite(measRecord.getCentroid())):
281 aperture.scale(self.
config.scale)
284 foot.clipTo(exposure.getBBox(lsst.afw.image.PARENT))
287 maskedImage = exposure.getMaskedImage()
289 maskBits = maskedImage.getMask().getPlaneBitMask(self.
config.mask)
290 logicalMask = np.logical_not(pixels.getMaskArray() & maskBits)
295 if np.any(logicalMask):
296 medVar = np.median(pixels.getVarianceArray()[logicalMask])
297 measRecord.set(self.
varValue, medVar)
299 raise MeasurementError(
"Footprint empty, or all pixels are masked, can't compute median",
302 def fail(self, measRecord, error=None):
305 if isinstance(error, MeasurementError):
310 measRecord.set(self.
varValue, np.nan)
311 GenericPlugin.fail(self, measRecord, error)
314SingleFrameVariancePlugin = VariancePlugin.makeSingleFramePlugin(
"base_Variance")
315"""Single-frame version of `VariancePlugin`.
318ForcedVariancePlugin = VariancePlugin.makeForcedPlugin(
"base_Variance")
319"""Forced version of `VariancePlugin`.
324 """Configuration for the input image counting plugin.
328class InputCountPlugin(GenericPlugin):
329 """Count the number of input images which contributed to a source.
333 config : `InputCountConfig`
334 Plugin configuration.
337 schema : `lsst.afw.table.Schema`
338 The schema for the measurement output catalog. New fields will be
339 added to hold measurements produced by this plugin.
340 metadata : `lsst.daf.base.PropertySet`
341 Plugin metadata that will be attached to the output catalog
345 Information is derived from the image's `~lsst.afw.image.CoaddInputs`.
346 Note these limitation:
348 - This records the number of images which contributed to the pixel in the
349 center of the source footprint, rather than to any or all pixels in the
351 - Clipping in the coadd is not taken into account.
354 ConfigClass = InputCountConfig
356 FAILURE_BAD_CENTROID = 1
357 """Denotes failures due to bad centroiding (`int`).
360 FAILURE_NO_INPUTS = 2
361 """Denotes failures due to the image not having coadd inputs. (`int`)
366 return BasePlugin.SHAPE_ORDER
368 def __init__(self, config, name, schema, metadata):
369 GenericPlugin.__init__(self, config, name, schema, metadata)
370 self.
numberKey = schema.addField(name +
'_value', type=
"I",
371 doc=
"Number of images contributing at center, not including any"
373 self.
noInputsFlag = schema.addField(name +
'_flag_noInputs', type=
"Flag",
374 doc=
"No coadd inputs available")
377 schema.getAliasMap().
set(name +
'_flag_badCentroid', schema.getAliasMap().apply(
"slot_Centroid_flag"))
379 def measure(self, measRecord, exposure, center):
380 if not exposure.getInfo().getCoaddInputs():
382 if not np.all(np.isfinite(center)):
385 ccds = exposure.getInfo().getCoaddInputs().ccds
386 measRecord.set(self.
numberKey, len(ccds.subsetContaining(center, exposure.getWcs())))
388 def fail(self, measRecord, error=None):
389 if error
is not None:
394 GenericPlugin.fail(self, measRecord, error)
397SingleFrameInputCountPlugin = InputCountPlugin.makeSingleFramePlugin(
"base_InputCount")
398"""Single-frame version of `InputCoutPlugin`.
401ForcedInputCountPlugin = InputCountPlugin.makeForcedPlugin(
"base_InputCount")
402"""Forced version of `InputCoutPlugin`.
407 """Configuration for the variance calculation plugin.
411class EvaluateLocalPhotoCalibPlugin(GenericPlugin):
412 """Evaluate the local value of the Photometric Calibration in the exposure.
414 The aim is to store the local calib value within the catalog for later
415 use in the Science Data Model functors.
417 ConfigClass = EvaluateLocalPhotoCalibPluginConfig
421 return BasePlugin.FLUX_ORDER
423 def __init__(self, config, name, schema, metadata):
424 GenericPlugin.__init__(self, config, name, schema, metadata)
428 doc=
"Local approximation of the PhotoCalib calibration factor at "
429 "the location of the src.")
433 doc=
"Error on the local approximation of the PhotoCalib "
434 "calibration factor at the location of the src.")
436 def measure(self, measRecord, exposure, center):
438 photoCalib = exposure.getPhotoCalib()
439 calib = photoCalib.getLocalCalibration(center)
440 measRecord.set(self.
photoKey, calib)
442 calibErr = photoCalib.getCalibrationErr()
446SingleFrameEvaluateLocalPhotoCalibPlugin = EvaluateLocalPhotoCalibPlugin.makeSingleFramePlugin(
447 "base_LocalPhotoCalib")
448"""Single-frame version of `EvaluatePhotoCalibPlugin`.
451ForcedEvaluateLocalPhotoCalibPlugin = EvaluateLocalPhotoCalibPlugin.makeForcedPlugin(
452 "base_LocalPhotoCalib")
453"""Forced version of `EvaluatePhotoCalibPlugin`.
458 """Configuration for the variance calculation plugin.
462class EvaluateLocalWcsPlugin(GenericPlugin):
463 """Evaluate the local, linear approximation of the Wcs.
465 The aim is to store the local calib value within the catalog for later
466 use in the Science Data Model functors.
468 ConfigClass = EvaluateLocalWcsPluginConfig
469 _scale = (1.0 * lsst.geom.arcseconds).asDegrees()
473 return BasePlugin.FLUX_ORDER
475 def __init__(self, config, name, schema, metadata):
476 GenericPlugin.__init__(self, config, name, schema, metadata)
478 f
"{name}_CDMatrix_1_1",
480 doc=
"(1, 1) element of the CDMatrix for the linear approximation "
481 "of the WCS at the src location. Gives units in radians.")
483 f
"{name}_CDMatrix_1_2",
485 doc=
"(1, 2) element of the CDMatrix for the linear approximation "
486 "of the WCS at the src location. Gives units in radians.")
488 f
"{name}_CDMatrix_2_1",
490 doc=
"(2, 1) element of the CDMatrix for the linear approximation "
491 "of the WCS at the src location. Gives units in radians.")
493 f
"{name}_CDMatrix_2_2",
495 doc=
"(2, 2) element of the CDMatrix for the linear approximation "
496 "of the WCS at the src location. Gives units in radians.")
498 def measure(self, measRecord, exposure, center):
499 wcs = exposure.getWcs()
507 """Create a local, linear approximation of the wcs transformation
510 The approximation is created as if the center is at RA=0, DEC=0. All
511 comparing x,y coordinate are relative to the position of center. Matrix
512 is initially calculated with units arcseconds and then converted to
513 radians. This yields higher precision results due to quirks in AST.
517 wcs : `lsst.afw.geom.SkyWcs`
519 center : `lsst.geom.Point2D`
520 Point at which to evaluate the LocalWcs.
524 localMatrix : `numpy.ndarray`
525 Matrix representation the local wcs approximation with units
528 skyCenter = wcs.pixelToSky(center)
531 measurementToLocalGnomonic = wcs.getTransform().then(
532 localGnomonicWcs.getTransform().inverted()
534 localMatrix = measurementToLocalGnomonic.getJacobian(center)
535 return np.radians(localMatrix / 3600)
538SingleFrameEvaluateLocalWcsPlugin = EvaluateLocalWcsPlugin.makeSingleFramePlugin(
"base_LocalWcs")
539"""Single-frame version of `EvaluateLocalWcsPlugin`.
542ForcedEvaluateLocalWcsPlugin = EvaluateLocalWcsPlugin.makeForcedPlugin(
"base_LocalWcs")
543"""Forced version of `EvaluateLocalWcsPlugin`.
548 """Configuration for the single frame peak centroiding algorithm.
552@register(
"base_PeakCentroid")
554 """Record the highest peak in a source footprint as its centroid.
556 This is of course a relatively poor measure of the true centroid of the
557 object; this algorithm is provided mostly for testing and debugging.
561 config : `SingleFramePeakCentroidConfig`
565 schema : `lsst.afw.table.Schema`
566 The schema for the measurement output catalog. New fields will be
567 added to hold measurements produced by this plugin.
568 metadata : `lsst.daf.base.PropertySet`
569 Plugin metadata that will be attached to the output catalog
572 ConfigClass = SingleFramePeakCentroidConfig
578 def __init__(self, config, name, schema, metadata):
579 SingleFramePlugin.__init__(self, config, name, schema, metadata)
580 self.
keyX = schema.addField(name +
"_x", type=
"D", doc=
"peak centroid", units=
"pixel")
581 self.
keyY = schema.addField(name +
"_y", type=
"D", doc=
"peak centroid", units=
"pixel")
582 self.
flag = schema.addField(name +
"_flag", type=
"Flag", doc=
"Centroiding failed")
585 peak = measRecord.getFootprint().getPeaks()[0]
586 measRecord.set(self.
keyX, peak.getFx())
587 measRecord.set(self.
keyY, peak.getFy())
589 def fail(self, measRecord, error=None):
590 measRecord.set(self.
flag,
True)
594 return SimpleCentroidTransform
598 """Configuration for the sky coordinates algorithm.
602@register(
"base_SkyCoord")
604 """Record the sky position of an object based on its centroid slot and WCS.
606 The position is record in the ``coord`` field, which is part of the
607 `~lsst.afw.table.SourceCatalog` minimal schema.
611 config : `SingleFrameSkyCoordConfig`
615 schema : `lsst.afw.table.Schema`
616 The schema for the measurement output catalog. New fields will be
617 added to hold measurements produced by this plugin.
618 metadata : `lsst.daf.base.PropertySet`
619 Plugin metadata that will be attached to the output catalog
622 ConfigClass = SingleFrameSkyCoordConfig
632 if not exposure.hasWcs():
633 raise RuntimeError(
"Wcs not attached to exposure. Required for " + self.
name +
" algorithm")
634 measRecord.updateCoord(exposure.getWcs())
636 def fail(self, measRecord, error=None):
644class SingleFrameMomentsClassifierConfig(SingleFramePluginConfig):
645 """Configuration for moments-based star-galaxy classifier."""
648 doc=
"Exponent to raise the PSF size squared (Ixx + Iyy) to, "
649 "in the likelihood normalization",
654@register("base_ClassificationSizeExtendedness")
656 """Classify objects by comparing their moments-based trace radius to PSF's.
658 The plugin computes chi^2 as ((T_obj - T_psf)/T_psf^exponent)^2, where
659 T_obj is the sum of Ixx and Iyy moments of the object, and T_psf is the
660 sum of Ixx and Iyy moments of the PSF. The exponent is configurable.
661 The measure of being a galaxy is then 1 - exp(-0.5*chi^2).
665 config : `MomentsClassifierConfig`
666 Plugin configuration.
669 schema : `~lsst.afw.table.Schema`
670 The schema for the measurement output catalog. New fields will be
671 added to hold measurements produced by this plugin.
672 metadata : `~lsst.daf.base.PropertySet`
673 Plugin metadata that will be attached to the output catalog.
677 The ``measure`` method of the plugin requires a value for the ``exposure``
678 argument to maintain consistent API, but it is not used in the measurement.
681 ConfigClass = SingleFrameMomentsClassifierConfig
687 def __init__(self, config, name, schema, metadata):
688 SingleFramePlugin.__init__(self, config, name, schema, metadata)
689 self.
key = schema.addField(name +
"_value",
691 doc=
"Measure of being a galaxy based on trace of second order moments",
693 self.
flag = schema.addField(name +
"_flag", type=
"Flag", doc=
"Moments-based classification failed")
695 def measure(self, measRecord, exposure) -> None:
698 if measRecord.getShapeFlag():
699 raise MeasurementError(
"Shape flag is set. Required for " + self.
name +
" algorithm")
701 shape = measRecord.getShape()
702 psf_shape = measRecord.getPsfShape()
706 ixx_psf = psf_shape.getIxx()
707 iyy_psf = psf_shape.getIyy()
710 psf_t = ixx_psf + iyy_psf
712 chi_sq = ((object_t - psf_t)/(psf_t**self.
config.exponent))**2.
713 likelihood = 1. - np.exp(-0.5*chi_sq)
714 measRecord.set(self.
key, likelihood)
716 def fail(self, measRecord, error=None) -> None:
718 measRecord.set(self.
key, np.nan)
719 measRecord.set(self.
flag,
True)
723 """Configuration for the forced peak centroid algorithm.
727@register(
"base_PeakCentroid")
729 """Record the highest peak in a source footprint as its centroid.
731 This is of course a relatively poor measure of the true centroid of the
732 object; this algorithm is provided mostly for testing and debugging.
734 This is similar to `SingleFramePeakCentroidPlugin`, except that transforms
735 the peak coordinate from the original (reference) coordinate system to the
736 coordinate system of the exposure being measured.
740 config : `ForcedPeakCentroidConfig`
744 schemaMapper : `lsst.afw.table.SchemaMapper`
745 A mapping from reference catalog fields to output
746 catalog fields. Output fields are added to the output schema.
747 metadata : `lsst.daf.base.PropertySet`
748 Plugin metadata that will be attached to the output catalog.
751 ConfigClass = ForcedPeakCentroidConfig
757 def __init__(self, config, name, schemaMapper, metadata):
758 ForcedPlugin.__init__(self, config, name, schemaMapper, metadata)
759 schema = schemaMapper.editOutputSchema()
760 self.
keyX = schema.addField(name +
"_x", type=
"D", doc=
"peak centroid", units=
"pixel")
761 self.
keyY = schema.addField(name +
"_y", type=
"D", doc=
"peak centroid", units=
"pixel")
763 def measure(self, measRecord, exposure, refRecord, refWcs):
764 targetWcs = exposure.getWcs()
765 peak = refRecord.getFootprint().getPeaks()[0]
767 result = targetWcs.skyToPixel(refWcs.pixelToSky(result))
768 measRecord.set(self.
keyX, result.getX())
769 measRecord.set(self.
keyY, result.getY())
773 return SimpleCentroidTransform
777 """Configuration for the forced transformed centroid algorithm.
781@register(
"base_TransformedCentroid")
783 """Record the transformation of the reference catalog centroid.
785 The centroid recorded in the reference catalog is tranformed to the
786 measurement coordinate system and stored.
790 config : `ForcedTransformedCentroidConfig`
794 schemaMapper : `lsst.afw.table.SchemaMapper`
795 A mapping from reference catalog fields to output
796 catalog fields. Output fields are added to the output schema.
797 metadata : `lsst.daf.base.PropertySet`
798 Plugin metadata that will be attached to the output catalog.
802 This is used as the slot centroid by default in forced measurement,
803 allowing subsequent measurements to simply refer to the slot value just as
804 they would in single-frame measurement.
807 ConfigClass = ForcedTransformedCentroidConfig
813 def __init__(self, config, name, schemaMapper, metadata):
814 ForcedPlugin.__init__(self, config, name, schemaMapper, metadata)
815 schema = schemaMapper.editOutputSchema()
817 xKey = schema.addField(name +
"_x", type=
"D", doc=
"transformed reference centroid column",
819 yKey = schema.addField(name +
"_y", type=
"D", doc=
"transformed reference centroid row",
825 if "slot_Centroid_flag" in schemaMapper.getInputSchema():
826 self.
flagKey = schema.addField(name +
"_flag", type=
"Flag",
827 doc=
"whether the reference centroid is marked as bad")
831 def measure(self, measRecord, exposure, refRecord, refWcs):
832 targetWcs = exposure.getWcs()
833 if not refWcs == targetWcs:
834 targetPos = targetWcs.skyToPixel(refWcs.pixelToSky(refRecord.getCentroid()))
837 measRecord.set(self.
centroidKey, refRecord.getCentroid())
839 measRecord.set(self.
flagKey, refRecord.getCentroidFlag())
843 """Configuration for the forced transformed coord algorithm.
847@register(
"base_TransformedCentroidFromCoord")
849 """Record the transformation of the reference catalog coord.
851 The coord recorded in the reference catalog is tranformed to the
852 measurement coordinate system and stored.
856 config : `ForcedTransformedCentroidFromCoordConfig`
860 schemaMapper : `lsst.afw.table.SchemaMapper`
861 A mapping from reference catalog fields to output
862 catalog fields. Output fields are added to the output schema.
863 metadata : `lsst.daf.base.PropertySet`
864 Plugin metadata that will be attached to the output catalog.
868 This can be used as the slot centroid in forced measurement when only a
869 reference coord exist, allowing subsequent measurements to simply refer to
870 the slot value just as they would in single-frame measurement.
873 ConfigClass = ForcedTransformedCentroidFromCoordConfig
875 def measure(self, measRecord, exposure, refRecord, refWcs):
876 targetWcs = exposure.getWcs()
878 targetPos = targetWcs.skyToPixel(refRecord.getCoord())
886 """Configuration for the forced transformed shape algorithm.
890@register(
"base_TransformedShape")
892 """Record the transformation of the reference catalog shape.
894 The shape recorded in the reference catalog is tranformed to the
895 measurement coordinate system and stored.
899 config : `ForcedTransformedShapeConfig`
903 schemaMapper : `lsst.afw.table.SchemaMapper`
904 A mapping from reference catalog fields to output
905 catalog fields. Output fields are added to the output schema.
906 metadata : `lsst.daf.base.PropertySet`
907 Plugin metadata that will be attached to the output catalog.
911 This is used as the slot shape by default in forced measurement, allowing
912 subsequent measurements to simply refer to the slot value just as they
913 would in single-frame measurement.
916 ConfigClass = ForcedTransformedShapeConfig
922 def __init__(self, config, name, schemaMapper, metadata):
923 ForcedPlugin.__init__(self, config, name, schemaMapper, metadata)
924 schema = schemaMapper.editOutputSchema()
926 xxKey = schema.addField(name +
"_xx", type=
"D", doc=
"transformed reference shape x^2 moment",
928 yyKey = schema.addField(name +
"_yy", type=
"D", doc=
"transformed reference shape y^2 moment",
930 xyKey = schema.addField(name +
"_xy", type=
"D", doc=
"transformed reference shape xy moment",
936 if "slot_Shape_flag" in schemaMapper.getInputSchema():
937 self.
flagKey = schema.addField(name +
"_flag", type=
"Flag",
938 doc=
"whether the reference shape is marked as bad")
942 def measure(self, measRecord, exposure, refRecord, refWcs):
943 targetWcs = exposure.getWcs()
944 if not refWcs == targetWcs:
947 measRecord.set(self.
shapeKey, refRecord.getShape().transform(localTransform.getLinear()))
949 measRecord.set(self.
shapeKey, refRecord.getShape())
951 measRecord.set(self.
flagKey, refRecord.getShapeFlag())
static std::shared_ptr< geom::SpanSet > fromShape(int r, Stencil s=Stencil::CIRCLE, lsst::geom::Point2I offset=lsst::geom::Point2I())
Factory function for creating SpanSets from a Stencil.
An ellipse defined by an arbitrary BaseCore and a center point.
A FunctorKey used to get or set a geom::ellipses::Quadrupole from a tuple of constituent Keys.
__init__(self, config, name, schema, metadata)
measure(self, measRecord, exposure, center)
__init__(self, config, name, schema, metadata)
measure(self, measRecord, exposure, center)
makeLocalTransformMatrix(self, wcs, center)
measure(self, measRecord, exposure, refRecord, refWcs)
__init__(self, config, name, schemaMapper, metadata)
fail(self, measRecord, error=None)
measure(self, measRecord, exposure)
__init__(self, config, name, schema, metadata)
measure(self, measRecord, exposure)
fail(self, measRecord, error=None)
__init__(self, config, name, schema, metadata)
__init__(self, config, name, schema, metadata)
None measure(self, measRecord, exposure)
None fail(self, measRecord, error=None)
fail(self, measRecord, error=None)
__init__(self, config, name, schema, metadata)
measure(self, measRecord, exposure)
fail(self, measRecord, error=None)
measure(self, measRecord, exposure)
int FAILURE_EMPTY_FOOTPRINT
__init__(self, config, name, schema, metadata)
fail(self, measRecord, error=None)
measure(self, measRecord, exposure, center)
daf::base::PropertySet * set
HeavyFootprint< ImagePixelT, MaskPixelT, VariancePixelT > makeHeavyFootprint(Footprint const &foot, lsst::afw::image::MaskedImage< ImagePixelT, MaskPixelT, VariancePixelT > const &img, HeavyFootprintCtrl const *ctrl=nullptr)
Create a HeavyFootprint with footprint defined by the given Footprint and pixel values from the given...
std::shared_ptr< SkyWcs > makeSkyWcs(daf::base::PropertySet &metadata, bool strip=false)
Construct a SkyWcs from FITS keywords.
std::shared_ptr< TransformPoint2ToPoint2 > makeWcsPairTransform(SkyWcs const &src, SkyWcs const &dst)
A Transform obtained by putting two SkyWcs objects "back to back".
lsst::geom::AffineTransform linearizeTransform(TransformPoint2ToPoint2 const &original, lsst::geom::Point2D const &inPoint)
Approximate a Transform by its local linearization.