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,
44 NaiveCentroidAlgorithm, NaiveCentroidControl, NaiveCentroidTransform,
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 "ForcedPeakCentroidConfig",
"ForcedPeakCentroidPlugin",
73 "ForcedTransformedCentroidConfig",
"ForcedTransformedCentroidPlugin",
74 "ForcedTransformedCentroidFromCoordConfig",
75 "ForcedTransformedCentroidFromCoordPlugin",
76 "ForcedTransformedShapeConfig",
"ForcedTransformedShapePlugin",
77 "EvaluateLocalPhotoCalibPlugin",
"EvaluateLocalPhotoCalibPluginConfig",
78 "EvaluateLocalWcsPlugin",
"EvaluateLocalWcsPluginConfig",
82wrapSimpleAlgorithm(PsfFluxAlgorithm, Control=PsfFluxControl,
83 TransformClass=PsfFluxTransform, executionOrder=BasePlugin.FLUX_ORDER,
84 shouldApCorr=
True, hasLogName=
True)
85wrapSimpleAlgorithm(PeakLikelihoodFluxAlgorithm, Control=PeakLikelihoodFluxControl,
86 TransformClass=PeakLikelihoodFluxTransform, executionOrder=BasePlugin.FLUX_ORDER)
87wrapSimpleAlgorithm(GaussianFluxAlgorithm, Control=GaussianFluxControl,
88 TransformClass=GaussianFluxTransform, executionOrder=BasePlugin.FLUX_ORDER,
91wrapSimpleAlgorithm(NaiveCentroidAlgorithm, Control=NaiveCentroidControl,
92 TransformClass=NaiveCentroidTransform, executionOrder=BasePlugin.CENTROID_ORDER,
93 deprecated=
"Plugin 'NaiveCentroid' is deprecated and will be removed after v27.")
94wrapSimpleAlgorithm(SdssCentroidAlgorithm, Control=SdssCentroidControl,
95 TransformClass=SdssCentroidTransform, executionOrder=BasePlugin.CENTROID_ORDER)
96wrapSimpleAlgorithm(PixelFlagsAlgorithm, Control=PixelFlagsControl,
97 executionOrder=BasePlugin.FLUX_ORDER)
98wrapSimpleAlgorithm(SdssShapeAlgorithm, Control=SdssShapeControl,
99 TransformClass=SdssShapeTransform, executionOrder=BasePlugin.SHAPE_ORDER)
100wrapSimpleAlgorithm(ScaledApertureFluxAlgorithm, Control=ScaledApertureFluxControl,
101 TransformClass=ScaledApertureFluxTransform, executionOrder=BasePlugin.FLUX_ORDER)
103wrapSimpleAlgorithm(CircularApertureFluxAlgorithm, needsMetadata=
True, Control=ApertureFluxControl,
104 TransformClass=ApertureFluxTransform, executionOrder=BasePlugin.FLUX_ORDER)
105wrapSimpleAlgorithm(BlendednessAlgorithm, Control=BlendednessControl,
106 TransformClass=BaseTransform, executionOrder=BasePlugin.SHAPE_ORDER)
108wrapSimpleAlgorithm(LocalBackgroundAlgorithm, Control=LocalBackgroundControl,
109 TransformClass=LocalBackgroundTransform, executionOrder=BasePlugin.FLUX_ORDER)
111wrapTransform(PsfFluxTransform)
112wrapTransform(PeakLikelihoodFluxTransform)
113wrapTransform(GaussianFluxTransform)
115wrapTransform(NaiveCentroidTransform)
116wrapTransform(SdssCentroidTransform)
117wrapTransform(SdssShapeTransform)
118wrapTransform(ScaledApertureFluxTransform)
119wrapTransform(ApertureFluxTransform)
120wrapTransform(LocalBackgroundTransform)
124 """Configuration for the focal plane position measurment algorithm.
128@register(
"base_FPPosition")
130 """Algorithm to calculate the position of a centroid on the focal plane.
134 config : `SingleFrameFPPositionConfig`
138 schema : `lsst.afw.table.Schema`
139 The schema for the measurement output catalog. New fields will be
140 added to hold measurements produced by this plugin.
141 metadata : `lsst.daf.base.PropertySet`
142 Plugin metadata that will be attached to the output catalog
145 ConfigClass = SingleFrameFPPositionConfig
151 def __init__(self, config, name, schema, metadata):
152 SingleFramePlugin.__init__(self, config, name, schema, metadata)
153 self.
focalValue = lsst.afw.table.Point2DKey.addFields(schema, name,
"Position on the focal plane",
155 self.
focalFlag = schema.addField(name +
"_flag", type=
"Flag", doc=
"Set to True for any fatal failure")
156 self.
detectorFlag = schema.addField(name +
"_missingDetector_flag", type=
"Flag",
157 doc=
"Set to True if detector object is missing")
160 det = exposure.getDetector()
165 center = measRecord.getCentroid()
166 fp = det.transform(center, lsst.afw.cameraGeom.PIXELS, lsst.afw.cameraGeom.FOCAL_PLANE)
169 def fail(self, measRecord, error=None):
174 """Configuration for the Jacobian calculation plugin.
180@register("base_Jacobian")
182 """Compute the Jacobian and its ratio with a nominal pixel area.
184 This enables one to compare relative, rather than absolute, pixel areas.
188 config : `SingleFrameJacobianConfig`
192 schema : `lsst.afw.table.Schema`
193 The schema for the measurement output catalog. New fields will be
194 added to hold measurements produced by this plugin.
195 metadata : `lsst.daf.base.PropertySet`
196 Plugin metadata that will be attached to the output catalog
199 ConfigClass = SingleFrameJacobianConfig
205 def __init__(self, config, name, schema, metadata):
206 SingleFramePlugin.__init__(self, config, name, schema, metadata)
207 self.
jacValue = schema.addField(name +
'_value', type=
"D", doc=
"Jacobian correction")
208 self.
jacFlag = schema.addField(name +
'_flag', type=
"Flag", doc=
"Set to 1 for any fatal failure")
213 center = measRecord.getCentroid()
216 result = np.abs(self.
scale*exposure.getWcs().linearizePixelToSky(
218 lsst.geom.arcseconds).getLinear().computeDeterminant())
219 measRecord.set(self.
jacValue, result)
221 def fail(self, measRecord, error=None):
222 measRecord.set(self.
jacFlag,
True)
226 """Configuration for the variance calculation plugin.
229 doc=
"Scale factor to apply to shape for aperture")
231 default=[
"DETECTED",
"DETECTED_NEGATIVE",
"BAD",
"SAT"])
235 """Compute the median variance corresponding to a footprint.
237 The aim here is to measure the background variance, rather than that of
238 the object itself. In order to achieve this, the variance is calculated
239 over an area scaled up from the shape of the input footprint.
243 config : `VarianceConfig`
247 schema : `lsst.afw.table.Schema`
248 The schema for the measurement output catalog. New fields will be
249 added to hold measurements produced by this plugin.
250 metadata : `lsst.daf.base.PropertySet`
251 Plugin metadata that will be attached to the output catalog
254 ConfigClass = VarianceConfig
256 FAILURE_BAD_CENTROID = 1
257 """Denotes failures due to bad centroiding (`int`).
260 FAILURE_EMPTY_FOOTPRINT = 2
261 """Denotes failures due to a lack of usable pixels (`int`).
266 return BasePlugin.FLUX_ORDER
268 def __init__(self, config, name, schema, metadata):
269 GenericPlugin.__init__(self, config, name, schema, metadata)
270 self.
varValue = schema.addField(name +
'_value', type=
"D", doc=
"Variance at object position")
272 doc=
"Set to True when the footprint has no usable pixels")
277 schema.getAliasMap().set(name +
'_flag_badCentroid', schema.getAliasMap().apply(
"slot_Centroid_flag"))
279 def measure(self, measRecord, exposure, center):
283 if not np.all(np.isfinite(measRecord.getCentroid())):
286 aperture.scale(self.
config.scale)
289 foot.clipTo(exposure.getBBox(lsst.afw.image.PARENT))
292 maskedImage = exposure.getMaskedImage()
294 maskBits = maskedImage.getMask().getPlaneBitMask(self.
config.mask)
295 logicalMask = np.logical_not(pixels.getMaskArray() & maskBits)
300 if np.any(logicalMask):
301 medVar = np.median(pixels.getVarianceArray()[logicalMask])
302 measRecord.set(self.
varValue, medVar)
304 raise MeasurementError(
"Footprint empty, or all pixels are masked, can't compute median",
307 def fail(self, measRecord, error=None):
310 if isinstance(error, MeasurementError):
315 measRecord.set(self.
varValue, np.nan)
316 GenericPlugin.fail(self, measRecord, error)
319SingleFrameVariancePlugin = VariancePlugin.makeSingleFramePlugin(
"base_Variance")
320"""Single-frame version of `VariancePlugin`.
323ForcedVariancePlugin = VariancePlugin.makeForcedPlugin(
"base_Variance")
324"""Forced version of `VariancePlugin`.
329 """Configuration for the input image counting plugin.
333class InputCountPlugin(GenericPlugin):
334 """Count the number of input images which contributed to a source.
338 config : `InputCountConfig`
339 Plugin configuration.
342 schema : `lsst.afw.table.Schema`
343 The schema for the measurement output catalog. New fields will be
344 added to hold measurements produced by this plugin.
345 metadata : `lsst.daf.base.PropertySet`
346 Plugin metadata that will be attached to the output catalog
350 Information is derived from the image's `~lsst.afw.image.CoaddInputs`.
351 Note these limitation:
353 - This records the number of images which contributed to the pixel in the
354 center of the source footprint, rather than to any or all pixels in the
356 - Clipping in the coadd is not taken into account.
359 ConfigClass = InputCountConfig
361 FAILURE_BAD_CENTROID = 1
362 """Denotes failures due to bad centroiding (`int`).
365 FAILURE_NO_INPUTS = 2
366 """Denotes failures due to the image not having coadd inputs. (`int`)
371 return BasePlugin.SHAPE_ORDER
373 def __init__(self, config, name, schema, metadata):
374 GenericPlugin.__init__(self, config, name, schema, metadata)
375 self.
numberKey = schema.addField(name +
'_value', type=
"I",
376 doc=
"Number of images contributing at center, not including any"
378 self.
noInputsFlag = schema.addField(name +
'_flag_noInputs', type=
"Flag",
379 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 exposure.getInfo().getCoaddInputs():
387 if not np.all(np.isfinite(center)):
390 ccds = exposure.getInfo().getCoaddInputs().ccds
391 measRecord.set(self.
numberKey, len(ccds.subsetContaining(center, exposure.getWcs())))
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):
443 photoCalib = exposure.getPhotoCalib()
444 calib = photoCalib.getLocalCalibration(center)
445 measRecord.set(self.
photoKey, calib)
447 calibErr = photoCalib.getCalibrationErr()
451SingleFrameEvaluateLocalPhotoCalibPlugin = EvaluateLocalPhotoCalibPlugin.makeSingleFramePlugin(
452 "base_LocalPhotoCalib")
453"""Single-frame version of `EvaluatePhotoCalibPlugin`.
456ForcedEvaluateLocalPhotoCalibPlugin = EvaluateLocalPhotoCalibPlugin.makeForcedPlugin(
457 "base_LocalPhotoCalib")
458"""Forced version of `EvaluatePhotoCalibPlugin`.
463 """Configuration for the variance calculation plugin.
467class EvaluateLocalWcsPlugin(GenericPlugin):
468 """Evaluate the local, linear approximation of the Wcs.
470 The aim is to store the local calib value within the catalog for later
471 use in the Science Data Model functors.
473 ConfigClass = EvaluateLocalWcsPluginConfig
474 _scale = (1.0 * lsst.geom.arcseconds).asDegrees()
478 return BasePlugin.FLUX_ORDER
480 def __init__(self, config, name, schema, metadata):
481 GenericPlugin.__init__(self, config, name, schema, metadata)
483 f
"{name}_CDMatrix_1_1",
485 doc=
"(1, 1) element of the CDMatrix for the linear approximation "
486 "of the WCS at the src location. Gives units in radians.")
488 f
"{name}_CDMatrix_1_2",
490 doc=
"(1, 2) 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_1",
495 doc=
"(2, 1) element of the CDMatrix for the linear approximation "
496 "of the WCS at the src location. Gives units in radians.")
498 f
"{name}_CDMatrix_2_2",
500 doc=
"(2, 2) element of the CDMatrix for the linear approximation "
501 "of the WCS at the src location. Gives units in radians.")
503 def measure(self, measRecord, exposure, center):
504 wcs = exposure.getWcs()
512 """Create a local, linear approximation of the wcs transformation
515 The approximation is created as if the center is at RA=0, DEC=0. All
516 comparing x,y coordinate are relative to the position of center. Matrix
517 is initially calculated with units arcseconds and then converted to
518 radians. This yields higher precision results due to quirks in AST.
522 wcs : `lsst.afw.geom.SkyWcs`
524 center : `lsst.geom.Point2D`
525 Point at which to evaluate the LocalWcs.
529 localMatrix : `numpy.ndarray`
530 Matrix representation the local wcs approximation with units
533 skyCenter = wcs.pixelToSky(center)
536 measurementToLocalGnomonic = wcs.getTransform().then(
537 localGnomonicWcs.getTransform().inverted()
539 localMatrix = measurementToLocalGnomonic.getJacobian(center)
540 return np.radians(localMatrix / 3600)
543SingleFrameEvaluateLocalWcsPlugin = EvaluateLocalWcsPlugin.makeSingleFramePlugin(
"base_LocalWcs")
544"""Single-frame version of `EvaluateLocalWcsPlugin`.
547ForcedEvaluateLocalWcsPlugin = EvaluateLocalWcsPlugin.makeForcedPlugin(
"base_LocalWcs")
548"""Forced version of `EvaluateLocalWcsPlugin`.
553 """Configuration for the single frame peak centroiding algorithm.
557@register(
"base_PeakCentroid")
559 """Record the highest peak in a source footprint as its centroid.
561 This is of course a relatively poor measure of the true centroid of the
562 object; this algorithm is provided mostly for testing and debugging.
566 config : `SingleFramePeakCentroidConfig`
570 schema : `lsst.afw.table.Schema`
571 The schema for the measurement output catalog. New fields will be
572 added to hold measurements produced by this plugin.
573 metadata : `lsst.daf.base.PropertySet`
574 Plugin metadata that will be attached to the output catalog
577 ConfigClass = SingleFramePeakCentroidConfig
583 def __init__(self, config, name, schema, metadata):
584 SingleFramePlugin.__init__(self, config, name, schema, metadata)
585 self.
keyX = schema.addField(name +
"_x", type=
"D", doc=
"peak centroid", units=
"pixel")
586 self.
keyY = schema.addField(name +
"_y", type=
"D", doc=
"peak centroid", units=
"pixel")
587 self.
flag = schema.addField(name +
"_flag", type=
"Flag", doc=
"Centroiding failed")
590 peak = measRecord.getFootprint().getPeaks()[0]
591 measRecord.set(self.
keyX, peak.getFx())
592 measRecord.set(self.
keyY, peak.getFy())
594 def fail(self, measRecord, error=None):
595 measRecord.set(self.
flag,
True)
599 return SimpleCentroidTransform
603 """Configuration for the sky coordinates algorithm.
607@register(
"base_SkyCoord")
609 """Record the sky position of an object based on its centroid slot and WCS.
611 The position is record in the ``coord`` field, which is part of the
612 `~lsst.afw.table.SourceCatalog` minimal schema.
616 config : `SingleFrameSkyCoordConfig`
620 schema : `lsst.afw.table.Schema`
621 The schema for the measurement output catalog. New fields will be
622 added to hold measurements produced by this plugin.
623 metadata : `lsst.daf.base.PropertySet`
624 Plugin metadata that will be attached to the output catalog
627 ConfigClass = SingleFrameSkyCoordConfig
637 if not exposure.hasWcs():
638 raise RuntimeError(
"Wcs not attached to exposure. Required for " + self.
name +
" algorithm")
639 measRecord.updateCoord(exposure.getWcs())
641 def fail(self, measRecord, error=None):
649class SingleFrameMomentsClassifierConfig(SingleFramePluginConfig):
650 """Configuration for moments-based star-galaxy classifier."""
653 doc=
"Exponent to raise the PSF size squared (Ixx + Iyy) to, "
654 "in the likelihood normalization",
659@register("base_ClassificationSizeExtendedness")
661 """Classify objects by comparing their moments-based trace radius to PSF's.
663 The plugin computes chi^2 as ((T_obj - T_psf)/T_psf^exponent)^2, where
664 T_obj is the sum of Ixx and Iyy moments of the object, and T_psf is the
665 sum of Ixx and Iyy moments of the PSF. The exponent is configurable.
666 The measure of being a galaxy is then 1 - exp(-0.5*chi^2).
670 config : `MomentsClassifierConfig`
671 Plugin configuration.
674 schema : `~lsst.afw.table.Schema`
675 The schema for the measurement output catalog. New fields will be
676 added to hold measurements produced by this plugin.
677 metadata : `~lsst.daf.base.PropertySet`
678 Plugin metadata that will be attached to the output catalog.
682 The ``measure`` method of the plugin requires a value for the ``exposure``
683 argument to maintain consistent API, but it is not used in the measurement.
686 ConfigClass = SingleFrameMomentsClassifierConfig
688 FAILURE_BAD_SHAPE = 1
689 """Denotes failures due to bad shape (`int`).
696 def __init__(self, config, name, schema, metadata):
697 SingleFramePlugin.__init__(self, config, name, schema, metadata)
698 self.
key = schema.addField(name +
"_value",
700 doc=
"Measure of being a galaxy based on trace of second order moments",
702 self.
flag = schema.addField(name +
"_flag", type=
"Flag", doc=
"Moments-based classification failed")
704 def measure(self, measRecord, exposure) -> None:
707 if measRecord.getShapeFlag():
708 raise MeasurementError(
709 "Shape flag is set. Required for " + self.
name +
" algorithm",
713 shape = measRecord.getShape()
714 psf_shape = measRecord.getPsfShape()
718 ixx_psf = psf_shape.getIxx()
719 iyy_psf = psf_shape.getIyy()
722 psf_t = ixx_psf + iyy_psf
724 chi_sq = ((object_t - psf_t)/(psf_t**self.
config.exponent))**2.
725 likelihood = 1. - np.exp(-0.5*chi_sq)
726 measRecord.set(self.
key, likelihood)
728 def fail(self, measRecord, error=None) -> None:
730 measRecord.set(self.
key, np.nan)
731 measRecord.set(self.
flag,
True)
735 """Configuration for the forced peak centroid algorithm.
739@register(
"base_PeakCentroid")
741 """Record the highest peak in a source footprint as its centroid.
743 This is of course a relatively poor measure of the true centroid of the
744 object; this algorithm is provided mostly for testing and debugging.
746 This is similar to `SingleFramePeakCentroidPlugin`, except that transforms
747 the peak coordinate from the original (reference) coordinate system to the
748 coordinate system of the exposure being measured.
752 config : `ForcedPeakCentroidConfig`
756 schemaMapper : `lsst.afw.table.SchemaMapper`
757 A mapping from reference catalog fields to output
758 catalog fields. Output fields are added to the output schema.
759 metadata : `lsst.daf.base.PropertySet`
760 Plugin metadata that will be attached to the output catalog.
763 ConfigClass = ForcedPeakCentroidConfig
769 def __init__(self, config, name, schemaMapper, metadata):
770 ForcedPlugin.__init__(self, config, name, schemaMapper, metadata)
771 schema = schemaMapper.editOutputSchema()
772 self.
keyX = schema.addField(name +
"_x", type=
"D", doc=
"peak centroid", units=
"pixel")
773 self.
keyY = schema.addField(name +
"_y", type=
"D", doc=
"peak centroid", units=
"pixel")
775 def measure(self, measRecord, exposure, refRecord, refWcs):
776 targetWcs = exposure.getWcs()
777 peak = refRecord.getFootprint().getPeaks()[0]
779 result = targetWcs.skyToPixel(refWcs.pixelToSky(result))
780 measRecord.set(self.
keyX, result.getX())
781 measRecord.set(self.
keyY, result.getY())
785 return SimpleCentroidTransform
789 """Configuration for the forced transformed centroid algorithm.
793@register(
"base_TransformedCentroid")
795 """Record the transformation of the reference catalog centroid.
797 The centroid recorded in the reference catalog is tranformed to the
798 measurement coordinate system and stored.
802 config : `ForcedTransformedCentroidConfig`
806 schemaMapper : `lsst.afw.table.SchemaMapper`
807 A mapping from reference catalog fields to output
808 catalog fields. Output fields are added to the output schema.
809 metadata : `lsst.daf.base.PropertySet`
810 Plugin metadata that will be attached to the output catalog.
814 This is used as the slot centroid by default in forced measurement,
815 allowing subsequent measurements to simply refer to the slot value just as
816 they would in single-frame measurement.
819 ConfigClass = ForcedTransformedCentroidConfig
825 def __init__(self, config, name, schemaMapper, metadata):
826 ForcedPlugin.__init__(self, config, name, schemaMapper, metadata)
827 schema = schemaMapper.editOutputSchema()
829 xKey = schema.addField(name +
"_x", type=
"D", doc=
"transformed reference centroid column",
831 yKey = schema.addField(name +
"_y", type=
"D", doc=
"transformed reference centroid row",
837 if "slot_Centroid_flag" in schemaMapper.getInputSchema():
838 self.
flagKey = schema.addField(name +
"_flag", type=
"Flag",
839 doc=
"whether the reference centroid is marked as bad")
843 def measure(self, measRecord, exposure, refRecord, refWcs):
844 targetWcs = exposure.getWcs()
845 if not refWcs == targetWcs:
846 targetPos = targetWcs.skyToPixel(refWcs.pixelToSky(refRecord.getCentroid()))
849 measRecord.set(self.
centroidKey, refRecord.getCentroid())
851 measRecord.set(self.
flagKey, refRecord.getCentroidFlag())
855 """Configuration for the forced transformed coord algorithm.
859@register(
"base_TransformedCentroidFromCoord")
861 """Record the transformation of the reference catalog coord.
863 The coord recorded in the reference catalog is tranformed to the
864 measurement coordinate system and stored.
868 config : `ForcedTransformedCentroidFromCoordConfig`
872 schemaMapper : `lsst.afw.table.SchemaMapper`
873 A mapping from reference catalog fields to output
874 catalog fields. Output fields are added to the output schema.
875 metadata : `lsst.daf.base.PropertySet`
876 Plugin metadata that will be attached to the output catalog.
880 This can be used as the slot centroid in forced measurement when only a
881 reference coord exist, allowing subsequent measurements to simply refer to
882 the slot value just as they would in single-frame measurement.
885 ConfigClass = ForcedTransformedCentroidFromCoordConfig
887 def measure(self, measRecord, exposure, refRecord, refWcs):
888 targetWcs = exposure.getWcs()
890 targetPos = targetWcs.skyToPixel(refRecord.getCoord())
898 """Configuration for the forced transformed shape algorithm.
902@register(
"base_TransformedShape")
904 """Record the transformation of the reference catalog shape.
906 The shape recorded in the reference catalog is tranformed to the
907 measurement coordinate system and stored.
911 config : `ForcedTransformedShapeConfig`
915 schemaMapper : `lsst.afw.table.SchemaMapper`
916 A mapping from reference catalog fields to output
917 catalog fields. Output fields are added to the output schema.
918 metadata : `lsst.daf.base.PropertySet`
919 Plugin metadata that will be attached to the output catalog.
923 This is used as the slot shape by default in forced measurement, allowing
924 subsequent measurements to simply refer to the slot value just as they
925 would in single-frame measurement.
928 ConfigClass = ForcedTransformedShapeConfig
934 def __init__(self, config, name, schemaMapper, metadata):
935 ForcedPlugin.__init__(self, config, name, schemaMapper, metadata)
936 schema = schemaMapper.editOutputSchema()
938 xxKey = schema.addField(name +
"_xx", type=
"D", doc=
"transformed reference shape x^2 moment",
940 yyKey = schema.addField(name +
"_yy", type=
"D", doc=
"transformed reference shape y^2 moment",
942 xyKey = schema.addField(name +
"_xy", type=
"D", doc=
"transformed reference shape xy moment",
948 if "slot_Shape_flag" in schemaMapper.getInputSchema():
949 self.
flagKey = schema.addField(name +
"_flag", type=
"Flag",
950 doc=
"whether the reference shape is marked as bad")
954 def measure(self, measRecord, exposure, refRecord, refWcs):
955 targetWcs = exposure.getWcs()
956 if not refWcs == targetWcs:
959 measRecord.set(self.
shapeKey, refRecord.getShape().transform(localTransform.getLinear()))
961 measRecord.set(self.
shapeKey, refRecord.getShape())
963 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)
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.