siderust-cpp 0.8.0
Header-only C++ wrapper for siderust
Loading...
Searching...
No Matches
altitude.hpp
Go to the documentation of this file.
1#pragma once
2
12#include "bodies.hpp"
13#include "coordinates.hpp"
14#include "ffi_core.hpp"
15#include "time.hpp"
16#include <cstdint>
17#include <vector>
18
19namespace siderust {
20
21// ============================================================================
22// Event types
23// ============================================================================
24
31
32 static CrossingEvent from_c(const siderust_crossing_event_t &c) {
33 return {Time<TT, MJD>(c.mjd), static_cast<CrossingDirection>(c.direction)};
34 }
35};
36
42 qtty::Degree altitude;
44
45 static CulminationEvent from_c(const siderust_culmination_event_t &c) {
46 return {Time<TT, MJD>(c.mjd), qtty::Degree(c.altitude_deg),
47 static_cast<CulminationKind>(c.kind)};
48 }
49};
50
51// ============================================================================
52// SearchOptions
53// ============================================================================
54
59 qtty::Day time_tolerance = qtty::Day(1e-9);
60
61 SearchOptions() = default;
62
64 SearchOptions &with_tolerance(qtty::Day tolerance) {
65 time_tolerance = tolerance;
66 return *this;
67 }
68
69 siderust_search_opts_t to_c() const { return {time_tolerance.value()}; }
70};
71
72// ============================================================================
73// Internal helpers
74// ============================================================================
75namespace detail {
76
77inline std::vector<Period<TT, MJD>> periods_from_c(tempoch_period_mjd_t *ptr, uintptr_t count) {
78 std::vector<Period<TT, MJD>> result;
79 result.reserve(count);
80 for (uintptr_t i = 0; i < count; ++i) {
81 result.push_back(Period<TT, MJD>::from_c(ptr[i]));
82 }
83 siderust_periods_free(ptr, count);
84 return result;
85}
86
87inline std::vector<CrossingEvent> crossings_from_c(siderust_crossing_event_t *ptr,
88 uintptr_t count) {
89 std::vector<CrossingEvent> result;
90 result.reserve(count);
91 for (uintptr_t i = 0; i < count; ++i) {
92 result.push_back(CrossingEvent::from_c(ptr[i]));
93 }
94 siderust_crossings_free(ptr, count);
95 return result;
96}
97
98inline std::vector<CulminationEvent> culminations_from_c(siderust_culmination_event_t *ptr,
99 uintptr_t count) {
100 std::vector<CulminationEvent> result;
101 result.reserve(count);
102 for (uintptr_t i = 0; i < count; ++i) {
103 result.push_back(CulminationEvent::from_c(ptr[i]));
104 }
105 siderust_culminations_free(ptr, count);
106 return result;
107}
108
109} // namespace detail
110
111// ============================================================================
112// Sun altitude
113// ============================================================================
114
115namespace sun {
116
120inline qtty::Radian altitude_at(const Geodetic &obs, const Time<TT, MJD> &mjd) {
121 double out;
122 check_status(siderust_altitude_at(detail::make_body_subject(SIDERUST_BODY_SUN), obs.to_c(),
123 mjd.value(), &out),
124 "sun::altitude_at");
125 return qtty::Radian(out);
126}
127
131inline std::vector<Period<TT, MJD>> above_threshold(const Geodetic &obs,
132 const Period<TT, MJD> &window,
133 qtty::Degree threshold,
134 const SearchOptions &opts = {}) {
135 tempoch_period_mjd_t *ptr = nullptr;
136 uintptr_t count = 0;
137 check_status(siderust_above_threshold(detail::make_body_subject(SIDERUST_BODY_SUN), obs.to_c(),
138 window.c_inner(), threshold.value(), opts.to_c(), &ptr,
139 &count),
140 "sun::above_threshold");
141 return detail::periods_from_c(ptr, count);
142}
143
147inline std::vector<Period<TT, MJD>> below_threshold(const Geodetic &obs,
148 const Period<TT, MJD> &window,
149 qtty::Degree threshold,
150 const SearchOptions &opts = {}) {
151 tempoch_period_mjd_t *ptr = nullptr;
152 uintptr_t count = 0;
153 check_status(siderust_below_threshold(detail::make_body_subject(SIDERUST_BODY_SUN), obs.to_c(),
154 window.c_inner(), threshold.value(), opts.to_c(), &ptr,
155 &count),
156 "sun::below_threshold");
157 return detail::periods_from_c(ptr, count);
158}
159
163inline std::vector<CrossingEvent> crossings(const Geodetic &obs, const Period<TT, MJD> &window,
164 qtty::Degree threshold,
165 const SearchOptions &opts = {}) {
166 siderust_crossing_event_t *ptr = nullptr;
167 uintptr_t count = 0;
168 check_status(siderust_crossings(detail::make_body_subject(SIDERUST_BODY_SUN), obs.to_c(),
169 window.c_inner(), threshold.value(), opts.to_c(), &ptr, &count),
170 "sun::crossings");
171 return detail::crossings_from_c(ptr, count);
172}
173
177inline std::vector<CulminationEvent>
178culminations(const Geodetic &obs, const Period<TT, MJD> &window, const SearchOptions &opts = {}) {
179 siderust_culmination_event_t *ptr = nullptr;
180 uintptr_t count = 0;
181 check_status(siderust_culminations(detail::make_body_subject(SIDERUST_BODY_SUN), obs.to_c(),
182 window.c_inner(), opts.to_c(), &ptr, &count),
183 "sun::culminations");
184 return detail::culminations_from_c(ptr, count);
185}
186
190inline std::vector<Period<TT, MJD>> altitude_ranges(const Geodetic &obs,
191 const Period<TT, MJD> &window,
192 qtty::Degree min_alt, qtty::Degree max_alt,
193 const SearchOptions &opts = {}) {
194 tempoch_period_mjd_t *ptr = nullptr;
195 uintptr_t count = 0;
196 check_status(siderust_altitude_ranges(detail::make_body_subject(SIDERUST_BODY_SUN), obs.to_c(),
197 window.c_inner(), min_alt.value(), max_alt.value(),
198 opts.to_c(), &ptr, &count),
199 "sun::altitude_ranges");
200 return detail::periods_from_c(ptr, count);
201}
202
203} // namespace sun
204
205// ============================================================================
206// Moon altitude
207// ============================================================================
208
209namespace moon {
210
214inline qtty::Radian altitude_at(const Geodetic &obs, const Time<TT, MJD> &mjd) {
215 double out;
216 check_status(siderust_altitude_at(detail::make_body_subject(SIDERUST_BODY_MOON), obs.to_c(),
217 mjd.value(), &out),
218 "moon::altitude_at");
219 return qtty::Radian(out);
220}
221
225inline std::vector<Period<TT, MJD>> above_threshold(const Geodetic &obs,
226 const Period<TT, MJD> &window,
227 qtty::Degree threshold,
228 const SearchOptions &opts = {}) {
229 tempoch_period_mjd_t *ptr = nullptr;
230 uintptr_t count = 0;
231 check_status(siderust_above_threshold(detail::make_body_subject(SIDERUST_BODY_MOON), obs.to_c(),
232 window.c_inner(), threshold.value(), opts.to_c(), &ptr,
233 &count),
234 "moon::above_threshold");
235 return detail::periods_from_c(ptr, count);
236}
237
241inline std::vector<Period<TT, MJD>> below_threshold(const Geodetic &obs,
242 const Period<TT, MJD> &window,
243 qtty::Degree threshold,
244 const SearchOptions &opts = {}) {
245 tempoch_period_mjd_t *ptr = nullptr;
246 uintptr_t count = 0;
247 check_status(siderust_below_threshold(detail::make_body_subject(SIDERUST_BODY_MOON), obs.to_c(),
248 window.c_inner(), threshold.value(), opts.to_c(), &ptr,
249 &count),
250 "moon::below_threshold");
251 return detail::periods_from_c(ptr, count);
252}
253
257inline std::vector<CrossingEvent> crossings(const Geodetic &obs, const Period<TT, MJD> &window,
258 qtty::Degree threshold,
259 const SearchOptions &opts = {}) {
260 siderust_crossing_event_t *ptr = nullptr;
261 uintptr_t count = 0;
262 check_status(siderust_crossings(detail::make_body_subject(SIDERUST_BODY_MOON), obs.to_c(),
263 window.c_inner(), threshold.value(), opts.to_c(), &ptr, &count),
264 "moon::crossings");
265 return detail::crossings_from_c(ptr, count);
266}
267
271inline std::vector<CulminationEvent>
272culminations(const Geodetic &obs, const Period<TT, MJD> &window, const SearchOptions &opts = {}) {
273 siderust_culmination_event_t *ptr = nullptr;
274 uintptr_t count = 0;
275 check_status(siderust_culminations(detail::make_body_subject(SIDERUST_BODY_MOON), obs.to_c(),
276 window.c_inner(), opts.to_c(), &ptr, &count),
277 "moon::culminations");
278 return detail::culminations_from_c(ptr, count);
279}
280
284inline std::vector<Period<TT, MJD>> altitude_ranges(const Geodetic &obs,
285 const Period<TT, MJD> &window,
286 qtty::Degree min_alt, qtty::Degree max_alt,
287 const SearchOptions &opts = {}) {
288 tempoch_period_mjd_t *ptr = nullptr;
289 uintptr_t count = 0;
290 check_status(siderust_altitude_ranges(detail::make_body_subject(SIDERUST_BODY_MOON), obs.to_c(),
291 window.c_inner(), min_alt.value(), max_alt.value(),
292 opts.to_c(), &ptr, &count),
293 "moon::altitude_ranges");
294 return detail::periods_from_c(ptr, count);
295}
296
297} // namespace moon
298
299// ============================================================================
300// Star altitude
301// ============================================================================
302
303namespace star_altitude {
304
308inline qtty::Radian altitude_at(const Star &s, const Geodetic &obs, const Time<TT, MJD> &mjd) {
309 double out;
311 siderust_altitude_at(detail::make_star_subject(s.c_handle()), obs.to_c(), mjd.value(), &out),
312 "star_altitude::altitude_at");
313 return qtty::Radian(out);
314}
315
319inline std::vector<Period<TT, MJD>> above_threshold(const Star &s, const Geodetic &obs,
320 const Period<TT, MJD> &window,
321 qtty::Degree threshold,
322 const SearchOptions &opts = {}) {
323 tempoch_period_mjd_t *ptr = nullptr;
324 uintptr_t count = 0;
325 check_status(siderust_above_threshold(detail::make_star_subject(s.c_handle()), obs.to_c(),
326 window.c_inner(), threshold.value(), opts.to_c(), &ptr,
327 &count),
328 "star_altitude::above_threshold");
329 return detail::periods_from_c(ptr, count);
330}
331
335inline std::vector<Period<TT, MJD>> below_threshold(const Star &s, const Geodetic &obs,
336 const Period<TT, MJD> &window,
337 qtty::Degree threshold,
338 const SearchOptions &opts = {}) {
339 tempoch_period_mjd_t *ptr = nullptr;
340 uintptr_t count = 0;
341 check_status(siderust_below_threshold(detail::make_star_subject(s.c_handle()), obs.to_c(),
342 window.c_inner(), threshold.value(), opts.to_c(), &ptr,
343 &count),
344 "star_altitude::below_threshold");
345 return detail::periods_from_c(ptr, count);
346}
347
351inline std::vector<CrossingEvent> crossings(const Star &s, const Geodetic &obs,
352 const Period<TT, MJD> &window, qtty::Degree threshold,
353 const SearchOptions &opts = {}) {
354 siderust_crossing_event_t *ptr = nullptr;
355 uintptr_t count = 0;
356 check_status(siderust_crossings(detail::make_star_subject(s.c_handle()), obs.to_c(),
357 window.c_inner(), threshold.value(), opts.to_c(), &ptr, &count),
358 "star_altitude::crossings");
359 return detail::crossings_from_c(ptr, count);
360}
361
365inline std::vector<CulminationEvent> culminations(const Star &s, const Geodetic &obs,
366 const Period<TT, MJD> &window,
367 const SearchOptions &opts = {}) {
368 siderust_culmination_event_t *ptr = nullptr;
369 uintptr_t count = 0;
370 check_status(siderust_culminations(detail::make_star_subject(s.c_handle()), obs.to_c(),
371 window.c_inner(), opts.to_c(), &ptr, &count),
372 "star_altitude::culminations");
373 return detail::culminations_from_c(ptr, count);
374}
375
376} // namespace star_altitude
377
378// ============================================================================
379// ICRS direction altitude
380// ============================================================================
381
382namespace icrs_altitude {
383
387inline qtty::Radian altitude_at(const spherical::direction::ICRS &dir, const Geodetic &obs,
388 const Time<TT, MJD> &mjd) {
389 double out;
391 siderust_altitude_at(detail::make_icrs_subject(dir.to_c()), obs.to_c(), mjd.value(), &out),
392 "icrs_altitude::altitude_at");
393 return qtty::Radian(out);
394}
395
399inline qtty::Radian altitude_at(qtty::Degree ra, qtty::Degree dec, const Geodetic &obs,
400 const Time<TT, MJD> &mjd) {
401 return altitude_at(spherical::direction::ICRS(ra, dec), obs, mjd);
402}
403
407inline std::vector<Period<TT, MJD>> above_threshold(const spherical::direction::ICRS &dir,
408 const Geodetic &obs,
409 const Period<TT, MJD> &window,
410 qtty::Degree threshold,
411 const SearchOptions &opts = {}) {
412 tempoch_period_mjd_t *ptr = nullptr;
413 uintptr_t count = 0;
414 check_status(siderust_above_threshold(detail::make_icrs_subject(dir.to_c()), obs.to_c(),
415 window.c_inner(), threshold.value(), opts.to_c(), &ptr,
416 &count),
417 "icrs_altitude::above_threshold");
418 return detail::periods_from_c(ptr, count);
419}
420
424inline std::vector<Period<TT, MJD>> below_threshold(const spherical::direction::ICRS &dir,
425 const Geodetic &obs,
426 const Period<TT, MJD> &window,
427 qtty::Degree threshold,
428 const SearchOptions &opts = {}) {
429 tempoch_period_mjd_t *ptr = nullptr;
430 uintptr_t count = 0;
431 check_status(siderust_below_threshold(detail::make_icrs_subject(dir.to_c()), obs.to_c(),
432 window.c_inner(), threshold.value(), opts.to_c(), &ptr,
433 &count),
434 "icrs_altitude::below_threshold");
435 return detail::periods_from_c(ptr, count);
436}
437
441inline std::vector<Period<TT, MJD>> altitude_ranges(const spherical::direction::ICRS &dir,
442 const Geodetic &obs,
443 const Period<TT, MJD> &window,
444 qtty::Degree min_alt, qtty::Degree max_alt,
445 const SearchOptions &opts = {}) {
446 tempoch_period_mjd_t *ptr = nullptr;
447 uintptr_t count = 0;
448 check_status(siderust_altitude_ranges(detail::make_icrs_subject(dir.to_c()), obs.to_c(),
449 window.c_inner(), min_alt.value(), max_alt.value(),
450 opts.to_c(), &ptr, &count),
451 "icrs_altitude::altitude_ranges");
452 return detail::periods_from_c(ptr, count);
453}
454
455} // namespace icrs_altitude
456
457} // namespace siderust
RAII Star handle, Planet value type, and catalog helpers.
RAII handle to a Star (opaque Rust object).
Definition bodies.hpp:176
const SiderustStar * c_handle() const
Access the raw C handle (for passing to altitude functions).
Definition bodies.hpp:206
Coordinate module umbrella.
Error handling and utility base for the siderust C++ wrapper.
std::vector< CrossingEvent > crossings_from_c(siderust_crossing_event_t *ptr, uintptr_t count)
Definition altitude.hpp:87
siderust_subject_t make_star_subject(const SiderustStar *h)
Build a siderust_subject_t for a star, borrowing the handle.
Definition ffi_core.hpp:266
siderust_subject_t make_body_subject(SiderustBody b)
Build a siderust_subject_t for a solar-system body.
Definition ffi_core.hpp:258
std::vector< CulminationEvent > culminations_from_c(siderust_culmination_event_t *ptr, uintptr_t count)
Definition altitude.hpp:98
siderust_subject_t make_icrs_subject(const siderust_spherical_dir_t &dir)
Build a siderust_subject_t for a fixed ICRS direction.
Definition ffi_core.hpp:274
std::vector< Period< TT, MJD > > periods_from_c(tempoch_period_mjd_t *ptr, uintptr_t count)
Definition altitude.hpp:77
std::vector< Period< TT, MJD > > below_threshold(const spherical::direction::ICRS &dir, const Geodetic &obs, const Period< TT, MJD > &window, qtty::Degree threshold, const SearchOptions &opts={})
Find periods when a fixed ICRS direction is below a threshold.
Definition altitude.hpp:424
std::vector< Period< TT, MJD > > altitude_ranges(const spherical::direction::ICRS &dir, const Geodetic &obs, const Period< TT, MJD > &window, qtty::Degree min_alt, qtty::Degree max_alt, const SearchOptions &opts={})
Find periods when a fixed ICRS direction's altitude is within [min, max].
Definition altitude.hpp:441
std::vector< Period< TT, MJD > > above_threshold(const spherical::direction::ICRS &dir, const Geodetic &obs, const Period< TT, MJD > &window, qtty::Degree threshold, const SearchOptions &opts={})
Find periods when a fixed ICRS direction is above a threshold.
Definition altitude.hpp:407
qtty::Radian altitude_at(const spherical::direction::ICRS &dir, const Geodetic &obs, const Time< TT, MJD > &mjd)
Compute altitude (radians) for a fixed ICRS direction.
Definition altitude.hpp:387
std::vector< Period< TT, MJD > > below_threshold(const Geodetic &obs, const Period< TT, MJD > &window, qtty::Degree threshold, const SearchOptions &opts={})
Find periods when the Moon is below a threshold altitude.
Definition altitude.hpp:241
std::vector< Period< TT, MJD > > altitude_ranges(const Geodetic &obs, const Period< TT, MJD > &window, qtty::Degree min_alt, qtty::Degree max_alt, const SearchOptions &opts={})
Find periods when the Moon's altitude is within [min, max].
Definition altitude.hpp:284
std::vector< CulminationEvent > culminations(const Geodetic &obs, const Period< TT, MJD > &window, const SearchOptions &opts={})
Find culmination events for the Moon.
Definition altitude.hpp:272
qtty::Radian altitude_at(const Geodetic &obs, const Time< TT, MJD > &mjd)
Compute the Moon's altitude (radians) at a given Time<TT, MJD> instant.
Definition altitude.hpp:214
std::vector< CrossingEvent > crossings(const Geodetic &obs, const Period< TT, MJD > &window, qtty::Degree threshold, const SearchOptions &opts={})
Find threshold-crossing events for the Moon.
Definition altitude.hpp:257
std::vector< Period< TT, MJD > > above_threshold(const Geodetic &obs, const Period< TT, MJD > &window, qtty::Degree threshold, const SearchOptions &opts={})
Find periods when the Moon is above a threshold altitude.
Definition altitude.hpp:225
std::vector< CulminationEvent > culminations(const Star &s, const Geodetic &obs, const Period< TT, MJD > &window, const SearchOptions &opts={})
Find culmination events for a star.
Definition altitude.hpp:365
qtty::Radian altitude_at(const Star &s, const Geodetic &obs, const Time< TT, MJD > &mjd)
Compute a star's altitude (radians) at a given Time<TT, MJD> instant.
Definition altitude.hpp:308
std::vector< Period< TT, MJD > > below_threshold(const Star &s, const Geodetic &obs, const Period< TT, MJD > &window, qtty::Degree threshold, const SearchOptions &opts={})
Find periods when a star is below a threshold altitude.
Definition altitude.hpp:335
std::vector< Period< TT, MJD > > above_threshold(const Star &s, const Geodetic &obs, const Period< TT, MJD > &window, qtty::Degree threshold, const SearchOptions &opts={})
Find periods when a star is above a threshold altitude.
Definition altitude.hpp:319
std::vector< CrossingEvent > crossings(const Star &s, const Geodetic &obs, const Period< TT, MJD > &window, qtty::Degree threshold, const SearchOptions &opts={})
Find threshold-crossing events for a star.
Definition altitude.hpp:351
qtty::Radian altitude_at(const Geodetic &obs, const Time< TT, MJD > &mjd)
Compute the Sun's altitude (radians) at a given Time<TT, MJD> instant.
Definition altitude.hpp:120
std::vector< Period< TT, MJD > > altitude_ranges(const Geodetic &obs, const Period< TT, MJD > &window, qtty::Degree min_alt, qtty::Degree max_alt, const SearchOptions &opts={})
Find periods when the Sun's altitude is within [min, max].
Definition altitude.hpp:190
std::vector< Period< TT, MJD > > above_threshold(const Geodetic &obs, const Period< TT, MJD > &window, qtty::Degree threshold, const SearchOptions &opts={})
Find periods when the Sun is above a threshold altitude.
Definition altitude.hpp:131
std::vector< Period< TT, MJD > > below_threshold(const Geodetic &obs, const Period< TT, MJD > &window, qtty::Degree threshold, const SearchOptions &opts={})
Find periods when the Sun is below a threshold altitude.
Definition altitude.hpp:147
std::vector< CrossingEvent > crossings(const Geodetic &obs, const Period< TT, MJD > &window, qtty::Degree threshold, const SearchOptions &opts={})
Find threshold-crossing events for the Sun.
Definition altitude.hpp:163
std::vector< CulminationEvent > culminations(const Geodetic &obs, const Period< TT, MJD > &window, const SearchOptions &opts={})
Find culmination events for the Sun.
Definition altitude.hpp:178
tempoch::EncodedTime< Scale, Format > Time
Definition time.hpp:36
void check_status(siderust_status_t status, const char *operation)
Definition ffi_core.hpp:111
tempoch::Period< Time< Scale, Format > > Period
Definition time.hpp:37
A threshold-crossing event (rising or setting).
Definition altitude.hpp:28
CrossingDirection direction
Definition altitude.hpp:30
Time< TT, MJD > time
Definition altitude.hpp:29
static CrossingEvent from_c(const siderust_crossing_event_t &c)
Definition altitude.hpp:32
A culmination (local altitude extremum) event.
Definition altitude.hpp:40
static CulminationEvent from_c(const siderust_culmination_event_t &c)
Definition altitude.hpp:45
Geodetic position (WGS84 ellipsoid).
Definition geodetic.hpp:29
siderust_geodetic_t to_c() const
Convert to C FFI struct.
Definition geodetic.hpp:44
Options for altitude search algorithms.
Definition altitude.hpp:58
siderust_search_opts_t to_c() const
Definition altitude.hpp:69
SearchOptions & with_tolerance(qtty::Day tolerance)
Set time tolerance.
Definition altitude.hpp:64
A direction on the celestial sphere, compile-time tagged by frame.
Definition spherical.hpp:50
siderust_spherical_dir_t to_c() const
Public siderust time tags and typed time/period aliases.