35#include "hdrl_barycorr.h"
78hdrl_eop_interpolate(
double mjd,
const cpl_table * eop_table, hdrl_parameter *
79 resample_par,
double *pmx,
double *pmy,
double *dut)
81 cpl_ensure_code (eop_table, CPL_ERROR_NULL_INPUT);
82 cpl_ensure_code (resample_par, CPL_ERROR_NULL_INPUT);
83 cpl_ensure_code (pmx, CPL_ERROR_NULL_INPUT);
84 cpl_ensure_code (pmy, CPL_ERROR_NULL_INPUT);
85 cpl_ensure_code (dut, CPL_ERROR_NULL_INPUT);
87 cpl_table * eop_table_loc = cpl_table_duplicate(eop_table);
91 if (!cpl_table_has_column(eop_table_loc,
"MJD") ||
92 !cpl_table_has_column(eop_table_loc,
"PMX") ||
93 !cpl_table_has_column(eop_table_loc,
"PMY") ||
94 !cpl_table_has_column(eop_table_loc,
"DUT")){
95 cpl_table_delete(eop_table_loc);
96 return cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
97 "The EOP table does not have all required "
98 "columns, i.e. MJD, PMX, PMY, DUT");
101 cpl_table_unselect_all (eop_table_loc);
102 cpl_table_or_selected_invalid (eop_table_loc,
"MJD");
103 cpl_table_or_selected_invalid (eop_table_loc,
"PMX");
104 cpl_table_or_selected_invalid (eop_table_loc,
"PMY");
105 cpl_table_or_selected_invalid (eop_table_loc,
"DUT");
106 cpl_table_erase_selected (eop_table_loc);
108 if (cpl_table_get_nrow(eop_table_loc) < 1){
109 cpl_table_delete(eop_table_loc);
110 return cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
111 "The EOP table does not have entries after "
112 "removing all invalid elements");
115 cpl_size mjd_max = cpl_table_get_column_max(eop_table_loc,
"MJD");
116 cpl_size mjd_min = cpl_table_get_column_min(eop_table_loc,
"MJD");
118 if (mjd < mjd_min || mjd > mjd_max) {
119 *pmx = cpl_table_get_column_median(eop_table_loc,
"PMX");
120 *pmy = cpl_table_get_column_median(eop_table_loc,
"PMY");
121 *dut = cpl_table_get_column_median(eop_table_loc,
"DUT");
122 cpl_msg_warning(cpl_func,
"The exposure MJD-OBS is outside the validity "
123 "range of the EOP calibration. Using median values instead of "
124 "interpolated values. Please provide a more up to date EOP file for "
125 "a higher accuracy.");
126 cpl_table_delete(eop_table_loc);
127 return cpl_error_get_code();
130 hdrl_spectrum1D * pmx_spec =
132 hdrl_spectrum1D_wave_scale_linear);
133 hdrl_spectrum1D * pmy_spec =
135 hdrl_spectrum1D_wave_scale_linear);
136 hdrl_spectrum1D * dut_spec =
138 hdrl_spectrum1D_wave_scale_linear);
140 cpl_array * mjd_out = cpl_array_new(1, CPL_TYPE_DOUBLE);
141 cpl_array_set_double(mjd_out, 0, mjd);
143 hdrl_spectrum1D * pmx_spec_resampled =
145 hdrl_spectrum1D * pmy_spec_resampled =
147 hdrl_spectrum1D * dut_spec_resampled =
150 cpl_array_delete(mjd_out);
155 int rej_pmx = 0, rej_pmy = 0, rej_dut = 0;
169 cpl_table_delete(eop_table_loc);
170 return cpl_error_get_code();
206 double mjdobs,
double time_to_mid_exposure,
207 double longitude,
double latitude,
double elevation,
208 double pressure,
double temperature,
209 double humidity,
double wavelength ,
double *barycorr){
211 cpl_ensure_code(ra >= 0. && ra < 360., CPL_ERROR_ILLEGAL_INPUT);
212 cpl_ensure_code(dec >= -90. && dec <= 90., CPL_ERROR_ILLEGAL_INPUT);
214 cpl_ensure_code(longitude >= -180. && longitude <= 180., CPL_ERROR_ILLEGAL_INPUT);
215 cpl_ensure_code(latitude >= -90. && latitude <= 90., CPL_ERROR_ILLEGAL_INPUT);
216 cpl_ensure_code(eop_table != NULL, CPL_ERROR_NULL_INPUT);
219 cpl_error_code err = CPL_ERROR_NONE;
220 ra *= CPL_MATH_RAD_DEG;
221 dec *= CPL_MATH_RAD_DEG;
222 longitude *= CPL_MATH_RAD_DEG;
223 latitude *= CPL_MATH_RAD_DEG;
226 double mean_mjd = mjdobs + (time_to_mid_exposure/3600./24.);
227 cpl_msg_info(cpl_func,
"Mean MJD-OBS used to derive barycorr: %g", mean_mjd);
231 double dut1 = 0, pmx = 0, pmy = 0;
237 hdrl_parameter * resample_par =
240 hdrl_eop_interpolate(mean_mjd, eop_table, resample_par, &pmx, &pmy, &dut1) ;
245 return cpl_error_set_message(cpl_func, err,
"Could not interpolate the "
246 "Earth Orientation Parameter table");
249 cpl_msg_debug(cpl_func,
"Using the following Earth Orientation Parameter for "
250 "MJD-OBS %g: pmx: %g, pmy: %g, dut1: %g", mean_mjd, pmx, pmy, dut1);
252 pmx = pmx / 3600.0 * CPL_MATH_RAD_DEG;
253 pmy = pmy / 3600.0 * CPL_MATH_RAD_DEG;
255 cpl_msg_debug(cpl_func,
"Input to the erfa function eraApco13():");
256 cpl_msg_indent_more();
257 cpl_msg_debug (cpl_func,
"%12s %50s: %20.20g",
"utc1 :",
"UTC as a 2-part... ", 2400000.5);
258 cpl_msg_debug (cpl_func,
"%12s %50s: %20.20g",
"utc2 :",
"...quasi Julian Date (Notes 1,2) ", mean_mjd);
259 cpl_msg_debug (cpl_func,
"%12s %50s: %20.20g",
"dut1 :",
"UT1-UTC (seconds, Note 3) ", dut1);
260 cpl_msg_debug (cpl_func,
"%12s %50s: %20.20g",
"elong :",
"longitude (radians, east +ve, Note 4) ", longitude);
261 cpl_msg_debug (cpl_func,
"%12s %50s: %20.20g",
"phi :",
"latitude (geodetic, radians, Note 4) ", latitude);
262 cpl_msg_debug (cpl_func,
"%12s %50s: %20.20g",
"hm :",
"height above ellipsoid (m, geodetic, Notes 4,6) ", elevation);
263 cpl_msg_debug (cpl_func,
"%12s %50s: %20.20g",
"xp :",
"polar motion coordinates (radians, Note 5) ", pmx);
264 cpl_msg_debug (cpl_func,
"%12s %50s: %20.20g",
"yp :",
"polar motion coordinates (radians, Note 5) ", pmy);
265 cpl_msg_debug (cpl_func,
"%12s %50s: %20.20g",
"phpa :",
"pressure at the observer (hPa = mB, Note 6) ", pressure);
266 cpl_msg_debug (cpl_func,
"%12s %50s: %20.20g",
"tc :",
"ambient temperature at the observer (deg C) ", temperature);
267 cpl_msg_debug (cpl_func,
"%12s %50s: %20.20g",
"rh :",
"relative humidity at the observer (range 0-1) ", humidity);
268 cpl_msg_debug (cpl_func,
"%12s %50s: %20.20g",
"wl :",
"wavelength (micrometers, Note 7) ", wavelength);
269 cpl_msg_indent_less();
273 int eraApco13_status = 0;
274 cpl_msg_info(cpl_func,
"Calling erfa function eraApco13() ...");
275 eraApco13_status = eraApco13 (2400000.5, mean_mjd, dut1,
276 longitude, latitude, elevation,
278 pressure, temperature, humidity, wavelength,
280 if (eraApco13_status < 0) {
282 return cpl_error_set_message(cpl_func, CPL_ERROR_UNSPECIFIED,
283 "Erfa function eraApco13() did not succeed in"
284 " computing the barycentric correction");
287 cpl_msg_debug(cpl_func,
"Output of the erfa function eraApco13():");
288 cpl_msg_indent_more();
290 cpl_msg_debug (cpl_func,
" pmt : /* PM time interval (SSB, Julian years) */ : %20.20g ", astrom.pmt);
291 cpl_msg_debug (cpl_func,
" eb[0] : /* SSB to observer (vector, au) */ : %20.20g ", astrom.eb[0]);
292 cpl_msg_debug (cpl_func,
" eb[1] : /* SSB to observer (vector, au) */ : %20.20g ", astrom.eb[1]);
293 cpl_msg_debug (cpl_func,
" eb[2] : /* SSB to observer (vector, au) */ : %20.20g ", astrom.eb[2]);
294 cpl_msg_debug (cpl_func,
" eh[0] : /* Sun to observer (unit vector) */ : %20.20g ", astrom.eh[0]);
295 cpl_msg_debug (cpl_func,
" eh[1] : /* Sun to observer (unit vector) */ : %20.20g ", astrom.eh[1]);
296 cpl_msg_debug (cpl_func,
" eh[2] : /* Sun to observer (unit vector) */ : %20.20g ", astrom.eh[2]);
297 cpl_msg_debug (cpl_func,
" em : /* distance from Sun to observer (au) */ : %20.20g ", astrom.em);
298 cpl_msg_debug (cpl_func,
" v[0] : /* barycentric observer velocity (vector, c) */ : %20.20g ", astrom.v[0]);
299 cpl_msg_debug (cpl_func,
" v[1] : /* barycentric observer velocity (vector, c) */ : %20.20g ", astrom.v[1]);
300 cpl_msg_debug (cpl_func,
" v[2] : /* barycentric observer velocity (vector, c) */ : %20.20g ", astrom.v[2]);
301 cpl_msg_debug (cpl_func,
" bm1 : /* sqrt(1-|v|^2): reciprocal of Lorenz factor */ : %20.20g ", astrom.bm1);
302 cpl_msg_debug (cpl_func,
" bpn[0][0] : /* bias-precession-nutation matrix */ : %20.20g ", astrom.bpn[0][0]);
303 cpl_msg_debug (cpl_func,
" along: : /* longitude + s' + dERA(DUT) (radians) */ : %20.20g ", astrom.along);
306 cpl_msg_debug (cpl_func,
" xpl : /* polar motion xp wrt local meridian (radians) */ : %20.20g ", astrom.xpl);
307 cpl_msg_debug (cpl_func,
" ypl : /* polar motion yp wrt local meridian (radians) */ : %20.20g ", astrom.ypl);
308 cpl_msg_debug (cpl_func,
" sphi : /* sine of geodetic latitude */ : %20.20g ", astrom.sphi);
309 cpl_msg_debug (cpl_func,
" cphi : /* cosine of geodetic latitude */ : %20.20g ", astrom.cphi);
310 cpl_msg_debug (cpl_func,
" diurab : /* magnitude of diurnal aberration vector */ : %20.20g ", astrom.diurab);
311 cpl_msg_debug (cpl_func,
" eral : /* local Earth rotation angle (radians) */ : %20.20g ", astrom.eral);
312 cpl_msg_debug (cpl_func,
" refa : /* refraction constant A (radians) */ : %20.20g ", astrom.refa);
313 cpl_msg_debug (cpl_func,
" refb : /* refraction constant B (radians) */ : %20.20g ", astrom.refb);
314 cpl_msg_debug (cpl_func,
" eo : /* equation of the origins (ERA-GST) */ : %20.20g ", astrom.refb);
315 cpl_msg_indent_less();
322 astrom.v[0]*cos(ra)*cos(dec)+
323 astrom.v[1]*sin(ra)*cos(dec)+
324 astrom.v[2]*sin(dec);
326 *barycorr *= CPL_PHYS_C;
328 return cpl_error_get_code();
cpl_error_code hdrl_barycorr_compute(double ra, double dec, const cpl_table *eop_table, double mjdobs, double time_to_mid_exposure, double longitude, double latitude, double elevation, double pressure, double temperature, double humidity, double wavelength, double *barycorr)
Derives the barycentric correction using the erfa function eraApco13(). The latter For a terrestrial ...
void hdrl_parameter_delete(hdrl_parameter *obj)
shallow delete of a parameter
hdrl_parameter * hdrl_spectrum1D_resample_interpolate_parameter_create(const hdrl_spectrum1D_interpolation_method method)
constructor for the hdrl_parameter in the case of interpolation
void hdrl_spectrum1D_delete(hdrl_spectrum1D **p_self)
hdrl_spectrum1D destructor
hdrl_spectrum1D * hdrl_spectrum1D_convert_from_table(const cpl_table *self, const char *flux_col_name, const char *wavelength_col_name, const char *flux_e_col_name, const char *flux_bpm_col_name, hdrl_spectrum1D_wave_scale scale)
convert a table to a spectrum
hdrl_spectrum1D * hdrl_spectrum1D_resample_on_array(const hdrl_spectrum1D *self, const cpl_array *waves, const hdrl_parameter *par)
resample a hdrl_spectrum1D on the wavelengths contained in waves
hdrl_value hdrl_spectrum1D_get_flux_value(const hdrl_spectrum1D *self, int idx, int *rej)
hdrl_spectrum1D getter for a flux value