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