flint.spice

SPICE-style cube trimming: mask everything outside small boxes around catalogued sources, crop to their union. A set of cubes (image and weight, across all Stokes) is trimmed with one shared set of boxes, so they all come out on the same grid. See flint.options.SpiceOptions.

Classes

SkyBoundingBox

A bounding box on the sky, held as angular offsets from a reference position.

SpiceCubeSetupInfo

Information about a cube that will be spiced after sanity checks

Functions

_component_sky_box(→ SkyBoundingBox)

Sky box of a single catalogue row's ellipse, or point if shape_cols is None.

_merge_sky_boxes(→ SkyBoundingBox)

Smallest sky box containing all inputs. All must share a reference position

_resolve_columns(→ tuple[str | None, str, str, ...)

Resolve (island_col, ra_col, dec_col, shape_cols) for a catalogue.

_row_psf_beam(→ radio_beam.Beam)

The PSF to re-convolve a deconvolved source size with: per-row columns

check_cubes_share_shape(→ tuple[int, ...])

The shape shared by every cube. Image and weight cubes across all Stokes

compress_methods(→ list[str])

Compression method for each image cube, then each weight cube.

cube_shape(→ tuple[int, ...])

Shape of a FITS file's primary HDU in numpy order, read from its header

island_sky_boxes(→ list[SkyBoundingBox])

Per-island sky boxes: group catalogue rows by island, merge each island's

keep_mask_from_boxes(→ numpy.ndarray)

Boolean mask, True inside the union of the supplied boxes

load_component_table(→ astropy.table.Table)

Return a table given either a loaded table or a path to one on disk

sanity_check_for_spicing(→ SpiceCubeSetupInfo)

Checks to ensure the provided cube can be spiced.

setup_spice_header(→ astropy.io.fits.Header)

Header for the spiced cube: cropped to overall, with the reference

shared_pixel_boxes(→ list[flint.coadd.linmos.BoundingBox])

Project sky boxes onto the pixel grid shared by every cube.

spice_fits(→ pathlib.Path)

Mask every pixel outside pixel_boxes to NaN and crop to their union.

Module Contents

class flint.spice.SkyBoundingBox(/, **data: Any)[source]

Bases: flint.options.BaseOptions

A bounding box on the sky, held as angular offsets from a reference position.

Offsets are on-sky angles (the longitude offset already carries the cos(dec) factor), so a box may be projected onto any image’s pixel grid.

to_bounding_box(wcs: astropy.wcs.WCS, image_shape: tuple[int, int]) → flint.coadd.linmos.BoundingBox | None[source]

Project onto an image’s pixel grid, or None if the box falls off it

Parameters:
  • wcs (WCS) – WCS of the target image

  • image_shape (tuple[int, int]) – Shape of a single plane of the target

Returns:

The clipped pixel box, or None if fully off-image

Return type:

BoundingBox | None

property corners: astropy.coordinates.SkyCoord[source]

The four corners of the box

lat_max_arcsec: float[source]

Largest latitude offset from the reference position

lat_min_arcsec: float[source]

Smallest latitude offset from the reference position

lon_max_arcsec: float[source]

Largest longitude offset from the reference position

lon_min_arcsec: float[source]

Smallest longitude offset from the reference position

reference_dec_deg: float[source]

Declination of the reference position, in degrees

reference_ra_deg: float[source]

Right ascension of the reference position, in degrees

class flint.spice.SpiceCubeSetupInfo[source]

Bases: NamedTuple

Information about a cube that will be spiced after sanity checks have been performed.

cube_shape: tuple[int, ...][source]

Shape of the cube in numpy order

fits_path: pathlib.Path[source]

Path to the cube

image_shape: tuple[int, int][source]

Shape of a single plane of the cube

flint.spice._component_sky_box(row: astropy.table.Row, ra_col: str, dec_col: str, shape_cols: tuple[str, str, str] | None, radec_unit: astropy.units.Unit, shape_unit: astropy.units.Unit, reference: astropy.coordinates.SkyCoord, deconvolved: bool, psf_beam: radio_beam.Beam | None) → SkyBoundingBox[source]

Sky box of a single catalogue row’s ellipse, or point if shape_cols is None.

No beamwidth padding applied here.

flint.spice._merge_sky_boxes(sky_boxes: list[SkyBoundingBox]) → SkyBoundingBox[source]

Smallest sky box containing all inputs. All must share a reference position

flint.spice._resolve_columns(table: astropy.table.Table, spice_options: flint.options.SpiceOptions, is_user_catalogue: bool) → tuple[str | None, str, str, tuple[str, str, str] | None][source]

Resolve (island_col, ra_col, dec_col, shape_cols) for a catalogue.

flint.spice._row_psf_beam(row: astropy.table.Row, spice_options: flint.options.SpiceOptions, is_user_catalogue: bool, common_beam_shape: flint.convol.BeamShape) → radio_beam.Beam[source]

The PSF to re-convolve a deconvolved source size with: per-row columns if given, otherwise the pipeline’s common restoring beam.

flint.spice.check_cubes_share_shape(fits_paths: list[pathlib.Path]) → tuple[int, ...][source]

The shape shared by every cube. Image and weight cubes across all Stokes come off the same linmos grid, so a disagreement means something upstream has gone wrong. Reads headers only.

Parameters:

fits_paths (list[Path]) – The cubes to compare

Returns:

The shape they share

Return type:

tuple[int, …]

Raises:

ValueError – The cubes do not all share a shape

flint.spice.compress_methods(compress_method: str, cube_count: int, weight_cube_count: int) → list[str][source]

Compression method for each image cube, then each weight cube.

Weight and background cubes are smooth, so quantizing them (‘tile-rice’) makes them bigger rather than smaller; they get lossless ‘tile-gzip’ instead.

flint.spice.cube_shape(fits_path: pathlib.Path) → tuple[int, ...][source]

Shape of a FITS file’s primary HDU in numpy order, read from its header

flint.spice.island_sky_boxes(table: astropy.table.Table, wcs: astropy.wcs.WCS, beam_shape: flint.convol.BeamShape, spice_options: flint.options.SpiceOptions, is_user_catalogue: bool) → list[SkyBoundingBox][source]

Per-island sky boxes: group catalogue rows by island, merge each island’s component ellipses into one box, then pad by spice_options.n_beamwidths restoring-beamwidths.

Boxes are returned on the sky, referenced to wcs’s reference position. Projection onto a pixel grid happens per target image in spice_fits.

flint.spice.keep_mask_from_boxes(bounding_boxes: list[flint.coadd.linmos.BoundingBox], image_shape: tuple[int, int]) → numpy.ndarray[source]

Boolean mask, True inside the union of the supplied boxes

flint.spice.load_component_table(catalogue: pathlib.Path | astropy.table.Table) → astropy.table.Table[source]

Return a table given either a loaded table or a path to one on disk

flint.spice.sanity_check_for_spicing(fits_path: pathlib.Path, hdul: astropy.io.fits.HDUList, overall: flint.coadd.linmos.BoundingBox) → SpiceCubeSetupInfo[source]

Checks to ensure the provided cube can be spiced.

Parameters:
  • fits_path (Path) – Path to the fits cube used for logging

  • hdul (fits.HDUList) – The open fits cube handler

  • overall (BoundingBox) – The overall bounding box of the spicing

Raises:
  • ValueError – Primary HDU holds no image

  • ValueError – Integer pixel type in the cube

  • ValueError – If an extra image extension is present in the fits file

Returns:

Information about the cube setup

Return type:

SpiceCubeSetupInfo

flint.spice.setup_spice_header(header: astropy.io.fits.Header, overall: flint.coadd.linmos.BoundingBox, history_message: str, no_of_empty_blocks: int = 3) → astropy.io.fits.Header[source]

Header for the spiced cube: cropped to overall, with the reference pixel shifted to match and spare room for later keywords

Parameters:
  • header (fits.Header) – Header of the cube being spiced. It is not modified

  • overall (BoundingBox) – The union of the island boxes being cropped to

  • history_message (str) – A message to add to the header’s history

  • no_of_empty_blocks (int, optional) – Number of spare 2880-byte header blocks (36 cards each) to reserve. Defaults to 3.

Returns:

The header for the spiced cube

Return type:

fits.Header

flint.spice.shared_pixel_boxes(fits_paths: list[pathlib.Path], sky_boxes: list[SkyBoundingBox]) → list[flint.coadd.linmos.BoundingBox][source]

Project sky boxes onto the pixel grid shared by every cube.

Spicing all cubes with this one set of boxes is what leaves them on an identical grid afterwards, so the cubes must start on one. Reads headers only.

Parameters:
  • fits_paths (list[Path]) – The cubes about to be spiced together

  • sky_boxes (list[SkyBoundingBox]) – Sky boxes to project

Returns:

Those boxes that land on the shared grid

Return type:

list[BoundingBox]

Raises:

ValueError – The cubes do not share a grid, or no box overlaps it

flint.spice.spice_fits(fits_path: pathlib.Path, pixel_boxes: list[flint.coadd.linmos.BoundingBox], output_path: pathlib.Path | None = None) → pathlib.Path[source]

Mask every pixel outside pixel_boxes to NaN and crop to their union.

Works on a single plane or a multi-channel cube. Extensions such as the beam table are carried through untouched. Every cube spiced with the one set of boxes from shared_pixel_boxes comes out on the same grid.

Parameters:
  • fits_path (Path) – The image or cube to spice

  • pixel_boxes (list[BoundingBox]) – Pixel boxes to keep, on this file’s grid

  • output_path (Path | None, optional) – Directory to write the spiced cube into, deleting fits_path once written. Defaults to replacing fits_path in place.

Returns:

The spiced cube

Return type:

Path