astroceleste-engine 0.0.2__tar.gz → 0.0.4__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.
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/Cargo.lock +3 -3
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/Cargo.toml +1 -1
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/PKG-INFO +4 -1
- {astroceleste_engine-0.0.2/crates/astroceleste-engine-py → astroceleste_engine-0.0.4}/README.md +3 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/README.md +41 -60
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/src/almanac.rs +49 -1
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/src/chart.rs +57 -11
- astroceleste_engine-0.0.4/crates/astroceleste-engine/src/election.rs +1688 -0
- astroceleste_engine-0.0.4/crates/astroceleste-engine/src/ephemeris/mod.rs +19 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/src/horary.rs +77 -20
- astroceleste_engine-0.0.4/crates/astroceleste-engine/src/houses.rs +385 -0
- astroceleste_engine-0.0.4/crates/astroceleste-engine/src/lib.rs +157 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/src/planets.rs +10 -1
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine-py/Cargo.toml +1 -1
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4/crates/astroceleste-engine-py}/README.md +3 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine-py/astroceleste_engine.pyi +24 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine-py/src/lib.rs +74 -2
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine-py/tests/test_engine.py +26 -0
- astroceleste_engine-0.0.2/crates/astroceleste-engine/src/ephemeris/mod.rs +0 -10
- astroceleste_engine-0.0.2/crates/astroceleste-engine/src/houses.rs +0 -139
- astroceleste_engine-0.0.2/crates/astroceleste-engine/src/lib.rs +0 -68
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/LICENSE-APACHE +0 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/LICENSE-MIT +0 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/NOTICE +0 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/Cargo.toml +0 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/LICENSE-APACHE +0 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/LICENSE-MIT +0 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/NOTICE +0 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/src/aspects.rs +0 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/src/catalog/derived_meanings.rs +0 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/src/catalog/fixed_stars.rs +0 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/src/catalog/mansions.rs +0 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/src/catalog/mod.rs +0 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/src/chiron.rs +0 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/src/constants.rs +0 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/src/data/chiron.bin +0 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/src/data/deltat.bin +0 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/src/derived.rs +0 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/src/ephemeris/kernels.rs +0 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/src/ephemeris/observe.rs +0 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/src/ephemeris/spk.rs +0 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/src/error.rs +0 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/src/fixed_stars.rs +0 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/src/frames/mod.rs +0 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/src/frames/nutation.rs +0 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/src/frames/nutation_data.rs +0 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/src/frames/precession.rs +0 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/src/frames/sidereal.rs +0 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/src/instant.rs +0 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/src/lots.rs +0 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/src/lunar.rs +0 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/src/pyfloat.rs +0 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/src/symbolic.rs +0 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/src/temperament.rs +0 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/src/time.rs +0 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/src/zodiac.rs +0 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine-py/LICENSE-APACHE +0 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine-py/LICENSE-MIT +0 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine-py/NOTICE +0 -0
- {astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/pyproject.toml +0 -0
|
@@ -4,7 +4,7 @@ version = 4
|
|
|
4
4
|
|
|
5
5
|
[[package]]
|
|
6
6
|
name = "astroceleste-engine"
|
|
7
|
-
version = "0.0.
|
|
7
|
+
version = "0.0.4"
|
|
8
8
|
dependencies = [
|
|
9
9
|
"serde",
|
|
10
10
|
"serde_json",
|
|
@@ -12,7 +12,7 @@ dependencies = [
|
|
|
12
12
|
|
|
13
13
|
[[package]]
|
|
14
14
|
name = "astroceleste-engine-py"
|
|
15
|
-
version = "0.0.
|
|
15
|
+
version = "0.0.4"
|
|
16
16
|
dependencies = [
|
|
17
17
|
"astroceleste-engine",
|
|
18
18
|
"pyo3",
|
|
@@ -22,7 +22,7 @@ dependencies = [
|
|
|
22
22
|
|
|
23
23
|
[[package]]
|
|
24
24
|
name = "astroceleste-engine-wasm"
|
|
25
|
-
version = "0.0.
|
|
25
|
+
version = "0.0.4"
|
|
26
26
|
dependencies = [
|
|
27
27
|
"astroceleste-engine",
|
|
28
28
|
"js-sys",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: astroceleste-engine
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.4
|
|
4
4
|
Classifier: Development Status :: 2 - Pre-Alpha
|
|
5
5
|
Classifier: Programming Language :: Rust
|
|
6
6
|
Classifier: Programming Language :: Python :: 3
|
|
@@ -28,6 +28,9 @@ Project-URL: Repository, https://github.com/ffalcinelli/astroceleste-engine
|
|
|
28
28
|
Python bindings for [astroceleste-engine](https://github.com/ffalcinelli/astroceleste-engine),
|
|
29
29
|
astrological chart calculation on NASA JPL ephemerides, written in Rust.
|
|
30
30
|
|
|
31
|
+
[Website and live demo](https://ffalcinelli.github.io/astroceleste-engine/) ·
|
|
32
|
+
[API guide](https://github.com/ffalcinelli/astroceleste-engine/blob/main/docs/api.md)
|
|
33
|
+
|
|
31
34
|
```python
|
|
32
35
|
from datetime import datetime, timezone
|
|
33
36
|
import astroceleste_engine as ace
|
{astroceleste_engine-0.0.2/crates/astroceleste-engine-py → astroceleste_engine-0.0.4}/README.md
RENAMED
|
@@ -7,6 +7,9 @@
|
|
|
7
7
|
Python bindings for [astroceleste-engine](https://github.com/ffalcinelli/astroceleste-engine),
|
|
8
8
|
astrological chart calculation on NASA JPL ephemerides, written in Rust.
|
|
9
9
|
|
|
10
|
+
[Website and live demo](https://ffalcinelli.github.io/astroceleste-engine/) ·
|
|
11
|
+
[API guide](https://github.com/ffalcinelli/astroceleste-engine/blob/main/docs/api.md)
|
|
12
|
+
|
|
10
13
|
```python
|
|
11
14
|
from datetime import datetime, timezone
|
|
12
15
|
import astroceleste_engine as ace
|
{astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/README.md
RENAMED
|
@@ -12,11 +12,15 @@ It is the calculation core of [Astroceleste](https://astroceleste.it). The same
|
|
|
12
12
|
on the server (Python bindings), in the desktop and mobile apps (native) and in the browser
|
|
13
13
|
(WASM), so every platform computes the same chart down to the arcsecond.
|
|
14
14
|
|
|
15
|
+
**[Website and live demo](https://ffalcinelli.github.io/astroceleste-engine/)** · [API docs](https://docs.rs/astroceleste-engine) ·
|
|
16
|
+
[Guides](https://github.com/ffalcinelli/astroceleste-engine/tree/main/docs)
|
|
17
|
+
|
|
15
18
|
> **Experimental (0.0.x):** the API may change in any release. Pin an exact version.
|
|
16
19
|
|
|
17
20
|
> Status: the complete chart pipeline is ported and matches the reference implementation
|
|
18
21
|
> on every golden chart: planets, lunar nodes, Chiron, Lilith, houses (Placidus, Whole Sign,
|
|
19
|
-
> Equal, Porphyry
|
|
22
|
+
> Equal, Porphyry; Koch, Regiomontanus, Campanus, Topocentric, Alcabitius, Morinus and Vehlow
|
|
23
|
+
> are checked against Swiss Ephemeris), aspects and orbs, fixed stars, Arabic parts, temperament, lunar status,
|
|
20
24
|
> horary charts (planetary hours from computed sunrise and sunset), transits, synastry and
|
|
21
25
|
> derived charts, with Python and WebAssembly bindings.
|
|
22
26
|
|
|
@@ -35,21 +39,32 @@ println!("{}", serde_json::to_string_pretty(&chart)?);
|
|
|
35
39
|
```
|
|
36
40
|
|
|
37
41
|
Charts serialize to the same JSON as the Astroceleste API. Other entry points:
|
|
38
|
-
`calculate_horary_chart`, `calculate_transit_chart`, `calculate_synastry
|
|
39
|
-
`calculate_derived_chart
|
|
42
|
+
`calculate_horary_chart`, `calculate_transit_chart`, `calculate_synastry`,
|
|
43
|
+
`calculate_derived_chart`, and for electional astrology `calculate_election_chart` and
|
|
44
|
+
`search_elections` (the best moments over a span of time). In the browser or on mobile, load the kernel from memory with
|
|
40
45
|
`Spk::from_bytes`.
|
|
41
46
|
|
|
42
47
|
## Bindings
|
|
43
48
|
|
|
44
49
|
- **Python** (`pip install astroceleste-engine`, CPython ≥ 3.12): `Engine([kernel paths])`
|
|
45
|
-
with `.chart()`, `.horary()`, `.transit()`, plus `synastry()` and `derived_chart()`,
|
|
46
|
-
returning plain dicts. See [crates/astroceleste-engine-py](crates/astroceleste-engine-py).
|
|
50
|
+
with `.chart()`, `.horary()`, `.transit()`, `.election()`, `.elections()`, plus `synastry()` and `derived_chart()`,
|
|
51
|
+
returning plain dicts. See [crates/astroceleste-engine-py](https://github.com/ffalcinelli/astroceleste-engine/tree/main/crates/astroceleste-engine-py).
|
|
47
52
|
- **JavaScript / WebAssembly** (`npm install astroceleste-engine`): the same API over
|
|
48
53
|
kernels loaded from memory, for browsers and Node. See
|
|
49
|
-
[crates/astroceleste-engine-wasm](crates/astroceleste-engine-wasm).
|
|
54
|
+
[crates/astroceleste-engine-wasm](https://github.com/ffalcinelli/astroceleste-engine/tree/main/crates/astroceleste-engine-wasm).
|
|
50
55
|
|
|
51
56
|
Both are tested against the same golden fixtures as the Rust crate.
|
|
52
57
|
|
|
58
|
+
## Documentation
|
|
59
|
+
|
|
60
|
+
- [API reference on docs.rs](https://docs.rs/astroceleste-engine)
|
|
61
|
+
- [API guide](https://github.com/ffalcinelli/astroceleste-engine/blob/main/docs/api.md): request options, the chart JSON, error codes in every
|
|
62
|
+
language
|
|
63
|
+
- [Ephemerides](https://github.com/ffalcinelli/astroceleste-engine/blob/main/docs/ephemerides.md): kernels, date coverage, loading from memory,
|
|
64
|
+
smaller excerpts for the web and mobile
|
|
65
|
+
- [Accuracy](https://github.com/ffalcinelli/astroceleste-engine/blob/main/docs/accuracy.md): how every number is verified
|
|
66
|
+
- [Architecture](https://github.com/ffalcinelli/astroceleste-engine/blob/main/docs/architecture.md): crates and calculation pipeline
|
|
67
|
+
|
|
53
68
|
## Layout
|
|
54
69
|
|
|
55
70
|
| Path | Content |
|
|
@@ -63,78 +78,44 @@ Both are tested against the same golden fixtures as the Rust crate.
|
|
|
63
78
|
| `scripts/make_spk_fixtures.py` | rebuilds the excerpt and the SPK reference states with `jplephem` |
|
|
64
79
|
| `scripts/make_reduction_fixtures.py` | stage-by-stage reference values from Skyfield |
|
|
65
80
|
| `scripts/gen_tables.py` | regenerates the embedded ΔT, nutation and Chiron tables |
|
|
81
|
+
| `scripts/build-site.sh` | builds the landing site and live demo into `target/site/` |
|
|
82
|
+
| `docs/` | guides |
|
|
83
|
+
| `site/` | landing site and live demo, deployed to GitHub Pages |
|
|
84
|
+
|
|
85
|
+
## Contributing
|
|
66
86
|
|
|
67
|
-
|
|
87
|
+
Contributions are welcome: see [CONTRIBUTING.md](https://github.com/ffalcinelli/astroceleste-engine/blob/main/CONTRIBUTING.md) for setup, the test
|
|
88
|
+
suite and the rules that keep every platform identical. Report vulnerabilities privately,
|
|
89
|
+
as described in [SECURITY.md](https://github.com/ffalcinelli/astroceleste-engine/blob/main/SECURITY.md). Maintainers release by pushing a version
|
|
90
|
+
tag ([RELEASING.md](https://github.com/ffalcinelli/astroceleste-engine/blob/main/RELEASING.md)).
|
|
68
91
|
|
|
69
92
|
```bash
|
|
70
93
|
cargo test --workspace --exclude astroceleste-engine-py # uses the committed excerpt
|
|
71
|
-
scripts/fetch-kernels.sh #
|
|
94
|
+
scripts/fetch-kernels.sh # full de440s (1849-2150): enables the golden and full-range tests
|
|
72
95
|
cargo clippy --workspace --all-targets -- -D warnings
|
|
73
|
-
|
|
74
|
-
# Python bindings (in a virtualenv)
|
|
75
|
-
pip install maturin pytest && maturin develop -m crates/astroceleste-engine-py/Cargo.toml
|
|
76
|
-
pytest crates/astroceleste-engine-py/tests
|
|
77
|
-
|
|
78
|
-
# WebAssembly bindings (needs wasm-pack and the wasm32-unknown-unknown target)
|
|
79
|
-
wasm-pack build --target nodejs --out-dir pkg-node crates/astroceleste-engine-wasm
|
|
80
|
-
node crates/astroceleste-engine-wasm/tests/golden.mjs
|
|
81
96
|
```
|
|
82
97
|
|
|
83
|
-
## Releasing
|
|
84
|
-
|
|
85
|
-
Releases are trunk-based: there are no release branches or release PRs. Pushing a
|
|
86
|
-
`vX.Y.Z` tag on `main` publishes that version.
|
|
87
|
-
|
|
88
|
-
1. Commits on `main` follow [Conventional Commits](https://www.conventionalcommits.org)
|
|
89
|
-
(`feat:`, `fix:`, `perf:`, `refactor:`, … and `!` for breaking changes). While the
|
|
90
|
-
version is 0.0.x, `feat`/`fix` bump the patch version and a breaking change bumps the
|
|
91
|
-
minor version.
|
|
92
|
-
2. Prepare the release on `main`: run `release-plz update` (or edit by hand) to bump the
|
|
93
|
-
workspace version, the bindings' `astroceleste-engine` dependency version and
|
|
94
|
-
`CHANGELOG.md`, then commit as `chore: release vX.Y.Z` and push.
|
|
95
|
-
3. Once CI is green, tag that commit and push the tag:
|
|
96
|
-
`git tag vX.Y.Z && git push origin vX.Y.Z`.
|
|
97
|
-
4. The `Release` workflow checks that the tag is on `main`, matches the version in
|
|
98
|
-
`Cargo.toml` and has a `CHANGELOG.md` entry. It then publishes the crate to crates.io,
|
|
99
|
-
creates the GitHub Release from the changelog entry, and publishes the Python wheels
|
|
100
|
-
(Linux x86_64/aarch64 glibc and musl, macOS universal2, Windows x64, sdist) to PyPI
|
|
101
|
-
and the WebAssembly package to npm.
|
|
102
|
-
|
|
103
|
-
Protect `v*` tags with a tag ruleset so only maintainers can trigger a release.
|
|
104
|
-
|
|
105
|
-
All three registries use Trusted Publishing (OIDC), so no long-lived token is stored.
|
|
106
|
-
crates.io and npm can only trust a workflow for a package that already exists, so the
|
|
107
|
-
first release uses short-lived tokens instead:
|
|
108
|
-
|
|
109
|
-
1. Create the `release`, `pypi` and `npm` environments in the repository settings
|
|
110
|
-
(optionally with required reviewers).
|
|
111
|
-
2. **crates.io**: create an API token scoped to `publish-new` and `publish-update` for the
|
|
112
|
-
crate `astroceleste-engine`, with a short expiry, and store it as the
|
|
113
|
-
`CARGO_REGISTRY_TOKEN` secret of the `release` environment.
|
|
114
|
-
3. **npm**: create a granular access token with publish rights and a short expiry, and store
|
|
115
|
-
it as the `NPM_TOKEN` secret of the `npm` environment.
|
|
116
|
-
4. **PyPI**: add a *pending* trusted publisher for project `astroceleste-engine` (workflow
|
|
117
|
-
`release.yml`, environment `pypi`). No token is needed.
|
|
118
|
-
5. Push the `vX.Y.Z` tag for the version in `Cargo.toml`.
|
|
119
|
-
6. Once the packages exist, add the trusted publisher on crates.io (crate settings →
|
|
120
|
-
*Trusted Publishing*: this repository, workflow `release.yml`, environment `release`)
|
|
121
|
-
and on npm (package settings: workflow `release.yml`, environment `npm`). Then delete
|
|
122
|
-
both secrets and revoke the tokens. The workflow prefers OIDC whenever it is available.
|
|
123
|
-
|
|
124
98
|
## Ephemerides
|
|
125
99
|
|
|
126
100
|
The engine reads NASA JPL SPK kernels (DE440s by default, DE441 for dates outside 1849–2150).
|
|
127
|
-
Dates outside the loaded kernels are reported as errors, never approximated.
|
|
101
|
+
Dates outside the loaded kernels are reported as errors, never approximated. See
|
|
102
|
+
[docs/ephemerides.md](https://github.com/ffalcinelli/astroceleste-engine/blob/main/docs/ephemerides.md) for coverage, sizes and excerpts.
|
|
128
103
|
|
|
129
104
|
## License
|
|
130
105
|
|
|
131
106
|
Licensed under either of
|
|
132
107
|
|
|
133
|
-
- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE))
|
|
134
|
-
- MIT license ([LICENSE-MIT](LICENSE-MIT))
|
|
108
|
+
- Apache License, Version 2.0 ([LICENSE-APACHE](https://github.com/ffalcinelli/astroceleste-engine/blob/main/LICENSE-APACHE))
|
|
109
|
+
- MIT license ([LICENSE-MIT](https://github.com/ffalcinelli/astroceleste-engine/blob/main/LICENSE-MIT))
|
|
135
110
|
|
|
136
111
|
at your option.
|
|
137
112
|
|
|
113
|
+
The astronomical reduction (ΔT, IAU 2000A nutation, IAU 2006 precession, light-time,
|
|
114
|
+
deflection and aberration) is ported from [Skyfield](https://github.com/skyfielders/python-skyfield)
|
|
115
|
+
by Brandon Rhodes, used under the MIT license: see
|
|
116
|
+
[NOTICE](https://github.com/ffalcinelli/astroceleste-engine/blob/main/NOTICE), which is shipped in
|
|
117
|
+
every package.
|
|
118
|
+
|
|
138
119
|
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion
|
|
139
120
|
in this work, as defined in the Apache-2.0 license, shall be dual licensed as above, without
|
|
140
121
|
any additional terms or conditions.
|
{astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/src/almanac.rs
RENAMED
|
@@ -155,7 +155,55 @@ pub fn rise_set(
|
|
|
155
155
|
let t_start = Time::from_ut1(jd_utc - 1.5);
|
|
156
156
|
let t_end = Time::from_ut1(jd_utc + 1.5);
|
|
157
157
|
let events = find_transitions(kernel, &site, t_start.tt(), t_end.tt())?;
|
|
158
|
+
Ok(select_rise_set(&events, jd_utc))
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/// Sunrises and sunsets over a span, found once for all the days in it.
|
|
162
|
+
pub(crate) struct SunEvents {
|
|
163
|
+
/// (TT Julian date, whether it is a sunrise), in time order.
|
|
164
|
+
events: Vec<(f64, bool)>,
|
|
165
|
+
/// TT span searched.
|
|
166
|
+
span: (f64, f64),
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
impl SunEvents {
|
|
170
|
+
/// Every sunrise and sunset from UT1 Julian date `jd0` to `jd1`, when a single kernel
|
|
171
|
+
/// covers the whole span (`None` otherwise).
|
|
172
|
+
pub fn find(
|
|
173
|
+
kernels: &KernelSet,
|
|
174
|
+
jd0: f64,
|
|
175
|
+
jd1: f64,
|
|
176
|
+
latitude: f64,
|
|
177
|
+
longitude: f64,
|
|
178
|
+
) -> Result<Option<Self>, EngineError> {
|
|
179
|
+
let kernel = require_kernel(kernels, jd0)?;
|
|
180
|
+
if !(kernel.start_jd..=kernel.end_jd).contains(&jd1) {
|
|
181
|
+
return Ok(None);
|
|
182
|
+
}
|
|
183
|
+
let site = Site::new(latitude, longitude);
|
|
184
|
+
let span = (Time::from_ut1(jd0).tt(), Time::from_ut1(jd1).tt());
|
|
185
|
+
let events = find_transitions(kernel, &site, span.0, span.1)?;
|
|
186
|
+
Ok(Some(SunEvents { events, span }))
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/// [`rise_set`] for `jd_utc`, from the events of its ±1.5 day window; `None` when
|
|
190
|
+
/// the window is not inside the span searched.
|
|
191
|
+
pub fn rise_set(&self, jd_utc: f64) -> Option<(f64, f64, f64)> {
|
|
192
|
+
let (t0, t1) = (
|
|
193
|
+
Time::from_ut1(jd_utc - 1.5).tt(),
|
|
194
|
+
Time::from_ut1(jd_utc + 1.5).tt(),
|
|
195
|
+
);
|
|
196
|
+
if t0 < self.span.0 || t1 > self.span.1 {
|
|
197
|
+
return None;
|
|
198
|
+
}
|
|
199
|
+
let from = self.events.partition_point(|e| e.0 < t0);
|
|
200
|
+
let to = self.events.partition_point(|e| e.0 <= t1);
|
|
201
|
+
Some(select_rise_set(&self.events[from..to], jd_utc))
|
|
202
|
+
}
|
|
203
|
+
}
|
|
158
204
|
|
|
205
|
+
/// The day's sunrise, sunset and next sunrise among the events around `jd_utc`.
|
|
206
|
+
fn select_rise_set(events: &[(f64, bool)], jd_utc: f64) -> (f64, f64, f64) {
|
|
159
207
|
let ut1 = |jd_tt: f64| Time::from_tt_jd(jd_tt).ut1();
|
|
160
208
|
let sunrises: Vec<f64> = events.iter().filter(|e| e.1).map(|e| ut1(e.0)).collect();
|
|
161
209
|
let sunsets: Vec<f64> = events.iter().filter(|e| !e.1).map(|e| ut1(e.0)).collect();
|
|
@@ -176,5 +224,5 @@ pub fn rise_set(
|
|
|
176
224
|
.copied()
|
|
177
225
|
.find(|&s| s > rise + 0.1)
|
|
178
226
|
.unwrap_or(rise + 1.0);
|
|
179
|
-
|
|
227
|
+
(rise, set, next_rise)
|
|
180
228
|
}
|
{astroceleste_engine-0.0.2 → astroceleste_engine-0.0.4}/crates/astroceleste-engine/src/chart.rs
RENAMED
|
@@ -8,7 +8,7 @@ use crate::aspects::{natal_aspects, Aspect, OrbSettings, Point};
|
|
|
8
8
|
use crate::ephemeris::KernelSet;
|
|
9
9
|
use crate::error::EngineError;
|
|
10
10
|
use crate::fixed_stars::{fixed_stars, FixedStarPosition};
|
|
11
|
-
use crate::houses::{calculate_houses, HouseSystem};
|
|
11
|
+
use crate::houses::{calculate_houses, HouseSystem, Houses};
|
|
12
12
|
use crate::instant::UtcInstant;
|
|
13
13
|
use crate::lots::{arabic_parts, Lot};
|
|
14
14
|
use crate::lunar::{lunar_status, LunarStatus};
|
|
@@ -16,7 +16,7 @@ use crate::planets::calculate_planets;
|
|
|
16
16
|
use crate::symbolic::symbolic_degree_number;
|
|
17
17
|
use crate::temperament::{temperament, Temperament};
|
|
18
18
|
use crate::zodiac::{
|
|
19
|
-
ayanamsa, ayanamsa_info, determine_house, longitude_to_zodiac, DEFAULT_AYANAMSA,
|
|
19
|
+
ayanamsa, ayanamsa_info, determine_house, longitude_to_zodiac, AyanamsaInfo, DEFAULT_AYANAMSA,
|
|
20
20
|
};
|
|
21
21
|
|
|
22
22
|
/// Every body a complete chart carries; missing ones are reported in
|
|
@@ -200,15 +200,28 @@ fn symbol_of(name: &str) -> &'static str {
|
|
|
200
200
|
}
|
|
201
201
|
}
|
|
202
202
|
|
|
203
|
-
///
|
|
204
|
-
|
|
203
|
+
/// The positions part of a chart: placements and house cusps, without aspects, fixed
|
|
204
|
+
/// stars, lots or temperament. Electional searches evaluate thousands of these.
|
|
205
|
+
pub(crate) struct Sky {
|
|
206
|
+
pub zodiac_type: &'static str,
|
|
207
|
+
pub is_sidereal: bool,
|
|
208
|
+
pub ayanamsa_code: &'static str,
|
|
209
|
+
pub info: AyanamsaInfo,
|
|
210
|
+
pub jd: f64,
|
|
211
|
+
/// Cusps 1-12, degrees.
|
|
212
|
+
pub cusps: Vec<f64>,
|
|
213
|
+
pub house_cusps: Vec<HouseCusp>,
|
|
214
|
+
pub planets: Vec<Placement>,
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/// Placements and houses of a request (the first half of [`calculate_chart`]).
|
|
218
|
+
pub(crate) fn sky(kernels: &KernelSet, req: &ChartRequest) -> Result<Sky, EngineError> {
|
|
205
219
|
let zodiac_type = match req.zodiac_type.trim().to_lowercase().as_str() {
|
|
206
220
|
"sidereal" => "sidereal",
|
|
207
221
|
_ => "tropical",
|
|
208
222
|
};
|
|
209
223
|
let is_sidereal = zodiac_type == "sidereal";
|
|
210
224
|
let ayanamsa_code = ayanamsa(req.ayanamsa).code;
|
|
211
|
-
let orbs = OrbSettings::merge(req.orb_settings)?;
|
|
212
225
|
|
|
213
226
|
let jd = req.instant.julian_day();
|
|
214
227
|
let info = ayanamsa_info(jd, ayanamsa_code);
|
|
@@ -242,16 +255,34 @@ pub fn calculate_chart(kernels: &KernelSet, req: &ChartRequest) -> Result<Chart,
|
|
|
242
255
|
})
|
|
243
256
|
.collect();
|
|
244
257
|
|
|
245
|
-
let
|
|
258
|
+
let raw: Vec<(&'static str, f64, f64, bool)> = engine
|
|
246
259
|
.bodies
|
|
247
260
|
.iter()
|
|
248
261
|
.map(|b| (b.name, b.longitude, b.speed, b.is_retrograde))
|
|
249
262
|
.collect();
|
|
263
|
+
let planets = placements(raw, &houses);
|
|
264
|
+
|
|
265
|
+
Ok(Sky {
|
|
266
|
+
zodiac_type,
|
|
267
|
+
is_sidereal,
|
|
268
|
+
ayanamsa_code,
|
|
269
|
+
info,
|
|
270
|
+
jd,
|
|
271
|
+
cusps,
|
|
272
|
+
house_cusps,
|
|
273
|
+
planets,
|
|
274
|
+
})
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/// Placements of bodies given as (name, longitude, speed, retrograde), followed by the
|
|
278
|
+
/// Ascendant and the Midheaven, with their houses.
|
|
279
|
+
pub(crate) fn placements(
|
|
280
|
+
mut raw: Vec<(&'static str, f64, f64, bool)>,
|
|
281
|
+
houses: &Houses,
|
|
282
|
+
) -> Vec<Placement> {
|
|
250
283
|
raw.push(("Ascendant", houses.ascendant, 0.0, false));
|
|
251
284
|
raw.push(("Midheaven", houses.midheaven, 0.0, false));
|
|
252
|
-
|
|
253
|
-
let planets: Vec<Placement> = raw
|
|
254
|
-
.iter()
|
|
285
|
+
raw.iter()
|
|
255
286
|
.map(|&(name, lon, speed, is_retrograde)| {
|
|
256
287
|
let z = longitude_to_zodiac(lon);
|
|
257
288
|
Placement {
|
|
@@ -262,13 +293,28 @@ pub fn calculate_chart(kernels: &KernelSet, req: &ChartRequest) -> Result<Chart,
|
|
|
262
293
|
degree: z.degree,
|
|
263
294
|
minute: z.minute,
|
|
264
295
|
ecliptic_longitude: lon,
|
|
265
|
-
house: determine_house(lon, &cusps),
|
|
296
|
+
house: determine_house(lon, &houses.cusps),
|
|
266
297
|
speed,
|
|
267
298
|
is_retrograde,
|
|
268
299
|
symbolic_degree: symbolic_degree_number(z.degree, z.minute),
|
|
269
300
|
}
|
|
270
301
|
})
|
|
271
|
-
.collect()
|
|
302
|
+
.collect()
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/// Compute a chart (`calculate_chart_data`).
|
|
306
|
+
pub fn calculate_chart(kernels: &KernelSet, req: &ChartRequest) -> Result<Chart, EngineError> {
|
|
307
|
+
let orbs = OrbSettings::merge(req.orb_settings)?;
|
|
308
|
+
let Sky {
|
|
309
|
+
zodiac_type,
|
|
310
|
+
is_sidereal,
|
|
311
|
+
ayanamsa_code,
|
|
312
|
+
info,
|
|
313
|
+
jd,
|
|
314
|
+
cusps,
|
|
315
|
+
house_cusps,
|
|
316
|
+
planets,
|
|
317
|
+
} = sky(kernels, req)?;
|
|
272
318
|
let points: Vec<Point> = planets
|
|
273
319
|
.iter()
|
|
274
320
|
.map(|p| Point {
|