libephemeris 0.1.6__tar.gz → 0.1.8__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. libephemeris-0.1.8/PKG-INFO +301 -0
  2. libephemeris-0.1.8/README.md +265 -0
  3. {libephemeris-0.1.6 → libephemeris-0.1.8}/libephemeris/__init__.py +15 -41
  4. {libephemeris-0.1.6 → libephemeris-0.1.8}/libephemeris/planets.py +54 -0
  5. {libephemeris-0.1.6 → libephemeris-0.1.8}/libephemeris/state.py +51 -9
  6. libephemeris-0.1.8/libephemeris/utils.py +77 -0
  7. libephemeris-0.1.8/libephemeris.egg-info/PKG-INFO +301 -0
  8. {libephemeris-0.1.6 → libephemeris-0.1.8}/pyproject.toml +1 -1
  9. libephemeris-0.1.6/PKG-INFO +0 -376
  10. libephemeris-0.1.6/README.md +0 -340
  11. libephemeris-0.1.6/libephemeris/utils.py +0 -36
  12. libephemeris-0.1.6/libephemeris.egg-info/PKG-INFO +0 -376
  13. {libephemeris-0.1.6 → libephemeris-0.1.8}/LICENSE +0 -0
  14. {libephemeris-0.1.6 → libephemeris-0.1.8}/MANIFEST.in +0 -0
  15. {libephemeris-0.1.6 → libephemeris-0.1.8}/libephemeris/angles.py +0 -0
  16. {libephemeris-0.1.6 → libephemeris-0.1.8}/libephemeris/arabic_parts.py +0 -0
  17. {libephemeris-0.1.6 → libephemeris-0.1.8}/libephemeris/constants.py +0 -0
  18. {libephemeris-0.1.6 → libephemeris-0.1.8}/libephemeris/crossing.py +0 -0
  19. {libephemeris-0.1.6 → libephemeris-0.1.8}/libephemeris/fixed_stars.py +0 -0
  20. {libephemeris-0.1.6 → libephemeris-0.1.8}/libephemeris/houses.py +0 -0
  21. {libephemeris-0.1.6 → libephemeris-0.1.8}/libephemeris/lunar.py +0 -0
  22. {libephemeris-0.1.6 → libephemeris-0.1.8}/libephemeris/minor_bodies.py +0 -0
  23. {libephemeris-0.1.6 → libephemeris-0.1.8}/libephemeris/time_utils.py +0 -0
  24. {libephemeris-0.1.6 → libephemeris-0.1.8}/libephemeris.egg-info/SOURCES.txt +0 -0
  25. {libephemeris-0.1.6 → libephemeris-0.1.8}/libephemeris.egg-info/dependency_links.txt +0 -0
  26. {libephemeris-0.1.6 → libephemeris-0.1.8}/libephemeris.egg-info/requires.txt +0 -0
  27. {libephemeris-0.1.6 → libephemeris-0.1.8}/libephemeris.egg-info/top_level.txt +0 -0
  28. {libephemeris-0.1.6 → libephemeris-0.1.8}/setup.cfg +0 -0
@@ -0,0 +1,301 @@
1
+ Metadata-Version: 2.4
2
+ Name: libephemeris
3
+ Version: 0.1.8
4
+ Summary: A high-precision, open-source astronomical ephemeris library for Python, powered by Skyfield.
5
+ Author-email: Giacomo Battaglia <giacomo.battaglia@example.com>
6
+ License: GNU LESSER GENERAL PUBLIC LICENSE
7
+ Version 3, 29 June 2007
8
+
9
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
10
+ Everyone is permitted to copy and distribute verbatim copies
11
+ of this license document, but changing it is not allowed.
12
+
13
+ This version of the GNU Lesser General Public License incorporates
14
+ the terms and conditions of version 3 of the GNU General Public
15
+ License, supplemented by the additional permissions listed below.
16
+
17
+ [... Please replace this with the full text of the LGPL v3 License ...]
18
+ [... Available at: https://www.gnu.org/licenses/lgpl-3.0.txt ...]
19
+
20
+ Project-URL: Homepage, https://github.com/g-battaglia/libephemeris
21
+ Project-URL: Repository, https://github.com/g-battaglia/libephemeris
22
+ Project-URL: Issues, https://github.com/g-battaglia/libephemeris/issues
23
+ Classifier: Development Status :: 2 - Pre-Alpha
24
+ Classifier: Intended Audience :: Science/Research
25
+ Classifier: Intended Audience :: Developers
26
+ Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)
27
+ Classifier: Programming Language :: Python :: 3
28
+ Classifier: Programming Language :: Python :: 3.10
29
+ Classifier: Topic :: Scientific/Engineering :: Astronomy
30
+ Requires-Python: >=3.10
31
+ Description-Content-Type: text/markdown
32
+ License-File: LICENSE
33
+ Requires-Dist: skyfield>=1.53
34
+ Requires-Dist: skyfield-data>=7.0.0
35
+ Dynamic: license-file
36
+
37
+ # LibEphemeris
38
+
39
+ **High-precision astronomical ephemeris library for Python (Swiss Ephemeris compatible, powered by Skyfield and JPL DE ephemerides).**
40
+
41
+ > [!WARNING]
42
+ > **Pre-Alpha Release**
43
+ >
44
+ > LibEphemeris is currently in an early pre-alpha stage. The public API is unstable and may change without notice. Do not rely on it in production yet.
45
+
46
+ LibEphemeris is an open-source alternative to Swiss Ephemeris that provides scientific-grade astronomical calculations using NASA JPL ephemerides via [Skyfield](https://rhodesmill.org/skyfield/). The goal is to mirror the Swiss Ephemeris API (as exposed by `pyswisseph`) while using modern, freely available data and a pure-Python implementation.
47
+
48
+ [![License: LGPL v3](https://img.shields.io/badge/License-LGPL%20v3-blue.svg)](https://www.gnu.org/licenses/lgpl-3.0)
49
+ [![Python](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org)
50
+
51
+ ---
52
+
53
+ ## Features at a Glance
54
+
55
+ - **Planetary positions**: Sun, Moon, all major planets and Pluto.
56
+ - **High precision**: Based on NASA JPL DE421 by default (configurable to other DE files).
57
+ - **Multiple coordinate systems**: Ecliptic, equatorial, J2000 and of-date frames.
58
+ - **Observation modes**: Geocentric, topocentric, heliocentric, barycentric.
59
+ - **Velocities**: Full 6-component state vectors (position + velocity).
60
+ - **House systems (19)**: Placidus, Koch, Regiomontanus, Campanus, Equal, Whole Sign, Porphyry, Alcabitius, Polich/Page (Topocentric), Morinus, Meridian, Vehlow, Horizontal, Carter, Krusinski, Natural Gradient, and more.
61
+ - **Sidereal zodiac (43 ayanamshas)**: Fagan/Bradley, Lahiri, Raman, Krishnamurti, star-based and historical variants.
62
+ - **Extended points**: Lunar nodes, Lilith (mean and true), major asteroids (Chiron, Pholus, Ceres, Pallas, Juno, Vesta), TNOs (Orcus, Haumea, Quaoar, Makemake, Gonggong, Eris, Sedna), major fixed stars and Arabic parts.
63
+ - **Event finding**: Sun/Moon longitude crossings (e.g. ingress), with additional events planned (eclipses, etc.).
64
+ - **Swiss Ephemeris compatibility**: Same function names, flags and result structure as `pyswisseph` in most common use cases.
65
+
66
+ ---
67
+
68
+ ## Installation
69
+
70
+ Using `pip`:
71
+
72
+ ```bash
73
+ pip install libephemeris
74
+ ```
75
+
76
+ Using [`uv`](https://github.com/astral-sh/uv) (recommended for development):
77
+
78
+ ```bash
79
+ uv pip install libephemeris
80
+ ```
81
+
82
+ From source:
83
+
84
+ ```bash
85
+ git clone https://github.com/g-battaglia/libephemeris.git
86
+ cd libephemeris
87
+ uv pip install -e .
88
+ ```
89
+
90
+ ### Requirements
91
+
92
+ - Python **3.10+**
93
+ - `skyfield>=1.53`
94
+ - `skyfield-data>=7.0.0`
95
+ - A JPL ephemeris file (DE421 by default, downloaded automatically on first use if not present locally)
96
+
97
+ ---
98
+
99
+ ## Quick Start
100
+
101
+ ### Basic planetary positions
102
+
103
+ ```python
104
+ import libephemeris as ephem
105
+ from libephemeris.constants import *
106
+
107
+ # Julian Day (J2000.0)
108
+ jd = ephem.swe_julday(2000, 1, 1, 12.0)
109
+
110
+ # Sun position (longitude, latitude, distance, and speeds)
111
+ sun, flags = ephem.swe_calc_ut(jd, SE_SUN, SEFLG_SWIEPH | SEFLG_SPEED)
112
+ print(f"Sun longitude: {sun[0]:.6f}°")
113
+ print(f"Sun speed: {sun[3]:.6f}°/day")
114
+
115
+ # Moon position
116
+ moon, _ = ephem.swe_calc_ut(jd, SE_MOON, SEFLG_SWIEPH)
117
+ print(f"Moon longitude: {moon[0]:.6f}°")
118
+ ```
119
+
120
+ ### Houses and angles
121
+
122
+ ```python
123
+ # Rome coordinates
124
+ lat, lon, alt = 41.9028, 12.4964, 0.0
125
+ jd = ephem.swe_julday(2024, 11, 5, 18.0)
126
+
127
+ # Placidus houses
128
+ cusps, ascmc = ephem.swe_houses(jd, lat, lon, b"P")
129
+
130
+ print(f"Ascendant: {ascmc[0]:.2f}°")
131
+ print(f"MC: {ascmc[1]:.2f}°")
132
+ print(f"House 1: {cusps[1]:.2f}°")
133
+ print(f"House 10: {cusps[10]:.2f}°")
134
+ ```
135
+
136
+ ### Sidereal calculations
137
+
138
+ ```python
139
+ # Lahiri ayanamsha
140
+ ephem.swe_set_sid_mode(SE_SIDM_LAHIRI)
141
+
142
+ ayanamsha = ephem.swe_get_ayanamsa_ut(jd)
143
+ print(f"Lahiri ayanamsha: {ayanamsha:.6f}°")
144
+
145
+ sun_sid, _ = ephem.swe_calc_ut(jd, SE_SUN, SEFLG_SWIEPH | SEFLG_SIDEREAL)
146
+ print(f"Sidereal Sun: {sun_sid[0]:.6f}°")
147
+ ```
148
+
149
+ ### Longitude crossings
150
+
151
+ ```python
152
+ # Next time the Sun enters 0° Aries
153
+ next_cross = ephem.swe_solcross_ut(0.0, jd, SEFLG_SWIEPH)
154
+ print(f"Next Aries ingress (JD): {next_cross:.6f}")
155
+ ```
156
+
157
+ ---
158
+
159
+ ## Configuring Ephemeris Files
160
+
161
+ By default, LibEphemeris uses the **JPL DE421** kernel (`de421.bsp`), which covers roughly **1900–2050**. The file is:
162
+
163
+ - loaded from a local path if already present, or
164
+ - automatically downloaded via Skyfield the first time it is needed.
165
+
166
+ You can control which ephemeris file is used and where it is loaded from.
167
+
168
+ ### Choosing a different JPL kernel
169
+
170
+ Use `set_ephemeris_file()` to select a different `.bsp` file:
171
+
172
+ ```python
173
+ from libephemeris import set_ephemeris_file
174
+
175
+ set_ephemeris_file("de431.bsp") # very long time span, larger file
176
+ ```
177
+
178
+ Supported JPL kernels include, for example:
179
+
180
+ - `de421.bsp`: 1900–2050 (default, ~16 MB)
181
+ - `de422.bsp`: −3000–3000 (~623 MB)
182
+ - `de430.bsp`: 1550–2650 (~128 MB)
183
+ - `de431.bsp`: −13200–17191 (~3.4 GB)
184
+
185
+ If the chosen file is not present locally, Skyfield will attempt to download it.
186
+
187
+ ### Custom ephemeris directory
188
+
189
+ Use `set_ephe_path()` to point LibEphemeris to a directory containing JPL kernels:
190
+
191
+ ```python
192
+ from libephemeris import set_ephe_path
193
+
194
+ set_ephe_path("/path/to/jpl-kernels")
195
+ ```
196
+
197
+ Resolution order for the ephemeris file is:
198
+
199
+ 1. The directory set via `set_ephe_path()`, if any.
200
+ 2. The project/workspace root.
201
+ 3. Download via Skyfield.
202
+
203
+ If you try to compute positions outside the date range covered by the selected kernel, LibEphemeris will raise an exception describing the supported range.
204
+
205
+ ---
206
+
207
+ ## Scientific Accuracy and Validation
208
+
209
+ ### Ephemeris data
210
+
211
+ - **Source**: NASA JPL DE ephemerides (DE421 by default).
212
+ - **Time span**: 1900–2050 for DE421; extendable by selecting other kernels.
213
+ - **Precision**: Sub-arcsecond accuracy for major planets within the supported range.
214
+ - **Reference frame**: ICRS/J2000.0.
215
+
216
+ ### Comparison with Swiss Ephemeris
217
+
218
+ LibEphemeris has been tested against Swiss Ephemeris using an automated test suite.
219
+
220
+ | Component | Tests | Pass Rate | Max Difference |
221
+ | ----------------------- | ----- | --------- | -------------- |
222
+ | Planetary positions | 229 | 100% | < 0.001° |
223
+ | House systems | 113 | 100% | < 0.001° |
224
+ | Ayanamsha values | 129 | 100% | < 0.06° |
225
+ | Lunar nodes / Lilith | 40+ | 100% | < 0.01° |
226
+ | Velocities | 100 | 100% | < 0.01°/day |
227
+
228
+ These comparisons are implemented in the `tests/` and `compare_scripts/` directories, and are run regularly during development.
229
+
230
+ ---
231
+
232
+ ## Swiss Ephemeris Compatibility
233
+
234
+ LibEphemeris aims to behave as a **drop-in replacement** for `pyswisseph` in many scenarios:
235
+
236
+ - Same function names (e.g. `swe_calc_ut`, `swe_houses`, `swe_julday`, `swe_revjul`, `swe_get_ayanamsa_ut`).
237
+ - Same integer constants and flags from `libephemeris.constants` (e.g. `SE_SUN`, `SEFLG_SWIEPH`, `SEFLG_SPEED`, `SE_SIDM_LAHIRI`).
238
+ - Similar return types and value ordering.
239
+
240
+ There are still differences and missing features compared to the full Swiss Ephemeris API, especially around:
241
+
242
+ - very long time ranges (beyond the chosen JPL kernel),
243
+ - eclipse and occultation functions,
244
+ - the full minor-planet and fixed-star catalogues.
245
+
246
+ Please open an issue if you hit a compatibility gap that is important for your use case.
247
+
248
+ ---
249
+
250
+ ## Development
251
+
252
+ ### Project layout
253
+
254
+ ```text
255
+ libephemeris/
256
+ ├── libephemeris/
257
+ │ ├── __init__.py
258
+ │ ├── constants.py # Constants and flags
259
+ │ ├── planets.py # Planetary calculations
260
+ │ ├── houses.py # House systems
261
+ │ ├── lunar.py # Nodes and Lilith
262
+ │ ├── minor_bodies.py # Asteroids and TNOs
263
+ │ ├── fixed_stars.py # Fixed stars and points
264
+ │ ├── crossing.py # Longitude crossing events
265
+ │ ├── angles.py # Angle helpers (Asc, MC, etc.)
266
+ │ ├── arabic_parts.py # Arabic parts calculations
267
+ │ ├── time_utils.py # Time conversion helpers
268
+ │ └── state.py # Global state (loader, ephemeris, sidereal mode)
269
+ ├── tests/ # Comprehensive test suite
270
+ ├── compare_scripts/ # Swiss Ephemeris comparison tools
271
+ └── README.md
272
+ ```
273
+
274
+ ### Development workflow
275
+
276
+ Install in editable mode with development dependencies:
277
+
278
+ ```bash
279
+ uv pip install -e ".[dev]"
280
+ ```
281
+
282
+ Run tests (via `poethepoet` tasks defined in `pyproject.toml`):
283
+
284
+ ```bash
285
+ poe test # run pytest
286
+ poe coverage # run tests with coverage
287
+ poe lint # run Ruff (lint)
288
+ poe format # run Ruff formatter
289
+ ```
290
+
291
+ ---
292
+
293
+ ## License
294
+
295
+ LibEphemeris is licensed under the **GNU Lesser General Public License v3.0 (LGPL-3.0)**.
296
+
297
+ See `LICENSE` for the full text.
298
+
299
+ ---
300
+
301
+ Built for the astronomical and astrological communities.
@@ -0,0 +1,265 @@
1
+ # LibEphemeris
2
+
3
+ **High-precision astronomical ephemeris library for Python (Swiss Ephemeris compatible, powered by Skyfield and JPL DE ephemerides).**
4
+
5
+ > [!WARNING]
6
+ > **Pre-Alpha Release**
7
+ >
8
+ > LibEphemeris is currently in an early pre-alpha stage. The public API is unstable and may change without notice. Do not rely on it in production yet.
9
+
10
+ LibEphemeris is an open-source alternative to Swiss Ephemeris that provides scientific-grade astronomical calculations using NASA JPL ephemerides via [Skyfield](https://rhodesmill.org/skyfield/). The goal is to mirror the Swiss Ephemeris API (as exposed by `pyswisseph`) while using modern, freely available data and a pure-Python implementation.
11
+
12
+ [![License: LGPL v3](https://img.shields.io/badge/License-LGPL%20v3-blue.svg)](https://www.gnu.org/licenses/lgpl-3.0)
13
+ [![Python](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org)
14
+
15
+ ---
16
+
17
+ ## Features at a Glance
18
+
19
+ - **Planetary positions**: Sun, Moon, all major planets and Pluto.
20
+ - **High precision**: Based on NASA JPL DE421 by default (configurable to other DE files).
21
+ - **Multiple coordinate systems**: Ecliptic, equatorial, J2000 and of-date frames.
22
+ - **Observation modes**: Geocentric, topocentric, heliocentric, barycentric.
23
+ - **Velocities**: Full 6-component state vectors (position + velocity).
24
+ - **House systems (19)**: Placidus, Koch, Regiomontanus, Campanus, Equal, Whole Sign, Porphyry, Alcabitius, Polich/Page (Topocentric), Morinus, Meridian, Vehlow, Horizontal, Carter, Krusinski, Natural Gradient, and more.
25
+ - **Sidereal zodiac (43 ayanamshas)**: Fagan/Bradley, Lahiri, Raman, Krishnamurti, star-based and historical variants.
26
+ - **Extended points**: Lunar nodes, Lilith (mean and true), major asteroids (Chiron, Pholus, Ceres, Pallas, Juno, Vesta), TNOs (Orcus, Haumea, Quaoar, Makemake, Gonggong, Eris, Sedna), major fixed stars and Arabic parts.
27
+ - **Event finding**: Sun/Moon longitude crossings (e.g. ingress), with additional events planned (eclipses, etc.).
28
+ - **Swiss Ephemeris compatibility**: Same function names, flags and result structure as `pyswisseph` in most common use cases.
29
+
30
+ ---
31
+
32
+ ## Installation
33
+
34
+ Using `pip`:
35
+
36
+ ```bash
37
+ pip install libephemeris
38
+ ```
39
+
40
+ Using [`uv`](https://github.com/astral-sh/uv) (recommended for development):
41
+
42
+ ```bash
43
+ uv pip install libephemeris
44
+ ```
45
+
46
+ From source:
47
+
48
+ ```bash
49
+ git clone https://github.com/g-battaglia/libephemeris.git
50
+ cd libephemeris
51
+ uv pip install -e .
52
+ ```
53
+
54
+ ### Requirements
55
+
56
+ - Python **3.10+**
57
+ - `skyfield>=1.53`
58
+ - `skyfield-data>=7.0.0`
59
+ - A JPL ephemeris file (DE421 by default, downloaded automatically on first use if not present locally)
60
+
61
+ ---
62
+
63
+ ## Quick Start
64
+
65
+ ### Basic planetary positions
66
+
67
+ ```python
68
+ import libephemeris as ephem
69
+ from libephemeris.constants import *
70
+
71
+ # Julian Day (J2000.0)
72
+ jd = ephem.swe_julday(2000, 1, 1, 12.0)
73
+
74
+ # Sun position (longitude, latitude, distance, and speeds)
75
+ sun, flags = ephem.swe_calc_ut(jd, SE_SUN, SEFLG_SWIEPH | SEFLG_SPEED)
76
+ print(f"Sun longitude: {sun[0]:.6f}°")
77
+ print(f"Sun speed: {sun[3]:.6f}°/day")
78
+
79
+ # Moon position
80
+ moon, _ = ephem.swe_calc_ut(jd, SE_MOON, SEFLG_SWIEPH)
81
+ print(f"Moon longitude: {moon[0]:.6f}°")
82
+ ```
83
+
84
+ ### Houses and angles
85
+
86
+ ```python
87
+ # Rome coordinates
88
+ lat, lon, alt = 41.9028, 12.4964, 0.0
89
+ jd = ephem.swe_julday(2024, 11, 5, 18.0)
90
+
91
+ # Placidus houses
92
+ cusps, ascmc = ephem.swe_houses(jd, lat, lon, b"P")
93
+
94
+ print(f"Ascendant: {ascmc[0]:.2f}°")
95
+ print(f"MC: {ascmc[1]:.2f}°")
96
+ print(f"House 1: {cusps[1]:.2f}°")
97
+ print(f"House 10: {cusps[10]:.2f}°")
98
+ ```
99
+
100
+ ### Sidereal calculations
101
+
102
+ ```python
103
+ # Lahiri ayanamsha
104
+ ephem.swe_set_sid_mode(SE_SIDM_LAHIRI)
105
+
106
+ ayanamsha = ephem.swe_get_ayanamsa_ut(jd)
107
+ print(f"Lahiri ayanamsha: {ayanamsha:.6f}°")
108
+
109
+ sun_sid, _ = ephem.swe_calc_ut(jd, SE_SUN, SEFLG_SWIEPH | SEFLG_SIDEREAL)
110
+ print(f"Sidereal Sun: {sun_sid[0]:.6f}°")
111
+ ```
112
+
113
+ ### Longitude crossings
114
+
115
+ ```python
116
+ # Next time the Sun enters 0° Aries
117
+ next_cross = ephem.swe_solcross_ut(0.0, jd, SEFLG_SWIEPH)
118
+ print(f"Next Aries ingress (JD): {next_cross:.6f}")
119
+ ```
120
+
121
+ ---
122
+
123
+ ## Configuring Ephemeris Files
124
+
125
+ By default, LibEphemeris uses the **JPL DE421** kernel (`de421.bsp`), which covers roughly **1900–2050**. The file is:
126
+
127
+ - loaded from a local path if already present, or
128
+ - automatically downloaded via Skyfield the first time it is needed.
129
+
130
+ You can control which ephemeris file is used and where it is loaded from.
131
+
132
+ ### Choosing a different JPL kernel
133
+
134
+ Use `set_ephemeris_file()` to select a different `.bsp` file:
135
+
136
+ ```python
137
+ from libephemeris import set_ephemeris_file
138
+
139
+ set_ephemeris_file("de431.bsp") # very long time span, larger file
140
+ ```
141
+
142
+ Supported JPL kernels include, for example:
143
+
144
+ - `de421.bsp`: 1900–2050 (default, ~16 MB)
145
+ - `de422.bsp`: −3000–3000 (~623 MB)
146
+ - `de430.bsp`: 1550–2650 (~128 MB)
147
+ - `de431.bsp`: −13200–17191 (~3.4 GB)
148
+
149
+ If the chosen file is not present locally, Skyfield will attempt to download it.
150
+
151
+ ### Custom ephemeris directory
152
+
153
+ Use `set_ephe_path()` to point LibEphemeris to a directory containing JPL kernels:
154
+
155
+ ```python
156
+ from libephemeris import set_ephe_path
157
+
158
+ set_ephe_path("/path/to/jpl-kernels")
159
+ ```
160
+
161
+ Resolution order for the ephemeris file is:
162
+
163
+ 1. The directory set via `set_ephe_path()`, if any.
164
+ 2. The project/workspace root.
165
+ 3. Download via Skyfield.
166
+
167
+ If you try to compute positions outside the date range covered by the selected kernel, LibEphemeris will raise an exception describing the supported range.
168
+
169
+ ---
170
+
171
+ ## Scientific Accuracy and Validation
172
+
173
+ ### Ephemeris data
174
+
175
+ - **Source**: NASA JPL DE ephemerides (DE421 by default).
176
+ - **Time span**: 1900–2050 for DE421; extendable by selecting other kernels.
177
+ - **Precision**: Sub-arcsecond accuracy for major planets within the supported range.
178
+ - **Reference frame**: ICRS/J2000.0.
179
+
180
+ ### Comparison with Swiss Ephemeris
181
+
182
+ LibEphemeris has been tested against Swiss Ephemeris using an automated test suite.
183
+
184
+ | Component | Tests | Pass Rate | Max Difference |
185
+ | ----------------------- | ----- | --------- | -------------- |
186
+ | Planetary positions | 229 | 100% | < 0.001° |
187
+ | House systems | 113 | 100% | < 0.001° |
188
+ | Ayanamsha values | 129 | 100% | < 0.06° |
189
+ | Lunar nodes / Lilith | 40+ | 100% | < 0.01° |
190
+ | Velocities | 100 | 100% | < 0.01°/day |
191
+
192
+ These comparisons are implemented in the `tests/` and `compare_scripts/` directories, and are run regularly during development.
193
+
194
+ ---
195
+
196
+ ## Swiss Ephemeris Compatibility
197
+
198
+ LibEphemeris aims to behave as a **drop-in replacement** for `pyswisseph` in many scenarios:
199
+
200
+ - Same function names (e.g. `swe_calc_ut`, `swe_houses`, `swe_julday`, `swe_revjul`, `swe_get_ayanamsa_ut`).
201
+ - Same integer constants and flags from `libephemeris.constants` (e.g. `SE_SUN`, `SEFLG_SWIEPH`, `SEFLG_SPEED`, `SE_SIDM_LAHIRI`).
202
+ - Similar return types and value ordering.
203
+
204
+ There are still differences and missing features compared to the full Swiss Ephemeris API, especially around:
205
+
206
+ - very long time ranges (beyond the chosen JPL kernel),
207
+ - eclipse and occultation functions,
208
+ - the full minor-planet and fixed-star catalogues.
209
+
210
+ Please open an issue if you hit a compatibility gap that is important for your use case.
211
+
212
+ ---
213
+
214
+ ## Development
215
+
216
+ ### Project layout
217
+
218
+ ```text
219
+ libephemeris/
220
+ ├── libephemeris/
221
+ │ ├── __init__.py
222
+ │ ├── constants.py # Constants and flags
223
+ │ ├── planets.py # Planetary calculations
224
+ │ ├── houses.py # House systems
225
+ │ ├── lunar.py # Nodes and Lilith
226
+ │ ├── minor_bodies.py # Asteroids and TNOs
227
+ │ ├── fixed_stars.py # Fixed stars and points
228
+ │ ├── crossing.py # Longitude crossing events
229
+ │ ├── angles.py # Angle helpers (Asc, MC, etc.)
230
+ │ ├── arabic_parts.py # Arabic parts calculations
231
+ │ ├── time_utils.py # Time conversion helpers
232
+ │ └── state.py # Global state (loader, ephemeris, sidereal mode)
233
+ ├── tests/ # Comprehensive test suite
234
+ ├── compare_scripts/ # Swiss Ephemeris comparison tools
235
+ └── README.md
236
+ ```
237
+
238
+ ### Development workflow
239
+
240
+ Install in editable mode with development dependencies:
241
+
242
+ ```bash
243
+ uv pip install -e ".[dev]"
244
+ ```
245
+
246
+ Run tests (via `poethepoet` tasks defined in `pyproject.toml`):
247
+
248
+ ```bash
249
+ poe test # run pytest
250
+ poe coverage # run tests with coverage
251
+ poe lint # run Ruff (lint)
252
+ poe format # run Ruff formatter
253
+ ```
254
+
255
+ ---
256
+
257
+ ## License
258
+
259
+ LibEphemeris is licensed under the **GNU Lesser General Public License v3.0 (LGPL-3.0)**.
260
+
261
+ See `LICENSE` for the full text.
262
+
263
+ ---
264
+
265
+ Built for the astronomical and astrological communities.
@@ -5,12 +5,17 @@ from .planets import (
5
5
  swe_calc,
6
6
  swe_get_ayanamsa_ut,
7
7
  swe_get_ayanamsa,
8
+ swe_get_ayanamsa_name,
8
9
  swe_set_sid_mode,
9
10
  )
10
11
  from .houses import swe_houses, swe_houses_ex, swe_house_name
11
- from .state import set_topo as swe_set_topo, set_ephe_path as swe_set_ephe_path
12
+ from .state import (
13
+ set_topo as swe_set_topo,
14
+ set_ephe_path as swe_set_ephe_path,
15
+ set_ephemeris_file as swe_set_ephemeris_file,
16
+ )
12
17
  from .crossing import swe_solcross_ut, swe_mooncross_ut, swe_cross_ut
13
- from .utils import difdeg2n
18
+ from .utils import difdeg2n, swe_calc_angles
14
19
  from .fixed_stars import swe_fixstar_ut
15
20
 
16
21
  # =============================================================================
@@ -36,11 +41,13 @@ house_name = swe_house_name
36
41
  # Ayanamsa (sidereal)
37
42
  get_ayanamsa_ut = swe_get_ayanamsa_ut
38
43
  get_ayanamsa = swe_get_ayanamsa
44
+ get_ayanamsa_name = swe_get_ayanamsa_name
39
45
  set_sid_mode = swe_set_sid_mode
40
46
 
41
47
  # Observer location
42
48
  set_topo = swe_set_topo
43
49
  set_ephe_path = swe_set_ephe_path
50
+ set_ephemeris_file = swe_set_ephemeris_file
44
51
 
45
52
  # Fixed Stars
46
53
  fixstar_ut = swe_fixstar_ut
@@ -50,46 +57,7 @@ solcross_ut = swe_solcross_ut
50
57
  mooncross_ut = swe_mooncross_ut
51
58
 
52
59
 
53
- # Helper function to pre-calculate positions for Arabic parts
54
- def swe_calc_angles(jd_ut: float, lat: float, lon: float):
55
- """
56
- Pre-calculate and cache astrological angles and planet positions
57
- for use with Arabic parts.
58
-
59
- Args:
60
- jd_ut: Julian Day (UT)
61
- lat: Latitude (degrees)
62
- lon: Longitude (degrees)
63
-
64
- Returns:
65
- Dictionary with calculated positions
66
- """
67
- from .state import set_angles_cache
68
- from .angles import calc_angles
69
60
 
70
- # Set observer location
71
- swe_set_topo(lon, lat, 0)
72
-
73
- # Calculate angles
74
- angles_dict = calc_angles(jd_ut, lat, lon)
75
-
76
- # Calculate and add planet positions for Arabic parts
77
- from .constants import SE_SUN, SE_MOON, SE_MERCURY, SE_VENUS
78
-
79
- sun_pos, _ = swe_calc_ut(jd_ut, SE_SUN, 0)
80
- moon_pos, _ = swe_calc_ut(jd_ut, SE_MOON, 0)
81
- mercury_pos, _ = swe_calc_ut(jd_ut, SE_MERCURY, 0)
82
- venus_pos, _ = swe_calc_ut(jd_ut, SE_VENUS, 0)
83
-
84
- angles_dict['Sun'] = sun_pos[0]
85
- angles_dict['Moon'] = moon_pos[0]
86
- angles_dict['Mercury'] = mercury_pos[0]
87
- angles_dict['Venus'] = venus_pos[0]
88
-
89
- # Cache for Arabic parts
90
- set_angles_cache(angles_dict)
91
-
92
- return angles_dict
93
61
 
94
62
  # Helper for Arabic parts
95
63
  from .arabic_parts import calc_all_arabic_parts
@@ -129,12 +97,17 @@ __all__ = [
129
97
  "get_ayanamsa_ut",
130
98
  "swe_get_ayanamsa",
131
99
  "get_ayanamsa",
100
+ "swe_get_ayanamsa",
101
+ "get_ayanamsa",
132
102
  "swe_get_ayanamsa_name",
103
+ "get_ayanamsa_name",
133
104
  # Observer location
134
105
  "swe_set_topo",
135
106
  "set_topo",
136
107
  "swe_set_ephe_path",
137
108
  "set_ephe_path",
109
+ "swe_set_ephemeris_file",
110
+ "set_ephemeris_file",
138
111
  # Crossings
139
112
  "swe_solcross_ut",
140
113
  "solcross_ut",
@@ -143,6 +116,7 @@ __all__ = [
143
116
  "swe_cross_ut",
144
117
  # Utilities
145
118
  "difdeg2n",
119
+ "swe_calc_angles",
146
120
  # Helpers
147
121
  "calc_all_arabic_parts",
148
122
  # Fixed Stars