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 <string.h>
00037
00038 #include "naco_recipe.h"
00039
00040 #include <irplib_stdstar.h>
00041 #include <irplib_wcs.h>
00042
00043
00044
00045
00046
00047 #define NFILTERS 8
00048
00049 #define RECIPE_STRING "naco_util_img_std_cat"
00050
00051
00052 #ifndef NACO_ASCII_MAXLINELEN
00053 #define NACO_ASCII_MAXLINELEN 1024
00054 #endif
00055
00056
00057
00058
00059
00060 NACO_RECIPE_DEFINE(naco_util_img_std_cat,
00061 0,
00062 "Standard star catalog creation",
00063 RECIPE_STRING " -- Standard star catalog creation.\n"
00064 "Convert ASCII-file(s) to a FITS standard star catalog.\n"
00065 "This recipe generates a FITS standard star catalog for "
00066 "imaging from one or more ASCII-files.\n"
00067 "Each line in the text file must have "
00068 "4+" IRPLIB_STRINGIFY(NFILTERS) " fields "
00069 "separated by white-space.\n"
00070 "The first field is the star name, e.g. 'HD108903' which "
00071 "will be stored in a "
00072 "table column labeled '" IRPLIB_STDSTAR_STAR_COL "'.\n"
00073 "The next field is the Right Ascension [degrees] which will "
00074 "be stored in a table column labeled '" IRPLIB_STDSTAR_RA_COL
00075 "'.\n"
00076 "The Right Ascension must be non-negative and less than "
00077 "360.\n"
00078 "The next field is the Declination [degrees] which will be "
00079 "stored in a table column labeled '" IRPLIB_STDSTAR_DEC_COL
00080 "'.\n"
00081 "The Declination must be within the range -90 to 90.\n"
00082 "The next field is the spectral type which will be "
00083 "stored in a table column labeled '" IRPLIB_STDSTAR_TYPE_COL
00084 "'.\n"
00085 "The " IRPLIB_STRINGIFY(NFILTERS) " next fields are the "
00086 "magnitudes for the " IRPLIB_STRINGIFY(NFILTERS) " supported "
00087 "image filters.\n"
00088 "Unknown magnitudes must be indicated by the "
00089 "value " IRPLIB_STRINGIFY(IRPLIB_STDSTAR_NOMAG) ".\n"
00090 "The filename (without path) of the ASCII file will for "
00091 "each star be added in a table column labeled 'CAT_NAME'.\n"
00092 "The " IRPLIB_STRINGIFY(NFILTERS) " filter names are "
00093 "hard-coded in the recipe.\n"
00094 "\n"
00095 "Lines beginning with a hash (#) are treated as comments.\n"
00096 "\n"
00097 "The files listed in the Set Of Frames (sof-file) "
00098 "must be tagged:\n"
00099 "NACO-ASCII-file " NACO_IMG_STD_ASCII "\n");
00100
00101 static IRPLIB_UTIL_SET_ROW(naco_util_img_std_set_row);
00102 static IRPLIB_UTIL_CHECK(naco_util_img_std_check);
00103
00104 static cpl_error_code naco_util_img_std_cat_cmp(const cpl_table *,
00105 cpl_boolean *,
00106 double, double,
00107 const char *,
00108 const char *,
00109 const char *,
00110 int,
00111 const double *, double, double);
00112
00113 static double magmin = IRPLIB_STDSTAR_NOMAG;
00114 static double magmax = -30.0;
00115 static const char * filters[] = {"J","H", "K", "Ks", "L", "M", "Lp", "Mp"};
00116
00117
00118
00119
00120
00121
00128
00129 static int naco_util_img_std_cat(cpl_frameset * framelist,
00130 const cpl_parameterlist * parlist)
00131 {
00132 irplib_framelist * allframes = NULL;
00133 irplib_framelist * rawframes = NULL;
00134 cpl_frameset * useframes = NULL;
00135 cpl_table * self = NULL;
00136 int ifilt;
00137
00138
00139 bug_if(sizeof(filters) != NFILTERS * sizeof(char*));
00140
00141
00142 skip_if (naco_dfs_set_groups(framelist));
00143
00144
00145
00146 allframes = irplib_framelist_cast(framelist);
00147 bug_if(allframes == NULL);
00148
00149 rawframes = irplib_framelist_extract(allframes, NACO_IMG_STD_ASCII);
00150 skip_if(rawframes == NULL);
00151
00152 irplib_framelist_empty(allframes);
00153
00154 useframes = irplib_frameset_cast(rawframes);
00155 bug_if(allframes == NULL);
00156
00157
00158 self = cpl_table_new(irplib_framelist_get_size(rawframes));
00159
00160 irplib_framelist_empty(rawframes);
00161
00162
00163
00164 bug_if (cpl_table_new_column(self, IRPLIB_STDSTAR_STAR_COL,
00165 CPL_TYPE_STRING));
00166 bug_if (cpl_table_new_column(self, IRPLIB_STDSTAR_TYPE_COL,
00167 CPL_TYPE_STRING));
00168 bug_if (cpl_table_new_column(self, "CAT_NAME", CPL_TYPE_STRING));
00169 bug_if (cpl_table_new_column(self, IRPLIB_STDSTAR_RA_COL,
00170 CPL_TYPE_DOUBLE));
00171 bug_if (cpl_table_new_column(self, IRPLIB_STDSTAR_DEC_COL,
00172 CPL_TYPE_DOUBLE));
00173
00174 bug_if(cpl_table_set_column_unit(self, IRPLIB_STDSTAR_RA_COL,
00175 "Degrees"));
00176 bug_if(cpl_table_set_column_unit(self, IRPLIB_STDSTAR_DEC_COL,
00177 "Degrees"));
00178 for (ifilt=0 ; ifilt < NFILTERS ; ifilt++) {
00179 bug_if (cpl_table_new_column(self, filters[ifilt], CPL_TYPE_DOUBLE));
00180 bug_if(cpl_table_set_column_unit(self, filters[ifilt], "Magnitude"));
00181 }
00182
00183 skip_if(irplib_dfs_table_convert(self, framelist, useframes,
00184 NACO_ASCII_MAXLINELEN, '#', NULL,
00185 NACO_IMG_STD_CAT, parlist, RECIPE_STRING,
00186 NULL, NULL, NULL, "NACO", naco_pipe_id,
00187 naco_util_img_std_set_row,
00188 naco_util_img_std_check));
00189
00190 end_skip;
00191
00192 cpl_table_delete(self);
00193 cpl_frameset_delete(useframes);
00194 irplib_framelist_delete(allframes);
00195 irplib_framelist_delete(rawframes);
00196
00197 return cpl_error_get_code();
00198 }
00199
00200
00220
00221 static cpl_error_code naco_util_img_std_cat_cmp(const cpl_table * self,
00222 cpl_boolean * puse,
00223 double ra,
00224 double dec,
00225 const char * sname,
00226 const char * stype,
00227 const char * cat_name,
00228 int irow,
00229 const double * mags,
00230 double dist_max,
00231 double mag_tol)
00232 {
00233
00234 const int nfilters = NFILTERS;
00235 int j;
00236
00237 *puse = CPL_FALSE;
00238
00239 bug_if(self == NULL);
00240 bug_if(filters == NULL);
00241 bug_if(mags == NULL);
00242 bug_if(sname == NULL);
00243 bug_if(stype == NULL);
00244 bug_if(cat_name == NULL);
00245
00246 for (j = 0; j < irow; j++) {
00247 const double raj
00248 = cpl_table_get_double(self, IRPLIB_STDSTAR_RA_COL, j, NULL);
00249 const double decj
00250 = cpl_table_get_double(self, IRPLIB_STDSTAR_DEC_COL, j, NULL);
00251 double dist;
00252 double mag_max_found = 0;
00253 int i;
00254
00255 if (fabs(decj - dec) > dist_max) continue;
00256
00257 dist = irplib_wcs_great_circle_dist(ra, dec, raj, decj);
00258
00259 if (dist > dist_max) continue;
00260
00261 for (i=0 ; i < nfilters ; i++) {
00262 const double mag
00263 = cpl_table_get_double(self, filters[i], j, NULL);
00264 double mag_dif;
00265
00266 if (mags[i] > IRPLIB_STDSTAR_LIMIT) continue;
00267
00268 if (mag > IRPLIB_STDSTAR_LIMIT) break;
00269
00270 mag_dif = fabs(mags[i] - mag);
00271
00272 if (mag_dif > mag_tol) break;
00273
00274 if (mag_dif > mag_max_found) mag_max_found = mag_dif;
00275 }
00276
00277
00278 if (i == nfilters) {
00279 cpl_msg_debug(cpl_func, "Skipping star: '%s' at table row %d in "
00280 "catalogue '%s' and the star %d have identical "
00281 "magnitudes (within %g <= %g) and a distance: "
00282 "%g <= %g", sname, 1+irow, cat_name, j+1,
00283 mag_max_found, mag_tol, dist, dist_max);
00284 if (cpl_msg_get_level() <= CPL_MSG_DEBUG)
00285 cpl_table_dump(self, j, 1, stdout);
00286 break;
00287 }
00288 if (dist > 0.0) {
00289 cpl_msg_info(cpl_func, "The stars at rows %d and %d ('%s' in "
00290 "catalogue '%s') have different magnitudes, but a "
00291 "distance: %g <= %g",
00292 1+j, 1+irow, sname, cat_name, dist, dist_max);
00293 } else {
00294 cpl_msg_info(cpl_func, "The stars at rows %d and %d ('%s' in "
00295 "catalogue '%s') have different magnitudes, but "
00296 "identical coordinates",
00297 1+j, 1+irow, sname, cat_name);
00298 }
00299 #if 0
00300 cpl_table_dump(self, j, 1, stderr);
00301 for (i=0 ; i < nfilters ; i++) {
00302 const double mag
00303 = cpl_table_get_double(self, filters[i], j, NULL);
00304 const double mag_dif = fabs(mags[i] - mag);
00305
00306 if (mag_dif > mag_tol)
00307 cpl_msg_warning(cpl_func, "%s(%d): |%g - %g| = %g > %g",
00308 filters[i], i, mag, mags[i], mag_dif, mag_tol);
00309 }
00310 #endif
00311 }
00312
00313 if (j == irow) *puse = CPL_TRUE;
00314
00315 end_skip;
00316
00317 return CPL_ERROR_NONE;
00318
00319 }
00320
00321
00322
00331
00332 static
00333 cpl_error_code naco_util_img_std_check(cpl_table * self,
00334 const cpl_frameset * useframes,
00335 const cpl_parameterlist * parlist)
00336 {
00337
00338 bug_if(0);
00339 bug_if(self == NULL);
00340 bug_if(parlist == NULL);
00341
00342 cpl_msg_info(cpl_func, "Created table of %d stars with "
00343 "magnitudes from %g to %g from %d catalogues",
00344 (int)cpl_table_get_nrow(self),
00345 magmin, magmax, (int)cpl_frameset_get_size(useframes));
00346
00347 end_skip;
00348
00349 return cpl_error_get_code();
00350 }
00351
00352
00353
00376
00377 static cpl_boolean naco_util_img_std_set_row(cpl_table * self,
00378 const char * line,
00379 int irow,
00380 const cpl_frame * rawframe,
00381 const cpl_parameterlist * parlist)
00382 {
00383
00384
00385 #define FORMAT "%s %lg %lg %s %lg %lg %lg %lg %lg %lg %lg %lg"
00386
00387 char sname[NACO_ASCII_MAXLINELEN];
00388 char stype[NACO_ASCII_MAXLINELEN];
00389 double mags[NFILTERS];
00390 double ra, dec;
00391 int nvals;
00392 int ifilt;
00393 cpl_boolean use = CPL_FALSE;
00394
00395 bug_if(0);
00396 bug_if(self == NULL);
00397 bug_if(line == NULL);
00398 bug_if(irow < 0);
00399 bug_if(rawframe == NULL);
00400 bug_if(parlist == NULL);
00401
00402 nvals = sscanf(line, FORMAT,
00403 sname, &ra, &dec, stype, &(mags[0]), &(mags[1]), &(mags[2]),
00404 &(mags[3]), &(mags[4]), &(mags[5]), &(mags[6]), &(mags[7]));
00405
00406 error_if (nvals != NFILTERS+4, CPL_ERROR_BAD_FILE_FORMAT,
00407 "Line with length=%u has %d not 4+" IRPLIB_STRINGIFY(NFILTERS)
00408 " items formatted: %s", (unsigned)strlen(line), nvals, FORMAT);
00409
00410 error_if (ra < 0.0, CPL_ERROR_BAD_FILE_FORMAT,
00411 "Negative RA=%g in line %s", ra, line);
00412
00413 error_if (ra >=360.0, CPL_ERROR_BAD_FILE_FORMAT,
00414 "RA=%g is not less than 360 in line %s", ra, line);
00415
00416 error_if (dec < -90.0, CPL_ERROR_BAD_FILE_FORMAT,
00417 "DEC=%g is not at least -90 in line %s", dec, line);
00418
00419 error_if (dec > 90.0, CPL_ERROR_BAD_FILE_FORMAT,
00420 "DEC=%g is not at most 90 in line %s", dec, line);
00421
00422 for (ifilt=0 ; ifilt < NFILTERS; ifilt++) {
00423 if (mags[ifilt] < IRPLIB_STDSTAR_LIMIT) break;
00424 }
00425
00426 if (ifilt == NFILTERS) {
00427 cpl_msg_debug(cpl_func, "Not setting row without a valid magnitude: "
00428 "(%d)", 1+irow);
00429 } else {
00430 const char * rawfile = cpl_frame_get_filename(rawframe);
00431
00432 const char * cat_name = strrchr(rawfile, '/');
00433
00434 cat_name = cat_name ? 1+cat_name : rawfile;
00435
00436 bug_if(cat_name == NULL);
00437
00438 skip_if(naco_util_img_std_cat_cmp(self, &use, ra, dec, sname,
00439 stype, cat_name, irow,
00440 mags, 0.25e-4, 1e-6));
00441
00442 if (use) {
00443 bug_if (cpl_table_set_string(self, IRPLIB_STDSTAR_STAR_COL, irow,
00444 sname));
00445
00446 bug_if (cpl_table_set_string(self, "CAT_NAME", irow, cat_name));
00447
00448 bug_if (cpl_table_set_string(self, IRPLIB_STDSTAR_TYPE_COL, irow,
00449 stype));
00450
00451 bug_if (cpl_table_set_double(self, IRPLIB_STDSTAR_RA_COL, irow,
00452 ra));
00453
00454 bug_if (cpl_table_set_double(self, IRPLIB_STDSTAR_DEC_COL, irow,
00455 dec));
00456
00457 for (ifilt=0 ; ifilt < NFILTERS; ifilt++) {
00458 if (mags[ifilt] > 27.0 && mags[ifilt] < IRPLIB_STDSTAR_LIMIT) {
00459
00460 cpl_msg_warning(cpl_func, "Setting faint (mag=%g) object "
00461 "(Filter-%s) in table row %d", mags[ifilt],
00462 filters[ifilt], 1+irow);
00463 }
00464 if (mags[ifilt] > magmax && mags[ifilt] < IRPLIB_STDSTAR_LIMIT)
00465 magmax = mags[ifilt];
00466 if (mags[ifilt] < magmin) magmin = mags[ifilt];
00467 bug_if(cpl_table_set_double(self, filters[ifilt], irow,
00468 mags[ifilt]));
00469 }
00470 }
00471 }
00472
00473 end_skip;
00474
00475 return use;
00476
00477 }