v1.0
[1.0.0] - 2024-03-01
This is the initial release of the SuperNOVAS library. Changes are indicated w.r.t. the upstream NOVAS C 3.1 library
from which SuperNOVAS is forked from.
Known Issues
- #15 --
cirs_to_itrs()
,itrs_to_cirs()
,tod_to_itrs()
, anditrs_to_tod()
all have a unit conversion bug in using theut1_to_tt
argument [s] when converting TT-based Julian date to UT1-based JD [day] internally. A fix for this bug is included in themain
branch and thev1.0.1
bug fix release. - #28 --
d_light()
divide by zero if called withpos
argument is a zero vector (e.g. Sun or SSB, depending on the solar-system calculator type). Fix available on themain
branch and will be included in thev1.0.2
bug fix release. - #29 -- [CRITICAL] All calculations in this release involving the IAU2000 nutation or
ee_ct()
yield invalid results on non-Intel x86 platforms, such as ARMv7 or PowerPC, due to a different signedness of thechar
integer type on these platforms. Fix available on themain
branch and will be included in thev1.0.2
bug fix release. - #35 --
tt2tdb()
had the wrong scaling in the period, resulting in an error up to ~3.4 ms. A fix will be included in thev1.1.0
release and is available on themain
branch. - #38 --
gcrs_to_j2000()
applied transformation in the wrong direction, resulting in an error up to 44 mas whenplace()
was called withNOVAS_TOD
as the desired output system (1). A fix will be included in thev1.1.0
release and is available on themain
branch. - #39 --
tod_to_itrs()
used the wrong Earth rotation measure (NOVAS_ERA
instead ofNOVAS_GST
). A fix will be included in thev1.1.0
release and is available on themain
branch. - #41:
grav_def()
gravitating body position antedated somewhat incorrectly (in v1.0) when observed source is a Solar-system object between the observer and the gravitating body. The resulting positional error is typically small at below 10 uas. A fix will be included in thev1.1.0
release and is available on themain
branch. - #45:
cel2ter()
invalid output with CIRS input coordinates (erot
=EROT_ERA
andclass
=NOVAS_DYNAMICAL_CLASS
) if output vector was distinct from input vector. Affects prior SuperNOVAS releases. A fix will be included in thev1.1.0
release and is available on themain
branch.
Fixed
-
Fixes the sidereal_time bug, whereby the
sidereal_time()
function had
an incorrect unit cast. This is a known issue of NOVAS C 3.1. -
Some remainder calculations in NOVAS C 3.1 used the result from
fmod()
unchecked, which led to the wrong results
when the numerator was negative. This affected the calculation of the mean anomaly insolsys3.c
(line 261) and
the fundamental arguments calculated infund_args()
andee_ct()
for dates prior to J2000. Less critically, it
also was the reasoncal_date()
did not work for negative JD values. -
Fixes antedating velocities and distances for light travel time in
ephemeris()
. When getting positions and
velocities for Solar-system sources, it is important to use the values from the time light originated from the
observed body rather than at the time that light arrives to the observer. This correction was done properly for
positions, but not for velocities or distances, resulting in incorrect observed radial velocities or apparent
distances being reported for spectroscopic observations or for angular-physical size conversions. -
Fixes bug in
ira_equinox()
which may return the result for the wrong type of equinox (mean vs. true) if the the
equinox
argument was changing from 1 to 0, and back to 1 again with the date being held the same. This affected
routines downstream also, such assidereal_time()
. -
Fixes accuracy switching bug in
cio_basis()
,cio_location()
,ecl2equ()
,equ2ecl_vec()
,ecl2equ_vec()
,
geo_posvel()
,place()
, andsidereal_time()
. All these functions returned a cached value for the other
accuracy if the other input parameters are the same as a prior call, except the accuracy. -
Fixes multiple bugs related to using cached values in
cio_basis()
with alternating CIO location reference
systems. -
Fixes bug in
equ2ecl_vec()
andecl2equ_vec()
whereby a query withcoord_sys = 2
(GCRS) has overwritten the
cached mean obliquity value forcoord_sys = 0
(mean equinox of date). As a result, a subsequent call with
coord_sys = 0
and the same date as before would return the results GCRS coordinates instead of the requested mean
equinox of date coordinates. -
Fixes
aberration()
returning NaN vectors if theve
argument is 0. It now returns the unmodified input vector
appropriately instead. -
Fixes unpopulated
az
output value inequ2hor()
at zenith. While any azimuth is acceptable really, it results in
unpredictable behavior. Hence, we setaz
to 0.0 for zenith to be consistent. -
Fixes potential string overflows and eliminates associated compiler warnings.
-
Fixes the ephem_close bug, whereby
ephem_close()
in
eph_manager.c
did not reset theEPHFILE
pointer to NULL. This is a known issue of NOVAS C 3.1. -
Supports calculations in parallel threads by making cached results thread-local.
Added
-
New debug mode and error traces. Simply call
novas_debug(NOVAS_DEBUG_ON)
ornovas_debug(NOVAS_DEBUG_EXTRA)
to enable. When enabled, any error conditions (such as NULL pointer arguments, or invalid input values etc.) will
be reported to the standard error, complete with call tracing within the SuperNOVAS library, s.t. users can have
a better idea of what exactly did not go to plan (and where). The debug messages can be disabled by passing
NOVAS_DEBUF_OFF
(0) as the argument to the same call. -
Added Doxygen markup of source code and header.
-
Added Makefile for GNU make.
-
Added continuous integration on GitHub, including regression testing, static analysis, and doxygen validation.
-
Added an number of precompiler constants and enums in
novas.h
to promote consistent usage and easier to read
code. -
New runtime configurability:
-
The planet position calculator function used by
ephemeris()
can be set at runtime viaset_planet_provider()
,
andset_planet_provider_hp()
(for high precision calculations). Similarly, ifplanet_ephem_provider()
or
planet_ephem_provider_hp()
(defined insolsys-ephem.c
) are set as the planet calculator functions, then
set_ephem_provider()
can set the user-specified function to use with these to actually read ephemeris data
(e.g. from a JPL ephemeris file). -
If CIO locations vs GSRS are important to the user, the user may call
set_cio_locator_file()
at runtime to
specify the location of the binary CIO interpolation table (e.g.cio_ra.bin
) to use, even if the library was
compiled with the different default CIO locator path. -
The default low-precision nutation calculator
nu2000k()
can be replaced by another suitable IAU 2006 nutation
approximation viaset_nutation_lp_provider()
. For example, the user may want to use theiau2000b()
model
instead or some custom algorithm instead.
-
-
New intutitive XYZ coordinate conversion functions:
- for GCRS - CIRS - ITRS (IAU 2000 standard):
gcrs_to_cirs()
,cirs_to_itrs()
, anditrs_to_cirs()
,
cirs_to_gcrs()
. - for GCRS - J2000 - TOD - ITRS (old methodology):
gcrs_to_j2000()
,j2000_to_tod()
,tod_to_itrs()
, and
itrs_to_tod()
,tod_to_j2000()
,j2000_to_gcrs()
.
- for GCRS - CIRS - ITRS (IAU 2000 standard):
-
New
itrs_to_hor()
andhor_to_itrs()
functions to convert Earth-fixed ITRS coordinates to astrometric azimuth
and elevation or back. Whereastod_to_itrs()
followed byitrs_to_hor()
is effectively a just a more explicit
2-step version of the existingequ2hor()
for converting from TOD to to local horizontal (old methodology), the
cirs_to_itrs()
followed byitrs_to_hor()
does the same from CIRS (new IAU standard methodology), and had no
prior equivalent in NOVAS C 3.1. -
New
ecl2equ()
for converting ecliptic coordinates to equatorial, complementing existingequ2ecl()
. -
New
gal2equ()
for converting galactic coordinates to ICRS equatorial, complementing existingequ2gal()
. -
New
refract_astro()
complements the existingrefract()
but takes an unrefracted (astrometric) zenith angle as
its argument. -
New convenience functions to wrap
place()
for simpler specific use:place_star()
,place_icrs()
,
place_gcrs()
,place_cirs()
, andplace_tod()
. -
New
radec_star()
andradec_planet()
as the common point for existing functions such asastro_star()
local_star()
,virtual_planet()
,topo_planet()
etc. -
New time conversion utilities
tt2tdb()
,get_utc_to_tt()
, andget_ut1_to_tt()
make it simpler to convert
between UTC, UT1, TT, and TDB time scales, and to supplyut1_to_tt
arguments toplace()
or topocentric
calculations. -
Co-existing
solarsystem()
variants. It is possible to use the differentsolarsystem()
implementations
provided bysolsys1.c
,solsys2.c
,solsys3.c
and/orsolsys-ephem.c
side-by-side, as they define their
functionalities with distinct, non-conflicting names, e.g.earth_sun_calc()
vsplanet_jplint()
vs
planet_eph_manager
vsplanet_ephem_provider()
. See the section on
Building and installation further above on including a selection of these in your library
build.) -
New
novas_case_sensitive(int)
to enable (or disable) case-sensitive processing of object names. (By default NOVAS
object
names were converted to upper-case, making them effectively case-insensitive.) -
New
make_planet()
andmake_ephem_object()
to make it simpler to configure Solar-system objects.
Changed
-
Changed to support for calculations in parallel threads by making cached results thread-local.
This works using the C11 standard_Thread_local
or else the earlier GNU C >= 3.3 standard__thread
modifier.
You can also set the preferred thread-local keyword for your compiler by passing it via-DTHREAD_LOCAL=...
in
config.mk
to ensure that your build is thread-safe. And, if your compiler has no support whatsoever for
thread_local variables, then SuperNOVAS will not be thread-safe, just as NOVAS C isn't. -
SuperNOVAS functions take
enum
s as their option arguments instead of raw integers. These enums are defined in
novas.h
. The same header also defines a number of useful constants. The enums allow for some compiler checking,
and make for more readable code that is easier to debug. They also make it easy to see what choices are available
for each function argument, without having to consult the documentation each and every time. -
All SuperNOVAS functions check for the basic validity of the supplied arguments (Such as NULL pointers or illegal
duplicate arguments) and will return -1 (witherrno
set, usually toEINVAL
) if the arguments supplied are
invalid (unless the NOVAS C API already defined a different return value for specific cases. If so, the NOVAS C
error code is returned for compatibility). -
All erroneous returns now set
errno
so that users can track the source of the error in the standard C way and use
functions such asperror()
andstrerror()
to print human-readable error messages. -
Many output values supplied via pointers are set to clearly invalid values in case of erroneous returns, such as
NAN
so that even if the caller forgets to check the error code, it becomes obvious that the values returned
should not be used as if they were valid. (No more sneaky silent errors.) -
Many SuperNOVAS functions allow
NULL
arguments, both for optional input values as well as outputs that are not
required (see the API Documentation for specifics).
This eliminates the need to declare dummy variables in your application code for quantities you do not require. -
All SuperNOVAS functions that take an input vector to produce an output vector allow the output vector argument
be the same as the input vector argument. For example,frame_tie(pos, J2000_TO_ICRS, pos)
using the same
pos
vector both as the input and the output. In this case thepos
vector is modified in place by the call.
This can greatly simplify usage, and can eliminate extraneous declarations, when intermediates are not required. -
SuperNOVAS declares function pointer arguments as
const
whenever the function does not modify the data content
being referenced. This supports better programming practices that generally aim to avoid unintended data
modifications. -
Catalog names can be up to 6 bytes (including termination), up from 4 in NOVAS C, while keeping
struct
layouts
the same as NOVAS C thanks to alignment, thus allowing cross-compatible binary exchange ofcat_entry
records
with NOVAS C 3.1. -
Object ID numbers are
long
instead ofshort
to accommodate NAIF IDs, which require minimum 32-bit integers. -
cel2ter()
andter2cel()
can now process 'option'/'class' = 1 (NOVAS_REFERENCE_CLASS
) regardless of the
methodology (EROT_ERA
orEROT_GST
) used to input or output coordinates in GCRS. -
Changed
make_object()
to retain the specified number argument (which can be different from thestarnumber
value
in the suppliedcat_entry
structure). -
cio_location()
will always return a valid value as long as neither output pointer argument is NULL. -
sun_eph()
insolsysl3.c
evaluates the series in reverse order compared to NOVAS C 3.1, accumulating the least
significant terms first, and thus resulting in higher precision result in the end. -
Changed
vector2radec()
to return NAN values if the input is a null-vector (i.e. all components are zero). -
IAU 2000A nutation model uses higher-order Delaunay arguments provided by
fund_args()
, instead of the linear
model in NOVAS C 3.1. -
IAU 2000 nutation made a bit faster, reducing the the number of floating-point multiplications necessary by
skipping terms that do not contribute. Its coefficients are also packed more frugally in memory, resulting in a
smaller foortprint. -
More efficient paging (cache management) for
cio_array()
, including I/O error checking. -
Changed the standard atmospheric model for (optical) refraction calculation to include a simple model for the
annual average temperature at the site (based on latitude and elevation). This results is a slightly more educated
guess of the actual refraction than the global fixed temperature of 10 °C assumed by NOVAC C 3.1 regardless of
observing location.
Deprecated
-
novascon.h
/novascon.c
: These definitions of constants was troublesome for two reasons: (1) They were
primarily meant for use internally within the library itself. As the library clearly defines in what units input
and output quantities are expressed, the user code can apply its own appropriate conversions that need not match
the internal system used by the library. Hence exposing these constants to users was half baked. (2) The naming of
constants was too simplistic (with names such asC
orF
) that it was rather prone to naming conflicts in user
code. As a result, the constants have been moved to novas.h with more unique names (such asNOVAS_C
and
NOVAS_EARTH_FLATTENING
. New code should rely on these definitions instead of the troubled constants of
novascon.c
/.h
if at all necessary. -
equ2hor()
: It's name does not make it clear that this function is suitable only for converting TOD (old
methodology) to horizontal but not CIRS to horizontal (IAU 2000 standard). You should use the equivalent but more
specifictod_to_itrs()
or the newly addedcirs_to_itrs()
, followed byitrs_to_hor()
instead. -
cel2ter()
/ter2cel()
: These function can be somewhat confusing to use. You are likely better off with
tod_to_itrs()
andcirs_to_itrs()
instead, and possibly followed by further conversions if desired. -
app_star()
,app_planet()
,topo_star()
andtopo_planet()
: These use the old (pre IAU 2000) methodology,
which isn't clear from their naming. Useplace()
orplace_star()
withNOVAS_TOD
orNOVAS_CIRS
as the system
instead, as appropriate. -
readeph()
: prone to memory leaks, and not flexible with its origin (necessarily at the barycenter). Instead, use
a similarnovas_ephem_provider
implementation andset_ephem_provider()
for a more flexible and less
troublesome equivalent, which also does not need to be baked into the library and can be configured at runtime. -
tdb2tt()
. Usett2tdb()
instead. It's both more intuitive to use (returning the time difference as a double) and
faster to calculate, not to mention that it implements the more standard approach.