00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031
00032
00033
00034
00035
00036 #include <math.h>
00037 #include <cpl.h>
00038
00039 #include "irplib_wcs.h"
00040
00041
00045
00046
00047 static cpl_error_code irplib_wcs_is_iso8601(int, int, int, int, int, double);
00048
00051
00062
00063 cpl_error_code irplib_wcs_xytoradec(const cpl_wcs *wcs,
00064 double x,
00065 double y,
00066 double *ra,
00067 double *dec)
00068 {
00069 cpl_matrix * xy;
00070 cpl_matrix * radec = NULL;
00071 cpl_array * status = NULL;
00072 cpl_error_code error;
00073
00074 cpl_ensure_code(ra != NULL, CPL_ERROR_NULL_INPUT);
00075 cpl_ensure_code(dec != NULL, CPL_ERROR_NULL_INPUT);
00076
00077
00078 xy = cpl_matrix_new(1, 2);
00079 cpl_matrix_set(xy, 0, 0, x);
00080 cpl_matrix_set(xy, 0, 1, y);
00081
00082
00083 error = cpl_wcs_convert(wcs, xy, &radec, &status, CPL_WCS_PHYS2WORLD);
00084
00085 cpl_matrix_delete(xy);
00086
00087 if (!error) {
00088
00089
00090 *ra = cpl_matrix_get(radec, 0, 0);
00091 *dec = cpl_matrix_get(radec, 0, 1);
00092
00093 }
00094
00095
00096 cpl_matrix_delete(radec);
00097 cpl_array_delete(status);
00098
00099 return cpl_error_set_where(cpl_func);
00100 }
00101
00102
00113
00114 cpl_error_code irplib_wcs_radectoxy(const cpl_wcs * wcs,
00115 double ra,
00116 double dec,
00117 double * x,
00118 double * y)
00119 {
00120 cpl_matrix * radec;
00121 cpl_matrix * xy = NULL;
00122 cpl_array * status = NULL;
00123 cpl_error_code error;
00124
00125 cpl_ensure_code(x != NULL, CPL_ERROR_NULL_INPUT);
00126 cpl_ensure_code(y != NULL, CPL_ERROR_NULL_INPUT);
00127
00128
00129 radec = cpl_matrix_new(1, 2);
00130 cpl_matrix_set(radec, 0, 0, ra);
00131 cpl_matrix_set(radec, 0, 1, dec);
00132
00133 error = cpl_wcs_convert(wcs, radec, &xy, &status, CPL_WCS_WORLD2PHYS);
00134
00135 cpl_matrix_delete(radec);
00136
00137 if (!error) {
00138
00139 *x = cpl_matrix_get(xy, 0, 0);
00140 *y = cpl_matrix_get(xy, 0, 1);
00141
00142 }
00143
00144
00145 cpl_array_delete(status);
00146 cpl_matrix_delete(xy);
00147
00148 return cpl_error_set_where(cpl_func);
00149
00150 }
00151
00152
00162
00163 double irplib_wcs_great_circle_dist(double ra1,
00164 double dec1,
00165 double ra2,
00166 double dec2)
00167 {
00168
00169
00170 const double dra = sin( CPL_MATH_RAD_DEG * (ra2 - ra1 )/2.0 );
00171 const double ddec = sin( CPL_MATH_RAD_DEG * (dec2 - dec1)/2.0 );
00172
00173 dec1 *= CPL_MATH_RAD_DEG;
00174 dec2 *= CPL_MATH_RAD_DEG;
00175
00176 return 2.0 * asin(sqrt( ddec*ddec + cos(dec1)*cos(dec2)*dra*dra))
00177 * CPL_MATH_DEG_RAD;
00178 }
00179
00180
00181
00195
00196 cpl_error_code irplib_wcs_mjd_from_iso8601(double * pmjd, int year, int month,
00197 int day, int hour, int minute,
00198 double second)
00199 {
00200
00201 cpl_ensure_code(pmjd != NULL, CPL_ERROR_NULL_INPUT);
00202 cpl_ensure_code(!irplib_wcs_is_iso8601(year, month, day, hour, minute,
00203 second), cpl_error_get_code());
00204
00205
00206 *pmjd = (double)((1461*(year - (12-month)/10 + 4712))/4
00207 + (306*((month+9)%12) + 5)/10
00208 - (3*((year - (12-month)/10 + 4900)/100))/4
00209 + day - 2399904)
00210 + (hour + (minute + second/60.0)/60.0)/24.0;
00211
00212 return CPL_ERROR_NONE;
00213
00214 }
00215
00216
00217
00233
00234 cpl_error_code irplib_wcs_iso8601_from_string(int * pyear, int * pmonth,
00235 int * pday, int * phour,
00236 int * pminute, double * psecond,
00237 const char * iso8601)
00238 {
00239
00240
00241 const char * iso8601format = "%4d-%2d-%2dT%2d:%2d:%lf";
00242
00243 cpl_ensure_code(pyear != NULL, CPL_ERROR_NULL_INPUT);
00244 cpl_ensure_code(pmonth != NULL, CPL_ERROR_NULL_INPUT);
00245 cpl_ensure_code(pday != NULL, CPL_ERROR_NULL_INPUT);
00246 cpl_ensure_code(phour != NULL, CPL_ERROR_NULL_INPUT);
00247 cpl_ensure_code(pminute != NULL, CPL_ERROR_NULL_INPUT);
00248 cpl_ensure_code(psecond != NULL, CPL_ERROR_NULL_INPUT);
00249 cpl_ensure_code(iso8601 != NULL, CPL_ERROR_NULL_INPUT);
00250
00251 cpl_error_ensure(sscanf(iso8601, iso8601format, pyear, pmonth,
00252 pday, phour, pminute, psecond) == 6,
00253 CPL_ERROR_ILLEGAL_INPUT, return cpl_error_get_code(),
00254 "%s is not formatted as %s", iso8601, iso8601format);
00255
00256 cpl_ensure_code(!irplib_wcs_is_iso8601(*pyear, *pmonth, *pday, *phour,
00257 *pminute, *psecond),
00258 cpl_error_get_code());
00259
00260 return CPL_ERROR_NONE;
00261 }
00262
00263
00264
00273
00274 cpl_error_code irplib_wcs_mjd_from_string(double * pmjd, const char * iso8601)
00275 {
00276
00277
00278 int year, day, month, hour, minute;
00279 double second;
00280
00281 return irplib_wcs_iso8601_from_string(&year, &month, &day, &hour,
00282 &minute, &second, iso8601)
00283 || irplib_wcs_mjd_from_iso8601(pmjd, year, month, day, hour, minute,
00284 second)
00285 ? cpl_error_set_where(cpl_func) : CPL_ERROR_NONE;
00286 }
00287
00288
00289
00290
00304
00305 cpl_error_code irplib_wcs_iso8601_from_mjd(int * pyear, int * pmonth,
00306 int * pday, int * phour,
00307 int * pminute, double * psecond,
00308 double mjd)
00309 {
00310
00311 int jd, n4, dd;
00312 double t;
00313
00314 cpl_ensure_code(pyear != NULL, CPL_ERROR_NULL_INPUT);
00315 cpl_ensure_code(pmonth != NULL, CPL_ERROR_NULL_INPUT);
00316 cpl_ensure_code(pday != NULL, CPL_ERROR_NULL_INPUT);
00317 cpl_ensure_code(phour != NULL, CPL_ERROR_NULL_INPUT);
00318 cpl_ensure_code(pminute != NULL, CPL_ERROR_NULL_INPUT);
00319 cpl_ensure_code(psecond != NULL, CPL_ERROR_NULL_INPUT);
00320
00321
00322
00323 jd = 2400001 + (int)mjd;
00324
00325 n4 = 4*(jd + ((2*((4*jd - 17918)/146097)*3)/4 + 1)/2 - 37);
00326 dd = 10*(((n4-237)%1461)/4) + 5;
00327
00328 *pyear = n4/1461 - 4712;
00329 *pmonth = (2 + dd/306)%12 + 1;
00330 *pday = (dd%306)/10 + 1;
00331
00332 t = mjd - (int)mjd;
00333
00334 t *= 24.0;
00335 *phour = (int)t;
00336 t = 60.0 * (t - *phour);
00337 *pminute = (int)t;
00338 *psecond = 60.0 * (t - *pminute);
00339
00340
00341 cpl_ensure_code(!irplib_wcs_is_iso8601(*pyear, *pmonth, *pday, *phour,
00342 *pminute, *psecond),
00343 CPL_ERROR_UNSPECIFIED);
00344
00345 return CPL_ERROR_NONE;
00346 }
00347
00348
00351
00363
00364 static cpl_error_code irplib_wcs_is_iso8601(int year, int month,
00365 int day, int hour,
00366 int minute, double second)
00367 {
00368
00369 const cpl_boolean is_leap = year % 4 ? CPL_FALSE : CPL_TRUE;
00370 const int mlen[] = {0, 31, is_leap ? 29 : 28, 31, 30, 31, 30, 31, 31, 30,
00371 31, 30, 31};
00372
00373 cpl_ensure_code(month > 0, CPL_ERROR_ILLEGAL_INPUT);
00374 cpl_ensure_code(month <= 12, CPL_ERROR_ILLEGAL_INPUT);
00375
00376 cpl_ensure_code(day > 0, CPL_ERROR_ILLEGAL_INPUT);
00377 cpl_ensure_code(day <= mlen[month], CPL_ERROR_ILLEGAL_INPUT);
00378
00379 cpl_ensure_code(minute < 60, CPL_ERROR_ILLEGAL_INPUT);
00380 cpl_ensure_code(minute >= 0, CPL_ERROR_ILLEGAL_INPUT);
00381
00382 cpl_ensure_code(second < 60.0, CPL_ERROR_ILLEGAL_INPUT);
00383 cpl_ensure_code(second >= 0.0, CPL_ERROR_ILLEGAL_INPUT);
00384
00385 cpl_ensure_code(hour >= 0, CPL_ERROR_ILLEGAL_INPUT);
00386
00387 cpl_ensure_code(hour <= (minute > 0 || second > 0.0 ? 23 : 24),
00388 CPL_ERROR_ILLEGAL_INPUT);
00389
00390 return CPL_ERROR_NONE;
00391 }