Source code for skysim.utils
1"""Utility functions for SkySim."""
2
3# License: GPLv3+ (see COPYING); Copyright (C) 2025 Tai Withers
4
5import tomllib
6from collections.abc import Collection
7from pathlib import Path
8from typing import ForwardRef # pylint: disable=unused-import
9from typing import Any
10
11import numpy as np
12from astropy.table import QTable
13from numpy.typing import NDArray
14
15# Type Aliases
16
17type FloatArray = NDArray[np.float64]
18type IntArray = NDArray[np.int64]
19
20
21# Constants
22
23
24TEMPFILE_SUFFIX = ".png"
25"""File extension to use for video frames."""
26
27
28# Methods
29
30
[docs]
31def round_columns(
32 table: QTable,
33 column_names: Collection[str] = ("ra", "dec", "magnitude"),
34 decimals: int | Collection[int] = 5,
35) -> QTable:
36 """
37 Round columns of an Astropy Table.
38
39 Parameters
40 ----------
41 table : astropy.table.Table
42 Table.
43 column_names : list[str], optional
44 Names of columns to be rounded, by default ["ra","dec","magnitude"].
45 decimals : int | list[int], optional
46 Number of decimal places to keep, can be list of ints (same size as
47 `column_names`) or a single value, by default 5.
48
49 Returns
50 -------
51 astropy.table.Table
52 `table` with `column_names` rounded to `decimals`.
53 """
54
55 if isinstance(decimals, int):
56 decimals = [decimals] * len(column_names)
57 else:
58 if len(decimals) != len(column_names):
59 raise ValueError(
60 f"{len(column_names)} columns were given to be rounded, but "
61 f"{len(decimals)} values were given as decimal points to round to."
62 )
63 for name, roundto in zip(column_names, decimals):
64 table[name] = table[name].round(roundto)
65
66 return table
67
68
[docs]
69def get_tempfile_path(
70 plot_settings: "PlotSettings", frame_index: int # type: ignore[name-defined]
71) -> Path:
72 """Get the path for a temporary file that ffmpeg will read an image from.
73
74 Parameters
75 ----------
76 plot_settings : PlotSettings
77 Configuration.
78 frame_index : int
79 Which frame.
80
81 Returns
82 -------
83 pathlib.Path
84 Path.
85 """
86 return (
87 plot_settings.tempfile_path
88 / f"{str(frame_index).zfill(plot_settings.tempfile_zfill)}{TEMPFILE_SUFFIX}"
89 )
90
91
[docs]
92def read_pyproject() -> dict[str, Any]:
93 """Load the pyproject.toml file and return the most relevant entries.
94 Used in conf.py for Sphinx configuration.
95
96 Returns
97 -------
98 dict[str, typing.Any]
99 Project metadata.
100 """
101 pyproject_path = Path(__file__).parent.parent / "pyproject.toml"
102 pyproject_path = pyproject_path.resolve()
103 tomldict = tomllib.load(pyproject_path.open("rb"))
104
105 return tomldict["tool"]["poetry"]