Skip to content

Commit

Permalink
make_on_surface() to leave humidity undefined to restore ABI compatib…
Browse files Browse the repository at this point in the history
…ility with 1.0
  • Loading branch information
attipaci committed Nov 17, 2024
1 parent c04b6b0 commit 8b2db8f
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 10 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
Release candidate for the next feature release, expected around 1 February 2025.


### Fixed

- `make_on_surface()` to leave humidity undefined. The `humidity` field was added in v1.1 only, and thus attempting
to initialize it to zero can use memory corruption or even segfaulting if called by objects that have been compiled
with v1.0. So, from now on the call will leave humidity uninitialized and it's up to the calle ro define it if it
is needed for the specific refraction model.

### Added

- #57: New `novas_make_redshifted_object()` to simplify the creation of distant catalog sources that are
Expand Down
25 changes: 19 additions & 6 deletions include/novas.h
Original file line number Diff line number Diff line change
Expand Up @@ -807,14 +807,12 @@ typedef struct {
} object;

/**
* data for an observer's location on the surface of
* the Earth. The atmospheric parameters are used
* only by the refraction function called from
* function 'equ2hor'. Additional parameters can be
* added to this structure if a more sophisticated
* refraction model is employed.
* Data for an observer's location on the surface of the Earth, and optional local weather data for
* refraction calculations only.
*
* @sa observer
* @sa make_on_surface()
* @sa ON_SURFACE_INIT
*/
typedef struct {
double latitude; ///< [deg] geodetic (ITRS) latitude; north positive
Expand All @@ -825,11 +823,20 @@ typedef struct {
double humidity; ///< [%] Relative humidity. @since 1.1
} on_surface;

/**
* Initialized for a NOVAS on_surface data structure.
*
* @sa on_surface
* @since 1.2
*/
#define ON_SURFACE_INIT { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }

/**
* data for an observer's location on Earth orbit
*
* @sa observer
* @sa IN_SPACE_INIT
* @sa make_in_space()
*/
typedef struct {
double sc_pos[3]; ///< [km] geocentric (or [AU] ICRS barycentric) position vector (x, y, z)
Expand All @@ -846,6 +853,11 @@ typedef struct {
/**
* Observer location.
*
* @sa make_observer()
* @sa make_observer_at_geocenter()
* @sa make_observer_on_earth()
* @sa make_observer_in_space()
* @sa make_solar_system_observer()
*/
typedef struct {
enum novas_observer_place where; ///< observer location type
Expand All @@ -860,6 +872,7 @@ typedef struct {
in_space near_earth;
} observer;


/**
* Celestial object's place on the sky; contains the output from place()
*
Expand Down
11 changes: 7 additions & 4 deletions src/novas.c
Original file line number Diff line number Diff line change
Expand Up @@ -6840,6 +6840,7 @@ int make_planet(enum novas_planet num, object *planet) {
* @sa make_observer_at_geocenter()
* @sa make_observer_on_surface()
* @sa make_observer_in_space()
* @sa make_solar_system_observer()
*/
short make_observer(enum novas_observer_place where, const on_surface *loc_surface, const in_space *loc_space, observer *obs) {
static const char *fn = "make_observer";
Expand Down Expand Up @@ -6956,9 +6957,9 @@ int make_observer_in_space(const double *sc_pos, const double *sc_vel, observer
* the given parameters.
*
* Note, that because this is an original NOVAS C routine, it does not have an argument to set
* a humidity value (e.g. for radio refraction). As such the call will set humidity to 0.0.
* To set the humidity, set the output structure's field after calling this funcion. Its unit
* is [%], and so the range is 0.0--100.0.
* a humidity value (e.g. for radio refraction). As such, the humidity value remains undefined
* after this call. To set the humidity, set the output structure's field after calling this
* funcion. Its unit is [%], and so the range is 0.0--100.0.
*
* @param latitude [deg] Geodetic (ITRS) latitude in degrees; north positive.
* @param longitude [deg] Geodetic (ITRS) longitude in degrees; east positive.
Expand All @@ -6981,7 +6982,9 @@ int make_on_surface(double latitude, double longitude, double height, double tem
loc->height = height;
loc->temperature = temperature;
loc->pressure = pressure;
loc->humidity = 0.0;

// FIXME starting v2.0 set humidity to 0.0
//loc->humidity = 0.0;

return 0;
}
Expand Down
6 changes: 6 additions & 0 deletions src/refract.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,12 @@ double novas_radio_refraction(double jd_tt, const on_surface *loc, enum novas_re
return NAN;
}


if(loc->humidity < -1.0 || loc->humidity > 101.0) {
novas_set_errno(EINVAL, fn, "invalid humidity value: %g", loc->humidity);
return NAN;
}

if(type == NOVAS_REFRACT_OBSERVED)
return novas_inv_refract(novas_radio_refraction, jd_tt, loc, NOVAS_REFRACT_ASTROMETRIC, el);

Expand Down
6 changes: 6 additions & 0 deletions test/src/test-errors.c
Original file line number Diff line number Diff line change
Expand Up @@ -1149,6 +1149,12 @@ static int test_refraction() {
novas_optical_refraction(NOVAS_JD_J2000, NULL, NOVAS_REFRACT_OBSERVED, 10.0);
novas_debug(0);

obs.humidity = -1.01;
if(check_nan("radio_refraction:humidity:lo", novas_radio_refraction(NOVAS_JD_J2000, &obs, NOVAS_REFRACT_OBSERVED, 10.0))) n++;

obs.humidity = 101.01;
if(check_nan("radio_refraction:humidity:hi", novas_radio_refraction(NOVAS_JD_J2000, &obs, NOVAS_REFRACT_OBSERVED, 10.0))) n++;

return n;
}

Expand Down

0 comments on commit 8b2db8f

Please sign in to comment.