panoptes.pocs.utils package

Subpackages

Submodules

panoptes.pocs.utils.alignment module

Polar alignment helpers for PANOPTES images.

Utilities to estimate celestial pole center and RA rotation center from FITS images, compute misalignment, and generate diagnostic plots for alignment.

class panoptes.pocs.utils.alignment.AlignmentResult(pole_center: tuple[float, float], rotate_center: tuple[float, float], rotate_radius: float, pix_scale: float, target_points: dict[str, tuple[float, float]], target_name: str, az_deg: float, alt_deg: float)[source]

Bases: object

Container for alignment results including centers, radius, and offsets.

alt_deg: float
az_deg: float
pix_scale: float
pole_center: tuple[float, float]
rotate_center: tuple[float, float]
rotate_radius: float
target_name: str
target_points: dict[str, tuple[float, float]]
to_csv_line()[source]

Convert the alignment result to a CSV line.

Returns:

CSV line with the alignment result.

Return type:

str

panoptes.pocs.utils.alignment.analyze_ra_rotation(rotate_fn: Path | str)[source]

Analyze the RA rotation image to get the center of rotation.

Parameters:

rotate_fn (Path | str) – FITS file of RA rotation image

Returns:

RA axis center of rotation XY coordinates

Return type:

tuple(int)

panoptes.pocs.utils.alignment.find_circle_params(points: dict[str, tuple[float, float]]) tuple[float, float, float][source]

Calculates the center (h, k) and radius (R) of a circle given a list of points.

Parameters:

points – A dictionary with keys as position names and values as tuples of (x, y) coordinates.

Returns:

A tuple (h, k, R) representing the center and radius of the circle. Returns (None, None, None) if the input is invalid or no circle can be found.

panoptes.pocs.utils.alignment.get_celestial_center(pole_fn: Path | str, **kwargs)[source]

Analyze the polar rotation image to get the center of the pole.

Parameters:

pole_fn (Path | str) – FITS file of polar center

Returns:

Polar center XY coordinates

Return type:

tuple(int)

panoptes.pocs.utils.alignment.plot_alignment_diff(cam_name: str, files: dict[str, str | Path], results: AlignmentResult) Figure[source]

Plot the difference between the celestial pole and RA rotation images.

Parameters:
  • cam_name (str) – Name of the camera.

  • files (dict[str, str | Path]) – Dictionary of image positions and their FITS file paths.

  • results (AlignmentResult) – Results from the alignment process.

Returns:

Matplotlib figure object.

Return type:

Figure

panoptes.pocs.utils.alignment.plot_center(pole_fn, rotate_fn, pole_center, rotate_center)[source]

Overlay the celestial pole and RA rotation axis images.

Parameters:
  • pole_fn (str) – FITS file of polar center

  • rotate_fn (str) – FITS file of RA rotation image

  • pole_center (tuple(int)) – Polar center XY coordinates

  • rotate_center (tuple(int)) – RA axis center of rotation XY coordinates

Returns:

Plotted image

Return type:

matplotlib.Figure

panoptes.pocs.utils.alignment.process_quick_alignment(files: dict[str, Path], target_name: str = 'Polaris', logger: Logger | None = None) AlignmentResult[source]

Process the quick alignment of polar rotation and RA rotation images.

Parameters:
  • files (dict[str, Path]) – Dictionary of image positions and their FITS file paths.

  • target_name (str) – Name of the target to align to (default: ‘Polaris’).

  • logger (Logger | None) – Logger instance for logging messages.

Returns:

Polar center coordinates, RA rotation center coordinates, dx, dy, pixel scale

Return type:

tuple

panoptes.pocs.utils.cloud module

panoptes.pocs.utils.coords module

Coordinate utilities for resolving targets to astropy SkyCoord objects.

panoptes.pocs.utils.coords.get_target_coords(target: str, obstime: datetime | Time | None = None, is_comet: bool = False, verbose: bool = False) SkyCoord[source]

Get the coordinates of the target.

This helper accepts a variety of inputs and returns an astropy SkyCoord.

Examples

Using common target names (requires internet for name resolution):

>>> from astropy.time import Time
>>> c = get_target_coords("M42", obstime=Time("2020-01-01"))
>>> type(c).__name__
'SkyCoord'
>>> get_target_coords("Andromeda Galaxy", obstime=Time("2020-01-01"), verbose=True)
<SkyCoord (ICRS): (ra, dec) in deg
    (10.6847..., 41.26875)>
>>> m = get_target_coords("Moon", obstime=Time("2020-01-01"))
>>> isinstance(m, SkyCoord)
True

A local, non-network coordinate string example (always works offline):

>>> get_target_coords("00h42m44.3s +41d16m9s", obstime=Time("2020-01-01"), verbose=True)
<SkyCoord (ICRS): (ra, dec) in deg
    (10.6845..., 41.26916667)>
>>> get_target_coords("10h00m00s +20d00m00s", obstime=Time("2020-01-01"))
<SkyCoord (ICRS): (ra, dec) in deg
    (150., 20.)>

Safety checks for hazardous or impossible targets:

>>> get_target_coords("sun", obstime=Time("2020-01-01"))
Traceback (most recent call last):
    ...
RuntimeError: Refusing to go to the sun.
>>> get_target_coords("earth", obstime=Time("2020-01-01"))
Traceback (most recent call last):
    ...
RuntimeError: It's hard for me to take a picture of earth.
Parameters:
  • target (str) – The target to look for. If a comet, use a designator like C/2025 N1 and set the is_comet flag to True.

  • obstime (datetime, Time, optional) – The time of the observation. Defaults to None.

  • is_comet (bool, optional) – Is the target a comet? Defaults to False.

  • verbose (bool, optional) – Print some information. Defaults to False.

Returns:

The coordinates of the target.

Return type:

SkyCoord

panoptes.pocs.utils.error module

POCS-specific error types extending panoptes.utils.error.PanError.

Defines light wrappers for domain-specific conditions such as camera busy, image saturation, twilight constraints, and safety violations.

exception panoptes.pocs.utils.error.AboveMaxExptime(msg='Exposure time is too high for camera.', **kwargs)[source]

Bases: PocsError

An invalid exptime for a camera, too high.

exception panoptes.pocs.utils.error.BelowMinExptime(msg='Exposure time is too low for camera.', **kwargs)[source]

Bases: PocsError

An invalid exptime for a camera, too low.

exception panoptes.pocs.utils.error.CameraBusy(msg='Camera busy.', **kwargs)[source]

Bases: PocsError

A camera is already busy.

exception panoptes.pocs.utils.error.ImageSaturated(msg='Image is saturated', **kwargs)[source]

Bases: PocsError

An image is saturated.

exception panoptes.pocs.utils.error.NotSafeError(msg='Not safe', **kwargs)[source]

Bases: PanError

Error for when safety fails.

exception panoptes.pocs.utils.error.NotTwilightError(msg='Not twilight', **kwargs)[source]

Bases: PanError

Error for when taking twilight flats and not twilight.

exception panoptes.pocs.utils.error.PocsError(msg='Problem with POCS', **kwargs)[source]

Bases: PanError

Error for a POCS level exception

panoptes.pocs.utils.location module

Location helpers for creating and configuring site/observer objects.

This module provides utilities to construct an astroplan Observer and related astropy EarthLocation from PANOPTES configuration, and to configure IERS table fetching used by astropy/astroplan for accurate time/earth orientation.

class panoptes.pocs.utils.location.SiteDetails(observer: Observer, earth_location: EarthLocation, location: dict)[source]

Bases: object

Container for site-specific objects and metadata.

observer

The astroplan Observer for the site.

Type:

astroplan.Observer

earth_location

The underlying EarthLocation.

Type:

astropy.coordinates.EarthLocation

location

Raw location configuration values used to construct the above.

Type:

dict

earth_location: EarthLocation
location: dict
observer: Observer
panoptes.pocs.utils.location.create_location_from_config() SiteDetails[source]

Construct site objects (Observer, EarthLocation) from configuration.

Reads the ‘location’ section from the PANOPTES configuration and constructs a dictionary of location parameters as well as the corresponding astropy EarthLocation and astroplan Observer.

Returns:

Container with observer, earth_location, and the raw location dict.

Return type:

SiteDetails

Raises:

panoptes.utils.error.PanError – If the location information is missing or invalid.

Notes

Expected location keys include: name, latitude, longitude, timezone, pressure, elevation, and horizon values (horizon, flat_horizon, focus_horizon, observe_horizon).

panoptes.pocs.utils.location.download_iers_a_file(iers_url: str = None)[source]

Download and configure the IERS A table URL.

This points astropy’s IERS auto URL at a PANOPTES mirror (if configured) and sets the auto-download behavior based on config.

Parameters:

iers_url (str | None) – Optional override URL for the IERS A file. If not provided, uses the value from configuration key ‘scheduler.iers_url’.

Returns:

None

Notes

Also sets astropy’s iers_conf.auto_download to the value of ‘scheduler.iers_auto’ (default False).

panoptes.pocs.utils.logger module

Logging utilities and factory for PANOPTES using loguru.

Provides get_logger() to configure project-wide logging and a PanLogger helper for dynamic formatting and handler tracking.

class panoptes.pocs.utils.logger.PanLogger[source]

Bases: object

Custom formatter to have dynamic widths for logging.

Also provides a handlers dictionary to track attached handlers by id.

See https://loguru.readthedocs.io/en/stable/resources/recipes.html#dynamically-formatting -messages-to-properly-align-values-with-padding

format(record)[source]

Return a loguru format string with dynamic padding for caller info.

Parameters:

record (dict) – Log record dictionary provided by loguru.

Returns:

The format string to use for this record.

Return type:

str

panoptes.pocs.utils.logger.get_logger(console_log_file='panoptes.log', full_log_file='panoptes_{time:YYYYMMDD!UTC}.log', serialize_full_log=False, log_dir=None, console_log_level='DEBUG', stderr_log_level='INFO', cloud_logging_level=None)[source]

Creates a root logger for PANOPTES used by the PanBase object.

Two log files are created, one suitable for viewing on the console (via tail) and a full log file suitable for archive and later inspection. The full log file is serialized into JSON.

Note: This clobbers all existing loggers and forces the two files.

Parameters:
  • console_log_file (str|None, optional) – Filename for the file that is suitable for tailing in a shell (i.e., read by humans). This file is rotated daily however the files are not retained.

  • full_log_file (str|None, optional) – Filename for log file that includes all levels and is serialized and rotated automatically. Useful for uploading to log service website. Defaults to panoptes_{time:YYYYMMDD!UTC}.log.gz with a daily rotation at 11:30am and a 7 day retention policy. If None then no file will be generated.

  • serialize_full_log (bool, optional) – If the full log should be written as json for log analysis, default False.

  • log_dir (str|None, optional) – The directory to place the log file, default local logs.

  • stderr_log_level (str, optional) – The log level to show on stderr, default INFO.

  • console_log_level (str, optional) – Log level for console file output, defaults to ‘SUCCESS’. Note that it should be a string that matches standard logging levels and also includes TRACE (below DEBUG) and SUCCESS (above INFO). Also note this is not the stderr output, but the output to the file to be tailed.

  • cloud_logging_level (bool|None, optional) – If a valid log level is specified, send logs to cloud at that level. If None (the default) don’t send logs to the cloud.

Returns:

A configured instance of the logger.

Return type:

loguru.logger

panoptes.pocs.utils.plotting module

Plotting utilities for POCS.

Currently includes a helper to generate autofocus plots combining thumbnails and focus metric scatter with an optional fit overlay.

panoptes.pocs.utils.plotting.make_autofocus_plot(output_path, initial_thumbnail, final_thumbnail, initial_focus, final_focus, focus_positions, metrics, merit_function, line_fit=None, plot_title='Autofocus Plot', plot_width=9, plot_height=18)[source]

Make autofocus plots.

This will make three plots, the top and bottom plots showing the initial and final thumbnail, respectively. The middle plot will contain the scatter plot for the metrics for the given focus_positions.

Parameters:
  • output_path (str) – Path for saving plot.

  • initial_thumbnail (np.array) – The data for the initial thumbnail.

  • final_thumbnail (np.array) – The data for the final thumbnail.

  • initial_focus (int) – The initial focus position.

  • final_focus (int) – The final focus position.

  • focus_positions (np.array) – An array of int corresponding the focus positions.

  • metrics (np.array) – An array of float corresponding to the measured metrics.

  • merit_function (str) – The name of the merit function used to produce the metrics.

  • line_fit (tuple(np.array, np.array)) – A tuple for the fitted line. The first entry should be an array of int used to calculate fit, the second entry should be an array of the fitted values.

  • plot_title (str) – Title to use for plot

  • plot_width (int) – The plot width in inches.

  • plot_height (int) – The plot height in inches.

Returns:

Full path the saved plot.

Return type:

str

panoptes.pocs.utils.theskyx module

Lightweight socket client for TheSkyX scripting interface.

Provides a minimal wrapper (TheSkyX) to connect, write commands, and read responses from a running TheSkyX instance over TCP.

class panoptes.pocs.utils.theskyx.TheSkyX(host='localhost', port=3040, connect=True, *args, **kwargs)[source]

Bases: object

A socket connection for communicating with TheSkyX.

connect()[source]

Establish a TCP connection to TheSkyX.

property is_connected

Whether the socket is currently connected.

Returns:

True if a TCP connection is established.

Return type:

bool

read(timeout=5)[source]

Read a response from TheSkyX.

Parameters:

timeout (int | float) – Seconds to wait before timing out. Defaults to 5.

Returns:

The response string, or None if empty.

Return type:

str | None

Raises:
write(value)[source]

Send a command string to TheSkyX.

Parameters:

value (str) – The command to send.

Raises:

panoptes.utils.error.BadConnection – If not connected.

Module contents