astra.image_handler#

Astronomical image processing and FITS file management utilities.

This module provides functions for handling astronomical images captured from observatory cameras. It manages image directory creation, data type conversion, and FITS file saving with proper headers and metadata.

Key features: - Automatic directory creation with date-based naming - Image data type conversion and array reshaping for FITS compatibility - FITS file saving with comprehensive metadata and WCS support - Intelligent filename generation based on observation parameters

The module handles various image types including light frames, bias frames, dark frames, and calibration images, ensuring proper metadata preservation and file organization for astronomical data processing pipelines.

Classes

ImageHandler(header[, image_directory, ...])

Class that stores image_directory and header.

class astra.image_handler.ImageHandler(header: ObservatoryHeader, image_directory: Path | None = None, filename_templates: FilenameTemplates | None = None, logger: Logger | None = None, observing_date: datetime | None = None)[source]#

Bases: object

Class that stores image_directory and header.

header#

FITS header template for images.

Type:

fits.Header

image_directory#

Directory path to save images. If None, must be set before saving images.

Type:

Path | None

last_image_path#

Path of the last saved image.

Type:

Path | None

last_image_timestamp#

Timestamp of the last saved image.

Type:

datetime | None

filename_templates#

Templates for generating filenames. Uses Python str.format() syntax by default. For more advanced logic, use JinjaFilenameTemplates class.

Type:

FilenameTemplates

logger#

Logger for logging messages.

Type:

logging.Logger

save_image(...)[source]#

Save an image as a FITS file with proper headers and filename.

from_action(...)[source]#

Create an ImageHandler instance from an action and observatory.

get_observatory_location()[source]#

Get the observatory location as an EarthLocation object.

has_image_directory()[source]#

Check if the image_directory is set.

Examples

>>> from astra.image_handler import ImageHandler
>>> from astra.header_manager import ObservatoryHeader
>>> from pathlib import Path
>>> header = ObservatoryHeader.get_test_header()
>>> header['FILTER'] = 'V'
>>> image_handler = ImageHandler(header=header, image_directory=Path("images"))
>>> image_handler.image_directory
PosixPath('images')
>>> image_handler.header['FILTER']
'V'
property image_directory: Path#
has_image_directory() bool[source]#
classmethod from_action(action: Action, paired_devices: PairedDevices, observatory_config: ObservatoryConfig, fits_config: DataFrame, logger: ObservatoryLogger)[source]#

Create ImageHandler from an action and observatory.

save_image(image: List[int] | ndarray, image_info: ImageMetadata, maxadu: int, device_name: str, exposure_start_datetime: datetime, sequence_counter: int = 0, header: ObservatoryHeader | None = None, image_directory: str | Path | None = None, wcs: WCS | None = None) Path[source]#

Save an astronomical image as a FITS file with proper headers and filename.

Transforms raw image data, updates FITS headers with observation metadata, optionally adds WCS information, and saves as a FITS file with an automatically generated filename based on image properties.

Parameters:
  • image (list[int] | np.ndarray) – Raw image data to save.

  • image_info (ImageMetadata) – Image metadata for data type determination.

  • maxadu (int) – Maximum ADU value for the image.

  • header (fits.Header) – FITS header containing FILTER, IMAGETYP, OBJECT, EXPTIME.

  • device_name (str) – Camera/device name for filename generation.

  • exposure_start_datetime (datetime) – UTC datetime when exposure started.

  • image_directory (str) – Subdirectory name within the images directory.

  • wcs (WCS, optional) – World Coordinate System information. Defaults to None.

Returns:

Path – Path to the saved FITS file.

Note

Filename formats: - Light frames: “{device}_{filter}_{object}_{exptime}_{timestamp}.fits” - Bias/Dark: “{device}_{imagetype}_{exptime}_{timestamp}.fits” - Other: “{device}_{filter}_{imagetype}_{exptime}_{timestamp}.fits”

Headers automatically updated with DATE-OBS, DATE, and WCS (if provided).

get_file_path(device_name: str, header: Header, date: datetime, sequence_counter: int, image_directory: Path) Path[source]#

Generate a file path for saving an image based on metadata and templates.

_resolve_image_directory(image_directory: str | Path | None) Path[source]#

Resolve the image directory path, combining user-specified and default directories.

static set_image_dir(user_specified_dir: str | None = None) Path | None[source]#

Create a directory for storing astronomical images.

Creates a directory for image storage using either a user-specified path or an auto-generated date-based path. The auto-generated path uses the local date calculated from the schedule start time and site longitude.

Parameters:
  • schedule_start_time (datetime, optional) – Start time of the observing schedule. Defaults to current UTC time.

  • site_long (float, optional) – Site longitude in degrees for local time conversion. Defaults to 0.

  • user_specified_dir (str | None, optional) – Custom directory path. If provided, this overrides auto-generation. Defaults to None.

Returns:

Path – Path object pointing to the created directory.

Note

Auto-generated directory format is YYYYMMDD based on local date calculated as schedule_start_time + (site_long / 15) hours.

static _transform_image_to_array(image: List[int] | ndarray, maxadu: int, image_info: ImageMetadata) ndarray[source]#

Transform raw image data to a FITS-compatible numpy array.

Converts raw image data to the appropriate data type and shape for FITS files. Handles data type selection based on image element type and maximum ADU value, and applies necessary array transpositions for FITS conventions.

Parameters:
  • image (list[int] | np.ndarray) – Raw image data as list or numpy array.

  • maxadu (int) – Maximum ADU (Analog-to-Digital Unit) value for the image.

  • image_info (ImageMetadata) – Metadata containing ImageElementType (0-3) and Rank (2 for grayscale, 3 for color).

Returns:

np.ndarray

Properly shaped and typed array ready for FITS file creation.

2D images are transposed, 3D images use transpose(2, 1, 0).

Raises:

ValueError – If ImageElementType is not in range 0-3.

Note

ImageElementType mapping: 0,1→uint16; 2→uint16 (≤65535) or int32 (>65535); 3→float64. Transpose operations match FITS conventions where first axis = columns, second = rows.

get_observatory_location()[source]#
static get_observing_night_date(observation_time: datetime, location: EarthLocation) datetime[source]#

Calculate the observing night date based on the sun’s position.

If the sun is up, the date is the current local date. If the sun is down:

  • If it’s morning (before noon), the date is yesterday.

  • If it’s evening (after noon), the date is today.

Parameters:
  • observation_time (datetime.datetime) – The time of observation (UTC).

  • location (EarthLocation) – The location of the observatory.

Returns:

datetime.datetime – The observing night date (at midnight).

static get_default_observing_date(longitude: float = 0)[source]#