22from __future__
import annotations
25 "SingleFrameCompensatedGaussianFluxConfig",
26 "SingleFrameCompensatedGaussianFluxPlugin",
31import scipy.stats
as sps
36from ..sfm
import SingleFramePlugin, SingleFramePluginConfig
37from ..pluginRegistry
import register
39from .._measBaseLib
import _compensatedGaussianFiltInnerProduct
47 kernel_widths = ListField(
48 doc=
"The widths (in pixels) of the kernels for which to measure compensated apertures.",
55 doc=
"Scale parameter of outer Gaussian compared to inner Gaussian.",
61@register("base_CompensatedGaussianFlux")
63 ConfigClass = SingleFrameCompensatedGaussianFluxConfig
71 config: SingleFrameCompensatedGaussianFluxConfig,
78 super().
__init__(config, name, schema, metadata, logName, **kwds)
82 f
"{name}_flag", type=
"Flag", doc=
"Set to 1 for any fatal failure."
87 f
"{name}_bounds_flag",
89 doc=
"Flag set to 1 if not all filters fit within exposure.",
97 for width
in config.kernel_widths:
98 base_key = f
"{name}_{width}"
101 flux_str = f
"{base_key}_instFlux"
102 flux_key = schema.addField(flux_str, type=
"D", doc=
"Compensated Gaussian flux measurement.")
105 err_str = f
"{base_key}_instFluxErr"
106 err_key = schema.addField(err_str, type=
"D", doc=
"Compensated Gaussian flux error.")
109 mask_str = f
"{base_key}_mask_bits"
110 mask_key = schema.addField(mask_str, type=np.int32, doc=
"Mask bits set within aperture.")
112 self.
width_keys[width] = (flux_key, err_key, mask_key)
113 self.
_rads[width] = math.ceil(sps.norm.ppf((0.995,), scale=width * config.t)[0])
117 def fail(self, measRecord, error=None):
118 if isinstance(error, OutOfBoundsError):
123 center = measRecord.getCentroid()
124 bbox = exposure.getBBox()
126 if Point2I(center)
not in exposure.getBBox().erodedBy(self.
_max_rad):
127 raise OutOfBoundsError(
"Not all the kernels for this source fit inside the exposure.")
129 y = center.getY() - bbox.beginY
130 x = center.getX() - bbox.beginX
132 y_floor = math.floor(y)
133 x_floor = math.floor(x)
135 for width, (flux_key, err_key, mask_key)
in self.
width_keys.items():
136 rad = self.
_rads[width]
137 y_slice = slice(y_floor - rad, y_floor + rad + 1, 1)
138 x_slice = slice(x_floor - rad, x_floor + rad + 1, 1)
139 y_mean = y - y_floor + rad
140 x_mean = x - x_floor + rad
142 flux, var = _compensatedGaussianFiltInnerProduct(
143 exposure.image.array[y_slice, x_slice],
144 exposure.variance.array[y_slice, x_slice],
150 measRecord.set(flux_key, flux)
151 measRecord.set(err_key, np.sqrt(var))
152 measRecord.set(mask_key, np.bitwise_or.reduce(exposure.mask.array[y_slice, x_slice], axis=
None))
measure(self, measRecord, exposure)
__init__(self, SingleFrameCompensatedGaussianFluxConfig config, str name, schema, metadata, logName=None, **kwds)
fail(self, measRecord, error=None)