stdpipe.astrometry_wcs module

stdpipe.astrometry_wcs.fit_zpn_wcs_from_points(xy: ndarray, sky: SkyCoord, wcs_init: WCS, pv_deg: int = 5, fit_crpix: bool = True, fit_crval: bool = True, fit_cd: bool = True, fit_pv: bool = True, robust_loss: str = 'soft_l1', f_scale_arcsec: float = 2.0, max_nfev: int = 200)[source]

Fit a ZPN WCS by optimizing WCS parameters against matched (x,y) <-> (ra,dec).

Parameters:
xy(N,2) array

Pixel coordinates (0-based as in astropy WCS, i.e. origin=0).

skySkyCoord (N)

Reference sky positions.

wcs_initastropy.wcs.WCS

Initial WCS; MUST already be ZPN (RA—ZPN/DEC–ZPN) or at least usable as base.

pv_degint

Degree for PV2_m coefficients to fit (PV2_0..PV2_pv_deg).

fit_*bool

Toggle which parameter blocks to optimize.

robust_lossstr

Passed to scipy.optimize.least_squares(loss=…). Good options: ‘linear’, ‘soft_l1’, ‘huber’, ‘cauchy’.

f_scale_arcsecfloat

Robust loss scale in arcsec.

max_nfevint

Optimization iterations (SciPy).

Returns:
wcs_bestastropy.wcs.WCS
resultscipy OptimizeResult (or None if SciPy not available)

Notes

For stability, the solver runs in two stages when fit_pv is True: it first fits CRPIX/CRVAL/CD with PV fixed, then fits all free parameters (including PV) with conservative bounds to prevent invalid projections.

stdpipe.astrometry_wcs.tan_wcs_to_zpn(w_tan: WCS, pv_deg: int = 7, n_samples: int = 256, theta_max_deg: float | None = None, drop_sip: bool = True) WCS[source]

Convert a celestial TAN WCS into a ZPN WCS with PV2_m initialized to approximate TAN.

Parameters:
w_tanastropy.wcs.WCS

Input TAN WCS (2D celestial).

pv_degint

Highest PV degree to initialize (PV2_0..PV2_pv_deg). 5–9 is usually plenty; higher can get wiggly.

n_samplesint

Samples used for the polynomial fit.

theta_max_degfloat or None

Max angular radius (deg) over which to match TAN. If None, estimated from image footprint corners using pixel_shape.

drop_sipbool

If True, removes SIP distortions from the returned WCS.

Returns:
w_zpnastropy.wcs.WCS

A ZPN WCS with same CRVAL/CRPIX/CD and PV2_m initialized.

Notes

TAN (gnomonic) radial law: r = tan(theta) [in radians] In “degrees” units (common in FITS WCS plane coordinates), that’s:

r_deg = tan(theta_rad) * (180/pi)

ZPN radial law: r_deg ≈ sum_{m=0..M} PV2_m * theta_deg^m We set PV2_0 = 0 and fit PV2_1..PV2_M to approximate the TAN law over theta in [0, theta_max_deg].

stdpipe.astrometry_wcs.convert_wcs_projection(wcs_input: WCS, target_projection: str, pv_deg: int = 5) WCS[source]

Convert a celestial WCS to a different projection type.

Parameters:
wcs_inputWCS

Input WCS (any celestial projection).

target_projectionstr

Target projection code, e.g. 'TAN', 'ZPN', 'STG', 'ARC', 'ZEA', 'SIN', etc.

pv_degint, optional

ZPN PV polynomial degree (only used when target_projection is 'ZPN'). Default 5.

Returns:
WCS

New WCS with the target projection. For ZPN the PV coefficients are initialised to approximate the input projection’s radial law. For other projections CRPIX/CRVAL/CD are copied and CTYPE is replaced.

stdpipe.astrometry_wcs.fit_wcs_from_points(xy, world_coords, proj_point='center', projection=None, sip_degree=None, pv_deg=5)[source]

Drop-in wrapper around astropy.wcs.utils.fit_wcs_from_points() that also handles ZPN projection (which astropy does not natively fit) and ZPN-SIP (ZPN radial distortion plus SIP polynomial corrections).

Parameters:
xytuple of arrays (x, y) or (2, N) array

Pixel coordinates (same convention as the astropy function).

world_coords~astropy.coordinates.SkyCoord

Reference sky positions.

proj_pointstr, optional

Passed through to astropy for non-ZPN projections.

projection~astropy.wcs.WCS or other, optional

Projection template. If this is a WCS with RA---ZPN / DEC--ZPN CTYPEs, the ZPN fitter is used instead of astropy’s.

sip_degreeint or None, optional

SIP polynomial degree. For TAN projections, controls SIP distortion order. For ZPN projections, if > 0, SIP corrections are fitted on top of ZPN PV parameters to capture non-radial distortions.

pv_degint, optional

ZPN PV polynomial degree (PV2_0 PV2_pv_deg). Default 5.

Returns:
wcs~astropy.wcs.WCS

Fitted WCS (same return type as the astropy function).