IIINSTRUMENT Pipeline Reference Manual 4.4.3
visir_util_img_std_cat.c
1/* $Id: visir_util_img_std_cat.c,v 1.58 2012-02-06 10:15:47 llundin Exp $
2 *
3 * This file is part of the VISIR 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: 2012-02-06 10:15:47 $
24 * $Revision: 1.58 $
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 <stdio.h>
37#include <string.h>
38#include <stdbool.h>
39#include <sys/types.h>
40#include <sys/stat.h>
41#include <fcntl.h>
42#include <ctype.h>
43
44#include "visir_recipe.h"
45
46/*-----------------------------------------------------------------------------
47 Defines
48 -----------------------------------------------------------------------------*/
49
50#define RECIPE_STRING "visir_util_img_std_cat"
51
52/*-----------------------------------------------------------------------------
53 Typedefs
54 -----------------------------------------------------------------------------*/
55
56typedef int (procfld_func_t)(const char * src, const int offset, void * extra);
57typedef struct { procfld_func_t * func; void * data; } procfld_ftor_t;
58typedef struct { int * count; double * dest; } scan_in_jansky_args_t;
59typedef struct { char ** dest; } scan_in_filtname_args_t;
60
61typedef struct
62{
63 const char * buf; // the char buffer to operate on (not changed)
64 off_t bufsz; // the number of chars to consume, in total
65 int skipf; // the number of fields to skip before calling ftor
66 int maxf; // the number of fields to (try to) process, after skipf
67 procfld_ftor_t * ftor; // a function to call for each field, after skipf
68} process_fields_args_t;
69
70typedef struct { int sz; double * const head; } darray_t; // array of doubles
71typedef struct { off_t const sz; char const * const head; } carray_t;
72typedef struct { int sz; char ** head; } sarray_t; // array of strings
73
74/*-----------------------------------------------------------------------------
75 Private Functions prototypes
76 -----------------------------------------------------------------------------*/
77
78static
79int visir_util_img_std_cat(cpl_frameset * framelist,
80 const cpl_parameterlist * parlist);
81
82static
83cpl_error_code visir_uisc_save(cpl_frameset *,
84 const cpl_parameterlist * parlist, const cpl_table * tab);
85
86static
87cpl_error_code visir_uisc_parse(carray_t src, char * sname, double * pra,
88 double * pdec, char * stype, darray_t dest);
89
90static
91cpl_error_code visir_uisc_check(cpl_frameset * framelist, sarray_t * filters);
92
93static
94cpl_error_code visir_uisc_flist_read(sarray_t * filts, carray_t src);
95
96static
97void visir_uisc_flist_free(sarray_t * flist);
98
99static
100char * visir_uisc_flist_2_str(sarray_t flist);
101
102static
103int scan_in_jansky(const char * src, const int offset, void * extra);
104
105static
106int scan_in_filtname(const char * src, const int offset, void * extra);
107
108static
109int process_fields(carray_t src, int skipf, int maxf, procfld_ftor_t * ftor);
110
111/*-----------------------------------------------------------------------------
112 Static variables
113 -----------------------------------------------------------------------------*/
114
115VISIR_RECIPE_DEFINE(visir_util_img_std_cat, 0,
116 "Convert ASCII-file(s) to a FITS standard star catalog",
117 "This recipe generates a FITS standard star catalog for imaging from one \n"
118 "or more ASCII-files. Each line in the text file must have at least 8 \n"
119 "fields separated by white-space. The first field is the star name, e.g.\n"
120 "'HD108903' which will be stored in a table column labeled 'STARS'. The \n"
121 "next 3 fields are the RA (hh mm ss) which will be stored in degrees in a\n"
122 "table column labeled 'RA' - all three are non-negative and hh and mm are\n"
123 "integer. The 3 next fields are the DEC (dd mm ss) which will be stored \n"
124 "in degrees in a table column labeled 'DEC' - all three are non-negative,\n"
125 "dd and mm are integer, while dd has either a '+' or a '-' prepended (in-\n"
126 "cluding -00). The next field is the spectral type which will be stored \n"
127 "in a table column labeled 'SP_TYPE'. Every field after the first 8 are \n"
128 "the JY values for the supported filters, and may be a mixture of image \n"
129 "or spectral filters. All JY values must be positive. For each filter \n"
130 "the JY value is stored in a table column labeled with the filter name \n"
131 "taken from the first row of column headings or, if there is no 1st row \n"
132 "of column headings, using a list of 44 filter names hard-coded in the \n"
133 "recipe (in which case the number of JY fields must be exactly 42 or else\n"
134 "an error is printed and execution ends). \n"
135 " \n"
136 "As mentioned, the 1st row may be a list of column headings. If this row\n"
137 "is supplied, the 1st 4 fields will be ignored (but dummy values must be \n"
138 "supplied anyway), and every field after those will be used as the column\n"
139 "label in the output table for that column's JY values. \n"
140 " \n"
141 "Lines beginning with a hash (#) are treated as comments. \n"
142 " \n"
143 "The ASCII-input should be tagged "VISIR_IMG_LINES_ASCII", but all input \n"
144 "files will currently be processed regardless. \n"
145);
146
147const int sanity_check_failed = 0 + CPL_ERROR_EOL;
148
149/*----------------------------------------------------------------------------*/
153/*----------------------------------------------------------------------------*/
154
155/*-----------------------------------------------------------------------------
156 Functions code
157 -----------------------------------------------------------------------------*/
158
159static
160void visir_uisc_flist_free(sarray_t * flist)
161{
162 for (int j = flist->sz; j-- > 0;) {
163 if (!flist->head[j]) continue;
164 cpl_free(flist->head[j]);
165 flist->head[j] = NULL;
166 }
167 if (flist->head) {
168 cpl_free(flist->head);
169 flist->head = NULL;
170 }
171 flist->sz = 0;
172}
173
174/* process whitespace-separated fields in a char buffer (a field starts on the
175 * transition from whitespace to non-whitespace; stops processing after a \n is
176 * hit, or maxf has been reached, or src.sz has been reached, whichever comes
177 * first (src.sz should always be provided otherwise -999 is returned) */
178static
179int process_fields(carray_t src, int skipf, int maxf, procfld_ftor_t * ftor)
180{
181 if (!src.sz) return -999;
182
183 int nfields = -skipf;
184 int ws = 1;
185 off_t i = 0;
186
187 // loop condition below reduces to the following:
188 // i < src.sz && src.head[i] != '\n' // the default
189 // i < src.sz && src.head[i] != '\n' && nfields < maxf // maxf > 0
190 for (; i < src.sz && src.head[i] != '\n' && (!maxf || nfields < maxf); ++i) {
191 if (src.head[i] == ' ' || src.head[i] == '\t') {
192 ws = 1;
193 continue;
194 }
195 if (ws) {
196 // new field detected: call given functor (if any) to process it
197 if (++nfields > 0 && ftor && ftor->func) {
198 // return value ignored for now
199 (void)ftor->func(src.head + i, nfields - 1, ftor->data);
200 }
201 }
202 ws = 0;
203 }
204
205 return nfields;
206}
207
208static
209int scan_in_filtname(const char * src, const int offset, void * extra)
210{
211 scan_in_filtname_args_t * in = extra;
212
213 char tmp[50] = {0};
214 if (EOF == sscanf(src, "%s", tmp)) {
215 cpl_msg_error(cpl_func, "Couldn't read formatted input");
216 return CPL_ERROR_FILE_IO;
217 }
218
219 // capitalise & correct incompat chars in filt name
220 in->dest[offset] = cpl_sprintf("%s", tmp);
221 for (char * p = in->dest[offset]; *p; ++p) {
222 if (*p == '.' || *p == '-') *p = '_';
223 *p = toupper(*p);
224 }
225
226 // "spec", if present, must be in lowercase
227 char * here = strstr(in->dest[offset], "SPEC");
228 if (here) for (char * p = here; *p; ++p) // assumes it's always at the end
229 *p = tolower(*p);
230
231 return CPL_ERROR_NONE;
232}
233
234/* read column headings into filters array */
235static
236cpl_error_code visir_uisc_flist_read(sarray_t * filts, carray_t src)
237{
238 assert(filts->sz); // function assumes size is prepopulated
239
240 // allocate space for & initialise filters array
241 filts->head = cpl_malloc(filts->sz * sizeof(char*));
242 for (int i = filts->sz; i > 0; filts->head[--i] = NULL);
243
244 // populate the array with filter names read in from the file contents
245 scan_in_filtname_args_t fargs = { .dest = filts->head };
246 procfld_ftor_t ftor = { scan_in_filtname, &fargs };
247 int n_fields_read = process_fields(src, 4, filts->sz, &ftor);
248
249 if (n_fields_read < filts->sz) {
250 cpl_msg_error(cpl_func, "buffer had unexpected number of fields");
251 cpl_ensure_code(0, CPL_ERROR_ILLEGAL_INPUT);
252 visir_uisc_flist_free(filts);
253 }
254
255 return cpl_error_get_code();
256}
257
258static
259char * visir_uisc_flist_2_str(sarray_t flist)
260{
261 char * slist = NULL;
262 for (int i = 0; i < flist.sz; ++i) {
263 char * new = cpl_sprintf("%s%s, ", slist ? slist : "", flist.head[i]);
264 if (slist) { cpl_free(slist); slist = NULL; }
265 slist = new;
266 }
267 return slist;
268}
269
270/*----------------------------------------------------------------------------*/
277/*----------------------------------------------------------------------------*/
278static
279cpl_error_code visir_uisc_check(cpl_frameset * framelist, sarray_t * filters)
280{
281 int fd = -1;
282 char * buffer = NULL;
283
284 int prev_data_cols = -1;
285 for (int file = 0; file < cpl_frameset_get_size(framelist); ++file) {
286 const cpl_frame * frame = cpl_frameset_get_position_const(framelist,
287 file);
288 skip_if (cpl_error_get_code() || !frame);
289 const char * fname = cpl_frame_get_filename(frame);
290 skip_if (cpl_error_get_code() || !fname);
291
292 fd = open(fname, O_RDONLY);
293 if (fd == -1) {
294 cpl_msg_error(cpl_func, "Could not open file %d: %s", file + 1,
295 fname);
296 cpl_ensure_code(0, CPL_ERROR_ASSIGNING_STREAM);
297 skip_if (1);
298 }
299
300 struct stat stbuf;
301 bool fail = (fstat(fd, &stbuf) != 0) || (!S_ISREG(stbuf.st_mode));
302 if (fail) {
303 cpl_msg_error(cpl_func, "Could not stat file %d, %s, or it is not a"
304 " regular file", file + 1, fname);
305 cpl_ensure_code(0, CPL_ERROR_FILE_IO);
306 skip_if (1);
307 }
308
309 off_t fsize = stbuf.st_size;
310 buffer = cpl_malloc(fsize);
311 if (!buffer) {
312 cpl_msg_error(cpl_func, "Could not allocate space to hold file "
313 "contents");
314 cpl_ensure_code(0, CPL_ERROR_NULL_INPUT);
315 skip_if (1);
316 }
317
318 off_t count = 0;
319 while (count < fsize) {
320 ssize_t batch = read(fd, buffer+count, fsize);
321 if (batch == -1) {
322 cpl_msg_error(cpl_func, "Error reading from file %d: %s",
323 file + 1, fname);
324 cpl_ensure_code(0, CPL_ERROR_FILE_IO);
325 skip_if (1);
326 }
327 count += batch;
328 }
329
330 if (count != fsize) {
331 cpl_msg_error(cpl_func, "Mismatch in bytes read vs. file size");
332 cpl_ensure_code(0, sanity_check_failed);
333 skip_if (1);
334 }
335
337 //int nlines = 0;
338 //for (off_t i = 0; i < fsize; ++i)
339 // if (buffer[i] == '\n') ++nlines;
340 //if (buffer[fsize - 1] != '\n') ++nlines;
341 //for (off_t i = 0; i < fsize; ++i)
342 // if (i < fsize-1 && buffer[i] == '\n' && buffer[i+1] == '#')
343 // --nlines;
344 //if (buffer[0] == '#') --nlines;
345
346 // find first uncommented line
347 off_t head = 0;
348 for (; head < fsize && buffer[head] == '#'; ++head) {
349 while (head < fsize && buffer[head] != '\n') ++head;
350 if (head >= fsize) break;
351 }
352
353 if (head >= fsize) {
354 cpl_msg_warning(cpl_func, "No uncommented lines in file %d: %s",
355 file + 1, fname);
356 if (buffer) { cpl_free(buffer); buffer = NULL; }
357 if (fd != -1) { close(fd); fd = -1; }
358 continue;
359 }
360
361 // find second uncommented line
362 off_t data = head+1;
363 do {
364 while (data < fsize && buffer[data] != '\n') ++data;
365 if (data >= fsize) break;
366 ++data;
367 } while (data < fsize && buffer[data] == '#');
368
369 if (data >= fsize) {
370 cpl_msg_warning(cpl_func, "There must at least 2 uncommented lines "
371 "in file %d: %s", file + 1, fname);
372 if (buffer) { cpl_free(buffer); buffer = NULL; }
373 if (fd != -1) { close(fd); fd = -1; }
374 continue;
375 }
376
377 carray_t head_src = { fsize - head, buffer + head };
378 carray_t data_src = { fsize - data, buffer + data };
379 int nheads = process_fields(head_src, 0, 0, 0);
380 int ndatas = process_fields(data_src, 0, 0, 0);
381 int diff = ndatas - nheads;
382
383 // data row has the correct # of additional cols
384 if (diff == 4) {
385 int nfilts = nheads - 4;
386
387 // filters found in a prior file: compare with those in this file
388 if (filters->head) {
389 // check that this file has the same number of filters
390 if (nfilts != filters->sz) {
391 cpl_msg_error(cpl_func, "Column headings in file %d, "
392 "%s, don't match a previous file (the "
393 "count differs)", file + 1, fname);
394 cpl_ensure_code(0, CPL_ERROR_BAD_FILE_FORMAT);
395 skip_if (1);
396 }
397
398 // allocate & initialise filters array with column headings
399 sarray_t filts = { nfilts, NULL };
400 skip_if (visir_uisc_flist_read(&filts, head_src));
401
402 for (int i = 0; i < filts.sz; ++i) {
403 if (strcmp(filts.head[i], filters->head[i])) {
404 cpl_msg_error(cpl_func, "Column headings in file %d, "
405 "%s, don't match a previous file (check "
406 "order and spelling)", file + 1, fname);
407 cpl_ensure_code(0, CPL_ERROR_BAD_FILE_FORMAT);
408 visir_uisc_flist_free(&filts);
409 skip_if (1);
410 }
411 }
412
413 visir_uisc_flist_free(&filts);
414 }
415 else {
416 // allocate & initialise filters array with column headings
417 filters->sz = nfilts;
418 skip_if (visir_uisc_flist_read(filters, head_src));
419
420 char * flist = visir_uisc_flist_2_str(*filters);
421 cpl_msg_info(cpl_func, "Found %d filters in file %d, %s, which "
422 "will be used as the column headings in the output "
423 "file. The filters are, in order: %s", nfilts,
424 file + 1, fname, flist);
425 cpl_free(flist);
426 }
427 }
428
429 // same col count in "header" and data row: prob both are data rows
430 else if (diff == 0) {
431 cpl_msg_info(cpl_func, "No filter names in file %d: %s", file + 1,
432 fname);
433 if (filters->head) {
434 if (ndatas-8 != filters->sz) {
435 cpl_msg_error(cpl_func, "Column structure in file %d, %s, "
436 "doesn't match a previous file", file + 1,
437 fname);
438 cpl_ensure_code(0, CPL_ERROR_BAD_FILE_FORMAT);
439 skip_if (1);
440 }
441 }
442 else if (prev_data_cols > -1 && prev_data_cols != ndatas) {
443 cpl_msg_error(cpl_func, "Column structure in file %d, %s, "
444 "doesn't match a previous file (different number "
445 "data columns)", file + 1, fname);
446 cpl_ensure_code(0, CPL_ERROR_BAD_FILE_FORMAT);
447 skip_if (1);
448 }
449 }
450
451 // some other weird configuration exists
452 else {
453 cpl_msg_error(cpl_func, "Unexpected column structure in file %d, "
454 "%s (header row doesn't match data rows, or data "
455 "rows don't match each other)", file + 1, fname);
456 cpl_ensure_code(0, CPL_ERROR_BAD_FILE_FORMAT);
457 skip_if (1);
458 }
459
460 prev_data_cols = ndatas;
461
462 cpl_free(buffer); buffer = NULL;
463 close(fd); fd = -1;
464 }
465
466 // no headers defined after processing all files: use the default list
467 if (!filters->head) {
468 char * defaults[] = {
469 "MV", "N_BAND", "SIC", "PAH1_1", "PAH1", "ARIII", "SIV_1", "SIV",
470 "PAH2_1", "SIV_2", "PAH2", "PAH2_2", "NEII_1", "NEII", "NEII_2",
471 "J7_9", "J8_9", "J9_8", "J12_1", "J12_2", "B8_7", "B9_7", "B10_7",
472 "B11_7", "B12_4", "Q0", "QH2", "Q1", "Q2", "Q3", "Q4", "Q7", "Q8",
473 "12_4_AGP", "10_5_4QP", "11_3_4QP", "N_SW_spec", "H2S4_spec",
474 "ARIII_spec", "NEII_2_spec", "H2S3_spec", "H2S1_spec",
475 "M_BAND", "L_BAND"
476 };
477 filters->sz = sizeof(defaults)/sizeof(char*);
478 filters->head = cpl_malloc(filters->sz * sizeof(char*));
479 for (int i = filters->sz; i-- > 0; )
480 filters->head[i] = cpl_sprintf("%s", defaults[i]);
481
482 prev_data_cols -= 8;
483 if (filters->sz > prev_data_cols) {
484 cpl_msg_error(cpl_func, "Fewer Jansky columns found (%d) than "
485 "there are default filters defined (%d)",
486 prev_data_cols, filters->sz);
487 cpl_ensure_code(0, CPL_ERROR_BAD_FILE_FORMAT);
488 skip_if (1);
489 }
490
491 char * flist = visir_uisc_flist_2_str(*filters);
492 cpl_msg_warning(cpl_func, "*** BIG ASSUMPTION ***: No filter names "
493 "were found in the file(s). Defaulting to a pre-defined set "
494 "and hoping they match the column data found! The default "
495 "filters are, in order: %s", flist);
496 cpl_free(flist);
497 }
498
499 end_skip;
500
501 if (cpl_error_get_code()) visir_uisc_flist_free(filters);
502 if (buffer) cpl_free(buffer);
503 if (fd != -1) close(fd);
504
505 return cpl_error_get_code();
506}
507
508/*----------------------------------------------------------------------------*/
516/*----------------------------------------------------------------------------*/
517static
518int visir_util_img_std_cat(cpl_frameset * framelist,
519 const cpl_parameterlist * parlist)
520{
521 FILE * in = NULL;
522 char line[2048];
523 cpl_table * tab = NULL;
524 char sname[512];
525 char stype[512];
526 const double max_radius = VISIR_STAR_MAX_RADIUS;
527 double mindist;
528 double * jys = NULL;
529 int iloc1, iloc2;
530 int nrows = 425; /* Some positive number */
531 int irow = 0;
532
533
534 if (cpl_error_get_code()) return cpl_error_get_code();
535
536 /* Identify the RAW frames in the input frameset */
537 skip_if (visir_dfs_set_groups(framelist));
538
539 /* check the files for consistency & read in the filters */
540 sarray_t filters = { 0, NULL };
541 skip_if (visir_uisc_check(framelist, &filters));
542 jys = cpl_malloc(filters.sz * sizeof(double));
543
544 /* Create the table */
545 tab = cpl_table_new(nrows);
546 skip_if (cpl_table_new_column(tab, "STARS", CPL_TYPE_STRING));
547 skip_if (cpl_table_new_column(tab, "SP_TYPE", CPL_TYPE_STRING));
548 skip_if (cpl_table_new_column(tab, "RA", CPL_TYPE_DOUBLE));
549 skip_if (cpl_table_new_column(tab, "DEC", CPL_TYPE_DOUBLE));
550
551 for (int j = 0; j < filters.sz; j++)
552 skip_if (cpl_table_new_column(tab, filters.head[j], CPL_TYPE_DOUBLE));
553
554 /* Loop on all input frames */
555 for (int i = 0; i < cpl_frameset_get_size(framelist); i++) {
556 const cpl_frame * frame = cpl_frameset_get_position_const(framelist, i);
557
558 /* Get file name */
559 const char * filename = cpl_frame_get_filename(frame);
560
561 /* Open the file */
562 skip_if (filename == NULL);
563 in = fopen(filename, "r");
564 if (in == NULL) {
565 cpl_msg_error(cpl_func, "Could not open the %d. file: %s", i+1,
566 filename);
567 skip_if (1);
568 }
569
570 int jrow = 0;
571 while (fgets(line, sizeof(line), in) != NULL) {
572 jrow++;
573 if (line[0] != '#') {
574 double ra, dec;
575
576 carray_t src = { sizeof(line), line };
577 darray_t dest = { filters.sz, jys };
578 if (visir_uisc_parse(src, sname, &ra, &dec, stype, dest)) {
579 cpl_msg_warning(cpl_func, "Unparsable line %d in file %d: "
580 "%s (may be header line, or corrupt)", jrow,
581 i+1, filename);
582 cpl_error_reset();
583 --jrow;
584 continue;
585 }
586 if (irow == nrows) {
587 /* Table needs more rows */
588 nrows *= 2;
589 skip_if (cpl_table_set_size(tab, nrows));
590 }
591 skip_if (cpl_table_set_string(tab, "STARS", irow, sname));
592 skip_if (cpl_table_set_string(tab, "SP_TYPE", irow, stype));
593 skip_if (cpl_table_set_double(tab, "RA", irow, ra));
594 skip_if (cpl_table_set_double(tab, "DEC", irow, dec));
595 for (int j = 0; j < filters.sz; j++) skip_if
596 (cpl_table_set_double(tab, filters.head[j], irow, jys[j]));
597 irow++;
598
599 }
600 }
601 fclose(in);
602 in = NULL;
603 if (jrow == 0) {
604 cpl_msg_warning(cpl_func, "No usable lines in file %s", filename);
605 }
606 }
607
608 skip_if (irow == 0);
609
610 /* Resize the table to the actual number of rows read */
611 nrows = irow;
612 skip_if (cpl_table_set_size(tab, nrows));
613
614 mindist = visir_star_dist_min(cpl_table_get_data_double(tab, "RA"),
615 cpl_table_get_data_double(tab, "DEC"), nrows,
616 &iloc1, &iloc2);
617
618 if (mindist < max_radius)
619 cpl_msg_warning(cpl_func, "The pair of closest stars is %s (%d) and %s "
620 "(%d) with the distance: %g",
621 cpl_table_get_string(tab, "STARS", iloc1), iloc1,
622 cpl_table_get_string(tab, "STARS", iloc2), iloc2,
623 mindist);
624 else
625 cpl_msg_info(cpl_func, "The pair of closest stars is %s (%d) and %s "
626 "(%d) with the distance: %g",
627 cpl_table_get_string(tab, "STARS", iloc1), iloc1,
628 cpl_table_get_string(tab, "STARS", iloc2), iloc2,
629 mindist);
630
631 /* Save the table */
632 cpl_msg_info(cpl_func, "Saving the table with %d rows and %d filters",
633 nrows, filters.sz);
634
635 skip_if (visir_uisc_save(framelist, parlist, tab));
636
637 end_skip;
638
639 visir_uisc_flist_free(&filters);
640 if (in) { fclose(in); in = NULL; }
641 if (jys) { cpl_free(jys); jys = NULL; }
642 cpl_table_delete(tab);
643
644 return cpl_error_get_code();
645}
646
647static
648int scan_in_jansky(const char * src, const int offset, void * extra)
649{
650 scan_in_jansky_args_t * in = extra;
651 return *in->count += sscanf(src, "%lg", in->dest + offset);
652}
653
654/*----------------------------------------------------------------------------*/
667/*----------------------------------------------------------------------------*/
668static
669cpl_error_code visir_uisc_parse(carray_t src, char * sname, double * pra,
670 double * pdec, char * stype, darray_t dest)
671{
672 int ra1, ra2;
673 int dec1, dec2;
674 double ra3, dec3;
675 char isign;
676
677 assert( src.head );
678 assert( sname );
679 assert( stype );
680 assert( dest.head );
681
682 // scan in the non-Janksy values
683 const char * format = "%s %d %d %lg %c%d %d %lg %s ";
684 int nvals = sscanf(src.head, format, sname, &ra1, &ra2, &ra3, &isign, &dec1,
685 &dec2, &dec3, stype);
686
687 // scan in the Jansky values
688 scan_in_jansky_args_t fargs = { .count = &nvals, .dest = dest.head };
689 procfld_ftor_t ftor = { scan_in_jansky, &fargs };
690 int nfields = process_fields(src, 8, dest.sz, &ftor);
691
692 if (nvals != dest.sz+9 || nfields < dest.sz) {
693 cpl_msg_warning(cpl_func, "Read %d items from line (length=%u) instead "
694 "of the expected %d items", nvals,
695 (unsigned)strlen(src.head), dest.sz+9);
696 cpl_ensure_code(0, CPL_ERROR_BAD_FILE_FORMAT);
697 return cpl_error_get_code();
698 }
699
700 return visir_star_convert(src.head, ra1, ra2, ra3, isign, dec1, dec2, dec3,
701 dest.head, dest.sz, pra, pdec);
702}
703
704/*----------------------------------------------------------------------------*/
712/*----------------------------------------------------------------------------*/
713static
714cpl_error_code visir_uisc_save(cpl_frameset * set,
715 const cpl_parameterlist * parlist, const cpl_table * tab)
716{
717 cpl_propertylist * applist = cpl_propertylist_new();
718
719
720 bug_if (cpl_propertylist_append_string(applist, "INSTRUME", "VISIR"));
721
722 skip_if (irplib_dfs_save_table(set, parlist, set, tab, NULL, RECIPE_STRING,
723 VISIR_IMA_STD_CAT_PROCATG,
724 applist, NULL, visir_pipe_id,
725 RECIPE_STRING CPL_DFS_FITS));
726
727 end_skip;
728
729 cpl_propertylist_delete(applist);
730
731 return cpl_error_get_code();
732}
733
int visir_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
Definition: visir_dfs.c:72