38 #include "naco_recipe.h"
40 #include <irplib_stdstar.h>
41 #include <irplib_wcs.h>
49 #define RECIPE_STRING "naco_util_img_std_cat"
52 #ifndef NACO_ASCII_MAXLINELEN
53 #define NACO_ASCII_MAXLINELEN 1024
60 NACO_RECIPE_DEFINE(naco_util_img_std_cat,
62 "Standard star catalog creation",
63 RECIPE_STRING
" -- Standard star catalog creation.\n"
64 "Convert ASCII-file(s) to a FITS standard star catalog.\n"
65 "This recipe generates a FITS standard star catalog for "
66 "imaging from one or more ASCII-files.\n"
67 "Each line in the text file must have "
68 "4+" IRPLIB_STRINGIFY(NFILTERS)
" fields "
69 "separated by white-space.\n"
70 "The first field is the star name, e.g. 'HD108903' which "
71 "will be stored in a "
72 "table column labeled '" IRPLIB_STDSTAR_STAR_COL
"'.\n"
73 "The next field is the Right Ascension [degrees] which will "
74 "be stored in a table column labeled '" IRPLIB_STDSTAR_RA_COL
76 "The Right Ascension must be non-negative and less than "
78 "The next field is the Declination [degrees] which will be "
79 "stored in a table column labeled '" IRPLIB_STDSTAR_DEC_COL
81 "The Declination must be within the range -90 to 90.\n"
82 "The next field is the spectral type which will be "
83 "stored in a table column labeled '" IRPLIB_STDSTAR_TYPE_COL
85 "The " IRPLIB_STRINGIFY(NFILTERS)
" next fields are the "
86 "magnitudes for the " IRPLIB_STRINGIFY(NFILTERS)
" supported "
88 "Unknown magnitudes must be indicated by the "
89 "value " IRPLIB_STRINGIFY(IRPLIB_STDSTAR_NOMAG)
".\n"
90 "The filename (without path) of the ASCII file will for "
91 "each star be added in a table column labeled 'CAT_NAME'.\n"
92 "The " IRPLIB_STRINGIFY(NFILTERS)
" filter names are "
93 "hard-coded in the recipe.\n"
95 "Lines beginning with a hash (#) are treated as comments.\n"
97 "The files listed in the Set Of Frames (sof-file) "
99 "NACO-ASCII-file " NACO_IMG_STD_ASCII
"\n");
101 static IRPLIB_UTIL_SET_ROW(naco_util_img_std_set_row);
102 static IRPLIB_UTIL_CHECK(naco_util_img_std_check);
104 static cpl_error_code naco_util_img_std_cat_cmp(
const cpl_table *,
111 const double *,
double,
double);
113 static double magmin = IRPLIB_STDSTAR_NOMAG;
114 static double magmax = -30.0;
115 static const char * filters[] = {
"J",
"H",
"K",
"Ks",
"L",
"M",
"Lp",
"Mp"};
129 static int naco_util_img_std_cat(cpl_frameset * framelist,
130 const cpl_parameterlist * parlist)
132 irplib_framelist * allframes = NULL;
133 irplib_framelist * rawframes = NULL;
134 cpl_frameset * useframes = NULL;
135 cpl_table *
self = NULL;
139 bug_if(
sizeof(filters) != NFILTERS *
sizeof(
char*));
147 bug_if(allframes == NULL);
150 skip_if(rawframes == NULL);
155 bug_if(allframes == NULL);
164 bug_if (cpl_table_new_column(
self, IRPLIB_STDSTAR_STAR_COL,
166 bug_if (cpl_table_new_column(
self, IRPLIB_STDSTAR_TYPE_COL,
168 bug_if (cpl_table_new_column(
self,
"CAT_NAME", CPL_TYPE_STRING));
169 bug_if (cpl_table_new_column(
self, IRPLIB_STDSTAR_RA_COL,
171 bug_if (cpl_table_new_column(
self, IRPLIB_STDSTAR_DEC_COL,
174 bug_if(cpl_table_set_column_unit(
self, IRPLIB_STDSTAR_RA_COL,
176 bug_if(cpl_table_set_column_unit(
self, IRPLIB_STDSTAR_DEC_COL,
178 for (ifilt=0 ; ifilt < NFILTERS ; ifilt++) {
179 bug_if (cpl_table_new_column(
self, filters[ifilt], CPL_TYPE_DOUBLE));
180 bug_if(cpl_table_set_column_unit(
self, filters[ifilt],
"Magnitude"));
184 NACO_ASCII_MAXLINELEN,
'#', NULL,
185 NACO_IMG_STD_CAT, parlist, RECIPE_STRING,
186 NULL, NULL, NULL,
"NACO", naco_pipe_id,
187 naco_util_img_std_set_row,
188 naco_util_img_std_check));
192 cpl_table_delete(
self);
193 cpl_frameset_delete(useframes);
197 return cpl_error_get_code();
221 static cpl_error_code naco_util_img_std_cat_cmp(
const cpl_table *
self,
227 const char * cat_name,
234 const int nfilters = NFILTERS;
239 bug_if(
self == NULL);
240 bug_if(filters == NULL);
241 bug_if(mags == NULL);
242 bug_if(sname == NULL);
243 bug_if(stype == NULL);
244 bug_if(cat_name == NULL);
246 for (j = 0; j < irow; j++) {
248 = cpl_table_get_double(
self, IRPLIB_STDSTAR_RA_COL, j, NULL);
250 = cpl_table_get_double(
self, IRPLIB_STDSTAR_DEC_COL, j, NULL);
252 double mag_max_found = 0;
255 if (fabs(decj - dec) > dist_max)
continue;
257 dist = irplib_wcs_great_circle_dist(ra, dec, raj, decj);
259 if (dist > dist_max)
continue;
261 for (i=0 ; i < nfilters ; i++) {
263 = cpl_table_get_double(
self, filters[i], j, NULL);
266 if (mags[i] > IRPLIB_STDSTAR_LIMIT)
continue;
268 if (mag > IRPLIB_STDSTAR_LIMIT)
break;
270 mag_dif = fabs(mags[i] - mag);
272 if (mag_dif > mag_tol)
break;
274 if (mag_dif > mag_max_found) mag_max_found = mag_dif;
279 cpl_msg_debug(cpl_func,
"Skipping star: '%s' at table row %d in "
280 "catalogue '%s' and the star %d have identical "
281 "magnitudes (within %g <= %g) and a distance: "
282 "%g <= %g", sname, 1+irow, cat_name, j+1,
283 mag_max_found, mag_tol, dist, dist_max);
284 if (cpl_msg_get_level() <= CPL_MSG_DEBUG)
285 cpl_table_dump(
self, j, 1, stdout);
289 cpl_msg_info(cpl_func,
"The stars at rows %d and %d ('%s' in "
290 "catalogue '%s') have different magnitudes, but a "
291 "distance: %g <= %g",
292 1+j, 1+irow, sname, cat_name, dist, dist_max);
294 cpl_msg_info(cpl_func,
"The stars at rows %d and %d ('%s' in "
295 "catalogue '%s') have different magnitudes, but "
296 "identical coordinates",
297 1+j, 1+irow, sname, cat_name);
300 cpl_table_dump(
self, j, 1, stderr);
301 for (i=0 ; i < nfilters ; i++) {
303 = cpl_table_get_double(
self, filters[i], j, NULL);
304 const double mag_dif = fabs(mags[i] - mag);
306 if (mag_dif > mag_tol)
307 cpl_msg_warning(cpl_func,
"%s(%d): |%g - %g| = %g > %g",
308 filters[i], i, mag, mags[i], mag_dif, mag_tol);
313 if (j == irow) *puse = CPL_TRUE;
317 return CPL_ERROR_NONE;
333 cpl_error_code naco_util_img_std_check(cpl_table *
self,
334 const cpl_frameset * useframes,
335 const cpl_parameterlist * parlist)
339 bug_if(
self == NULL);
340 bug_if(parlist == NULL);
342 cpl_msg_info(cpl_func,
"Created table of %d stars with "
343 "magnitudes from %g to %g from %d catalogues",
344 (
int)cpl_table_get_nrow(
self),
345 magmin, magmax, (
int)cpl_frameset_get_size(useframes));
349 return cpl_error_get_code();
377 static cpl_boolean naco_util_img_std_set_row(cpl_table *
self,
380 const cpl_frame * rawframe,
381 const cpl_parameterlist * parlist)
385 #define FORMAT "%s %lg %lg %s %lg %lg %lg %lg %lg %lg %lg %lg"
387 char sname[NACO_ASCII_MAXLINELEN];
388 char stype[NACO_ASCII_MAXLINELEN];
389 double mags[NFILTERS];
393 cpl_boolean use = CPL_FALSE;
396 bug_if(
self == NULL);
397 bug_if(line == NULL);
399 bug_if(rawframe == NULL);
400 bug_if(parlist == NULL);
402 nvals = sscanf(line, FORMAT,
403 sname, &ra, &dec, stype, &(mags[0]), &(mags[1]), &(mags[2]),
404 &(mags[3]), &(mags[4]), &(mags[5]), &(mags[6]), &(mags[7]));
406 error_if (nvals != NFILTERS+4, CPL_ERROR_BAD_FILE_FORMAT,
407 "Line with length=%u has %d not 4+" IRPLIB_STRINGIFY(NFILTERS)
408 " items formatted: %s", (
unsigned)strlen(line), nvals, FORMAT);
410 error_if (ra < 0.0, CPL_ERROR_BAD_FILE_FORMAT,
411 "Negative RA=%g in line %s", ra, line);
413 error_if (ra >=360.0, CPL_ERROR_BAD_FILE_FORMAT,
414 "RA=%g is not less than 360 in line %s", ra, line);
416 error_if (dec < -90.0, CPL_ERROR_BAD_FILE_FORMAT,
417 "DEC=%g is not at least -90 in line %s", dec, line);
419 error_if (dec > 90.0, CPL_ERROR_BAD_FILE_FORMAT,
420 "DEC=%g is not at most 90 in line %s", dec, line);
422 for (ifilt=0 ; ifilt < NFILTERS; ifilt++) {
423 if (mags[ifilt] < IRPLIB_STDSTAR_LIMIT)
break;
426 if (ifilt == NFILTERS) {
427 cpl_msg_debug(cpl_func,
"Not setting row without a valid magnitude: "
430 const char * rawfile = cpl_frame_get_filename(rawframe);
432 const char * cat_name = strrchr(rawfile,
'/');
434 cat_name = cat_name ? 1+cat_name : rawfile;
436 bug_if(cat_name == NULL);
438 skip_if(naco_util_img_std_cat_cmp(
self, &use, ra, dec, sname,
439 stype, cat_name, irow,
440 mags, 0.25e-4, 1e-6));
443 bug_if (cpl_table_set_string(
self, IRPLIB_STDSTAR_STAR_COL, irow,
446 bug_if (cpl_table_set_string(
self,
"CAT_NAME", irow, cat_name));
448 bug_if (cpl_table_set_string(
self, IRPLIB_STDSTAR_TYPE_COL, irow,
451 bug_if (cpl_table_set_double(
self, IRPLIB_STDSTAR_RA_COL, irow,
454 bug_if (cpl_table_set_double(
self, IRPLIB_STDSTAR_DEC_COL, irow,
457 for (ifilt=0 ; ifilt < NFILTERS; ifilt++) {
458 if (mags[ifilt] > 27.0 && mags[ifilt] < IRPLIB_STDSTAR_LIMIT) {
460 cpl_msg_warning(cpl_func,
"Setting faint (mag=%g) object "
461 "(Filter-%s) in table row %d", mags[ifilt],
462 filters[ifilt], 1+irow);
464 if (mags[ifilt] > magmax && mags[ifilt] < IRPLIB_STDSTAR_LIMIT)
465 magmax = mags[ifilt];
466 if (mags[ifilt] < magmin) magmin = mags[ifilt];
467 bug_if(cpl_table_set_double(
self, filters[ifilt], irow,
cpl_frameset * irplib_frameset_cast(const irplib_framelist *self)
Create a CPL frameset from an irplib_framelist.
int naco_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
cpl_error_code irplib_dfs_table_convert(cpl_table *self, cpl_frameset *allframes, const cpl_frameset *useframes, int maxlinelen, char commentchar, const char *product_name, const char *procatg, const cpl_parameterlist *parlist, const char *recipe_name, const cpl_propertylist *mainlist, const cpl_propertylist *extlist, const char *remregexp, const char *instrume, const char *pipe_id, cpl_boolean(*table_set_row)(cpl_table *, const char *, int, const cpl_frame *, const cpl_parameterlist *), cpl_error_code(*table_check)(cpl_table *, const cpl_frameset *, const cpl_parameterlist *))
Create a DFS product with one table from one or more (ASCII) file(s)
void irplib_framelist_empty(irplib_framelist *self)
Erase all frames from a framelist.
irplib_framelist * irplib_framelist_extract(const irplib_framelist *self, const char *tag)
Extract the frames with the given tag from a framelist.
void irplib_framelist_delete(irplib_framelist *self)
Deallocate an irplib_framelist with its frames and properties.
irplib_framelist * irplib_framelist_cast(const cpl_frameset *frameset)
Create an irplib_framelist from a cpl_framelist.
int irplib_framelist_get_size(const irplib_framelist *self)
Get the size of a framelist.