API Reference

Core tracking model for the Southern African Large Telescope (SALT).

This module provides the SaltTrackingModel class, which encapsulates the unique fixed-altitude tracking geometry of SALT. It handles data loading from empirical visibility files and provides high-performance interpolation for track limits and available track lengths using NumPy.

The model is designed as a singleton to ensure that the underlying data file is only loaded and parsed once per session.

class saltshaker.model.SaltTrackingModel[source]

Bases: object

A mathematical model for SALT’s fixed-altitude tracking geometry.

SALT is a fixed-altitude telescope (37° from zenith) that tracks targets using a moving payload (the tracker) at the focal plane. This class models the available tracking time and hour angle limits based on a target’s declination.

declinations

A sorted array of declinations (degrees) available in the empirical data file.

Type:

np.ndarray

UT_TO_ST_FACTOR

The conversion factor from Universal Time to Sidereal Time (approx 1.0027379).

Type:

float

UT_TO_ST_FACTOR = 1.00273790935
get_east_track(declination)[source]

Calculates the start and end hour angles for the eastern (rising) track.

get_max_track_length(declination)[source]

Calculates the maximum possible track length for a given declination.

get_west_track(declination)[source]

Calculates the start and end hour angles for the western (setting) track.

track_length(declination, hour_angle)[source]

Returns the available track length (in seconds) for a target. Supports scalar or NumPy array inputs for hour_angle.

saltshaker.model.get_model()[source]

Returns the singleton instance of the SaltTrackingModel.

Specialized Observer for the Southern African Large Telescope (SALT).

This module provides the SaltObserver class, which extends the standard astroplan.Observer with SALT-specific tracking and planning capabilities.

class saltshaker.observer.SaltObserver(**kwargs)[source]

Bases: Observer

A specialized Observer for SALT.

This class inherits from astroplan.Observer and maintains SALT’s geographic location. It adds methods for calculating SALT-specific visibility tracks and available track lengths using the SaltTrackingModel.

tracking_model

The singleton instance of the SALT tracking geometry model.

Type:

SaltTrackingModel

get_tracks(target, time)[source]

Calculates all visibility windows for a target on a given date.

This is a convenience wrapper for saltshaker.planning.get_visibility_windows.

Parameters:
  • target (SkyCoord) – The celestial coordinates of the target.

  • time (Time) – The observation date. This typically represents the noon-to-noon observing window.

Returns:

A list of objects representing the

time intervals when the target is observable.

Return type:

list[VisibilityWindow]

local_sidereal_time(time)[source]

Cached version of local_sidereal_time (for scalars only).

track_length(target, time)[source]

Returns the remaining track length for a target at a specific time.

This is a convenience wrapper for saltshaker.planning.get_track_length.

Parameters:
  • target (SkyCoord) – The celestial coordinates of the target.

  • time (Time) – The exact moment to check.

Returns:

The available tracking duration in units of time (seconds).

Return type:

Quantity

saltshaker.observer.get_salt_observer()[source]

Factory function to get a pre-configured SaltObserver instance. Uses a cached singleton instance for performance.

Returns:

An observer instance set to SALT’s coordinates.

Return type:

SaltObserver

Observation planning and scheduling utilities for SALT.

This module provides the core functional API for determining when targets are visible at SALT and managing observing semesters.

It handles the conversion of theoretical tracking limits into actual Universal Time (UTC) windows and provides night-by-night semester iterators.

class saltshaker.planning.VisibilityWindow(start_time, end_time)[source]

Bases: object

Represents a specific time interval when a target is visible at SALT.

start_time

The exact beginning of the visibility window.

Type:

Time

end_time

The exact end of the visibility window.

Type:

Time

duration

The total duration of the window in seconds.

Type:

float

property end_time_utc

Returns the end time as a UTC ISO string.

property start_time_utc

00’).

Type:

Returns the start time as a UTC ISO string (e.g., ‘2026-01-15 18

Type:

30

saltshaker.planning.get_semester_end(year, semester)[source]

Returns the official end date of a SALT observing semester.

Parameters:
  • year (int) – The calendar year.

  • semester (int) – The semester number (1 or 2).

Returns:

End of the semester (12:00:00 UTC).

Return type:

Time

saltshaker.planning.get_semester_nights(year, semester, observer=None)[source]

Generates a sequence of observing nights for an entire semester.

A “night” is defined as the period between evening astronomical twilight (-18° altitude) and morning astronomical twilight.

This implementation uses a vectorized grid-based approach for maximum performance, providing a ~5-10x speedup over iterative methods.

Parameters:
  • year (int) – The calendar year.

  • semester (int) – The semester number (1 or 2).

  • observer (SaltObserver | None) – The observer instance to use for twilight calculations. Defaults to a standard SaltObserver.

Returns:

A list of tuples, where each tuple is

(evening_twilight, morning_twilight).

Return type:

list[tuple[Time, Time]]

saltshaker.planning.get_semester_start(year, semester)[source]

Returns the official start date of a SALT observing semester.

  • Semester 1 (e.g., 2026-1) starts March 1st.

  • Semester 2 (e.g., 2026-2) starts October 1st.

Parameters:
  • year (int) – The calendar year.

  • semester (int) – The semester number (1 or 2).

Returns:

Start of the semester (12:00:00 UTC).

Return type:

Time

saltshaker.planning.get_track_length(target, time, observer=None)[source]

Returns the available track length for a target at a specific moment.

The “Track Length” is the remaining duration (in seconds) that the tracker can follow the object before reaching its physical limit. This is highly dependent on both declination and the target’s current position in the tracking zone (hour angle).

Parameters:
  • target (SkyCoord) – The celestial coordinates of the target.

  • time (Time) – The exact moment of observation.

  • observer (SaltObserver | None) – The observer instance to use. Defaults to a standard SaltObserver.

Returns:

The remaining tracking duration in units of time (seconds).

Return type:

Quantity

saltshaker.planning.get_tracks(target_coord, obs_date)[source]

Compatibility wrapper for get_visibility_windows.

Deprecated: Use get_visibility_windows instead.

Parameters:
  • target_coord (SkyCoord | float) – Target coordinate or declination.

  • obs_date (str | Time) – Date of observation.

Returns:

Observable time windows.

Return type:

list[VisibilityWindow]

saltshaker.planning.get_visibility_windows(target_coord, obs_date, observer=None)[source]

Calculates the observable UTC windows for a target (or targets) on a specific date.

This function converts tracking hour angle limits into a sequence of UTC time intervals. For many declinations, this will return two windows (an Eastern rising track and a Western setting track).

Parameters:
  • target_coord (SkyCoord) – The celestial coordinates of the target(s).

  • obs_date (str | Time) – The date of observation. If a string is provided (e.g., ‘2026-01-15’), the 24-hour window starts at 12:00:00 UTC on that day.

  • observer (SaltObserver | None) – The observer instance to use for LST and coordinate calculations. Defaults to a standard SaltObserver.

Returns:

A list of

visibility windows (for a single target) or a list of lists (for multiple targets).

Return type:

list[VisibilityWindow] | list[list[VisibilityWindow]]

saltshaker.planning.is_target_observable(target)[source]

Checks if a target is EVER observable from SALT based on its declination.

SALT’s fixed-altitude design limits visibility to a specific range of declinations (approximately -75° to +10°). This function returns True if the target’s declination ever enters SALT’s tracking annulus.

Parameters:

target (SkyCoord | float | np.ndarray) – The target(s) to check. Can be an astropy SkyCoord object, a float, or a NumPy array representing the declination(s) in degrees.

Returns:

True if the target is observable, False otherwise.

Return type:

bool | np.ndarray

SALT-specific observation constraints for astroplan.

This module provides constraint classes that integrate with the astroplan scheduling ecosystem to enforce SALT’s unique tracking and lunar limits.

class saltshaker.constraints.SaltMoonConstraint(max_illumination=1.0)[source]

Bases: Constraint

Constraint on Moon phase and position.

This constraint is satisfied if:

  1. The Moon’s illuminated fraction is less than or equal to max_illumination.

  2. OR, the Moon is currently below the horizon.

max_illumination

Maximum allowed illuminated fraction (0 to 1).

Type:

float

compute_constraint(times, observer, targets)[source]

Evaluates the constraint for a set of times and targets.

class saltshaker.constraints.SaltTrackLengthConstraint(min_track_length=None)[source]

Bases: Constraint

Constraint on the remaining track length of a target.

This constraint ensures that at any given time, the target has a remaining track length of at least min_track_length. This is essential for scheduling exposures that must not be interrupted by the tracker reaching its physical limit.

min_track_length

The minimum required track duration.

Type:

Quantity

tracking_model

The singleton model used for calculations.

Type:

SaltTrackingModel

compute_constraint(times, observer, targets)[source]

Evaluates the constraint for a set of times and targets.

This implementation is fully vectorized for maximum performance.