From 3f40c9d9b992b340e5aa11eb2198c3c9f82af5b7 Mon Sep 17 00:00:00 2001 From: Attila Kovacs Date: Thu, 9 Jan 2025 15:14:54 +0100 Subject: [PATCH] New set of example files --- CHANGELOG.md | 8 +- examples/example-calceph | Bin 0 -> 17280 bytes examples/example-calceph.c | 179 ++++++++++++++++++++ examples/example-cspice | Bin 0 -> 17280 bytes examples/example-cspice.c | 175 +++++++++++++++++++ examples/example-high-z | Bin 0 -> 17232 bytes examples/example-high-z.c | 168 ++++++++++++++++++ examples/example-orbital | Bin 0 -> 17184 bytes examples/example-orbital.c | 184 ++++++++++++++++++++ examples/example-star.c | 339 +++++++++++++++---------------------- examples/example-usno.txt | 32 ---- 11 files changed, 845 insertions(+), 240 deletions(-) create mode 100755 examples/example-calceph create mode 100644 examples/example-calceph.c create mode 100755 examples/example-cspice create mode 100644 examples/example-cspice.c create mode 100755 examples/example-high-z create mode 100644 examples/example-high-z.c create mode 100755 examples/example-orbital create mode 100644 examples/example-orbital.c delete mode 100644 examples/example-usno.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index e5912459..ef986776 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [1.2.0-rc5] - 2025-01-01 +## [Unreleased] Release candidate for the next feature release, expected around 1 February 2025. @@ -80,6 +80,9 @@ Release candidate for the next feature release, expected around 1 February 2025. - #98: Added `gcrs_to_tod()` / `tod_to_gcrs()` and `gcrs_to_mod()` / `mod_to_gcrs()` vector conversion functions for convenience. + + - #106: New example files under `examples/` demonstrating the recommended approach for using SuperNOVAS to calculate + positions for various types of object. - Added various `object` initializer macros in `novas.h` for the major planets, Sun, Moon, and barycenters, e.g. `NOVAS_EARTH_INIT` or `NOVAS_SSB_INIT`. These wrap the parametric `NOVAS_PLANET_INIT(num, name)` macro, and can be @@ -112,6 +115,9 @@ Release candidate for the next feature release, expected around 1 February 2025. - #97: Updated `NOVAS_PLANETS`, `NOVAS_PLANET_NAMES_INIT`, and `NOVAS_RMASS_INIT` macros to include the added planet constants. + - #106: The old (legacy) NOVAS C example has been removed. Instead a new set of examples are provided, which are + better suited for SuperNOVAS. + - `make check` now runs both static analysis by cppcheck (new `analysis` target) and regression tests (`test` target), in closer conformance to GNU Makefile standards. diff --git a/examples/example-calceph b/examples/example-calceph new file mode 100755 index 0000000000000000000000000000000000000000..87c613c5374af75d48c103368ebf63e6682e2f84 GIT binary patch literal 17280 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 literal 0 HcmV?d00001 diff --git a/examples/example-calceph.c b/examples/example-calceph.c new file mode 100644 index 00000000..cf509d5e --- /dev/null +++ b/examples/example-calceph.c @@ -0,0 +1,179 @@ +/** + * @file + * + * @date Created on Jan 9, 2025 + * @author Attila Kovacs + * + * Example file for using the SuperNOVAS C/C++ library for determining positions for + * Solary-system sources, with the CALCEPH C library providing access to ephemeris + * files. + * + * You will need access to the CALCEPH library (unversioned `libcalceph.so` or else + * `libcalceph.a`) and C headers (`calceph.h`), and the SuperNOVAS + * `libsolsys-calceph.so` (or `libsoslsys-calceph.a`) module. + * + * Link with: + * + * ``` + * -lsupernovas -lsolsys-calceph -lcalceph + * ``` + */ + +#include +#include +#include + +#include ///< SuperNOVAS functions and definitions +#include ///< CALCEPH adapter functions to SuperNOVAS + + +// Below are some Earth orientation values. Here we define them as constants, but they may +// of course be variables. They should be set to the appropriate values for the time +// of observation based on the IERS Bulletins... + +#define LEAP_SECONDS 37 ///< [s] current leap seconds +#define DUT1 0.114 ///< [s] current UT1 - UTC time difference from IERS Bulletin A +#define POLAR_DX 230.0 ///< [mas] Earth polar offset x, e.g. from IERS Bulletin A. +#define POLAR_DY -62.0 ///< [mas] Earth polar offset y, e.g. from IERS Bulletin A. + +int main() { + // SuperNOVAS aariables used for the calculations -------------------------> + cat_entry star = CAT_ENTRY_INIT; // catalog information about a sidereal source + object source; // observed source + observer obs; // observer location + novas_timespec obs_time; // astrometric time of observation + novas_frame obs_frame; // observing frame defined for observing time and location + enum novas_accuracy accuracy; // NOVAS_FULL_ACCURACY or NOVAS_REDUCED_ACCURACY + sky_pos apparent; // calculated precise observed (apparent) position of source + + // Calculated quantities -------------------------------------------------> + double az, el; // calculated azimuth and elevation at observing site + + // Intermediate variables we'll use --------------------------------------> + t_calcephbin *de440; // CALCEPH ephemeris binary + struct timespec unix_time; // Standard precision UNIX time structure + + + // We'll print debugging messages and error traces... + novas_debug(NOVAS_DEBUG_ON); + + // ------------------------------------------------------------------------- + // We'll use the CALCEPH library to provide ephemeris data + + // First open one or more ephemeris files with CALCEPH to use + // E.g. the DE440 (short-term) ephemeris data from JPL. + de440 = calceph_open("path/to/de440s.bsp"); + if(!de440) { + fprintf(stderr, "ERROR! could not open ephemeris data\n"); + return 1; + } + + // Make de440 provide ephemeris data for the major planets. + novas_use_calceph_planets(de440); + + // We could specify to use a calceph ephemeris binary for generic + // Solar-systems sources also (including planets too if + // novas_use_calceph_planets() is not called separately + // + // E.g. Jovian satellites: + // t_calcephbin jovian = calceph_open("/path/to/jup365.bsp"); + // novas_use_calceph(jovian); + + // Since we have an ephemeris provider for major planets, we can unlock the + // ultimate accuracy of SuperNOVAS. + accuracy = NOVAS_FULL_ACCURACY; // sub-uas precision + + + // ------------------------------------------------------------------------- + // Define a Solar-system source + + // To define a major planet (or Sun, Moon, SSB, or EMB): + if(make_planet(NOVAS_MARS, &source) != 0) { + fprintf(stderr, "ERROR! defining planet.\n"); + return 1; + } + + // ... Or, to define a minor body, such as an asteroid or satellite + // with a name and ID number. + /* + if(make_ephem_object("Io", 501, &source) != 0) { + fprintf(stderr, "ERROR! defining ephemeris body.\n"); + return 1; + } + */ + + /* + // If the object uses CALCEPH IDs instead of NAIF, then + novas_calceph_use_ids(NOVAS_ID_CALCEPH); + */ + + + // ------------------------------------------------------------------------- + // Define observer somewhere on Earth (we can also define observers in Earth + // or Sun orbit, at the geocenter or at the Solary-system barycenter...) + + // Specify the location we are observing from + // 50.7374 deg N, 7.0982 deg E, 60m elevation + if(make_observer_on_surface(50.7374, 7.0982, 60.0, 0.0, 0.0, &obs) != 0) { + fprintf(stderr, "ERROR! defining Earth-based observer location.\n"); + return 1; + } + + + // ------------------------------------------------------------------------- + // Set the astrometric time of observation... + + // Get the current system time, with up to nanosecond resolution... + clock_gettime(CLOCK_REALTIME, &unix_time); + + // Set the time of observation to the precise UTC-based UNIX time + if(novas_set_unix_time(unix_time.tv_sec, unix_time.tv_nsec, LEAP_SECONDS, DUT1, &obs_time) != 0) { + fprintf(stderr, "ERROR! failed to set time of observation.\n"); + return 1; + } + + // ... Or you could set a time explicily in any known timescale. + /* + // Let's set a TDB-based time for the start of the J2000 epoch exactly... + if(novas_set_time(NOVAS_TDB, NOVAS_JD_J2000, LEAP_SECONDS, DUT1, &obs_time) != 0) { + fprintf(stderr, "ERROR! failed to set time of observation.\n"); + return 1; + } + */ + + // ------------------------------------------------------------------------- + // Initialize the observing frame with the given observing and Earth + // orientation patameters. + // + if(novas_make_frame(accuracy, &obs, &obs_time, POLAR_DX, POLAR_DY, &obs_frame) != 0) { + fprintf(stderr, "ERROR! failed to define observing frame.\n"); + return 1; + } + + + // ------------------------------------------------------------------------- + // Calculate the precise apparent position (here in CIRS coordinates) + if(novas_sky_pos(&source, &obs_frame, NOVAS_CIRS, &apparent) != 0) { + fprintf(stderr, "ERROR! failed to calculate apparent position.\n"); + return 1; + } + + // Let's print the apparent position + printf(" RA = %.9f h, Dec = %.9f deg, rad_vel = %.6f km/s\n", apparent.ra, apparent.dec, apparent.rv); + + + // ------------------------------------------------------------------------- + // Convert the apparent position in CIRS on sky to horizontal coordinates + // We'll use a standard (fixed) atmospheric model to estimate an optical refraction + // (You might use other refraction models, or NULL to ignore refraction corrections) + if(novas_app_to_hor(&obs_frame, NOVAS_CIRS, apparent.ra, apparent.dec, novas_standard_refraction, &az, &el) != 0) { + fprintf(stderr, "ERROR! failed to calculate azimuth / elevation.\n"); + return 1; + } + + // Let's print the calculated azimuth and elevation + printf(" Az = %.6f deg, El = %.6f deg\n", az, el); + + return 0; +} + diff --git a/examples/example-cspice b/examples/example-cspice new file mode 100755 index 0000000000000000000000000000000000000000..c333358c5fe4a2c683101cb437a45aa3fe3a6167 GIT binary patch literal 17280 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 EH%ixLWdHyG literal 0 HcmV?d00001 diff --git a/examples/example-cspice.c b/examples/example-cspice.c new file mode 100644 index 00000000..cafc9a41 --- /dev/null +++ b/examples/example-cspice.c @@ -0,0 +1,175 @@ +/** + * @file + * + * @date Created on Jan 9, 2025 + * @author Attila Kovacs + * + * Example file for using the SuperNOVAS C/C++ library for determining positions for + * Solary-system sources, with the NAIF CSPICE toolkit providing access to ephemeris + * files. + * + * You will need access to the NAIF CSPICE library (unversioned `libcspice.so` or else + * `libcspice.a`) and C headers (`cspice/*.h`), and the SuperNOVAS `libsolsys-cspice.so` + * (or `libsoslsys-cspice.a`) module. + * + * To compile CSPICE as a shared (.so) library, you may want to check out the GitHub + * repository: + * + * - https://github.com/Smithsonian/cspice-sharedlib + * + * Link with: + * + * ``` + * -lsupernovas -lsolsys-cspice -lcspice + * ``` + */ + +#include +#include +#include + +#include ///< SuperNOVAS functions and definitions +#include ///< CSPICE adapter functions to SuperNOVAS + + +// Below are some Earth orientation values. Here we define them as constants, but they may +// of course be variables. They should be set to the appropriate values for the time +// of observation based on the IERS Bulletins... + +#define LEAP_SECONDS 37 ///< [s] current leap seconds +#define DUT1 0.114 ///< [s] current UT1 - UTC time difference from IERS Bulletin A +#define POLAR_DX 230.0 ///< [mas] Earth polar offset x, e.g. from IERS Bulletin A. +#define POLAR_DY -62.0 ///< [mas] Earth polar offset y, e.g. from IERS Bulletin A. + +int main() { + // SuperNOVAS aariables used for the calculations -------------------------> + cat_entry star = CAT_ENTRY_INIT; // catalog information about a sidereal source + object source; // observed source + observer obs; // observer location + novas_timespec obs_time; // astrometric time of observation + novas_frame obs_frame; // observing frame defined for observing time and location + enum novas_accuracy accuracy; // NOVAS_FULL_ACCURACY or NOVAS_REDUCED_ACCURACY + sky_pos apparent; // calculated precise observed (apparent) position of source + + // Calculated quantities -------------------------------------------------> + double az, el; // calculated azimuth and elevation at observing site + + // Intermediate variables we'll use --------------------------------------> + struct timespec unix_time; // Standard precision UNIX time structure + + + // We'll print debugging messages and error traces... + novas_debug(NOVAS_DEBUG_ON); + + + // ------------------------------------------------------------------------- + // We'll use the NAIF CSPICE Toolkit to provide ephemeris data + + // Open one or more ephemeris files to use...' + // E.g. the DE440 (short-term) ephemeris data from JPL. + if(cspice_add_kernel("path/to/de440s.bsp") != 0) { + fprintf(stderr, "ERROR! could not open ephemeris data\n"); + return 1; + } + + // ... You can open multiple NAIF kernels + // E.g. add Jovian satellites... + // cspice_add_kernel("path/to/jup365.bsp"); + + // Now we can use the loaded ephemeris files for Solar-system objects. + // (major planets and minor bodies alike). + novas_use_cspice(); + + // And, since we have an ephemeris provider for major planets, we can unlock + // the ultimate accuracy of SuperNOVAS. + accuracy = NOVAS_FULL_ACCURACY; // sub-uas precision + + + // ------------------------------------------------------------------------- + // Define a Solar-system source + + // To define a major planet (or Sun, Moon, SSB, or EMB): + if(make_planet(NOVAS_MARS, &source) != 0) { + fprintf(stderr, "ERROR! defining planet.\n"); + return 1; + } + + // ... Or, to define a minor body, such as an asteroid or satellite + // with a name and NAIF ID. + /* + if(make_ephem_object("Io", 501, &source) != 0) { + fprintf(stderr, "ERROR! defining ephemeris body.\n"); + return 1; + } + */ + + + // ------------------------------------------------------------------------- + // Define observer somewhere on Earth (we can also define observers in Earth + // or Sun orbit, at the geocenter or at the Solary-system barycenter...) + + // Specify the location we are observing from + // 50.7374 deg N, 7.0982 deg E, 60m elevation + if(make_observer_on_surface(50.7374, 7.0982, 60.0, 0.0, 0.0, &obs) != 0) { + fprintf(stderr, "ERROR! defining Earth-based observer location.\n"); + return 1; + } + + + // ------------------------------------------------------------------------- + // Set the astrometric time of observation... + + // Get the current system time, with up to nanosecond resolution... + clock_gettime(CLOCK_REALTIME, &unix_time); + + // Set the time of observation to the precise UTC-based UNIX time + if(novas_set_unix_time(unix_time.tv_sec, unix_time.tv_nsec, LEAP_SECONDS, DUT1, &obs_time) != 0) { + fprintf(stderr, "ERROR! failed to set time of observation.\n"); + return 1; + } + + // ... Or you could set a time explicily in any known timescale. + /* + // Let's set a TDB-based time for the start of the J2000 epoch exactly... + if(novas_set_time(NOVAS_TDB, NOVAS_JD_J2000, LEAP_SECONDS, DUT1, &obs_time) != 0) { + fprintf(stderr, "ERROR! failed to set time of observation.\n"); + return 1; + } + */ + + // ------------------------------------------------------------------------- + // Initialize the observing frame with the given observing and Earth + // orientation patameters. + // + if(novas_make_frame(accuracy, &obs, &obs_time, POLAR_DX, POLAR_DY, &obs_frame) != 0) { + fprintf(stderr, "ERROR! failed to define observing frame.\n"); + return 1; + } + + + // ------------------------------------------------------------------------- + // Calculate the precise apparent position (here in CIRS coordinates) + if(novas_sky_pos(&source, &obs_frame, NOVAS_CIRS, &apparent) != 0) { + fprintf(stderr, "ERROR! failed to calculate apparent position.\n"); + return 1; + } + + // Let's print the apparent position + printf(" RA = %.9f h, Dec = %.9f deg, rad_vel = %.6f km/s\n", apparent.ra, apparent.dec, apparent.rv); + + + // ------------------------------------------------------------------------- + // Convert the apparent position in CIRS on sky to horizontal coordinates + // We'll use a standard (fixed) atmospheric model to estimate an optical refraction + // (You might use other refraction models, or NULL to ignore refraction corrections) + if(novas_app_to_hor(&obs_frame, NOVAS_CIRS, apparent.ra, apparent.dec, novas_standard_refraction, &az, &el) != 0) { + fprintf(stderr, "ERROR! failed to calculate azimuth / elevation.\n"); + return 1; + } + + // Let's print the calculated azimuth and elevation + printf(" Az = %.6f deg, El = %.6f deg\n", az, el); + + return 0; +} + diff --git a/examples/example-high-z b/examples/example-high-z new file mode 100755 index 0000000000000000000000000000000000000000..1ceb357051a5f3589453ef9ce0d3324c4a0343fb GIT binary patch literal 17232 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 +#include +#include + +#include ///< SuperNOVAS functions and definitions + +// Below are some Earth orientation values. Here we define them as constants, but they may +// of course be variables. They should be set to the appropriate values for the time +// of observation based on the IERS Bulletins... + +#define LEAP_SECONDS 37 ///< [s] current leap seconds +#define DUT1 0.114 ///< [s] current UT1 - UTC time difference from IERS Bulletin A +#define POLAR_DX 230.0 ///< [mas] Earth polar offset x, e.g. from IERS Bulletin A. +#define POLAR_DY -62.0 ///< [mas] Earth polar offset y, e.g. from IERS Bulletin A. + +int main() { + // SuperNOVAS aariables used for the calculations -------------------------> + object source; // a celestial object: sidereal, planet, ephemeris or orbital source + observer obs; // observer location + novas_timespec obs_time; // astrometric time of observation + novas_frame obs_frame; // observing frame defined for observing time and location + enum novas_accuracy accuracy; // NOVAS_FULL_ACCURACY or NOVAS_REDUCED_ACCURACY + sky_pos apparent; // calculated precise observed (apparent) position of source + + // Calculated quantities -------------------------------------------------> + double az, el; // calculated azimuth and elevation at observing site + + // Intermediate variables we'll use --------------------------------------> + struct timespec unix_time; // Standard precision UNIX time structure + + + // We'll print debugging messages and error traces... + novas_debug(NOVAS_DEBUG_ON); + + + // ------------------------------------------------------------------------- + // Define a high-z source. + + // 12h29m6.6997s +2d3m8.598s (ICRS) z=0.158339 + if(make_redshifted_object("3c273", 12.4851944, 2.0523883, 0.158339, &source) != 0) { + fprintf(stderr, "ERROR! defining cat_entry.\n"); + return 1; + } + + // If we did not use ICRS catalog coordinates, we would have to convert them to ICRS... + + /* E.g. change B1950 to the J2000 (FK5) system... + if(transform_cat(CHANGE_EPOCH, NOVAS_JD_B1950, &source.star, NOVAS_JD_J2000, "FK5", &source.star) != 0) { + fprintf(stderr, "ERROR! converting B1950 catalog coordinates to J2000.\n"); + return 1; + } */ + + /* Then convert J2000 coordinates to ICRS (also in place). Here the dates don't matter... + if(transform_cat(CHANGE_J2000_TO_ICRS, 0.0, &source.star, 0.0, "ICRS", &source.star) != 0) { + fprintf(stderr, "ERROR! converting J2000 catalog coordinates to ICRS.\n"); + return 1; + } */ + + + // ------------------------------------------------------------------------- + // Define observer somewhere on Earth (we can also define observers in Earth + // or Sun orbit, at the geocenter or at the Solary-system barycenter...) + + // Specify the location we are observing from + // 50.7374 deg N, 7.0982 deg E, 60m elevation + if(make_observer_on_surface(50.7374, 7.0982, 60.0, 0.0, 0.0, &obs) != 0) { + fprintf(stderr, "ERROR! defining Earth-based observer location.\n"); + return 1; + } + + + // ------------------------------------------------------------------------- + // Set the astrometric time of observation... + + // Get the current system time, with up to nanosecond resolution... + clock_gettime(CLOCK_REALTIME, &unix_time); + + // Set the time of observation to the precise UTC-based UNIX time + if(novas_set_unix_time(unix_time.tv_sec, unix_time.tv_nsec, LEAP_SECONDS, DUT1, &obs_time) != 0) { + fprintf(stderr, "ERROR! failed to set time of observation.\n"); + return 1; + } + + // ... Or you could set a time explicily in any known timescale. + /* + // Let's set a TDB-based time for the start of the J2000 epoch exactly... + if(novas_set_time(NOVAS_TDB, NOVAS_JD_J2000, LEAP_SECONDS, DUT1, &obs_time) != 0) { + fprintf(stderr, "ERROR! failed to set time of observation.\n"); + return 1; + } + */ + + + // ------------------------------------------------------------------------- + // You might want to set a provider for precise planet positions so we might + // calculate Earth, Sun and major planet positions accurately. If an planet + // provider is configured, we can unlock the ultimate (sub-uas) accuracy of + // SuperNOVAS. + // + // There are many ways to set a provider of planet positions. For example, + // you may use CALCEPH: + // + // t_calcephbin *planets = calceph_open("path/to/de440s.bsp"); + // novas_use_calceph(planets); + // + // accuracy = NOVAS_FULL_ACCURACY; // sub-uas precision + + // Without a planet provider, we are stuck with reduced (mas) precisions + // only... + accuracy = NOVAS_REDUCED_ACCURACY; // mas-level precision, typically + + + // ------------------------------------------------------------------------- + // Initialize the observing frame with the given observing and Earth + // orientation patameters. + // + if(novas_make_frame(accuracy, &obs, &obs_time, POLAR_DX, POLAR_DY, &obs_frame) != 0) { + fprintf(stderr, "ERROR! failed to define observing frame.\n"); + return 1; + } + + + // ------------------------------------------------------------------------- + // Calculate the precise apparent position (here in CIRS coordinates) + if(novas_sky_pos(&source, &obs_frame, NOVAS_CIRS, &apparent) != 0) { + fprintf(stderr, "ERROR! failed to calculate apparent position.\n"); + return 1; + } + + // Let's print the apparent position + printf(" RA = %.9f h, Dec = %.9f deg, z_obs = %.9f\n", apparent.ra, apparent.dec, novas_v2z(apparent.rv)); + + + // ------------------------------------------------------------------------- + // Convert the apparent position in CIRS on sky to horizontal coordinates + // We'll use a standard (fixed) atmospheric model to estimate an optical refraction + // (You might use other refraction models, or NULL to ignore refraction corrections) + if(novas_app_to_hor(&obs_frame, NOVAS_CIRS, apparent.ra, apparent.dec, novas_standard_refraction, &az, &el) != 0) { + fprintf(stderr, "ERROR! failed to calculate azimuth / elevation.\n"); + return 1; + } + + // Let's print the calculated azimuth and elevation + printf(" Az = %.6f deg, El = %.6f deg\n", az, el); + + return 0; +} + diff --git a/examples/example-orbital b/examples/example-orbital new file mode 100755 index 0000000000000000000000000000000000000000..bd589fe2038587aa7905e1547fa147a9a2f5f437 GIT binary patch literal 17184 zcmeGje{dA#^}7oMP$3t7Xap-O0!Ag5OTYkOkPXR&jf0Q|#B{2zo4ZYNaJjqQ?O{Tl zX%JCDj6sPq zPXB1{Wp>~9-uHfeZ@=CBzPFce1XtF3Js!c}71s--27Iby*=He?C6XlGA~8{@LJ>1X zA#ldPp~@b_c8l>zuie3TJjoRRMm;cMgQAYYml2yWM~GPJQNPnOvc8Lk9a#8m8ui9v zlW0NXWBe`|Wz2FJe+nuCxZ<2T&So=q>S1mM%k2KarK)T&wkR*#2(uoNsCSn1&XOME z0ZIg8&L@VCM+uF;q(B7*GPKJb8S1# zb5+@3JkMqe#_aFQpoe++XMrzs6Zy+^9ZD$wj48b`mjQ5wb7sY=n}oMp^kXdC?-3qJ zPoRLjL~}pNPK5*0iu&_cPo7_M;^r5orSGp=bZX+`AOEzi9%V32)Ik{pl;{g!w5xVGi# z@rR^`;p?6S_VAqN;9N9Qg%;B7*f%sV3^3;@q;U%~bX?N=kj5>{P`{*qhBR(#hIUK( z$4KMWXK0tCA3++oSwlM{{T-xnt2fjw=?9R;UG`8y(%X^7?d#C(lD-RR+=dM`N_rF0 z7a*+yjpM6$x1s06ZCcMCwJmR+Xw4=RaIz9@oY`mixQZk2?vldJkYx1Q0s^==4Zc@-~66LJ!iCo?=8~~o-NQkhqV)5 zSj8C&9hE`y_BYw;npjAIhKJj)L0ecYKf*t?#C8 z>E#!bFxZ|~Kh%D5B-o7!Ie=GbaQhd-!$*RjVf%w3-`GD*L0lZ%g~TZ$eu%{Hh}ez9 z%S0SS;zc6%BJnH{{YX4R#Bn70i8!hC?Q8_ET3@hR>p7wIJhgxG-It34J7%k5@U_pe zW9I-M(3$uxspA`q80O?oL_M#z7QO!_9Iv$&m7aj(XscEf>mS?=I&d*cQ4Y!_TF*h8 zdtyHh?Z885{1iy+m2>lbIBR`d&wL8rdJZ1|2{9Nz*S&krBCpr(>gz+JTJN;k;26C; zwQmlHYCT5=9~tp>6?wY`x@>Pp(OV+pZL{>&*LYSAYU~@6!9?%U0YrT}rH8&fIO5*m zXFQxE;Nrk%nE^cw1rQw2)fpFO(Z$4!i_4{poj!1(_3c4VFg%&%o)i1<_QRMT8!?z7 zgE+J7m`mq?!C!)eouTKU1Fk@yY6rbFfF^slmI4};_5;nJw-;~d!QsEl@sa2r6xI6r zghV^XOSBauYv?%&*L~kEsJZcQ5AWv~ud!pC16T3IYwbZ};l++|2gX>!F`k|W0dAG{ zd$*!}w$^{(CCUpwMO9^03;e0Lzfxudm(&yCz)e&kay&wXvln@|!R-0; zlM{$;Bx8&fz zl7p}1;P(+9_eM@Q0z|R6RA3ze0Sg`ybiJ)39@A5nk+gJObQl{HTslN-&XjveV_ zs}V9qEWXi5>8TA}dLo`8N(#3ojgCyWY3b=$q*J#d8J>|y=vG{Bk0;4^vL#{}QE;-} z3|V9;Y__D^*oS4r!bUQzCrz*&vLf-A2u0(e4SJhtNyEAhvn)h0cNmeFNLgVsnG}g+ zBxbdW);p3B%M>7#N+-;u3>~Ln1+qfesuC+!HY~5zEB%%J>oV<%g_-931(+Q#d_Nxp zQ`Grq(^zmq@PNeofN>rmq^C!qb~Hx(723%A_BS7dX@Go-kJ)=f1M6H=LQ_vr5YFgcN zg%UPfBe6)VO$owuZ!c>xQf64;>8`*eGjO{3FJSprBN7D(E3TwWOTo#f#9K*$MWuJL zKO!$Zfwa7p(4)Lhz_JbJ$cKz*C>=E{Q-K@CNSZNAfg3GC;RvOvMp>%N@h@&w+UF^C zW{9b<*)~r}8ex5-8I`=MR%Js+d5RpJ&(EevN7`yv$`vzeZX7ilA(Wa;Y)yIyW{d-A z+g4wHW_eA;LH(`?vkKJ*kKa1EE%?N;vEO^3+EX@1z4s4Sw%pLvr1sC<@N%tht=jg= zpVwczq(yz~(1o75^}k+bXJM7P{?ymD-ygnAEts%A|3&15X@{rF!J_Gp-q<9?fN2iWq(^JlnqugkTl*Qtf=?{rDjn(tTn%e3LQCnZV=sbe;E2{(N>0VI-CK?;67l<{% z>VSx>fzzlEVEJ<$-=JQiiFCNChTnN7z2unC+)a+(w>V4`NuhnYh~Q1 zuBe&qnQv5N{;#8uo&(urrcoc`Y%+qb^TmX-$?&scke(UYWEAp+KgK}FCi8pJXZ)|q zaI7=V6Eny9F8P!}WjWz}Jx2Ux*xiM(VU6L=0#$Y?@@&_TvdMo5`n~Y9<2;Z!{AZ2L zZ=}31zmoX;9A~};4G+|d+ErDu__?!I@}~-Z4$DqBeH{+;%kKr|-wO?on38#}GyhR& zWQ%`q4*o%DXR`2Jr9x{oWV7=kh_c);*!4}<-Ows&uz9-m&4A@Ir#XCDYWm7C!IsS2lxs* zbKr-7U+ndXZL?JeSBUQ;A3SsupKC@>06*J!p9j7V=1;;k-ru0Sw@~qU5s0UZoL77>v`^u`C8yjlD zAiU4@pr+fsT3wUSSFBvUyk@1oy1sr*aILXt-;>Dpzo!R6D9Xoaumau5N}6 z%Mfxql!bA5t^>SOzQF^ya;-ki{ z>uYbUrRzaD84>>TG6T**%+Kp7Z@Q1r%;MB%e((ZvT6e;{TAjOE# zp%1cZpaQiLQLvkg%ZcDO+i3>3he47lI|h3y+c9t(%orV!5cr6L6*&2&IolXq9N~vM zssnBm;ipBU953)Ob~$3dVOhyYOWJ~)^4|vB7vWw49upEu3RJ>2ZBup|&$xbY0{&dj zsozZc{QsI*_jCe3=b2Xn4W~Y@OYWo%lEQ+7-TJG650CE5ek}9+lM72Bc;Cln-1?8X z^c8x3Dx}}fiiC*`?;;!UzapLf2S|T_1U~1Do=cxd@m04zt?LG81IYVYmUqW*kUn3( zk^ld-HF#gk`WUMdB0zisdq39a{jQ?eQl%u!`&;+*$0>+=UDoIQu%_6G@|V{ngT7gx z_ocYb!xXVT@2_`X0ZahiPurB8Yi=Xn0tfD8S)cc>&&{%>F1L~3_*ste4(P|dG1I(1 zK12E{>Ejrk@e^A-3=O;{tk3)Lz?HUyMuP0$J^mk&{&JGz{e36tb3Fj{u?FDQe;jxi z7yIY+RQGIP0-VH72e3Y~o`i-|pVzVc|Ihf1#0l>CcMLk6`rGEJQhXaNxbAZ*L)-2D zCE($AN1Ou)T(9B(hjz;|&G-$_DT0Ibc^`4646U8(kM$ViI=v7M*5~y-|9|@c&bGI#x?6`V135;UDv74`-MT$PmEU2_-B1DC_D9ez1|$K72Veh zWu1WY3vF@yy#Bp~^xg3*PGx9MB>yCy>1BOR_ literal 0 HcmV?d00001 diff --git a/examples/example-orbital.c b/examples/example-orbital.c new file mode 100644 index 00000000..a4559492 --- /dev/null +++ b/examples/example-orbital.c @@ -0,0 +1,184 @@ +/** + * @file + * + * @date Created on Jan 9, 2025 + * @author Attila Kovacs + * + * Example file for using the SuperNOVAS C/C++ library for determining positions for + * Solar-system objects define through a set of orbital parameters. + * + * For example, the IAU Minor Planet Center (MPC) publishes current orbital + * parameters for known asteroids, comets, and near-Earth objects. While orbitals are + * not super precise in general, they can provide sufficienly accurate positions on + * the arcsecond level (or below), and may be the best/only source of position data + * for newly discovered objects. + * + * See https://minorplanetcenter.net/data + * + * Link with + * + * ``` + * -lsupernovas + * ``` + */ + +#include +#include +#include + +#include ///< SuperNOVAS functions and definitions + + +// Below are some Earth orientation values. Here we define them as constants, but they may +// of course be variables. They should be set to the appropriate values for the time +// of observation based on the IERS Bulletins... + +#define LEAP_SECONDS 37 ///< [s] current leap seconds +#define DUT1 0.114 ///< [s] current UT1 - UTC time difference from IERS Bulletin A +#define POLAR_DX 230.0 ///< [mas] Earth polar offset x, e.g. from IERS Bulletin A. +#define POLAR_DY -62.0 ///< [mas] Earth polar offset y, e.g. from IERS Bulletin A. + +int main() { + // SuperNOVAS aariables used for the calculations -------------------------> + novas_orbital orbit = NOVAS_ORBIT_INIT; // Orbital parameters + object source; // a celestial object: sidereal, planet, ephemeris or orbital source + observer obs; // observer location + novas_timespec obs_time; // astrometric time of observation + novas_frame obs_frame; // observing frame defined for observing time and location + enum novas_accuracy accuracy; // NOVAS_FULL_ACCURACY or NOVAS_REDUCED_ACCURACY + sky_pos apparent; // calculated precise observed (apparent) position of source + + // Calculated quantities -------------------------------------------------> + double az, el; // calculated azimuth and elevation at observing site + + // Intermediate variables we'll use --------------------------------------> + struct timespec unix_time; // Standard precision UNIX time structure + + + // We'll print debugging messages and error traces... + novas_debug(NOVAS_DEBUG_ON); + + + // Orbitals assume Keplerian motion, and are never going to be accurate much below the + // tens of arcsec level even for the most current MPC orbits. Orbitals for planetary + // satellites are even less precise. So, with orbitals, there is no point on pressing + // for ultra-high (sub-uas level) accuracy... + accuracy = NOVAS_REDUCED_ACCURACY; // mas-level precision, typically + + + // ------------------------------------------------------------------------- + // Define a sidereal source + + // Orbital Parameters for the asteroid Ceres from the Minor Planet Center + // (MPC) at JD 2460600.5 + orbit.jd_tdb = 2460600.5; // [day] TDB date + orbit.a = 2.7666197; // [AU] + orbit.e = 0.079184; + orbit.i = 10.5879; // [deg] + orbit.omega = 73.28579; // [deg] + orbit.Omega = 80.25414; // [deg] + orbit.M0 = 145.84905; // [deg] + orbit.n = 0.21418047; // [deg/day] + + // Define Ceres as the observed object (we can use whatever ID numbering + // system here, since it's irrelevant to SuperNOVAS in this context). + make_orbital_object("Ceres", 2000001, &orbit, &source); + + + // ... Or, you could define orbitals for a satellite instead: + /* + // E.g. Callisto's orbital parameters from JPL Horizons + // https://ssd.jpl.nasa.gov/sats/elem/sep.html + // 1882700. 0.007 43.8 87.4 0.3 309.1 16.690440 277.921 577.264 268.7 64.8 + orbit.system.center = NOVAS_JUPITER; + novas_set_orbsys_pole(NOVAS_GCRS, 268.7 / 15.0, 64.8, &orbit->system); + + orbit.jd_tdb = NOVAS_JD_J2000; + orbit.a = 1882700.0 * 1e3 / AU; + orbit.e = 0.007; + orbit.omega = 43.8; + orbit.M0 = 87.4; + orbit.i = 0.3; + orbit.Omega = 309.1; + orbit.n = TWOPI / 16.690440; + orbit.apsis_period = 277.921 * 365.25; + orbit.node_period = 577.264 * 365.25; + + // Set Callisto as the observed object + make_orbital_object("Callisto", 501, &orbit, &source); + */ + + + // ------------------------------------------------------------------------- + // Define observer somewhere on Earth (we can also define observers in Earth + // or Sun orbit, at the geocenter or at the Solary-system barycenter...) + + // Specify the location we are observing from + // 50.7374 deg N, 7.0982 deg E, 60m elevation + if(make_observer_on_surface(50.7374, 7.0982, 60.0, 0.0, 0.0, &obs) != 0) { + fprintf(stderr, "ERROR! defining Earth-based observer location.\n"); + return 1; + } + + + // ------------------------------------------------------------------------- + // Set the astrometric time of observation... + + // Get the current system time, with up to nanosecond resolution... + clock_gettime(CLOCK_REALTIME, &unix_time); + + // Set the time of observation to the precise UTC-based UNIX time + // (We can set astromtric time using an other time measure also...) + if(novas_set_unix_time(unix_time.tv_sec, unix_time.tv_nsec, LEAP_SECONDS, DUT1, &obs_time) != 0) { + fprintf(stderr, "ERROR! failed to set time of observation.\n"); + return 1; + } + + + // ------------------------------------------------------------------------- + // You might want to set a provider for precise planet positions so we might + // calculate Earth, Sun and major planet positions accurately. It is needed + // if you have orbitals defined around a major planet. + // + // There are many ways to set a provider of planet positions. For example, + // you may use CALCEPH: + // + // t_calcephbin *planets = calceph_open("path/to/de440s.bsp"); + // novas_use_calceph(planets); + + + // ------------------------------------------------------------------------- + // Initialize the observing frame with the given observing and Earth + // orientation patameters. + // + if(novas_make_frame(accuracy, &obs, &obs_time, POLAR_DX, POLAR_DY, &obs_frame) != 0) { + fprintf(stderr, "ERROR! failed to define observing frame.\n"); + return 1; + } + + // ------------------------------------------------------------------------- + // Calculate the precise apparent position (here in CIRS coordinates) + if(novas_sky_pos(&source, &obs_frame, NOVAS_CIRS, &apparent) != 0) { + fprintf(stderr, "ERROR! failed to calculate apparent position.\n"); + return 1; + } + + // Let's print the apparent position + printf(" RA = %.9f h, Dec = %.9f deg, rad_vel = %.6f km/s\n", apparent.ra, apparent.dec, apparent.rv); + + + // ------------------------------------------------------------------------- + // Convert the apparent position in CIRS on sky to horizontal coordinates + // We'll use a standard (fixed) atmospheric model to estimate an optical refraction + // (You might use other refraction models, or NULL to ignore refraction corrections) + if(novas_app_to_hor(&obs_frame, NOVAS_CIRS, apparent.ra, apparent.dec, novas_standard_refraction, &az, &el) != 0) { + fprintf(stderr, "ERROR! failed to calculate azimuth / elevation.\n"); + return 1; + } + + // Let's print the calculated azimuth and elevation + printf(" Az = %.6f deg, El = %.6f deg\n", az, el); + + return 0; +} + diff --git a/examples/example-star.c b/examples/example-star.c index 7c811827..7deab73f 100644 --- a/examples/example-star.c +++ b/examples/example-star.c @@ -1,249 +1,174 @@ -/* - Naval Observatory Vector Astrometry Software (NOVAS) - C Edition, Version 3.1 - - example.c: Examples of NOVAS calculations - - U. S. Naval Observatory - Astronomical Applications Dept. - Washington, DC - http://www.usno.navy.mil/USNO/astronomical-applications +/** + * @file + * + * @date Created on Jan 9, 2025 + * @author Attila Kovacs + * + * Example file for using the SuperNOVAS C/C++ library for determining positions for + * nearby (non-high-z) sidereal sources, such as a star. + * + * Link with + * + * ``` + * -lsupernovas + * ``` */ #include #include -#include +#include -#include "novas.h" -#include "eph_manager.h" // For solsys1.c +#include ///< SuperNOVAS functions and definitions -int main(void) { - /* - NOVAS 3.1 Example Calculations - - See Chapter 3 of User's Guide for explanation. - - Written for use with solsys version 1. - - To adapt for use with solsys version 2, see comments throughout file. - Assumes JPL ephemeris file "JPLEPH" located in same directory as - application. - */ - - const double latitude = 42.0; ///< [deg] geodetic latitude of observer - const double longitude = -70; ///< [deg] geodetic longitude of observer - const double height = 0.0; ///< [m] observer's altitude above sea level - const double temperature = 10.0; ///< [C] Ambient temperature at observing location (for refraction correction) - const double pressure = 1010.0; ///< [mbar] Atmospheric pressure at observing location (for refraction correction) - - const int leap_secs = 33; ///< [s] Leap seconds (UTC - TAI; see IERS Bulletins) - const double x_pole = -0.002; ///< [arcsec] Celestial pole offset in x (see IERS Bulletins) - const double y_pole = +0.529; ///< [arcsec] Celestial pole offset in y (see IERS Bulletins) - const double ut1_utc = -0.387845; ///< [s] UT1 - UTC time difference (see IERS Bulletins) - - // Various variables we will calculate / populate.... - double jd_beg, jd_end, jd_utc, jd_tt, jd_ut1, jd_tdb, delta_t, ra, dec, dis, rat, dect, dist, zd, az, rar, decr, gast, last, theta, jd[2], - pos[3], vel[3], pose[3], elon, elat, r, lon_rad, lat_rad, sin_lon, cos_lon, sin_lat, cos_lat, vter[3], vcel[3]; - - - observer obs_loc; - on_surface *geo_loc; - cat_entry star; - object moon, mars; - sky_pos t_place; - - int error = 0; - short de_num = 0; - - // Make structures of type 'on_surface' and 'observer-on-surface' containing - // the observer's position and weather (latitude, longitude, height, - //temperature, and atmospheric pressure) - make_observer_on_surface(latitude, longitude, height, temperature, pressure, &obs_loc); - geo_loc = &obs_loc.on_surf; - - // Make a structure of type 'cat_entry' containing the ICRS position - // and motion of star FK6 1307. - make_cat_entry("GMB 1830", "FK6", 1307, 11.88299133, 37.71867646, 4003.27, -5815.07, 109.21, -98.8, &star); - - if((error = make_object(NOVAS_PLANET, NOVAS_MOON, "Moon", NULL, &moon)) != 0) { - printf("Error %d from make_object (Moon)\n", error); - return (error); - } +// Below are some Earth orientation values. Here we define them as constants, but they may +// of course be variables. They should be set to the appropriate values for the time +// of observation based on the IERS Bulletins... - if((error = make_object(NOVAS_PLANET, NOVAS_MARS, "Mars", NULL, &mars)) != 0) { - printf("Error %d from make_object (Mars)\n", error); - return (error); - } - - // Open the JPL binary ephemeris file, here named "JPLEPH". - error = ephem_open("JPLEPH", &jd_beg, &jd_end, &de_num); - if(error != 0) { - if(error == 1) printf("JPL ephemeris file not found.\n"); - else printf("Error reading JPL ephemeris file header.\n"); - return (error); - } - else { - printf("JPL ephemeris DE%d open. Start JD = %10.2f End JD = %10.2f\n", de_num, jd_beg, jd_end); - printf("\n"); - } +#define LEAP_SECONDS 37 ///< [s] current leap seconds +#define DUT1 0.114 ///< [s] current UT1 - UTC time difference from IERS Bulletin A +#define POLAR_DX 230.0 ///< [mas] Earth polar offset x, e.g. from IERS Bulletin A. +#define POLAR_DY -62.0 ///< [mas] Earth polar offset y, e.g. from IERS Bulletin A. - // Set the planet calculator to the one using eph_manager - set_planet_provider(planet_eph_manager); - set_planet_provider_hp(planet_eph_manager_hp); +int main() { + // SuperNOVAS aariables used for the calculations -------------------------> + cat_entry star = CAT_ENTRY_INIT; // catalog information about a sidereal source + object source; // a celestial object: sidereal, planet, ephemeris or orbital source + observer obs; // observer location + novas_timespec obs_time; // astrometric time of observation + novas_frame obs_frame; // observing frame defined for observing time and location + enum novas_accuracy accuracy; // NOVAS_FULL_ACCURACY or NOVAS_REDUCED_ACCURACY + sky_pos apparent; // calculated precise observed (apparent) position of source - // Write banner. - printf("NOVAS Sample Calculations\n"); - printf("-------------------------\n"); - printf("\n"); + // Calculated quantities -------------------------------------------------> + double az, el; // calculated azimuth and elevation at observing site - // Write assumed longitude, latitude, height (ITRS = WGS-84). - printf("Geodetic location:\n"); - printf("%15.10f %15.10f %15.10f\n\n", geo_loc->longitude, geo_loc->latitude, geo_loc->height); + // Intermediate variables we'll use --------------------------------------> + struct timespec unix_time; // Standard precision UNIX time structure - // Establish time arguments. - jd_utc = julian_date(2008, 4, 24, 10.605); - jd_tt = jd_utc + ((double) leap_secs + 32.184) / 86400.0; - jd_ut1 = jd_utc + ut1_utc / 86400.0; - delta_t = get_ut1_to_tt(leap_secs, ut1_utc); - jd_tdb = jd_tt; /* Approximation good to 0.0017 seconds. */ + // We'll print debugging messages and error traces... + novas_debug(NOVAS_DEBUG_ON); - printf("TT and UT1 Julian Dates and Delta-T:\n"); - printf("%15.6f %15.6f %16.11f\n", jd_tt, jd_ut1, delta_t); - printf("\n"); - // Apparent and topocentric place of star FK6 1307 = GMB 1830. - error = app_star(jd_tt, &star, NOVAS_FULL_ACCURACY, &ra, &dec); - if(error != 0) { - printf("Error %d from app_star.\n", error); - return (error); - } + // ------------------------------------------------------------------------- + // Define a sidereal source - error = topo_star(jd_tt, delta_t, &star, &obs_loc.on_surf, NOVAS_FULL_ACCURACY, &rat, &dect); - if(error != 0) { - printf("Error %d from topo_star.\n", error); - return (error); + // Let's assume we have B1950 (FK4) coordinates... + // 16h26m20.1918s, -26d19m23.138s (B1950), proper motion -12.11, -23.30 mas/year, + // parallax 5.89 mas, radial velocity -3.4 km/s. + if(make_cat_entry("Antares", "FK4", 1, 16.43894213, -26.323094, -12.11, -23.30, 5.89, -3.4, &star) != 0) { + fprintf(stderr, "ERROR! defining cat_entry.\n"); + return 1; } - printf("FK6 1307 geocentric and topocentric positions:\n"); - printf("%15.10f %15.10f\n", ra, dec); - printf("%15.10f %15.10f\n", rat, dect); - printf("\n"); - - // Apparent and topocentric place of the Moon. - error = app_planet(jd_tt, &moon, NOVAS_FULL_ACCURACY, &ra, &dec, &dis); - if(error != 0) { - printf("Error %d from app_planet.", error); - return (error); + // First change the catalog coordinates (in place) to the J2000 (FK5) system... + if(transform_cat(CHANGE_EPOCH, NOVAS_JD_B1950, &star, NOVAS_JD_J2000, "FK5", &star) != 0) { + fprintf(stderr, "ERROR! converting B1950 catalog coordinates to J2000.\n"); + return 1; } - error = topo_planet(jd_tt, &moon, delta_t, &obs_loc.on_surf, NOVAS_FULL_ACCURACY, &rat, &dect, &dist); - if(error != 0) { - printf("Error %d from topo_planet.", error); - return (error); + // Then convert J2000 coordinates to ICRS (also in place). Here the dates don't matter... + if(transform_cat(CHANGE_J2000_TO_ICRS, 0.0, &star, 0.0, "ICRS", &star) != 0) { + fprintf(stderr, "ERROR! converting J2000 catalog coordinates to ICRS.\n"); + return 1; } - printf("Moon geocentric and topocentric positions:\n"); - printf("%15.10f %15.10f %15.12f\n", ra, dec, dis); - printf("%15.10f %15.10f %15.12f\n", rat, dect, dist); - // Topocentric (True of Date) place of the Moon using function 'place'-- should be - // same as above. - error = place(jd_tt, &moon, &obs_loc, delta_t, NOVAS_TOD, NOVAS_FULL_ACCURACY, &t_place); - if(error != 0) { - printf("Error %d from place.", error); - return (error); + // ------------------------------------------------------------------------- + // Wrap the sidereal souce into an object structure... + if(make_cat_object(&star, &source) != 0) { + fprintf(stderr, "ERROR! configuring observed object\n"); + return 1; } - printf("%15.10f %15.10f %15.12f\n", t_place.ra, t_place.dec, t_place.dis); - printf("\n"); - // Position of the Moon in local horizon coordinates. (Polar motion ..ignored here.) - equ2hor(jd_ut1, delta_t, NOVAS_FULL_ACCURACY, 0.0, 0.0, &obs_loc.on_surf, rat, dect, NOVAS_STANDARD_ATMOSPHERE, // - &zd, &az, &rar, &decr); + // ------------------------------------------------------------------------- + // Define observer somewhere on Earth (we can also define observers in Earth + // or Sun orbit, at the geocenter or at the Solary-system barycenter...) - printf("Moon zenith distance and azimuth:\n"); - printf("%15.10f %15.10f\n", zd, az); - printf("\n"); - - // Greenwich and local apparent sidereal time and Earth Rotation Angle. - error = sidereal_time(jd_ut1, 0.0, delta_t, NOVAS_TRUE_EQUINOX, EROT_ERA, NOVAS_FULL_ACCURACY, &gast); - if(error != 0) { - printf("Error %d from sidereal_time.", error); - return (error); + // Specify the location we are observing from + // 50.7374 deg N, 7.0982 deg E, 60m elevation + if(make_observer_on_surface(50.7374, 7.0982, 60.0, 0.0, 0.0, &obs) != 0) { + fprintf(stderr, "ERROR! defining Earth-based observer location.\n"); + return 1; } - last = remainder(gast + geo_loc->longitude / 15.0, 24.0); - if(last < 0.0) last += 24.0; - - theta = era(jd_ut1, 0.0); - printf("Greenwich and local sidereal time and Earth Rotation Angle:\n"); - printf("%16.11f %16.11f %15.10f\n", gast, last, theta); - printf("\n"); + // ------------------------------------------------------------------------- + // Set the astrometric time of observation... - // Heliocentric position of Mars in BCRS. + // Get the current system time, with up to nanosecond resolution... + clock_gettime(CLOCK_REALTIME, &unix_time); - // TDB ~ TT approximation could lead to error of ~50 m in position of Mars. - jd[0] = jd_tdb; - jd[1] = 0.0; - - error = ephemeris(jd, &mars, NOVAS_HELIOCENTER, NOVAS_FULL_ACCURACY, pos, vel); - if(error != 0) { - printf("Error %d from ephemeris (Mars).", error); - return (error); - } - - error = equ2ecl_vec(NOVAS_JD_J2000, NOVAS_MEAN_EQUATOR, NOVAS_FULL_ACCURACY, pos, pose); - if(error != 0) { - printf("Error %d from equ2ecl_vec.", error); - return (error); + // Set the time of observation to the precise UTC-based UNIX time + if(novas_set_unix_time(unix_time.tv_sec, unix_time.tv_nsec, LEAP_SECONDS, DUT1, &obs_time) != 0) { + fprintf(stderr, "ERROR! failed to set time of observation.\n"); + return 1; } - if((error = vector2radec(pose, &elon, &elat)) != 0) { - printf("Error %d from vector2radec.", error); - return (error); + // ... Or you could set a time explicily in any known timescale. + /* + // Let's set a TDB-based time for the start of the J2000 epoch exactly... + if(novas_set_time(NOVAS_TDB, NOVAS_JD_J2000, LEAP_SECONDS, DUT1, &obs_time) != 0) { + fprintf(stderr, "ERROR! failed to set time of observation.\n"); + return 1; } - elon *= 15.0; - - r = sqrt(pose[0] * pose[0] + pose[1] * pose[1] + pose[2] * pose[2]); - - printf("Mars heliocentric ecliptic longitude and latitude and radius vector:\n"); - printf("%15.10f %15.10f %15.12f\n", elon, elat, r); - printf("\n"); - - // Terrestrial to celestial transformation. - lon_rad = geo_loc->longitude * DEG2RAD; - lat_rad = geo_loc->latitude * DEG2RAD; - sin_lon = sin(lon_rad); - cos_lon = cos(lon_rad); - sin_lat = sin(lat_rad); - cos_lat = cos(lat_rad); - - // Form vector toward local zenith (orthogonal to ellipsoid) in ITRS. - vter[0] = cos_lat * cos_lon; - vter[1] = cos_lat * sin_lon; - vter[2] = sin_lat; - - // Transform vector to GCRS. - error = ter2cel(jd_ut1, 0.0, delta_t, EROT_ERA, NOVAS_FULL_ACCURACY, NOVAS_REFERENCE_CLASS, x_pole, y_pole, vter, vcel); - if(error != 0) { - printf("Error %d from ter2cel.", error); - return (error); + */ + + + // ------------------------------------------------------------------------- + // You might want to set a provider for precise planet positions so we might + // calculate Earth, Sun and major planet positions accurately. If an planet + // provider is configured, we can unlock the ultimate (sub-uas) accuracy of + // SuperNOVAS. + // + // There are many ways to set a provider of planet positions. For example, + // you may use CALCEPH: + // + // t_calcephbin *planets = calceph_open("path/to/de440s.bsp"); + // novas_use_calceph(planets); + // + // accuracy = NOVAS_FULL_ACCURACY; // sub-uas precision + + // Without a planet provider, we are stuck with reduced (mas) precisions + // only... + accuracy = NOVAS_REDUCED_ACCURACY; // mas-level precision, typically + + + // ------------------------------------------------------------------------- + // Initialize the observing frame with the given observing and Earth + // orientation patameters. + // + if(novas_make_frame(accuracy, &obs, &obs_time, POLAR_DX, POLAR_DY, &obs_frame) != 0) { + fprintf(stderr, "ERROR! failed to define observing frame.\n"); + return 1; } - error = vector2radec(vcel, &ra, &dec); - if(error != 0) { - printf("Error %d from vector2radec.", error); - return (error); + + // ------------------------------------------------------------------------- + // Calculate the precise apparent position (here in CIRS coordinates) + if(novas_sky_pos(&source, &obs_frame, NOVAS_CIRS, &apparent) != 0) { + fprintf(stderr, "ERROR! failed to calculate apparent position.\n"); + return 1; } - printf("Direction of zenith vector (RA & Dec) in GCRS:\n"); - printf("%15.10f %15.10f\n", ra, dec); - printf("\n"); + // Let's print the apparent position + printf(" RA = %.9f h, Dec = %.9f deg, rad_vel = %.6f km/s\n", apparent.ra, apparent.dec, apparent.rv); - ephem_close(); /* remove this line for use with solsys version 2 */ - return (0); + // ------------------------------------------------------------------------- + // Convert the apparent position in CIRS on sky to horizontal coordinates + // We'll use a standard (fixed) atmospheric model to estimate an optical refraction + // (You might use other refraction models, or NULL to ignore refraction corrections) + if(novas_app_to_hor(&obs_frame, NOVAS_CIRS, apparent.ra, apparent.dec, novas_standard_refraction, &az, &el) != 0) { + fprintf(stderr, "ERROR! failed to calculate azimuth / elevation.\n"); + return 1; + } + + // Let's print the calculated azimuth and elevation + printf(" Az = %.6f deg, El = %.6f deg\n", az, el); + + return 0; } + diff --git a/examples/example-usno.txt b/examples/example-usno.txt deleted file mode 100644 index 682aded3..00000000 --- a/examples/example-usno.txt +++ /dev/null @@ -1,32 +0,0 @@ -JPL ephemeris DE405 open. Start JD = 2305424.50 End JD = 2525008.50 - -NOVAS Sample Calculations -------------------------- - -Geodetic location: - -70.0000000000 42.0000000000 0.0000000000 - -TT and UT1 Julian Dates and Delta-T: - 2454580.942629 2454580.941871 65.57184500000 - -FK6 1307 geocentric and topocentric positions: - 11.8915509892 37.6586357955 - 11.8915479153 37.6586695456 - -Moon geocentric and topocentric positions: - 17.1390774264 -27.5374448869 0.002710296515 - 17.1031967646 -28.2902502967 0.002703785126 - 17.1031967646 -28.2902502967 0.002703785126 - -Moon zenith distance and azimuth: - 81.6891016502 219.2708903405 - -Greenwich and local sidereal time and Earth Rotation Angle: - 0.79362134148 20.12695467481 11.7956158462 - -Mars heliocentric ecliptic longitude and latitude and radius vector: - 148.0032235906 1.8288284075 1.664218258879 - -Direction of zenith vector (RA & Dec) in GCRS: - 20.1221838608 41.9769823554 -