Harvey-Shack Scatter¶
A Harvey-Shack profile in pixels, to set as a PSF of its own. The camera’s scattered light, added
to diffraction or a set PSF, is set in angles with CameraModel::set_scatter() instead.
-
template<IsSpectral TSpectral>
class HarveyShackScatter : public huira::PSF<TSpectral>¶ Harvey-Shack style scattered-light point spread component.
Models the broad, smooth “wings” of a real optical system’s PSF caused by surface micro-roughness, coating defects, and particulate contamination, using an image-plane power-law profile:
I(r) = (1 + (r / r0)^2)^(-b / 2)
which is flat near the origin (finite, integrable core) and falls off as r^-b for r >> r0. Exponents b of roughly 2 to 3 match measured stellar PSF wings (King 1971, Racine 1996).
This component is achromatic: all spectral channels receive the same profile. Set as a PSF (see CameraModel::set_psf()), it is taken as complete within its radius. The camera’s own scattered light, added to diffraction or to a PSF that was set, is set in angles with CameraModel::set_scatter() instead, and reaches across the frame.
- Template Parameters:
TSpectral – The spectral type (e.g., RGB, Visible8)
Public Functions
-
HarveyShackScatter(float falloff_exponent, float r0, float cutoff_radius = 0.f)¶
Constructs a HarveyShackScatter profile with the given parameters.
- Parameters:
falloff_exponent – Power-law exponent b (typically 2 to 3).
r0 – Shoulder radius in pixels.
cutoff_radius – Hard cutoff radius in pixels (0 means no cutoff).
- Throws:
std::runtime_error – if the exponent or r0 is not positive and finite, r0 is too small to square, or the cutoff is negative or NaN.
-
~HarveyShackScatter() override = default¶
-
HarveyShackScatter(const HarveyShackScatter&) = delete¶
-
HarveyShackScatter &operator=(const HarveyShackScatter&) = delete¶
-
virtual TSpectral evaluate(float x, float y) override¶
Evaluates the scatter profile at the given pixel offset from center.
- Parameters:
x – Horizontal offset from the center in pixel coordinates.
y – Vertical offset from the center in pixel coordinates.
- Returns:
The (achromatic) profile value for each spectral channel.
-
inline virtual bool is_pixel_integrated() const¶
Whether evaluate() gives the light a pixel centered at (x, y) receives, rather than the PSF’s intensity at that point.
A PSF’s intensity is integrated over each pixel. One that is already integrated over a pixel (see PSFSampling::PixelIntegrated) is instead taken at each pixel’s center, so that it is not integrated twice.
-
inline virtual bool includes_defocus() const¶
Whether the PSF already holds the defocus the camera’s focus gives, rather than being a point’s in focus, which the focus then blurs as it blurs diffraction (see PSFFocus).
-
inline int radius() const¶
How far from the source, in pixels, the PSF holds light; 0 if not set, in which case CameraModel::set_psf() gives it CameraModel::DEFAULT_PSF_RADIUS.