stdpipe.photometry_measure module

Aperture photometry measurement routines.

This module contains functions for performing aperture photometry on detected objects.

stdpipe.photometry_measure.measure_objects(obj, image, aper=3, bkgann=None, bkg_order=0, fwhm=None, psf=None, optimal=False, group_sources=True, grouper_radius=None, mask=None, bg=None, err=None, gain=None, bg_size=64, sn=None, centroid_iter=0, centroid_method='com', keep_negative=True, get_bg=False, verbose=False)[source]

Photometry at the positions of already detected objects.

Supports both standard aperture photometry and optimal extraction that provides ~10% S/N improvement for point sources (Naylor 1998).

It will estimate and subtract the background unless external background estimation (bg) is provided, and use user-provided noise map (err) if requested.

The results may optionally be filtered to drop detections with low signal to noise ratio if sn is set and positive. It will also filter out events with negative flux unless keep_negative is True.

Parameters:
objastropy.table.Table

Table with initial object detections to be measured.

imagendarray

Input image as a NumPy array.

aperfloat

Circular aperture radius in pixels for flux measurement. For optimal extraction, this is the clipping radius.

bkganntuple of float or None

Background annulus (inner, outer radii) for local background estimation. If None, global background model is used instead.

bkg_orderint

Polynomial order for local background fitting. 0 = constant (mean), 1 = plane (linear gradient, recommended), 2 = quadratic surface. Only used if bkgann is set.

fwhmfloat, callable, or None

If provided, aper and bkgann are measured in units of FWHM. Also used to define Gaussian PSF for optimal extraction if psf is not provided. A callable (e.g. a stdpipe.photometry.FWHMMap) is accepted and evaluated at each source position for the optimal-extraction PSF width; aperture/bkgann scaling, PSF-weighted centroiding, and local background annuli still use the scalar summary float(fwhm).

psfdict or None

PSF model for optimal extraction and PSF-weighted centroiding. Can be a dict from psf.run_psfex(), psf.load_psf(), or psf.create_psf_model(). If None, a Gaussian PSF is created from the fwhm parameter.

optimalbool

If True, use optimal extraction instead of aperture photometry. Requires either psf or fwhm to define the PSF profile.

group_sourcesbool

If True and optimal=True, use grouped optimal extraction for overlapping sources. Fits nearby sources simultaneously for better accuracy in crowded fields.

grouper_radiusfloat or None

Radius in pixels for grouping nearby sources. Sources within this distance are fitted simultaneously. If None, defaults to 2*aper. Only used if group_sources=True.

maskndarray of bool or None

Image mask (True values are masked).

bgndarray or None

If provided, use this background instead of automatically computed one. Must have the same shape as input image.

errndarray or None

Image noise map to use instead of automatically computed one.

gainfloat or None

Image gain in e-/ADU, used to build image noise model.

bg_sizeint

Background grid size in pixels.

snfloat or None

Minimal S/N ratio. If set, measurements with magnitude errors exceeding 1/sn will be discarded.

centroid_iterint

Number of centroiding iterations to run before photometry.

centroid_methodstr

Centroiding method: ‘com’ (center-of-mass) or ‘psf’ (PSF-weighted). PSF-weighted is more accurate but degrades with heavy random masking (>20%). Requires psf or fwhm parameter.

keep_negativebool

If False, measurements with negative fluxes will be discarded.

get_bgbool

If True, also return estimated background and background noise images.

verbosebool or callable

Whether to show verbose messages. May be boolean or a print-like function.

Returns:
objastropy.table.Table

Copy of original table with flux, fluxerr, mag and magerr columns replaced with measured values.

bg_imagendarray

Background image (only returned if get_bg=True).

err_imagendarray

Error image (only returned if get_bg=True).

Notes

Quality flags set in the flags column:

  • 0x200: At least one aperture pixel is masked

  • 0x400: Invalid position or local background estimation failed

  • 0x800: Optimal extraction failed (NaN result)

  • 0x1000: Poor fit quality (chi2 > 1000, numerical instability)

stdpipe.photometry_measure.measure_objects_sep(obj, image, aper=3, bkgann=None, fwhm=None, psf=None, optimal=False, group_sources=True, group_factor=2.0, group_radius_factor=1.0, group_halo_factor=1.2, maxiter=20, fit_positions=True, fit_radius=0.0, damp_snthresh=0.0, mask=None, bg=None, err=None, gain=None, bg_size=64, sn=None, centroid_iter=0, centroid_psf=None, keep_negative=True, get_bg=False, clip_sigma=3.0, clip_iters=5, verbose=False)[source]

Photometry at the positions of already detected objects using SEP routines.

Uses SEP’s built-in features for optimal extraction with sigma-clipped background (via sum_circle_optimal), PSF fitting photometry (via sep.psf_fit), and iterative centroiding (via winpos).

Only available if SEP version 1.4+ with these features is installed.

Parameters:
objastropy.table.Table

Table with initial object detections to be measured.

imagendarray

Input image as a NumPy array.

aperfloat

Circular aperture radius in pixels for flux measurement.

bkganntuple of float or None

Background annulus (inner, outer radii) for local background. For optimal extraction, SEP handles this internally with sigma-clipping. For aperture photometry, sep.stats_circann() is used.

fwhmfloat, callable, or None

If provided, aper and bkgann are measured in units of FWHM. Also used for Gaussian PSF in optimal extraction, PSF fitting, and centroiding. A callable (e.g. a stdpipe.photometry.FWHMMap) is accepted and evaluated at each source position: per-source aperture/bkgann arrays feed the SEP photometry routines and the per-source width feeds sep.sum_circle_optimal. The scalar summary float(fwhm) is used for the SEP windowed centroider (which requires a scalar sigma).

psfdict, sep.PSF, or None

PSF model for PSF fitting photometry. When provided, PSF fitting is used instead of aperture or optimal extraction. Can be a PSFEx dict from stdpipe.psf.run_psfex() or a sep.PSF object.

optimalbool

If True, use optimal extraction via sep.sum_circle_optimal(). Requires fwhm. Ignored when psf is provided.

group_sourcesbool

If True, use grouped fitting for optimal or PSF photometry.

group_factorfloat

Local fitting halo factor for grouped PSF fitting. Only used for PSF fitting when group_sources=True; SEP determines PSF-fit connectivity from direct fit-support overlap.

group_radius_factorfloat

Connectivity scale for grouped optimal extraction. Only used for optimal extraction when group_sources=True. The default 1.0 groups sources whose apertures overlap.

group_halo_factorfloat or None

Local context halo scale for grouped optimal extraction. The default 1.2 keeps a modest expanded solve context without widening source connectivity. None lets SEP use group_radius_factor.

maxiterint

Maximum number of PSF fitting iterations.

fit_positionsbool

If True, fit source positions during PSF fitting.

fit_radiusfloat

If > 0, only pixels within this radius (in pixels) of the source center participate in PSF fitting. 0 means use the full PSF stamp. Values of 2-3x FWHM reduce scatter in crowded fields.

damp_snthreshfloat

S/N threshold for damping PSF fit updates.

maskndarray of bool or None

Image mask (True values are masked).

bgndarray or None

If provided, use this background instead of automatically computed one.

errndarray or None

Image noise map.

gainfloat or None

Image gain in e-/ADU, used to build image noise model.

bg_sizeint

Background grid size in pixels.

snfloat or None

Minimal S/N ratio for filtering.

centroid_iterint

Number of centroiding iterations (uses SEP’s built-in iteration).

centroid_psfdict, sep.PSF, or None

PSF model for centroiding. If None, uses psf if available, otherwise Gaussian windowed centroiding.

keep_negativebool

If False, measurements with negative fluxes will be discarded.

get_bgbool

If True, also return estimated background and noise images.

clip_sigmafloat

Sigma value for clipping when bkgann is provided.

clip_itersint

Maximum number of clipping iterations when bkgann is provided. Set to 0 to disable clipping.

verbosebool or callable

Whether to show verbose messages. May be boolean or print-like function.

Returns:
objastropy.table.Table

Copy of table with flux, fluxerr, mag and magerr columns from SEP measurements. When psf is provided, also includes x_psf, y_psf (fitted positions), chi2_psf, niter_psf, and flags_psf columns.

bg_imagendarray

Background image (only returned if get_bg=True).

err_imagendarray

Error image (only returned if get_bg=True).

Notes

Quality flags set in the flags column:

  • 0x200: At least one aperture pixel is masked (aperture/optimal paths)

  • 0x400: Invalid position

  • 0x800: Optimal extraction failed (NaN result)

  • 0x1000: PSF fit returned non-zero quality flag, or PSF fit failed (NaN result)

  • 0x2000: Large centroid shift during PSF fit (>1 pixel)

stdpipe.photometry_measure.measure_aperture_deblended(image, x, y, aper, psf, *, flux_seed, flux_psf, flux_psf_err=None, target=None, fwhm=None, err=None, mask=None, gain=None, bg=None, aperture_correction='ratio_field', correction_field_kwargs=None, ratio_clip=(0.5, 3.0), outlier_clip=5.0, min_for_field_fit=6, bad_flag=4096, propagate_neighbour_errors=True, overlap_subpixel=4, diagnostics=False, verbose=False)[source]

Aperture photometry with PSF-based neighbour subtraction.

For every position in (x[target], y[target]) measure the aperture flux on image, subtract the modelled contribution of every other detection inside that aperture (using each one’s PSF-scaled total flux), and add back the target’s own modelled contribution. The result is an aperture flux that handles crowding the way PSF photometry would, while remaining robust to PSF-model mismatch on the target itself: PSF-model error feeds only into the small neighbour-subtraction term, partially cancelling between model_flux and self_flux.

The “total flux” used to scale each detection’s PSF stamp in the neighbour model is

total_i = flux_seed_i * ratio(x_i, y_i)

where ratio = flux_psf / flux_seed is fit as a smooth field across the frame from the per-source ratios. This provides a position-dependent aperture correction even when the PSF model has smoothly varying shape.

Parameters:
image2-D ndarray

Background-subtracted image (or pass the background separately via bg).

x, y(N,) array-like

Pixel positions of all detections in the region (targets + neighbours used only to model contamination).

aperfloat

Aperture radius. In image pixels by default; interpreted as a multiple of fwhm when fwhm is given (matching the convention of measure_objects()).

psfdict

PSF model as returned by stdpipe.psf.run_psfex(), stdpipe.psf.load_psf(), or stdpipe.psf.create_psf_model(). May be position-dependent.

flux_seed(N,) array-like

Per-source aperture flux from the upstream detection pass. Used to anchor the smooth aperture-correction ratio field.

flux_psf(N,) array-like

Per-source PSF-fitted flux from the upstream PSF-fitting pass. Used to anchor the ratio field and to scale neighbour PSF stamps in the model image.

flux_psf_err(N,) array-like, optional

Per-source PSF-fit flux errors. Required when propagate_neighbour_errors=True.

target(N,) bool mask or array of int indices, optional

Which detections to measure. Detections not in target still appear in the neighbour model. Default: every detection.

fwhmfloat, optional

Source FWHM in pixels. When given, aper is interpreted as a multiple of FWHM.

err2-D ndarray, optional

Per-pixel 1-sigma error map for the input image. Used by sep.sum_circle to compute the aperture noise.

mask2-D bool ndarray, optional

Bad-pixel mask. True pixels are excluded from aperture sums.

gainfloat, optional

Detector gain in e-/ADU; forwarded to sep.sum_circle for Poisson noise on the aperture sum.

bg2-D ndarray, optional

Background map. If given, it is subtracted from image before the aperture sums (so image itself need not be background- subtracted).

aperture_correction{‘ratio_field’, ‘fixed’, ‘none’}

How to map flux_seed to “total flux” when scaling neighbour PSF stamps. 'ratio_field' fits a smooth 2-D field of the per-source PSF/seed ratio (default; see correction_field_kwargs and min_for_field_fit); 'fixed' uses a single MAD-clipped median ratio; 'none' uses flux_seed as the total flux.

correction_field_kwargsdict, optional

Forwarded to stdpipe.smoothing.fit_vector_field_2d(). The default uses the LOESS backend with k=100 and per-axis scales chosen from the spread of the input positions, which is a quality upgrade over the rigid 2-D quadratic used in earlier prototypes.

ratio_clip(lo, hi)

Hard limits applied to the modelled ratio at every position to guard against extrapolation pathologies.

outlier_clipfloat

MAD multiple used to reject outliers from the per-source ratio sample before fitting the field.

min_for_field_fitint

Minimum number of clean ratios required to fit the smooth field; below this, the median ratio is used everywhere.

bad_flagint

Flag bit OR’ed into the output flags for measurements that could not be computed.

propagate_neighbour_errorsbool

If True (default), inflate fluxerr by the quadrature sum of each near neighbour’s PSF-flux error scaled by its overlap with the target aperture. Requires flux_psf_err.

overlap_subpixelint

Sub-pixel sampling factor for the per-neighbour aperture overlap integrals. 1 for a faster pixel-centre mask.

diagnosticsbool

If True, attach extra columns to the output table: flux_ap_raw, flux_model, flux_total_model, flux_ratio_model, self_frac, flux_neighbour_err.

verbosebool or callable

Boolean to enable default print logging, or a print-like callable.

Returns:
astropy.table.Table

One row per measured target, in the order they appeared in the input. Columns: x, y, flux, fluxerr, mag, magerr, flags. Diagnostic columns when diagnostics=True.