IIINSTRUMENT Pipeline Reference Manual 4.4.12
naco_util_img_std_cat.c
1/* $Id: naco_util_img_std_cat.c,v 1.13 2013-03-12 08:03:07 llundin Exp $
2 *
3 * This file is part of the NACO Pipeline
4 * Copyright (C) 2002,2003 European Southern Observatory
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
19 */
20
21/*
22 * $Author: llundin $
23 * $Date: 2013-03-12 08:03:07 $
24 * $Revision: 1.13 $
25 * $Name: not supported by cvs2svn $
26 */
27
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31
32/*-----------------------------------------------------------------------------
33 Includes
34 -----------------------------------------------------------------------------*/
35
36#include <string.h>
37
38#include "naco_recipe.h"
39
40#include <irplib_stdstar.h>
41#include <irplib_wcs.h>
42
43/*-----------------------------------------------------------------------------
44 Defines
45 -----------------------------------------------------------------------------*/
46
47#define NFILTERS 8
48
49#define RECIPE_STRING "naco_util_img_std_cat"
50
51/* Largest seen so far is 74 */
52#ifndef NACO_ASCII_MAXLINELEN
53#define NACO_ASCII_MAXLINELEN 1024
54#endif
55
56/*-----------------------------------------------------------------------------
57 Private Functions prototypes
58 -----------------------------------------------------------------------------*/
59
60NACO_RECIPE_DEFINE(naco_util_img_std_cat,
61 0,
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
75 "'.\n"
76 "The Right Ascension must be non-negative and less than "
77 "360.\n"
78 "The next field is the Declination [degrees] which will be "
79 "stored in a table column labeled '" IRPLIB_STDSTAR_DEC_COL
80 "'.\n"
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
84 "'.\n"
85 "The " IRPLIB_STRINGIFY(NFILTERS) " next fields are the "
86 "magnitudes for the " IRPLIB_STRINGIFY(NFILTERS) " supported "
87 "image filters.\n"
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"
94 "\n"
95 "Lines beginning with a hash (#) are treated as comments.\n"
96 "\n"
97 "The files listed in the Set Of Frames (sof-file) "
98 "must be tagged:\n"
99 "NACO-ASCII-file " NACO_IMG_STD_ASCII "\n");
100
101static IRPLIB_UTIL_SET_ROW(naco_util_img_std_set_row);
102static IRPLIB_UTIL_CHECK(naco_util_img_std_check);
103
104static cpl_error_code naco_util_img_std_cat_cmp(const cpl_table *,
105 cpl_boolean *,
106 double, double,
107 const char *,
108 const char *,
109 const char *,
110 int,
111 const double *, double, double);
112
113static double magmin = IRPLIB_STDSTAR_NOMAG;
114static double magmax = -30.0;
115static const char * filters[] = {"J","H", "K", "Ks", "L", "M", "Lp", "Mp"};
116
117/*-----------------------------------------------------------------------------
118 Functions code
119 -----------------------------------------------------------------------------*/
120
121/*----------------------------------------------------------------------------*/
128/*----------------------------------------------------------------------------*/
129static int naco_util_img_std_cat(cpl_frameset * framelist,
130 const cpl_parameterlist * parlist)
131{
132 irplib_framelist * allframes = NULL;
133 irplib_framelist * rawframes = NULL;
134 cpl_frameset * useframes = NULL;
135 cpl_table * self = NULL;
136 int ifilt;
137
138
139 bug_if(sizeof(filters) != NFILTERS * sizeof(char*));
140
141 /* Identify the RAW and CALIB frames in the input frameset */
142 skip_if (naco_dfs_set_groups(framelist));
143
144 /* FIXME: Using framelists is the simplest way to extract the relevant
145 frames :-( */
146 allframes = irplib_framelist_cast(framelist);
147 bug_if(allframes == NULL);
148
149 rawframes = irplib_framelist_extract(allframes, NACO_IMG_STD_ASCII);
150 skip_if(rawframes == NULL);
151
152 irplib_framelist_empty(allframes);
153
154 useframes = irplib_frameset_cast(rawframes);
155 bug_if(allframes == NULL);
156
157 /* At least one row per file */
158 self = cpl_table_new(irplib_framelist_get_size(rawframes));
159
160 irplib_framelist_empty(rawframes);
161
162
163 /* Create the table columns - with units */
164 bug_if (cpl_table_new_column(self, IRPLIB_STDSTAR_STAR_COL,
165 CPL_TYPE_STRING));
166 bug_if (cpl_table_new_column(self, IRPLIB_STDSTAR_TYPE_COL,
167 CPL_TYPE_STRING));
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,
170 CPL_TYPE_DOUBLE));
171 bug_if (cpl_table_new_column(self, IRPLIB_STDSTAR_DEC_COL,
172 CPL_TYPE_DOUBLE));
173
174 bug_if(cpl_table_set_column_unit(self, IRPLIB_STDSTAR_RA_COL,
175 "Degrees"));
176 bug_if(cpl_table_set_column_unit(self, IRPLIB_STDSTAR_DEC_COL,
177 "Degrees"));
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"));
181 }
182
183 skip_if(irplib_dfs_table_convert(self, framelist, useframes,
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));
189
190 end_skip;
191
192 cpl_table_delete(self);
193 cpl_frameset_delete(useframes);
194 irplib_framelist_delete(allframes);
195 irplib_framelist_delete(rawframes);
196
197 return cpl_error_get_code();
198}
199
200/*----------------------------------------------------------------------------*/
220/*----------------------------------------------------------------------------*/
221static cpl_error_code naco_util_img_std_cat_cmp(const cpl_table * self,
222 cpl_boolean * puse,
223 double ra,
224 double dec,
225 const char * sname,
226 const char * stype,
227 const char * cat_name,
228 int irow,
229 const double * mags,
230 double dist_max,
231 double mag_tol)
232{
233
234 const int nfilters = NFILTERS;
235 int j;
236
237 *puse = CPL_FALSE;
238
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);
245
246 for (j = 0; j < irow; j++) {
247 const double raj
248 = cpl_table_get_double(self, IRPLIB_STDSTAR_RA_COL, j, NULL);
249 const double decj
250 = cpl_table_get_double(self, IRPLIB_STDSTAR_DEC_COL, j, NULL);
251 double dist;
252 double mag_max_found = 0;
253 int i;
254
255 if (fabs(decj - dec) > dist_max) continue;
256
257 dist = irplib_wcs_great_circle_dist(ra, dec, raj, decj);
258
259 if (dist > dist_max) continue;
260
261 for (i=0 ; i < nfilters ; i++) {
262 const double mag
263 = cpl_table_get_double(self, filters[i], j, NULL);
264 double mag_dif;
265
266 if (mags[i] > IRPLIB_STDSTAR_LIMIT) continue;
267
268 if (mag > IRPLIB_STDSTAR_LIMIT) break;
269
270 mag_dif = fabs(mags[i] - mag);
271
272 if (mag_dif > mag_tol) break;
273
274 if (mag_dif > mag_max_found) mag_max_found = mag_dif;
275 }
276
277
278 if (i == nfilters) {
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);
286 break;
287 }
288 if (dist > 0.0) {
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);
293 } else {
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);
298 }
299#if 0
300 cpl_table_dump(self, j, 1, stderr);
301 for (i=0 ; i < nfilters ; i++) {
302 const double mag
303 = cpl_table_get_double(self, filters[i], j, NULL);
304 const double mag_dif = fabs(mags[i] - mag);
305
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);
309 }
310#endif
311 }
312
313 if (j == irow) *puse = CPL_TRUE;
314
315 end_skip;
316
317 return CPL_ERROR_NONE;
318
319}
320
321
322/*----------------------------------------------------------------------------*/
331/*----------------------------------------------------------------------------*/
332static
333cpl_error_code naco_util_img_std_check(cpl_table * self,
334 const cpl_frameset * useframes,
335 const cpl_parameterlist * parlist)
336{
337
338 bug_if(0);
339 bug_if(self == NULL);
340 bug_if(parlist == NULL);
341
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));
346
347 end_skip;
348
349 return cpl_error_get_code();
350}
351
352
353/*----------------------------------------------------------------------------*/
376/*----------------------------------------------------------------------------*/
377static cpl_boolean naco_util_img_std_set_row(cpl_table * self,
378 const char * line,
379 int irow,
380 const cpl_frame * rawframe,
381 const cpl_parameterlist * parlist)
382{
383
384 /* gcc can only check sscanf()s format when it is a string literal */
385#define FORMAT "%" CPL_STRINGIFY(NACO_ASCII_MAXLINELEN) "s %lg %lg %" \
386 CPL_STRINGIFY(NACO_ASCII_MAXLINELEN) "s %lg %lg %lg %lg %lg %lg %lg %lg"
387
388 char sname[NACO_ASCII_MAXLINELEN + 1];
389 char stype[NACO_ASCII_MAXLINELEN + 1];
390 double mags[NFILTERS];
391 double ra, dec;
392 int nvals;
393 int ifilt;
394 cpl_boolean use = CPL_FALSE;
395
396 bug_if(0);
397 bug_if(self == NULL);
398 bug_if(line == NULL);
399 bug_if(irow < 0);
400 bug_if(rawframe == NULL);
401 bug_if(parlist == NULL);
402
403 nvals = sscanf(line, FORMAT,
404 sname, &ra, &dec, stype, &(mags[0]), &(mags[1]), &(mags[2]),
405 &(mags[3]), &(mags[4]), &(mags[5]), &(mags[6]), &(mags[7]));
406
407 error_if (nvals != NFILTERS+4, CPL_ERROR_BAD_FILE_FORMAT,
408 "Line with length=%u has %d not 4+" IRPLIB_STRINGIFY(NFILTERS)
409 " items formatted: %s", (unsigned)strlen(line), nvals, FORMAT);
410
411 error_if (ra < 0.0, CPL_ERROR_BAD_FILE_FORMAT,
412 "Negative RA=%g in line %s", ra, line);
413
414 error_if (ra >=360.0, CPL_ERROR_BAD_FILE_FORMAT,
415 "RA=%g is not less than 360 in line %s", ra, line);
416
417 error_if (dec < -90.0, CPL_ERROR_BAD_FILE_FORMAT,
418 "DEC=%g is not at least -90 in line %s", dec, line);
419
420 error_if (dec > 90.0, CPL_ERROR_BAD_FILE_FORMAT,
421 "DEC=%g is not at most 90 in line %s", dec, line);
422
423 for (ifilt=0 ; ifilt < NFILTERS; ifilt++) {
424 if (mags[ifilt] < IRPLIB_STDSTAR_LIMIT) break;
425 }
426
427 if (ifilt == NFILTERS) {
428 cpl_msg_debug(cpl_func, "Not setting row without a valid magnitude: "
429 "(%d)", 1+irow);
430 } else {
431 const char * rawfile = cpl_frame_get_filename(rawframe);
432 /* Skip path, if any */
433 const char * cat_name = strrchr(rawfile, '/');
434
435 cat_name = cat_name ? 1+cat_name : rawfile;
436
437 bug_if(cat_name == NULL);
438
439 skip_if(naco_util_img_std_cat_cmp(self, &use, ra, dec, sname,
440 stype, cat_name, irow,
441 mags, 0.25e-4, 1e-6));
442
443 if (use) {
444 bug_if (cpl_table_set_string(self, IRPLIB_STDSTAR_STAR_COL, irow,
445 sname));
446
447 bug_if (cpl_table_set_string(self, "CAT_NAME", irow, cat_name));
448
449 bug_if (cpl_table_set_string(self, IRPLIB_STDSTAR_TYPE_COL, irow,
450 stype));
451
452 bug_if (cpl_table_set_double(self, IRPLIB_STDSTAR_RA_COL, irow,
453 ra));
454
455 bug_if (cpl_table_set_double(self, IRPLIB_STDSTAR_DEC_COL, irow,
456 dec));
457
458 for (ifilt=0 ; ifilt < NFILTERS; ifilt++) {
459 if (mags[ifilt] > 27.0 && mags[ifilt] < IRPLIB_STDSTAR_LIMIT) {
460 /* 27 is about the limit of the UT */
461 cpl_msg_warning(cpl_func, "Setting faint (mag=%g) object "
462 "(Filter-%s) in table row %d", mags[ifilt],
463 filters[ifilt], 1+irow);
464 }
465 if (mags[ifilt] > magmax && mags[ifilt] < IRPLIB_STDSTAR_LIMIT)
466 magmax = mags[ifilt];
467 if (mags[ifilt] < magmin) magmin = mags[ifilt];
468 bug_if(cpl_table_set_double(self, filters[ifilt], irow,
469 mags[ifilt]));
470 }
471 }
472 }
473
474 end_skip;
475
476 return use;
477
478}
int naco_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
Definition: naco_dfs.c:62