1
/* This file, getcols.c, contains routines that read data elements from */
2
/* a FITS image or table, with a character string datatype. */
4
/* The FITSIO software was written by William Pence at the High Energy */
5
/* Astrophysic Science Archive Research Center (HEASARC) at the NASA */
6
/* Goddard Space Flight Center. */
10
/* stddef.h is apparently needed to define size_t */
14
/*--------------------------------------------------------------------------*/
15
int ffgcvs( fitsfile *fptr, /* I - FITS file pointer */
16
int colnum, /* I - number of column to read (1 = 1st col) */
17
long firstrow, /* I - first row to read (1 = 1st row) */
18
long firstelem, /* I - first vector element to read (1 = 1st) */
19
long nelem, /* I - number of strings to read */
20
char *nulval, /* I - string for null pixels */
21
char **array, /* O - array of values that are read */
22
int *anynul, /* O - set to 1 if any values are null; else 0 */
23
int *status) /* IO - error status */
25
Read an array of string values from a column in the current FITS HDU.
26
Any undefined pixels will be set equal to the value of 'nulval' unless
27
nulval = null in which case no checks for undefined pixels will be made.
32
ffgcls(fptr, colnum, firstrow, firstelem, nelem, 1, nulval,
33
array, cdummy, anynul, status);
36
/*--------------------------------------------------------------------------*/
37
int ffgcfs( fitsfile *fptr, /* I - FITS file pointer */
38
int colnum, /* I - number of column to read (1 = 1st col) */
39
long firstrow, /* I - first row to read (1 = 1st row) */
40
long firstelem, /* I - first vector element to read (1 = 1st) */
41
long nelem, /* I - number of strings to read */
42
char **array, /* O - array of values that are read */
43
char *nularray, /* O - array of flags = 1 if nultyp = 2 */
44
int *anynul, /* O - set to 1 if any values are null; else 0 */
45
int *status) /* IO - error status */
47
Read an array of string values from a column in the current FITS HDU.
48
Nularray will be set = 1 if the corresponding array pixel is undefined,
49
otherwise nularray will = 0.
54
ffgcls(fptr, colnum, firstrow, firstelem, nelem, 2, dummy,
55
array, nularray, anynul, status);
58
/*--------------------------------------------------------------------------*/
59
int ffgcls( fitsfile *fptr, /* I - FITS file pointer */
60
int colnum, /* I - number of column to read (1 = 1st col) */
61
long firstrow, /* I - first row to read (1 = 1st row) */
62
long firstelem, /* I - first vector element to read (1 = 1st) */
63
long nelem, /* I - number of strings to read */
64
int nultyp, /* I - null value handling code: */
65
/* 1: set undefined pixels = nulval */
66
/* 2: set nularray=1 for undefined pixels */
67
char *nulval, /* I - value for null pixels if nultyp = 1 */
68
char **array, /* O - array of values that are read */
69
char *nularray, /* O - array of flags = 1 if nultyp = 2 */
70
int *anynul, /* O - set to 1 if any values are null; else 0 */
71
int *status) /* IO - error status */
73
Read an array of string values from a column in the current FITS HDU.
74
Returns a formated string value, regardless of the datatype of the column
77
int tcode, hdutype, tstatus, scaled, intcol, dwidth;
80
char message[FLEN_ERRMSG], *carray, keyname[FLEN_KEYWORD];
81
char cform[20], dispfmt[20], tmpstr[80];
83
double *darray, tscale = 1.0;
85
if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */
88
/* reset position to the correct HDU if necessary */
89
if (fptr->HDUposition != (fptr->Fptr)->curhdu)
90
ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
92
/* rescan header if data structure is undefined */
93
else if ((fptr->Fptr)->datastart == DATA_UNDEFINED)
94
if ( ffrdef(fptr, status) > 0)
97
if (colnum < 1 || colnum > (fptr->Fptr)->tfield)
99
sprintf(message, "Specified column number is out of range: %d",
102
return(*status = BAD_COL_NUM);
105
colptr = (fptr->Fptr)->tableptr; /* point to first column */
106
colptr += (colnum - 1); /* offset to correct column structure */
107
tcode = abs(colptr->tdatatype);
109
if (tcode == TSTRING)
111
/* simply call the string column reading routine */
112
ffgcls2(fptr, colnum, firstrow, firstelem, nelem, nultyp, nulval,
113
array, nularray, anynul, status);
115
else if (tcode == TLOGICAL)
117
/* allocate memory for the array of logical values */
118
carray = (char *) malloc(nelem);
120
/* call the logical column reading routine */
121
ffgcll(fptr, colnum, firstrow, firstelem, nelem, nultyp, *nulval,
122
carray, nularray, anynul, status);
126
/* convert logical values to "T", "F", or "N" (Null) */
127
for (ii = 0; ii < nelem; ii++)
130
strcpy(array[ii], "T");
131
else if (carray[ii] == 0)
132
strcpy(array[ii], "F");
133
else /* undefined values = 2 */
134
strcpy(array[ii],"N");
138
free(carray); /* free the memory */
140
else if (tcode == TCOMPLEX)
142
/* allocate memory for the array of double values */
143
earray = (float *) calloc(nelem * 2, sizeof(float) );
145
ffgcle(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2,
146
1, 1, FLOATNULLVALUE, earray, nularray, anynul, status);
151
/* determine the format for the output strings */
153
ffgcdw(fptr, colnum, &dwidth, status);
154
dwidth = (dwidth - 3) / 2;
156
/* use the TDISPn keyword if it exists */
157
ffkeyn("TDISP", colnum, keyname, status);
161
if (ffgkys(fptr, keyname, dispfmt, NULL, &tstatus) == 0)
163
/* convert the Fortran style format to a C style format */
164
ffcdsp(dispfmt, cform);
168
strcpy(cform, "%14.6E");
170
/* write the formated string for each value: "(real,imag)" */
172
for (ii = 0; ii < nelem; ii++)
174
strcpy(array[ii], "(");
176
/* test for null value */
177
if (earray[jj] == FLOATNULLVALUE)
179
strcpy(tmpstr, "NULL");
184
sprintf(tmpstr, cform, earray[jj]);
186
strncat(array[ii], tmpstr, dwidth);
187
strcat(array[ii], ",");
190
/* test for null value */
191
if (earray[jj] == FLOATNULLVALUE)
193
strcpy(tmpstr, "NULL");
198
sprintf(tmpstr, cform, earray[jj]);
200
strncat(array[ii], tmpstr, dwidth);
201
strcat(array[ii], ")");
206
free(earray); /* free the memory */
208
else if (tcode == TDBLCOMPLEX)
210
/* allocate memory for the array of double values */
211
darray = (double *) calloc(nelem * 2, sizeof(double) );
213
ffgcld(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2,
214
1, 1, DOUBLENULLVALUE, darray, nularray, anynul, status);
218
/* determine the format for the output strings */
220
ffgcdw(fptr, colnum, &dwidth, status);
221
dwidth = (dwidth - 3) / 2;
223
/* use the TDISPn keyword if it exists */
224
ffkeyn("TDISP", colnum, keyname, status);
228
if (ffgkys(fptr, keyname, dispfmt, NULL, &tstatus) == 0)
230
/* convert the Fortran style format to a C style format */
231
ffcdsp(dispfmt, cform);
235
strcpy(cform, "%23.15E");
237
/* write the formated string for each value: "(real,imag)" */
239
for (ii = 0; ii < nelem; ii++)
241
strcpy(array[ii], "(");
243
/* test for null value */
244
if (darray[jj] == DOUBLENULLVALUE)
246
strcpy(tmpstr, "NULL");
251
sprintf(tmpstr, cform, darray[jj]);
253
strncat(array[ii], tmpstr, dwidth);
254
strcat(array[ii], ",");
257
/* test for null value */
258
if (darray[jj] == DOUBLENULLVALUE)
260
strcpy(tmpstr, "NULL");
265
sprintf(tmpstr, cform, darray[jj]);
267
strncat(array[ii], tmpstr, dwidth);
268
strcat(array[ii], ")");
273
free(darray); /* free the memory */
277
/* allocate memory for the array of double values */
278
darray = (double *) calloc(nelem, sizeof(double) );
280
/* read all other numeric type columns as doubles */
281
if (ffgcld(fptr, colnum, firstrow, firstelem, nelem, 1, nultyp,
282
DOUBLENULLVALUE, darray, nularray, anynul, status) > 0)
288
/* determine the format for the output strings */
290
ffgcdw(fptr, colnum, &dwidth, status);
292
/* check if column is scaled */
293
ffkeyn("TSCAL", colnum, keyname, status);
296
if (ffgkyd(fptr, keyname, &tscale, NULL, &tstatus) == 0)
299
scaled = 1; /* yes, this is a scaled column */
303
if (tcode <= TLONG && !scaled)
304
intcol = 1; /* this is an unscaled integer column */
306
/* use the TDISPn keyword if it exists */
307
ffkeyn("TDISP", colnum, keyname, status);
311
if (ffgkys(fptr, keyname, dispfmt, NULL, &tstatus) == 0)
313
/* convert the Fortran style TDISPn to a C style format */
314
ffcdsp(dispfmt, cform);
319
/* no TDISPn keyword; use TFORMn instead */
321
ffkeyn("TFORM", colnum, keyname, status);
322
ffgkys(fptr, keyname, dispfmt, NULL, status);
324
if (scaled && tcode <= TSHORT)
326
/* scaled short integer column == float */
327
strcpy(cform, "%14.6G");
329
else if (scaled && tcode == TLONG)
331
/* scaled long integer column == double */
332
strcpy(cform, "%23.15G");
336
ffghdt(fptr, &hdutype, status);
337
if (hdutype == ASCII_TBL)
339
/* convert the Fortran style TFORMn to a C style format */
340
ffcdsp(dispfmt, cform);
344
/* this is a binary table, need to convert the format */
345
if (tcode <= TBYTE) /* 'X' and 'B' */
346
strcpy(cform, "%4d");
347
else if (tcode == TSHORT) /* 'I' */
348
strcpy(cform, "%6d");
349
else if (tcode == TLONG) /* 'J' */
350
strcpy(cform, "%11d");
351
else if (tcode == TFLOAT) /* 'E' */
352
strcpy(cform, "%14.6E");
353
else if (tcode == TDOUBLE) /* 'D' */
354
strcpy(cform, "%23.15E");
359
/* write the formated string for each value */
360
for (ii = 0; ii < nelem; ii++)
362
/* test for null value */
363
if ( (nultyp == 1 && darray[ii] == DOUBLENULLVALUE) ||
364
(nultyp == 2 && nularray[ii]) )
367
strncat(array[ii], "NULL", dwidth);
372
sprintf(tmpstr, cform, (int) darray[ii]);
374
sprintf(tmpstr, cform, darray[ii]);
377
strncat(array[ii], tmpstr, dwidth);
381
free(darray); /* free the memory */
385
/*--------------------------------------------------------------------------*/
386
int ffgcdw( fitsfile *fptr, /* I - FITS file pointer */
387
int colnum, /* I - number of column (1 = 1st col) */
388
int *width, /* O - display width */
389
int *status) /* IO - error status */
391
Get Column Display Width.
396
char message[FLEN_ERRMSG], keyname[FLEN_KEYWORD], dispfmt[20];
397
int tcode, hdutype, tstatus, scaled;
400
if (*status > 0) /* inherit input status value if > 0 */
403
if (fptr->HDUposition != (fptr->Fptr)->curhdu)
404
ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
406
if (colnum < 1 || colnum > (fptr->Fptr)->tfield)
408
sprintf(message, "Specified column number is out of range: %d",
411
return(*status = BAD_COL_NUM);
414
colptr = (fptr->Fptr)->tableptr; /* point to first column */
415
colptr += (colnum - 1); /* offset to correct column structure */
416
tcode = abs(colptr->tdatatype);
418
/* use the TDISPn keyword if it exists */
419
ffkeyn("TDISP", colnum, keyname, status);
423
if (ffgkys(fptr, keyname, dispfmt, NULL, &tstatus) == 0)
425
/* parse TDISPn get the display width */
427
while(*cptr == ' ') /* skip leading blanks */
430
if (*cptr == 'A' || *cptr == 'a' ||
431
*cptr == 'I' || *cptr == 'i' ||
432
*cptr == 'O' || *cptr == 'o' ||
433
*cptr == 'Z' || *cptr == 'z' ||
434
*cptr == 'F' || *cptr == 'f' ||
435
*cptr == 'E' || *cptr == 'e' ||
436
*cptr == 'D' || *cptr == 'd' ||
437
*cptr == 'G' || *cptr == 'g')
440
while(!isdigit((int) *cptr) && *cptr != '\0') /* find 1st digit */
444
if (tcode >= TCOMPLEX)
445
*width = (2 * (*width)) + 3;
451
/* no valid TDISPn keyword; use TFORMn instead */
453
ffkeyn("TFORM", colnum, keyname, status);
454
ffgkys(fptr, keyname, dispfmt, NULL, status);
456
/* check if column is scaled */
457
ffkeyn("TSCAL", colnum, keyname, status);
461
if (ffgkyd(fptr, keyname, &tscale, NULL, &tstatus) == 0)
464
scaled = 1; /* yes, this is a scaled column */
467
if (scaled && tcode <= TSHORT)
469
/* scaled short integer col == float; default format is 14.6E */
472
else if (scaled && tcode == TLONG)
474
/* scaled long integer col == double; default format is 23.15E */
479
ffghdt(fptr, &hdutype, status); /* get type of table */
480
if (hdutype == ASCII_TBL)
482
/* parse TFORMn get the display width */
484
while(!isdigit((int) *cptr) && *cptr != '\0') /* find 1st digit */
491
/* this is a binary table */
492
if (tcode <= TBYTE) /* 'X' and 'B' */
494
else if (tcode == TSHORT) /* 'I' */
496
else if (tcode == TLONG) /* 'J' */
498
else if (tcode == TFLOAT) /* 'E' */
500
else if (tcode == TDOUBLE) /* 'D' */
502
else if (tcode == TCOMPLEX) /* 'C' */
504
else if (tcode == TDBLCOMPLEX) /* 'M' */
506
else if (tcode == TLOGICAL) /* 'L' */
508
else if (tcode == TSTRING) /* 'A' */
511
while(!isdigit((int) *cptr) && *cptr != '\0')
521
/*--------------------------------------------------------------------------*/
522
int ffgcls2 ( fitsfile *fptr, /* I - FITS file pointer */
523
int colnum, /* I - number of column to read (1 = 1st col) */
524
long firstrow, /* I - first row to read (1 = 1st row) */
525
long firstelem, /* I - first vector element to read (1 = 1st) */
526
long nelem, /* I - number of strings to read */
527
int nultyp, /* I - null value handling code: */
528
/* 1: set undefined pixels = nulval */
529
/* 2: set nularray=1 for undefined pixels */
530
char *nulval, /* I - value for null pixels if nultyp = 1 */
531
char **array, /* O - array of values that are read */
532
char *nularray, /* O - array of flags = 1 if nultyp = 2 */
533
int *anynul, /* O - set to 1 if any values are null; else 0 */
534
int *status) /* IO - error status */
536
Read an array of string values from a column in the current FITS HDU.
540
int tcode, maxelem, hdutype, nulcheck;
541
long twidth, incre, rownum;
542
long ii, jj, ntodo, tnull, remain, next;
543
OFF_T repeat, startpos, elemnum, readptr, rowlen;
546
char message[FLEN_ERRMSG];
547
char snull[20]; /* the FITS null value */
550
double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */
551
char *buffer, *arrayptr;
553
if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */
556
if (fptr->HDUposition != (fptr->Fptr)->curhdu)
557
ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
563
memset(nularray, 0, nelem); /* initialize nullarray */
565
/*---------------------------------------------------*/
566
/* Check input and get parameters about the column: */
567
/*---------------------------------------------------*/
568
if (colnum < 1 || colnum > (fptr->Fptr)->tfield)
570
sprintf(message, "Specified column number is out of range: %d",
573
return(*status = BAD_COL_NUM);
576
colptr = (fptr->Fptr)->tableptr; /* point to first column */
577
colptr += (colnum - 1); /* offset to correct column structure */
578
tcode = colptr->tdatatype;
580
if (tcode == -TSTRING) /* variable length column in a binary table? */
582
/* only read a single string; ignore value of firstelem */
584
if (ffgcpr( fptr, colnum, firstrow, 1, 1, 0, &scale, &zero,
585
tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre,
586
&repeat, &rowlen, &hdutype, &tnull, snull, status) > 0)
592
else if (tcode == TSTRING)
594
if (ffgcpr( fptr, colnum, firstrow, firstelem, nelem, 0, &scale, &zero,
595
tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre,
596
&repeat, &rowlen, &hdutype, &tnull, snull, status) > 0)
602
return(*status = NOT_ASCII_COL);
604
nullen = strlen(snull); /* length of the undefined pixel string */
608
/*------------------------------------------------------------------*/
609
/* Decide whether to check for null values in the input FITS file: */
610
/*------------------------------------------------------------------*/
611
nulcheck = nultyp; /* by default check for null values in the FITS file */
613
if (nultyp == 1 && nulval[0] == 0)
614
nulcheck = 0; /* calling routine does not want to check for nulls */
616
else if (snull[0] == ASCII_NULL_UNDEFINED)
617
nulcheck = 0; /* null value string in ASCII table not defined */
619
else if (nullen > twidth)
620
nulcheck = 0; /* null value string is longer than width of column */
621
/* thus impossible for any column elements to = null */
623
/*---------------------------------------------------------------------*/
624
/* Now read the strings one at a time from the FITS column. */
625
/*---------------------------------------------------------------------*/
626
next = 0; /* next element in array to be read */
627
rownum = 0; /* row number, relative to firstrow */
631
/* limit the number of pixels to process a one time to the number that
632
will fit in the buffer space or to the number of pixels that remain
633
in the current vector, which ever is smaller.
635
ntodo = minvalue(remain, maxelem);
636
ntodo = minvalue(ntodo, (repeat - elemnum));
638
readptr = startpos + ((OFF_T)rownum * rowlen) + (elemnum * incre);
639
ffmbyt(fptr, readptr, REPORT_EOF, status); /* move to read position */
641
/* read the array of strings from the FITS file into the buffer */
644
ffgbyt(fptr, ntodo * twidth, cbuff, status);
646
ffgbytoff(fptr, twidth, ntodo, incre - twidth, cbuff, status);
648
/* copy from the buffer into the user's array of strings */
649
/* work backwards from last char of last string to 1st char of 1st */
651
buffer = ((char *) cbuff) + (ntodo * twidth) - 1;
653
for (ii = next + ntodo - 1; ii >= next; ii--)
655
arrayptr = array[ii] + twidth - 1;
657
for (jj = twidth - 1; jj > 0; jj--) /* ignore trailing blanks */
667
*(arrayptr + 1) = 0; /* write the string terminator */
669
for (; jj >= 0; jj--) /* copy the string itself */
676
/* check if null value is defined, and if the */
677
/* column string is identical to the null string */
678
if (nulcheck && !strncmp(snull, array[ii], nullen) )
680
*anynul = 1; /* this is a null value */
682
strcpy(array[ii], nulval);
688
if (*status > 0) /* test for error during previous read operation */
691
"Error reading elements %ld thru %ld of data array (ffpcls).",
698
/*--------------------------------------------*/
699
/* increment the counters for the next loop */
700
/*--------------------------------------------*/
706
if (elemnum == repeat) /* completed a row; start on next row */
712
} /* End of main while Loop */