Skip to content

correct_smile_xcorr

Straighten the spectral lines of ctx.image from the frame's own lines.

Category Preprocessing (2-D image)
Backend astropy - wraps the domain-standard astropy implementation
Version 1.0.0
Reads ctx.image (an ImageFrame)
Writes image, extras.smile_xcorr, metrics.applied, metrics.n_bands, metrics.n_bands_rejected, metrics.fit_rms_px, metrics.amplitude_px, metrics.reference_row, metrics.row_lo, metrics.row_hi, metrics.poly_order

Lit columns: from the mean row profile of the reference band, median-filtered over 31 columns, above floor + signal_floor_margin × (max − floor), the floor being the median of the first (floor_edge = 'low') or last ('high') n_cols/12 columns ; fewer than 16 such columns means every column. Lit rows: the same rule on the mean column profile over the lit columns, with the floor at its minimum ; fewer than 32 means every row. Each band of band_height rows (starting at the first lit row) is averaged over the lit columns, Gaussian pre-smoothed by presmooth_px, flattened by a running median of continuum_window, and cross-correlated with the band starting at reference_row − band_height/2 over lags ±max_lag_px (plain overlap, parabolic refinement) ; bands with a peak below min_correlation or a lag at the search boundary are dropped. shift(row) = −lag is fitted with an astropy Polynomial1D of poly_order (LinearLSQFitter) with up to two 3σ clipping passes, re-anchored so shift(reference_row) = 0 and held constant outside the fitted rows. Skips (applied = 0, frame untouched): lit columns narrower than 4·max_lag_px, reference row outside the lit rows, fewer than min_bands bands, fit rms above max_fit_rms_px, amplitude above max_amplitude_px (the last two with fit_rms_px, amplitude_px and n_bands reported). Applied: every row resampled by numpy.interp at x + shift(row) (edge values held), image meta smile_corrected = True, and ctx.extras[output_key] = {shift_coefficients (lowest degree first), reference_row, fit_row_range, poly_order, fit_rms_px, n_bands}. Companions: correct_smile_polynomial applies a given Schroeder radius ; measure_arc_geometry measures the curvature on an arc-lamp frame.

Parameters

Parameter Default Required Description
reference_row None - Row whose columns stay fixed (shift = 0) ; null means the middle row. Use the row the extraction is centred on.
band_height 20 - Rows averaged per measurement band (at least 2).
poly_order 2 - Degree of shift(row): 2 captures a smile, 1 is a pure tilt.
max_lag_px 40 - Half-width (columns) of the cross-correlation lag search.
min_correlation 0.5 - Drop bands whose peak correlation is below this.
min_bands 8 - Skip with fewer surviving bands than this.
max_fit_rms_px 0.5 - Skip when the polynomial fit residual exceeds this (px).
max_amplitude_px 80.0 - Skip when the total shift across the frame exceeds this (px).
continuum_window 151 - Running-median window (columns) that flattens each band.
presmooth_px 1.0 - Gaussian pre-smoothing (columns) of each band ; 0 disables it.
signal_floor_margin 0.06 - Lit threshold = floor + this fraction of (max − floor), for columns and rows.
floor_edge 'low' - Which edge of the frame holds the unlit columns: 'low' or 'high'.
output_key 'smile_xcorr' - ctx.extras key that receives the fitted shift polynomial.

Use it

from spectro_kernel import run_algorithm

output = run_algorithm("correct_smile_xcorr", ctx, {
    "reference_row": None,
    "band_height": 20,
    "poly_order": 2,
    "max_lag_px": 40,
    "min_correlation": 0.5,
    "min_bands": 8,
    "max_fit_rms_px": 0.5,
    "max_amplitude_px": 80.0,
    "continuum_window": 151,
    "presmooth_px": 1.0,
    "signal_floor_margin": 0.06,
    "floor_edge": "low",
    "output_key": "smile_xcorr"
})

The CLI loads a single 1-D spectrum with --input; this algorithm needs ctx.image (an ImageFrame). Run it from Python or as a step of a pipeline preset.

{
  "tool": "correct_smile_xcorr",
  "arguments": {
    "session_id": "<session_id>",
    "params": {
      "reference_row": null,
      "band_height": 20,
      "poly_order": 2,
      "max_lag_px": 40,
      "min_correlation": 0.5,
      "min_bands": 8,
      "max_fit_rms_px": 0.5,
      "max_amplitude_px": 80.0,
      "continuum_window": 151,
      "presmooth_px": 1.0,
      "signal_floor_margin": 0.06,
      "floor_edge": "low",
      "output_key": "smile_xcorr"
    }
  }
}

Every algorithm is an MCP tool of the same name; describe_algorithm returns this page's metadata as JSON.

References

  • Kelson 2003, PASP 115, 688–699, arXiv:astro-ph/0303507 — line curvature modelled from the data on the unrectified frame.
  • Massey, Valdes & Barnes 1992 — A User's Guide to Reducing Slit Spectra with IRAF, NOAO (identify / reidentify along the slit, fitcoords, transform).
  • Tonry & Davis 1979, AJ 84, 1511 — cross-correlation with parabolic peak refinement.