Skip to content

Source footprint

cutana.source_footprint

Check that a catalogue's sources actually fall inside the products they name.

The failure this exists to catch is silent. A source outside its FITS file's footprint still produces a cutout -- an array of the requested size, entirely edge-trim -- so a run completes, writes N files, and reports nothing wrong. Nothing else in the validation path notices: the columns are present, the coordinates are legal sky positions, and the file is readable. Only the pairing of the two is wrong.

Two outcomes, and the difference decides what a user does next:

  • the centre is outside the image -- an error, since that cutout is entirely trim and the row is a mistake
  • the centre is inside but the requested box runs past an edge -- a warning, since a partial cutout is often exactly what was wanted at a survey boundary

check_sources_in_products is exported from the package. It is the one validation helper that is, because it is the one an external tool has a reason to call on its own: a catalogue builder wants to check its own output before handing it over, and reaching into a submodule for that would be a dependency with no compatibility promise.

read_image_footprint(fits_path)

Read the celestial WCS and pixel dimensions of a FITS file.

Parameters:

Name Type Description Default
fits_path str

File to read.

required

Returns:

Type Description
Optional[Tuple[WCS, Tuple[int, int]]]

The WCS and the (height, width) of the HDU it came from, or None when no HDU has a

Optional[Tuple[WCS, Tuple[int, int]]]

celestial WCS. That is not an error here -- check_fits_files_exist owns whether a file is

Optional[Tuple[WCS, Tuple[int, int]]]

usable at all, and this check has nothing to say about a file it cannot place on the sky.

Raises:

Type Description
KeyError

If a celestial HDU has no NAXIS1/NAXIS2. Having found the WCS, an unreadable shape is a broken invariant rather than a reason to keep looking: continuing would return None and leave the file silently unchecked.

source_offset_from_image(wcs_obj, shape, ra, dec)

Locate a sky position in an image, and say how far outside it is if it is.

world_to_pixel returns 0-based pixel centres, so an image of width W covers -0.5 to W - 0.5. Treating it as 0 to W - 1 makes the outer half-pixel of every edge read as outside, which turns legitimate sources into errors that fail the whole run.

Parameters:

Name Type Description Default
wcs_obj WCS

The image's celestial WCS.

required
shape Tuple[int, int]

The image's (height, width) in pixels.

required
ra float

Right ascension in degrees.

required
dec float

Declination in degrees.

required

Returns:

Type Description
float

The x and y pixel coordinates, and how many pixels outside the image the position falls --

float

zero when it is inside. The distance is what makes a report actionable: two pixels past an

float

edge is a rounding argument, twenty thousand is the wrong tile.

cutout_fits_inside(x, y, shape, diameter)

Whether a box of diameter pixels centred on (x, y) lies wholly inside the image.

The same -0.5 convention as source_offset_from_image, so a source that is inside cannot have a cutout the two functions disagree about.

Parameters:

Name Type Description Default
x float

Column of the centre, 0-based.

required
y float

Row of the centre, 0-based.

required
shape Tuple[int, int]

The image's (height, width) in pixels.

required
diameter int

Cutout side length in pixels.

required

Returns:

Type Description
bool

True when nothing would be trimmed.

check_sources_in_products(catalogue_df, sample_size=DEFAULT_SAMPLE_SIZE)

Check that each source falls inside every FITS file its row names.

Returns the same (errors, warnings) shape as check_fits_files_exist, so it slots into the same place in a validation report.

Parameters:

Name Type Description Default
catalogue_df DataFrame

Catalogue with SourceID, RA, Dec and fits_file_paths, and one of diameter_pixel or diameter_arcsec.

required
sample_size int

Rows to check when the catalogue is larger than this.

DEFAULT_SAMPLE_SIZE

Returns:

Type Description
List[str]

Errors for sources whose position falls outside a file they name, warnings for cutouts

List[str]

that fit only partly inside one. A file with no readable celestial WCS produces neither --

Tuple[List[str], List[str]]

this check has nothing to say about a file it cannot place on the sky, and

Tuple[List[str], List[str]]

check_fits_files_exist owns whether the file is usable at all.

Tuple[List[str], List[str]]

A malformed fits_file_paths cell is an error rather than an exception, because this runs

Tuple[List[str], List[str]]

inside a validation pass whose job is to collect problems rather than stop at the first.