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.
37from deprecated.sphinx
import deprecated
38from ._measBaseLib
import (ApertureFluxControl, ApertureFluxTransform,
39 BaseTransform, BlendednessAlgorithm,
40 BlendednessControl, CircularApertureFluxAlgorithm,
41 GaussianFluxAlgorithm, GaussianFluxControl,
42 GaussianFluxTransform, LocalBackgroundAlgorithm,
43 LocalBackgroundControl, LocalBackgroundTransform,
45 PeakLikelihoodFluxAlgorithm,
46 PeakLikelihoodFluxControl,
47 PeakLikelihoodFluxTransform, PixelFlagsAlgorithm,
48 PixelFlagsControl, PsfFluxAlgorithm, PsfFluxControl,
49 PsfFluxTransform, ScaledApertureFluxAlgorithm,
50 ScaledApertureFluxControl,
51 ScaledApertureFluxTransform, SdssCentroidAlgorithm,
52 SdssCentroidControl, SdssCentroidTransform,
53 SdssShapeAlgorithm, SdssShapeControl,
56from .baseMeasurement
import BaseMeasurementPluginConfig
57from .forcedMeasurement
import ForcedPlugin, ForcedPluginConfig
58from .pluginRegistry
import register
59from .pluginsBase
import BasePlugin
60from .sfm
import SingleFramePlugin, SingleFramePluginConfig
61from .transforms
import SimpleCentroidTransform
62from .wrappers
import GenericPlugin, wrapSimpleAlgorithm, wrapTransform
65 "SingleFrameFPPositionConfig",
"SingleFrameFPPositionPlugin",
66 "SingleFrameJacobianConfig",
"SingleFrameJacobianPlugin",
67 "VarianceConfig",
"SingleFrameVariancePlugin",
"ForcedVariancePlugin",
68 "InputCountConfig",
"SingleFrameInputCountPlugin",
"ForcedInputCountPlugin",
69 "SingleFramePeakCentroidConfig",
"SingleFramePeakCentroidPlugin",
70 "SingleFrameSkyCoordConfig",
"SingleFrameSkyCoordPlugin",
71 "SingleFrameMomentsClassifierConfig",
"SingleFrameMomentsClassifierPlugin",
72 "SingleFrameClassificationSizeExtendednessConfig",
73 "SingleFrameClassificationSizeExtendednessPlugin",
74 "ForcedPeakCentroidConfig",
"ForcedPeakCentroidPlugin",
75 "ForcedTransformedCentroidConfig",
"ForcedTransformedCentroidPlugin",
76 "ForcedTransformedCentroidFromCoordConfig",
77 "ForcedTransformedCentroidFromCoordPlugin",
78 "ForcedTransformedShapeConfig",
"ForcedTransformedShapePlugin",
79 "EvaluateLocalPhotoCalibPlugin",
"EvaluateLocalPhotoCalibPluginConfig",
80 "EvaluateLocalWcsPlugin",
"EvaluateLocalWcsPluginConfig",
85 TransformClass=PsfFluxTransform, executionOrder=BasePlugin.FLUX_ORDER,
86 shouldApCorr=
True, hasLogName=
True)
88 TransformClass=PeakLikelihoodFluxTransform, executionOrder=BasePlugin.FLUX_ORDER)
90 TransformClass=GaussianFluxTransform, executionOrder=BasePlugin.FLUX_ORDER,
93 TransformClass=SdssCentroidTransform, executionOrder=BasePlugin.CENTROID_ORDER)
95 executionOrder=BasePlugin.FLUX_ORDER)
97 TransformClass=SdssShapeTransform, executionOrder=BasePlugin.SHAPE_ORDER)
99 TransformClass=ScaledApertureFluxTransform, executionOrder=BasePlugin.FLUX_ORDER)
102 TransformClass=ApertureFluxTransform, executionOrder=BasePlugin.FLUX_ORDER)
104 TransformClass=BaseTransform, executionOrder=BasePlugin.SHAPE_ORDER)
107 TransformClass=LocalBackgroundTransform, executionOrder=BasePlugin.FLUX_ORDER)
118log = logging.getLogger(__name__)
122 """Configuration for the focal plane position measurment algorithm.
128 """Algorithm to calculate the position of a centroid on the focal plane.
132 config : `SingleFrameFPPositionConfig`
136 schema : `lsst.afw.table.Schema`
137 The schema for the measurement output catalog. New fields will be
138 added to hold measurements produced by this plugin.
139 metadata : `lsst.daf.base.PropertySet`
140 Plugin metadata that will be attached to the output catalog
143 ConfigClass = SingleFrameFPPositionConfig
149 def __init__(self, config, name, schema, metadata):
150 SingleFramePlugin.__init__(self, config, name, schema, metadata)
151 self.
focalValue = lsst.afw.table.Point2DKey.addFields(schema, name,
"Position on the focal plane",
153 self.
focalFlag = schema.addField(name +
"_flag", type=
"Flag", doc=
"Set to True for any fatal failure")
154 self.
detectorFlag = schema.addField(name +
"_missingDetector_flag", type=
"Flag",
155 doc=
"Set to True if detector object is missing")
158 det = exposure.getDetector()
163 center = measRecord.getCentroid()
164 fp = det.transform(center, lsst.afw.cameraGeom.PIXELS, lsst.afw.cameraGeom.FOCAL_PLANE)
167 def fail(self, measRecord, error=None):
172 """Configuration for the Jacobian calculation plugin.
175 pixelScale = lsst.pex.config.Field(dtype=float, default=0.5, doc=
"Nominal pixel size (arcsec)")
178@register("base_Jacobian")
180 """Compute the Jacobian and its ratio with a nominal pixel area.
182 This enables one to compare relative, rather than absolute, pixel areas.
186 config : `SingleFrameJacobianConfig`
190 schema : `lsst.afw.table.Schema`
191 The schema for the measurement output catalog. New fields will be
192 added to hold measurements produced by this plugin.
193 metadata : `lsst.daf.base.PropertySet`
194 Plugin metadata that will be attached to the output catalog
197 ConfigClass = SingleFrameJacobianConfig
203 def __init__(self, config, name, schema, metadata):
204 SingleFramePlugin.__init__(self, config, name, schema, metadata)
205 self.
jacValue = schema.addField(name +
'_value', type=
"D", doc=
"Jacobian correction")
206 self.
jacFlag = schema.addField(name +
'_flag', type=
"Flag", doc=
"Set to 1 for any fatal failure")
212 center = measRecord.getCentroid()
215 result = np.abs(self.
scale*exposure.getWcs().linearizePixelToSky(
217 lsst.geom.arcseconds).getLinear().computeDeterminant())
218 measRecord.set(self.
jacValue, result)
220 def fail(self, measRecord, error=None):
221 measRecord.set(self.
jacFlag,
True)
225 """Configuration for the variance calculation plugin.
227 scale = lsst.pex.config.Field(dtype=float, default=5.0, optional=
True,
228 doc=
"Scale factor to apply to shape for aperture")
229 mask = lsst.pex.config.ListField(doc=
"Mask planes to ignore", dtype=str,
230 default=[
"DETECTED",
"DETECTED_NEGATIVE",
"BAD",
"SAT"])
234 """Compute the median variance corresponding to a footprint.
236 The aim here is to measure the background variance, rather than that of
237 the object itself. In order to achieve this, the variance is calculated
238 over an area scaled up from the shape of the input footprint.
242 config : `VarianceConfig`
246 schema : `lsst.afw.table.Schema`
247 The schema for the measurement output catalog. New fields will be
248 added to hold measurements produced by this plugin.
249 metadata : `lsst.daf.base.PropertySet`
250 Plugin metadata that will be attached to the output catalog
253 ConfigClass = VarianceConfig
255 FAILURE_BAD_CENTROID = 1
256 """Denotes failures due to bad centroiding (`int`).
259 FAILURE_EMPTY_FOOTPRINT = 2
260 """Denotes failures due to a lack of usable pixels (`int`).
265 return BasePlugin.FLUX_ORDER
267 def __init__(self, config, name, schema, metadata):
268 GenericPlugin.__init__(self, config, name, schema, metadata)
269 self.
varValue = schema.addField(name +
'_value', type=
"D", doc=
"Variance at object position")
271 doc=
"Set to True when the footprint has no usable pixels")
276 schema.getAliasMap().set(name +
'_flag_badCentroid', schema.getAliasMap().apply(
"slot_Centroid_flag"))
278 def measure(self, measRecord, exposure, center):
282 if not np.all(np.isfinite(measRecord.getCentroid())):
284 aperture = lsst.afw.geom.Ellipse(measRecord.getShape(), measRecord.getCentroid())
285 aperture.scale(self.
config.scale)
288 foot.clipTo(exposure.getBBox(lsst.afw.image.PARENT))
291 maskedImage = exposure.getMaskedImage()
293 maskBits = maskedImage.getMask().getPlaneBitMask(self.
config.mask)
294 logicalMask = np.logical_not(pixels.getMaskArray() & maskBits)
299 if np.any(logicalMask):
300 medVar = np.median(pixels.getVarianceArray()[logicalMask])
301 measRecord.set(self.
varValue, medVar)
303 raise MeasurementError(
"Footprint empty, or all pixels are masked, can't compute median",
306 def fail(self, measRecord, error=None):
309 if isinstance(error, MeasurementError):
314 measRecord.set(self.
varValue, np.nan)
315 GenericPlugin.fail(self, measRecord, error)
318SingleFrameVariancePlugin = VariancePlugin.makeSingleFramePlugin(
"base_Variance")
319"""Single-frame version of `VariancePlugin`.
322ForcedVariancePlugin = VariancePlugin.makeForcedPlugin(
"base_Variance")
323"""Forced version of `VariancePlugin`.
328 """Configuration for the input image counting plugin.
332class InputCountPlugin(GenericPlugin):
333 """Count the number of input images which contributed to a source.
337 config : `InputCountConfig`
338 Plugin configuration.
341 schema : `lsst.afw.table.Schema`
342 The schema for the measurement output catalog. New fields will be
343 added to hold measurements produced by this plugin.
344 metadata : `lsst.daf.base.PropertySet`
345 Plugin metadata that will be attached to the output catalog
349 Information is derived from the image's `~lsst.afw.image.CoaddInputs`.
350 Note these limitation:
352 - This records the number of images which contributed to the pixel in the
353 center of the source footprint, rather than to any or all pixels in the
355 - Clipping in the coadd is not taken into account.
358 ConfigClass = InputCountConfig
360 FAILURE_BAD_CENTROID = 1
361 """Denotes failures due to bad centroiding (`int`).
364 FAILURE_NO_INPUTS = 2
365 """Denotes failures due to the image not having coadd inputs. (`int`)
370 return BasePlugin.SHAPE_ORDER
372 def __init__(self, config, name, schema, metadata):
373 GenericPlugin.__init__(self, config, name, schema, metadata)
374 self.
numberKey = schema.addField(name +
'_value', type=
"I",
375 doc=
"Number of images contributing at center, not including any"
377 self.
noInputsFlag = schema.addField(name +
'_flag_noInputs', type=
"Flag",
378 doc=
"No coadd inputs available")
382 schema.getAliasMap().set(name +
'_flag_badCentroid', schema.getAliasMap().apply(
"slot_Centroid_flag"))
384 def measure(self, measRecord, exposure, center):
385 if not (coaddInputs := exposure.getInfo().getCoaddInputs()):
387 if not np.all(np.isfinite(center)):
390 count = len(coaddInputs.subset_containing_ccds(center, exposure.wcs))
393 def fail(self, measRecord, error=None):
394 if error
is not None:
399 GenericPlugin.fail(self, measRecord, error)
402SingleFrameInputCountPlugin = InputCountPlugin.makeSingleFramePlugin(
"base_InputCount")
403"""Single-frame version of `InputCoutPlugin`.
406ForcedInputCountPlugin = InputCountPlugin.makeForcedPlugin(
"base_InputCount")
407"""Forced version of `InputCoutPlugin`.
412 """Configuration for the variance calculation plugin.
416class EvaluateLocalPhotoCalibPlugin(GenericPlugin):
417 """Evaluate the local value of the Photometric Calibration in the exposure.
419 The aim is to store the local calib value within the catalog for later
420 use in the Science Data Model functors.
422 ConfigClass = EvaluateLocalPhotoCalibPluginConfig
426 return BasePlugin.FLUX_ORDER
428 def __init__(self, config, name, schema, metadata):
429 GenericPlugin.__init__(self, config, name, schema, metadata)
433 doc=
"Local approximation of the PhotoCalib calibration factor at "
434 "the location of the src.")
438 doc=
"Error on the local approximation of the PhotoCalib "
439 "calibration factor at the location of the src.")
441 def measure(self, measRecord, exposure, center):
442 photoCalib = exposure.getPhotoCalib()
443 if photoCalib
is None:
445 "%s: photoCalib is None. Setting localPhotoCalib to NaN for record %d",
453 calib = photoCalib.getLocalCalibration(center)
454 calibErr = photoCalib.getCalibrationErr()
455 measRecord.set(self.
photoKey, calib)
459SingleFrameEvaluateLocalPhotoCalibPlugin = EvaluateLocalPhotoCalibPlugin.makeSingleFramePlugin(
460 "base_LocalPhotoCalib")
461"""Single-frame version of `EvaluatePhotoCalibPlugin`.
464ForcedEvaluateLocalPhotoCalibPlugin = EvaluateLocalPhotoCalibPlugin.makeForcedPlugin(
465 "base_LocalPhotoCalib")
466"""Forced version of `EvaluatePhotoCalibPlugin`.
471 """Configuration for the variance calculation plugin.
475class EvaluateLocalWcsPlugin(GenericPlugin):
476 """Evaluate the local, linear approximation of the Wcs.
478 The aim is to store the local calib value within the catalog for later
479 use in the Science Data Model functors.
481 ConfigClass = EvaluateLocalWcsPluginConfig
482 _scale = (1.0 * lsst.geom.arcseconds).asDegrees()
486 return BasePlugin.FLUX_ORDER
488 def __init__(self, config, name, schema, metadata):
489 GenericPlugin.__init__(self, config, name, schema, metadata)
491 f
"{name}_CDMatrix_1_1",
493 doc=
"(1, 1) element of the CDMatrix for the linear approximation "
494 "of the WCS at the src location. Gives units in radians.")
496 f
"{name}_CDMatrix_1_2",
498 doc=
"(1, 2) element of the CDMatrix for the linear approximation "
499 "of the WCS at the src location. Gives units in radians.")
501 f
"{name}_CDMatrix_2_1",
503 doc=
"(2, 1) element of the CDMatrix for the linear approximation "
504 "of the WCS at the src location. Gives units in radians.")
506 f
"{name}_CDMatrix_2_2",
508 doc=
"(2, 2) element of the CDMatrix for the linear approximation "
509 "of the WCS at the src location. Gives units in radians.")
511 def measure(self, measRecord, exposure, center):
512 wcs = exposure.getWcs()
515 "%s: WCS is None. Setting localWcs matrix values to NaN for record %d",
519 localMatrix = np.array([[np.nan, np.nan], [np.nan, np.nan]])
529 """Create a local, linear approximation of the wcs transformation
532 The approximation is created as if the center is at RA=0, DEC=0. All
533 comparing x,y coordinate are relative to the position of center. Matrix
534 is initially calculated with units arcseconds and then converted to
535 radians. This yields higher precision results due to quirks in AST.
539 wcs : `lsst.afw.geom.SkyWcs`
541 center : `lsst.geom.Point2D`
542 Point at which to evaluate the LocalWcs.
546 localMatrix : `numpy.ndarray`
547 Matrix representation the local wcs approximation with units
550 skyCenter = wcs.pixelToSky(center)
553 measurementToLocalGnomonic = wcs.getTransform().then(
554 localGnomonicWcs.getTransform().inverted()
556 localMatrix = measurementToLocalGnomonic.getJacobian(center)
557 return np.radians(localMatrix / 3600)
560SingleFrameEvaluateLocalWcsPlugin = EvaluateLocalWcsPlugin.makeSingleFramePlugin(
"base_LocalWcs")
561"""Single-frame version of `EvaluateLocalWcsPlugin`.
564ForcedEvaluateLocalWcsPlugin = EvaluateLocalWcsPlugin.makeForcedPlugin(
"base_LocalWcs")
565"""Forced version of `EvaluateLocalWcsPlugin`.
570 """Configuration for the single frame peak centroiding algorithm.
576 """Record the highest peak in a source footprint as its centroid.
578 This is of course a relatively poor measure of the true centroid of the
579 object; this algorithm is provided mostly for testing and debugging.
583 config : `SingleFramePeakCentroidConfig`
587 schema : `lsst.afw.table.Schema`
588 The schema for the measurement output catalog. New fields will be
589 added to hold measurements produced by this plugin.
590 metadata : `lsst.daf.base.PropertySet`
591 Plugin metadata that will be attached to the output catalog
594 ConfigClass = SingleFramePeakCentroidConfig
600 def __init__(self, config, name, schema, metadata):
601 SingleFramePlugin.__init__(self, config, name, schema, metadata)
602 self.
keyX = schema.addField(name +
"_x", type=
"D", doc=
"peak centroid", units=
"pixel")
603 self.
keyY = schema.addField(name +
"_y", type=
"D", doc=
"peak centroid", units=
"pixel")
604 self.
flag = schema.addField(name +
"_flag", type=
"Flag", doc=
"Centroiding failed")
607 peak = measRecord.getFootprint().getPeaks()[0]
608 measRecord.set(self.
keyX, peak.getFx())
609 measRecord.set(self.
keyY, peak.getFy())
611 def fail(self, measRecord, error=None):
612 measRecord.set(self.
flag,
True)
616 return SimpleCentroidTransform
620 """Configuration for the sky coordinates algorithm.
626 """Record the sky position and uncertainties of an object based on its
627 centroid slot and WCS.
629 The position is recorded in the ``coord`` field, which is part of the
630 `~lsst.afw.table.SourceCatalog` minimal schema.
634 config : `SingleFrameSkyCoordConfig`
638 schema : `lsst.afw.table.Schema`
639 The schema for the measurement output catalog. New fields will be
640 added to hold measurements produced by this plugin.
641 metadata : `lsst.daf.base.PropertySet`
642 Plugin metadata that will be attached to the output catalog
645 ConfigClass = SingleFrameSkyCoordConfig
651 def __init__(self, config, name, schema, metadata):
652 SingleFramePlugin.__init__(self, config, name, schema, metadata)
653 if "coord_raErr" not in schema:
660 if not exposure.hasWcs():
661 raise RuntimeError(
"Wcs not attached to exposure. Required for " + self.
name +
" algorithm")
662 measRecord.updateCoord(exposure.getWcs())
664 def fail(self, measRecord, error=None):
672class SingleFrameClassificationSizeExtendednessConfig(SingleFramePluginConfig):
673 """Configuration for moments-based star-galaxy classifier."""
675 exponent = lsst.pex.config.Field[float](
676 doc=
"Exponent to raise the PSF size squared (Ixx + Iyy) to, "
677 "in the likelihood normalization",
682@register("base_ClassificationSizeExtendedness")
684 """Classify objects by comparing their moments-based trace radius to PSF's.
686 The plugin computes chi^2 as ((T_obj - T_psf)/T_psf^exponent)^2, where
687 T_obj is the sum of Ixx and Iyy moments of the object, and T_psf is the
688 sum of Ixx and Iyy moments of the PSF. The exponent is configurable.
689 The measure of being a galaxy is then 1 - exp(-0.5*chi^2).
693 config : `SingleFrameClassificationSizeExtendednessConfig`
694 Plugin configuration.
697 schema : `~lsst.afw.table.Schema`
698 The schema for the measurement output catalog. New fields will be
699 added to hold measurements produced by this plugin.
700 metadata : `~lsst.daf.base.PropertySet`
701 Plugin metadata that will be attached to the output catalog.
705 The ``measure`` method of the plugin requires a value for the ``exposure``
706 argument to maintain consistent API, but it is not used in the measurement.
709 ConfigClass = SingleFrameClassificationSizeExtendednessConfig
711 FAILURE_BAD_SHAPE = 1
712 """Denotes failures due to bad shape (`int`).
719 def __init__(self, config, name, schema, metadata):
720 SingleFramePlugin.__init__(self, config, name, schema, metadata)
721 self.
key = schema.addField(name +
"_value",
723 doc=
"Measure of being a galaxy based on trace of second order moments",
725 self.
flag = schema.addField(name +
"_flag", type=
"Flag", doc=
"Moments-based classification failed")
727 def measure(self, measRecord, exposure) -> None:
730 if measRecord.getShapeFlag():
732 "Shape flag is set. Required for " + self.
name +
" algorithm",
736 shape = measRecord.getShape()
737 psf_shape = measRecord.getPsfShape()
741 ixx_psf = psf_shape.getIxx()
742 iyy_psf = psf_shape.getIyy()
745 psf_t = ixx_psf + iyy_psf
747 chi_sq = ((object_t - psf_t)/(psf_t**self.
config.exponent))**2.
748 likelihood = 1. - np.exp(-0.5*chi_sq)
749 measRecord.set(self.
key, likelihood)
751 def fail(self, measRecord, error=None) -> None:
753 measRecord.set(self.
key, np.nan)
754 measRecord.set(self.
flag,
True)
757@deprecated(reason=
"Use SingleFrameClassificationSizeExtendednessConfig instead", version=
"v29.0.0",
758 category=FutureWarning)
763@deprecated(reason=
"Use SingleFrameClassificationSizeExtendednessPlugin instead", version=
"v29.0.0",
764 category=FutureWarning)
766 ConfigClass = SingleFrameMomentsClassifierConfig
770 """Configuration for the forced peak centroid algorithm.
776 """Record the highest peak in a source footprint as its centroid.
778 This is of course a relatively poor measure of the true centroid of the
779 object; this algorithm is provided mostly for testing and debugging.
781 This is similar to `SingleFramePeakCentroidPlugin`, except that transforms
782 the peak coordinate from the original (reference) coordinate system to the
783 coordinate system of the exposure being measured.
787 config : `ForcedPeakCentroidConfig`
791 schemaMapper : `lsst.afw.table.SchemaMapper`
792 A mapping from reference catalog fields to output
793 catalog fields. Output fields are added to the output schema.
794 metadata : `lsst.daf.base.PropertySet`
795 Plugin metadata that will be attached to the output catalog.
798 ConfigClass = ForcedPeakCentroidConfig
804 def __init__(self, config, name, schemaMapper, metadata):
805 ForcedPlugin.__init__(self, config, name, schemaMapper, metadata)
806 schema = schemaMapper.editOutputSchema()
807 self.
keyX = schema.addField(name +
"_x", type=
"D", doc=
"peak centroid", units=
"pixel")
808 self.
keyY = schema.addField(name +
"_y", type=
"D", doc=
"peak centroid", units=
"pixel")
810 def measure(self, measRecord, exposure, refRecord, refWcs):
811 targetWcs = exposure.getWcs()
812 peak = refRecord.getFootprint().getPeaks()[0]
814 result = targetWcs.skyToPixel(refWcs.pixelToSky(result))
815 measRecord.set(self.
keyX, result.getX())
816 measRecord.set(self.
keyY, result.getY())
820 return SimpleCentroidTransform
824 """Configuration for the forced transformed centroid algorithm.
828@
register(
"base_TransformedCentroid")
830 """Record the transformation of the reference catalog centroid.
832 The centroid recorded in the reference catalog is tranformed to the
833 measurement coordinate system and stored.
837 config : `ForcedTransformedCentroidConfig`
841 schemaMapper : `lsst.afw.table.SchemaMapper`
842 A mapping from reference catalog fields to output
843 catalog fields. Output fields are added to the output schema.
844 metadata : `lsst.daf.base.PropertySet`
845 Plugin metadata that will be attached to the output catalog.
849 This is used as the slot centroid by default in forced measurement,
850 allowing subsequent measurements to simply refer to the slot value just as
851 they would in single-frame measurement.
854 ConfigClass = ForcedTransformedCentroidConfig
860 def __init__(self, config, name, schemaMapper, metadata):
861 ForcedPlugin.__init__(self, config, name, schemaMapper, metadata)
862 schema = schemaMapper.editOutputSchema()
865 xKey = schema.addField(name +
"_x", type=
"D", doc=
"transformed reference centroid column",
867 yKey = schema.addField(name +
"_y", type=
"D", doc=
"transformed reference centroid row",
873 if "slot_Centroid_flag" in schemaMapper.getInputSchema():
874 self.
flagKey = schema.addField(name +
"_flag", type=
"Flag",
875 doc=
"whether the reference centroid is marked as bad")
879 def measure(self, measRecord, exposure, refRecord, refWcs):
880 targetWcs = exposure.getWcs()
881 if not refWcs == targetWcs:
882 targetPos = targetWcs.skyToPixel(refWcs.pixelToSky(refRecord.getCentroid()))
885 measRecord.set(self.
centroidKey, refRecord.getCentroid())
887 measRecord.set(self.
flagKey, refRecord.getCentroidFlag())
891 """Configuration for the forced transformed coord algorithm.
895@
register(
"base_TransformedCentroidFromCoord")
897 """Record the transformation of the reference catalog coord.
899 The coord recorded in the reference catalog is tranformed to the
900 measurement coordinate system and stored.
904 config : `ForcedTransformedCentroidFromCoordConfig`
908 schemaMapper : `lsst.afw.table.SchemaMapper`
909 A mapping from reference catalog fields to output
910 catalog fields. Output fields are added to the output schema.
911 metadata : `lsst.daf.base.PropertySet`
912 Plugin metadata that will be attached to the output catalog.
916 This can be used as the slot centroid in forced measurement when only a
917 reference coord exist, allowing subsequent measurements to simply refer to
918 the slot value just as they would in single-frame measurement.
921 ConfigClass = ForcedTransformedCentroidFromCoordConfig
923 def measure(self, measRecord, exposure, refRecord, refWcs):
924 targetWcs = exposure.getWcs()
926 targetPos = targetWcs.skyToPixel(refRecord.getCoord())
930 measRecord.set(self.
flagKey, refRecord.getCentroidFlag())
934 """Configuration for the forced transformed shape algorithm.
940 """Record the transformation of the reference catalog shape.
942 The shape recorded in the reference catalog is tranformed to the
943 measurement coordinate system and stored.
947 config : `ForcedTransformedShapeConfig`
951 schemaMapper : `lsst.afw.table.SchemaMapper`
952 A mapping from reference catalog fields to output
953 catalog fields. Output fields are added to the output schema.
954 metadata : `lsst.daf.base.PropertySet`
955 Plugin metadata that will be attached to the output catalog.
959 This is used as the slot shape by default in forced measurement, allowing
960 subsequent measurements to simply refer to the slot value just as they
961 would in single-frame measurement.
964 ConfigClass = ForcedTransformedShapeConfig
970 def __init__(self, config, name, schemaMapper, metadata):
971 ForcedPlugin.__init__(self, config, name, schemaMapper, metadata)
972 schema = schemaMapper.editOutputSchema()
975 xxKey = schema.addField(name +
"_xx", type=
"D", doc=
"transformed reference shape x^2 moment",
977 yyKey = schema.addField(name +
"_yy", type=
"D", doc=
"transformed reference shape y^2 moment",
979 xyKey = schema.addField(name +
"_xy", type=
"D", doc=
"transformed reference shape xy moment",
985 if "slot_Shape_flag" in schemaMapper.getInputSchema():
986 self.
flagKey = schema.addField(name +
"_flag", type=
"Flag",
987 doc=
"whether the reference shape is marked as bad")
991 def measure(self, measRecord, exposure, refRecord, refWcs):
992 targetWcs = exposure.getWcs()
993 if not refWcs == targetWcs:
996 measRecord.set(self.
shapeKey, refRecord.getShape().transform(localTransform.getLinear()))
998 measRecord.set(self.
shapeKey, refRecord.getShape())
1000 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())
static ErrorKey addErrorFields(Schema &schema)
Exception to be thrown when a measurement algorithm experiences a known failure mode.
__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)
None fail(self, measRecord, error=None)
__init__(self, config, name, schema, metadata)
None measure(self, measRecord, exposure)
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)
fail(self, measRecord, error=None)
__init__(self, config, name, schema, metadata)
measure(self, measRecord, exposure)
__init__(self, config, name, schema, metadata)
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)
HeavyFootprint< ImagePixelT, MaskPixelT, VariancePixelT > makeHeavyFootprint(Footprint const &foot, lsst::afw::image::MaskedImage< ImagePixelT, MaskPixelT, VariancePixelT > const &img, HeavyFootprintCtrl const *ctrl=nullptr)
std::shared_ptr< SkyWcs > makeSkyWcs(daf::base::PropertySet &metadata, bool strip=false)
std::shared_ptr< TransformPoint2ToPoint2 > makeWcsPairTransform(SkyWcs const &src, SkyWcs const &dst)
lsst::geom::AffineTransform linearizeTransform(TransformPoint2ToPoint2 const &original, lsst::geom::Point2D const &inPoint)
register(name, shouldApCorr=False, apCorrList=())
wrapTransform(transformClass, hasLogName=False)
wrapSimpleAlgorithm(AlgClass, executionOrder, name=None, needsMetadata=False, hasMeasureN=False, hasLogName=False, deprecated=None, **kwds)