Skip to content

Commit cc03c76

Browse files
committed
Tests for refract.c
1 parent a7a8815 commit cc03c76

File tree

6 files changed

+147
-102
lines changed

6 files changed

+147
-102
lines changed

include/novas.h

+2
Original file line numberDiff line numberDiff line change
@@ -1144,6 +1144,8 @@ double novas_optical_refraction(double jd_tt, const on_surface *loc, enum novas_
11441144

11451145
double novas_radio_refraction(double jd_tt, const on_surface *loc, enum novas_refraction_type type, double el);
11461146

1147+
double novas_inv_refract(RefractionModel model, double jd_tt, const on_surface *loc, enum novas_refraction_type type, double el0);
1148+
11471149
// <================= END of SuperNOVAS API =====================>
11481150

11491151
#include "solarsystem.h"

src/novas.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -6521,8 +6521,8 @@ double refract(const on_surface *location, enum novas_refraction_model option, d
65216521

65226522
zd_obs = fabs(zd_obs);
65236523

6524-
// Compute refraction up to zenith distance 90.1 degrees.
6525-
if(zd_obs > 90.1)
6524+
// Compute refraction up to zenith distance 91 degrees.
6525+
if(zd_obs > 91.0)
65266526
return 0.0;
65276527

65286528
// If observed weather data are available, use them. Otherwise, use

src/refract.c

+22-14
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,18 @@
2121

2222

2323
static double novas_refraction(enum novas_refraction_model model, const on_surface *loc, enum novas_refraction_type type, double el) {
24-
if(!loc)
25-
return novas_error(-1, EINVAL, "novas_refraction", "NULL on surface observer location");
24+
if(!loc) {
25+
novas_error(-1, EINVAL, "novas_refraction", "NULL on surface observer location");
26+
return NAN;
27+
}
2628

2729
if(type == NOVAS_REFRACT_OBSERVED)
28-
return refract(loc, NOVAS_WEATHER_AT_LOCATION, 90.0 - el);
30+
return refract(loc, model, 90.0 - el);
31+
32+
if(type == NOVAS_REFRACT_ASTROMETRIC)
33+
return refract_astro(loc, model, 90.0 - el);
2934

30-
return refract_astro(loc, NOVAS_WEATHER_AT_LOCATION, 90.0 - el);
35+
return NAN;
3136
}
3237

3338
/**
@@ -120,6 +125,8 @@ double novas_optical_refraction(double jd_tt, const on_surface *loc, enum novas_
120125
* data is fully defined, and that the humidity was explicitly set after calling
121126
* `make_on_surface()`.
122127
*
128+
* Adapted from FORTAN code provided by Berman &amp; Rockwell 1976.
129+
*
123130
* REFERENCES:
124131
* <ol>
125132
* <li>Berman, Allan L., and Rockwell, Stephen T. (1976), NASA JPL Technical Report 32-1601</li>
@@ -140,7 +147,6 @@ double novas_optical_refraction(double jd_tt, const on_surface *loc, enum novas_
140147
double novas_radio_refraction(double jd_tt, const on_surface *loc, enum novas_refraction_type type, double el) {
141148
// Various coefficients...
142149
static const double E[] = { 0.0, 46.625, 45.375, 4.1572, 1.4468, 0.25391, 2.2716, -1.3465, -4.3877, 3.1484, 4.520, -1.8982, 0.8900 };
143-
//static const double EULER = 2.71828182845905; // Euler's number
144150

145151
double E0, TK;
146152
double y = 1.0, z;
@@ -149,23 +155,27 @@ double novas_radio_refraction(double jd_tt, const on_surface *loc, enum novas_re
149155
double refraction;
150156
int j;
151157

152-
// The Bermann
153-
if(type == NOVAS_REFRACT_OBSERVED) {
154-
return novas_inv_refract(novas_radio_refraction, jd_tt, loc, NOVAS_REFRACT_ASTROMETRIC, el);
158+
if(!loc) {
159+
novas_error(-1, EINVAL, "novas_radio_refraction", "NULL on surface observer location");
160+
return NAN;
155161
}
156162

157-
// TODO check which type of argument it takes.
163+
if(type != NOVAS_REFRACT_OBSERVED && type != NOVAS_REFRACT_ASTROMETRIC) {
164+
novas_error(-1, EINVAL, "novas_radio_refraction", "invalid refraction type: %d", type);
165+
return NAN;
166+
}
167+
168+
// The Bermann
169+
if(type == NOVAS_REFRACT_OBSERVED)
170+
return novas_inv_refract(novas_radio_refraction, jd_tt, loc, NOVAS_REFRACT_ASTROMETRIC, el);
158171

159172
// Zenith angle in degrees
160173
z = (90.0 - el) / DEGREE;
161174

162175
// Temperature in Kelvin
163176
TK = loc->temperature + 273.16;
164-
165177
fptem = (loc->pressure / 1000.) * (273.16 / TK);
166-
167178
E0 = (z - E[1]) / E[2];
168-
169179
poly = E[11];
170180

171181
for(j = 1; j <= 8; j++)
@@ -174,9 +184,7 @@ double novas_radio_refraction(double jd_tt, const on_surface *loc, enum novas_re
174184
if(poly <= -80.) poly = 0.;
175185

176186
poly = exp(poly) - E[12];
177-
178187
refraction = poly * fptem;
179-
180188
y = exp(((TK * 17.149) - 4684.1) / (TK - 38.45));
181189

182190
return refraction * 1.0 + (y * loc->humidity * 71.) / (TK * loc->pressure * 0.760);

src/timescale.c

+7
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ int novas_set_time(enum novas_timescale timescale, double jd, int leap, double d
7474
* precision is reached if the fractional part is on the order of &le;= 1 day. In that case, the
7575
* time may be specified to picosecond accuracy, if needed.
7676
*
77+
* The accuracy of Barycentric Time measures (TDB and TCB) relative to other time measures is
78+
* limited by the precision of `tbd2tt()` implementation, to around 10 &mu;s.
79+
*
80+
*
7781
* REFERENCES:
7882
* <ol>
7983
* <li>IAU 1991, RECOMMENDATION III. XXIst General Assembly of the
@@ -223,6 +227,9 @@ double novas_get_time(const novas_timespec *time, enum novas_timescale timescale
223227
* at the picosecond level, as opposed to `novas_set_time()`, whose precision is limited to a
224228
* ew microseconds. Ultimately, the accutacy of the time will depend on how it was set.
225229
*
230+
* The accuracy of Barycentric Time measures (TDB and TCB) relative to other time measures is
231+
* limited by the precision of the `tbd2tt()` implemenation, to around 10 &mu;s.
232+
*
226233
* REFERENCES:
227234
* <ol>
228235
* <li>IAU 1991, RECOMMENDATION III. XXIst General Assembly of the

test/src/test-errors.c

+24-1
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ static int test_refract() {
162162
if(check("refract:model", 1, r == 0.0 && errno == EINVAL)) n++;
163163

164164
errno = 0;
165-
r = refract(&o, NOVAS_STANDARD_ATMOSPHERE, 91.0);
165+
r = refract(&o, NOVAS_STANDARD_ATMOSPHERE, 91.01);
166166
if(check("refract:zd", 1, r == 0.0)) n++;
167167

168168
return n;
@@ -905,6 +905,28 @@ static int test_time() {
905905
return n;
906906
}
907907

908+
static int test_refraction() {
909+
int n = 0;
910+
on_surface obs = {};
911+
912+
if(check_nan("stardard_refraction:loc", novas_standard_refraction(NOVAS_JD_J2000, NULL, NOVAS_REFRACT_OBSERVED, 10.0))) n++;
913+
if(check_nan("stardard_refraction:type:-2", novas_standard_refraction(NOVAS_JD_J2000, &obs, -2, 10.0))) n++;
914+
if(check_nan("stardard_refraction:type:1", novas_standard_refraction(NOVAS_JD_J2000, &obs, 1, 10.0))) n++;
915+
if(check_nan("stardard_refraction:el:neg", novas_standard_refraction(NOVAS_JD_J2000, &obs, 1, -10.0))) n++;
916+
917+
if(check_nan("optical_refraction:loc", novas_optical_refraction(NOVAS_JD_J2000, NULL, NOVAS_REFRACT_OBSERVED, 10.0))) n++;
918+
if(check_nan("optical_refraction:type:-2", novas_optical_refraction(NOVAS_JD_J2000, &obs, -2, 10.0))) n++;
919+
if(check_nan("optical_refraction:type:1", novas_optical_refraction(NOVAS_JD_J2000, &obs, 1, 10.0))) n++;
920+
if(check_nan("optical_refraction:el:neg", novas_optical_refraction(NOVAS_JD_J2000, &obs, 1, -10.0))) n++;
921+
922+
if(check_nan("radio_refraction:loc", novas_radio_refraction(NOVAS_JD_J2000, NULL, NOVAS_REFRACT_OBSERVED, 10.0))) n++;
923+
if(check_nan("radio_refraction:type:-2", novas_radio_refraction(NOVAS_JD_J2000, &obs, -2, 10.0))) n++;
924+
if(check_nan("radio_refraction:type:1", novas_radio_refraction(NOVAS_JD_J2000, &obs, 1, 10.0))) n++;
925+
if(check_nan("radio_refraction:el:neg", novas_radio_refraction(NOVAS_JD_J2000, &obs, 1, -10.0))) n++;
926+
927+
return n;
928+
}
929+
908930
int main() {
909931
int n = 0;
910932

@@ -998,6 +1020,7 @@ int main() {
9981020

9991021
if(test_obs_posvel()) n++;
10001022
if(test_time()) n++;
1023+
if(test_refraction()) n++;
10011024

10021025
if(n) fprintf(stderr, " -- FAILED %d tests\n", n);
10031026
else fprintf(stderr, " -- OK\n");

0 commit comments

Comments
 (0)