Skip to content

Shift-and-stack: joint position+rate covariance weighting (interim: report at time centroid) #399

Description

@matthewholman

Summary

The "streak" rate-fitting path is really the model for shift-and-stack measurements (shift each exposure by an assumed motion, coadd; the best rate pair focuses the flux into a PSF). Such a detection yields a joint estimate of position and rate from the same photons, so the two are correlated. layup currently weights the position and rate rows with a strictly diagonal weight matrix, which drops those correlations. This issue records the model and the interim guidance; a fuller treatment is future work.

Measurement model

Shift-and-stack fits θ(t) = θ₀ + ω·(t − t_ref) to the exposures, giving the focused-PSF position θ₀ at t_ref and the rate ω jointly — an intercept + slope estimate over the exposure epochs. Its covariance is the usual linear-fit one:

  • Cov(θ₀, ω) = 0 iff t_ref is the (SNR-weighted) time centroid of the exposures. Off-centroid, position and rate are correlated with scale ~(t_ref − t̄).
  • σ_ω ≈ σ_θ / T_eff (T_eff = the baseline spread): the rate precision is set by the position precision and the time baseline — they are not independent inputs.
  • σ_ω is really the curvature of the SNR-vs-rate ("focus") surface.

Current state in layup

  • Forward model is already consistent: for a streak/shift-stack row, both the apparent position and the apparent rate are evaluated at the single epoch this_det.epoch (light-time corrected, incl. the (1−q/c) rate factor). No model change needed as long as that epoch is the stack reference/centroid.
  • get_weight_matrix (orbit_fit.cpp) is diagonal: four independent weights from rmsRA/rmsDec (position) and rmsRArate/rmsDecrate (rate). It drops (a) the position↔rate cross-block, and (b) the within-blocks (RA–Dec, RARate–DecRate).
  • Observation::inverse_covariance (detection.cpp) is declared + pybind-exposed but unused — it's the natural home for a per-observation covariance block.

Interim guidance (no code change)

Instruct users to report the shift-and-stack position at the time centroid of the exposures, and to supply position/rate uncertainties derived at that reference. At the centroid the position–rate cross-covariance vanishes, so the current diagonal weighting is a good approximation and the correlations we don't yet fit are avoided. (Worth stating in the streak/shift-stack ingestion docs.)

Future work

  • Ingest and use the joint (θ₀, ω) covariance (a 4×4, or position-at-centroid + rate + cross terms) via the existing inverse_covariance slot, so off-centroid references and reported position–rate/RA–Dec/RARate–DecRate correlations are weighted correctly.
  • Note the structural gap: a single epoch + four scalar σ's can't represent σ_ω ≈ σ_θ/T_eff (the baseline tying them together isn't carried) — full covariance ingestion resolves this.
  • Consider renaming the internal "streak" concept to reflect shift-and-stack (or document that it covers both trailed-source and shift-and-stack measurements, which share the (position, rate) model but differ in how the covariance arises).

From a modeling discussion with @matthewholman.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestorbitfittasks that need to be completed as part of layup orbfit

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions