Loading [MathJax]/extensions/TeX/AMSsymbols.js
LALPulsar 7.1.1.1-5e288d3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
FITSFileIO.c
Go to the documentation of this file.
1//
2// Copyright (C) 2016 Karl Wette
3//
4// This program is free software; you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation; either version 2 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with with program; see the file COPYING. If not, write to the
16// Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17// MA 02110-1301 USA
18//
19
20#include <config.h>
21#include <stdlib.h>
22#include <stdio.h>
23#include <errno.h>
24#include <string.h>
25#include <ctype.h>
26#include <math.h>
27#include <limits.h>
28#include <float.h>
29
30#if defined(HAVE_LIBCFITSIO)
31
32// disable -Wstrict-prototypes flag for this header file as this causes
33// a build failure for cfitsio-3.440+
34#pragma GCC diagnostic ignored "-Wstrict-prototypes"
35#include <fitsio.h>
36#pragma GCC diagnostic pop
37
38// If fffree() is missing, use free() instead
39#if !defined(HAVE_FFFREE)
40#undef fits_free_memory
41#define fits_free_memory(ptr, status) free(ptr)
42
43// If ffree() is present but not declared, declare it
44#elif defined(HAVE_DECL_FFFREE) && !HAVE_DECL_FFFREE
45int fffree( void *, int * );
46#undef fits_free_memory
47#define fits_free_memory fffree
48
49#endif // ffree()
50
51#endif // defined(HAVE_LIBCFITSIO)
52
53#include <lal/FITSFileIO.h>
54#include <lal/LALString.h>
55#include <lal/StringVector.h>
56#include <lal/Date.h>
57#include <lal/UserInput.h>
58#include <lal/GSLHelpers.h>
59
60#if defined(__GNUC__)
61#define UNUSED __attribute__ ((unused))
62#else
63#define UNUSED
64#endif
65
66#if defined(HAVE_LIBCFITSIO)
67
68// Convenience macros for CFITSIO error checking
69#define CHECK_FITS_VAL(errnum, function) \
70 do { \
71 if (status != 0) { \
72 CHAR _check_fits_buf_[FLEN_STATUS + FLEN_ERRMSG]; \
73 fits_get_errstatus(status, _check_fits_buf_); \
74 XLAL_PRINT_ERROR("%s() failed: %s", #function, _check_fits_buf_); \
75 while (fits_read_errmsg(_check_fits_buf_) > 0) { \
76 XLAL_PRINT_ERROR("%s() error: %s", #function, _check_fits_buf_); \
77 } \
78 XLAL_ERROR_FAIL(errnum); \
79 } \
80 } while(0)
81#define CHECK_FITS(function) \
82 CHECK_FITS_VAL(XLAL_EIO, function)
83#define CALL_FITS_VAL(errnum, function, ...) \
84 do { \
85 function(__VA_ARGS__, &status); \
86 CHECK_FITS_VAL(errnum, function); \
87 } while(0)
88#define CALL_FITS(function, ...) \
89 CALL_FITS_VAL(XLAL_EIO, function, __VA_ARGS__)
90
91// Internal representation of a FITS file opened for reading or writing
92struct tagFITSFile {
93 fitsfile *ff; // Pointer to a CFITSIO FITS file representation
94 int write; // True if the file is open for writing (otherwise reading)
95 int hdutype; // Type of current HDU
96 CHAR hduname[FLEN_VALUE]; // Name of current HDU
97 CHAR hducomment[FLEN_COMMENT]; // Comment for name of current HDU
98 struct { // Parameters of current array
99 int naxis; // Number of dimensions of array
100 long naxes[FFIO_MAX]; // Size of dimensions of array
101 int bitpix; // Bits per pixel of array
102 int datatype; // Datatype of array
103 size_t size; // Number of bytes in element of array
104 } array;
105 struct { // Parameters of current table
106 int tfields; // Number of columns in table
107 size_t field_size[FFIO_MAX]; // Sizes of fields in table row record
108 size_t noffsets[FFIO_MAX]; // Number of nested offsets to field in table row record
109 size_t offsets[FFIO_MAX][2]; // List of nested offsets to field in table row record
110 CHAR ttype[FFIO_MAX][FLEN_VALUE]; // Names of columns in table
111 CHAR tform[FFIO_MAX][FLEN_VALUE]; // Format of columns in table
112 CHAR tunit[FFIO_MAX][FLEN_VALUE]; // Units of columns in table
113 int colnum[FFIO_MAX]; // Index of columns in table
114 int datatype[FFIO_MAX]; // Datatype of columns in table
115 LONGLONG nelements[FFIO_MAX]; // Number of elements in columns in table
116 LONGLONG nrows; // Number of rows in table
117 LONGLONG irow; // Index of current row in table
118 } table;
119 char *buf; // Buffer for reading/writing table columns
120 size_t buf_size; // Current length of the buffer
121};
122
123///
124/// Write a formatted string to a FITS file using the given function
125///
126static int WriteFormattedString( FITSFile *file, const CHAR *format, va_list ap, int ( *fcn )( fitsfile *, const char *, int * ) )
127{
128
129 int UNUSED status = 0;
130
131 // Check input
132 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
134 XLAL_CHECK_FAIL( fcn != NULL, XLAL_EFAULT );
135
136 // Format the string
137 CHAR buf[4096];
138 XLAL_CHECK_FAIL( vsnprintf( buf, sizeof( buf ), format, ap ) < ( int )sizeof( buf ), XLAL_EERR, "Formatted string is too long" );
139
140 // Split the string by newlines, removing any empty lines
141 CHAR *p = buf;
142 CHAR *t = XLALStringToken( &p, "\n", 0 );
143 while ( t != NULL ) {
144
145 // Replace any nonprintable characters with spaces
146 for ( CHAR *u = t; *u != '\0'; ++u ) {
147 if ( !isprint( *u ) ) {
148 *u = ' ';
149 }
150 }
151
152 // Write the string
153 CALL_FITS( fcn, file->ff, t );
154
155 t = XLALStringToken( &p, "\n", 0 );
156 }
157
158 return XLAL_SUCCESS;
159
160XLAL_FAIL:
161 return XLAL_FAILURE;
162
163}
164
165///
166/// Extract unit from a keyword or column name
167///
168static int ExtractUnit( const CHAR *name_unit, CHAR *name, CHAR *unit )
169{
170
171 int UNUSED status = 0;
172
173 // Check input
174 XLAL_CHECK_FAIL( name_unit != NULL, XLAL_EFAULT );
175
176 // Copy name, possibly with unit
177 strcpy( name, name_unit );
178
179 // If name contains a unit, extract it, and remove unit and any trailing whitespace from name
180 if ( unit != NULL ) {
181 unit[0] = '\0';
182 CHAR *unit_start = strchr( name, '[' );
183 if ( unit_start != NULL ) {
184 CHAR *unit_end = strchr( unit_start, ']' );
185 XLAL_CHECK_FAIL( unit_end != NULL, XLAL_EINVAL, "Invalid unit in '%s'", name );
186 XLAL_CHECK_FAIL( unit_end - unit_start - 1 < FLEN_VALUE, XLAL_EINVAL, "Unit in '%s' are too long", name );
187 *unit_start = *unit_end = '\0';
188 strcpy( unit, unit_start + 1 );
189 while ( --unit_start > name && isspace( *unit_start ) ) {
190 *unit_start = '\0';
191 }
192 }
193 }
194
195 return XLAL_SUCCESS;
196
197XLAL_FAIL:
198 return XLAL_FAILURE;
199
200}
201
202///
203/// Format and check a FITS keyword
204///
205static int CheckFITSKeyword( const CHAR *key, CHAR *keyword, CHAR *unit )
206{
207
208 int UNUSED status = 0;
209
210 // Check input
211 XLAL_CHECK_FAIL( key != NULL, XLAL_EFAULT );
212 XLAL_CHECK_FAIL( strlen( key ) < FLEN_KEYWORD, XLAL_EINVAL, "Key '%s' is too long", key );
213 XLAL_CHECK_FAIL( keyword != NULL, XLAL_EFAULT );
214
215 // Extract unit
216 XLAL_CHECK_FAIL( ExtractUnit( key, keyword, unit ) == XLAL_SUCCESS, XLAL_EINVAL );
217
218 // Force keyword to upper case
219 XLALStringToUpperCase( keyword );
220
221 if ( strlen( keyword ) <= 8 && strchr( keyword, ' ' ) == NULL ) {
222
223 // Test for compliant FITS keyword
224 CALL_FITS( fits_test_keyword, keyword );
225
226 } else {
227
228 // Format a hierarchical FITS keyword
229 XLAL_CHECK_FAIL( 9 + strlen( keyword ) < FLEN_KEYWORD, XLAL_EINVAL, "Key '%s' is too long", keyword );
230 CHAR buf[FLEN_KEYWORD - 9];
231 strncpy( buf, keyword, sizeof( buf ) );
232 snprintf( keyword, FLEN_KEYWORD, "HIERARCH %s", buf );
233
234 }
235
236 return XLAL_SUCCESS;
237
238XLAL_FAIL:
239 return XLAL_FAILURE;
240
241}
242
243#endif // defined(HAVE_LIBCFITSIO)
244
246{
247#if !defined(HAVE_LIBCFITSIO)
248 XLAL_ERROR_VOID( XLAL_EFAILED, "CFITSIO is not available" );
249#else // defined(HAVE_LIBCFITSIO)
250
251 int UNUSED status = 0;
252 if ( file != NULL ) {
253 if ( file->ff != NULL ) {
254 fits_close_file( file->ff, &status );
255 }
256 XLALFree( file->buf );
257 XLALFree( file );
258 }
259
260#endif // !defined(HAVE_LIBCFITSIO)
261}
262
263FITSFile *XLALFITSFileOpenWrite( const CHAR UNUSED *file_name )
264{
265#if !defined(HAVE_LIBCFITSIO)
266 XLAL_ERROR_NULL( XLAL_EFAILED, "CFITSIO is not available" );
267#else // defined(HAVE_LIBCFITSIO)
268
269 int UNUSED status = 0;
270 FITSFile *file = NULL;
271 CHAR *url = NULL;
272
273 // Check input
275
276 // Create FITSFile struct
277 file = XLALCalloc( 1, sizeof( *file ) );
278 XLAL_CHECK_FAIL( file != NULL, XLAL_ENOMEM );
279
280 // Set FITSFile fields
281 file->write = 1;
282
283 // Create FITS file URL which will overwrite any existing file
284 url = XLALStringAppendFmt( NULL, "!file://%s", file_name );
285 XLAL_CHECK_FAIL( url != NULL, XLAL_EFUNC );
286
287 // Open FITS file for writing
288 CALL_FITS_VAL( XLAL_ESYS, fits_create_file, &file->ff, url );
289
290 // By convention, create an empty image for the first HDU,
291 // so that the correct FITS header 'SIMPLE = T' is written
292 CALL_FITS( fits_create_img, file->ff, SHORT_IMG, 0, NULL );
293 file->hdutype = INT_MAX;
294
295 // Write warning for FITS long string keyword convention
296 CALL_FITS( fits_write_key_longwarn, file->ff );
297
298 // Write the current system date to the FITS file
299 CALL_FITS( fits_write_date, file->ff );
300
301 XLALFree( url );
302 return file;
303
304XLAL_FAIL:
305
306 // Delete FITS file and free memory on error
307 if ( file != NULL ) {
308 if ( file->ff != NULL ) {
309 fits_delete_file( file->ff, &status );
310 }
311 XLALFree( file );
312 }
313
314 XLALFree( url );
315 return NULL;
316
317#endif // !defined(HAVE_LIBCFITSIO)
318}
319
320FITSFile *XLALFITSFileOpenRead( const CHAR UNUSED *file_name )
321{
322#if !defined(HAVE_LIBCFITSIO)
323 XLAL_ERROR_NULL( XLAL_EFAILED, "CFITSIO is not available" );
324#else // defined(HAVE_LIBCFITSIO)
325
326 int UNUSED status = 0;
327 FITSFile *file = NULL;
328 FILE *f = NULL;
329
330 // Check input
332
333 // Create FITSFile struct
334 file = XLALCalloc( 1, sizeof( *file ) );
335 XLAL_CHECK_FAIL( file != NULL, XLAL_ENOMEM );
336
337 // Set FITSFile fields
338 file->write = 0;
339
340 // Check that file can be opened for reading
341 errno = 0;
342 f = fopen( file_name, "r" );
343 if ( f == NULL ) {
344 switch ( errno ) {
345 case ENOENT:
347 default:
349 }
350 }
351
352 // Open FITS file for reading
353 CALL_FITS_VAL( XLAL_ESYS, fits_open_diskfile, &file->ff, file_name, READONLY );
354
355 if ( f != NULL ) {
356 fclose( f );
357 }
358 return file;
359
360XLAL_FAIL:
361
362 // Close FITS file and free memory on error
363 if ( file != NULL ) {
364 if ( file->ff != NULL ) {
365 fits_close_file( file->ff, &status );
366 }
367 XLALFree( file );
368 }
369
370 if ( f != NULL ) {
371 fclose( f );
372 }
373 return NULL;
374
375#endif // !defined(HAVE_LIBCFITSIO)
376}
377
379{
380#if !defined(HAVE_LIBCFITSIO)
381 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
382#else // defined(HAVE_LIBCFITSIO)
383
384 int UNUSED status = 0;
385
386 // Check input
387 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
388
389 // Seek primary HDU
390 CALL_FITS( fits_movabs_hdu, file->ff, 1, NULL );
391
392 return XLAL_SUCCESS;
393
394XLAL_FAIL:
395 return XLAL_FAILURE;
396
397#endif // !defined(HAVE_LIBCFITSIO)
398}
399
400int XLALFITSFileSeekNamedHDU( FITSFile UNUSED *file, const CHAR UNUSED *name )
401{
402#if !defined(HAVE_LIBCFITSIO)
403 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
404#else // defined(HAVE_LIBCFITSIO)
405
406 int UNUSED status = 0;
407
408 // Check input
409 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
410 XLAL_CHECK_FAIL( name != NULL, XLAL_EFAULT );
411 XLAL_CHECK( strlen( name ) < FLEN_VALUE, XLAL_EINVAL, "HDU name '%s' is too long", name );
412
413 // Set current HDU
414 file->hdutype = ANY_HDU;
415 strncpy( file->hduname, name, sizeof( file->hduname ) - 1 );
416
417 // Seek any HDU with given name, starting from primary HDU
418 CALL_FITS( fits_movabs_hdu, file->ff, 1, NULL );
419 CALL_FITS( fits_movnam_hdu, file->ff, file->hdutype, file->hduname, 0 );
420
421 return XLAL_SUCCESS;
422
423XLAL_FAIL:
424 return XLAL_FAILURE;
425
426#endif // !defined(HAVE_LIBCFITSIO)
427}
428
429int XLALFITSFileWriteHistory( FITSFile UNUSED *file, const CHAR UNUSED *format, ... )
430{
431#if !defined(HAVE_LIBCFITSIO)
432 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
433#else // defined(HAVE_LIBCFITSIO)
434
435 int UNUSED status = 0;
436
437 // Check input
438 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
439 XLAL_CHECK_FAIL( file->write, XLAL_EINVAL, "FITS file is not open for writing" );
441
442 // Seek primary HDU
443 CALL_FITS( fits_movabs_hdu, file->ff, 1, NULL );
444
445 // Write history to primary header
446 va_list ap;
447 va_start( ap, format );
448 XLAL_CHECK_FAIL( WriteFormattedString( file, format, ap, fits_write_history ) == XLAL_SUCCESS, XLAL_EFUNC );
449 va_end( ap );
450
451 return XLAL_SUCCESS;
452
453XLAL_FAIL:
454
455 // Delete FITS file on error
456 if ( file != NULL && file->ff != NULL ) {
457 fits_delete_file( file->ff, &status );
458 file->ff = NULL;
459 }
460
461 return XLAL_FAILURE;
462
463#endif // !defined(HAVE_LIBCFITSIO)
464}
465
466int XLALFITSFileWriteVCSInfo( FITSFile UNUSED *file, const LALVCSInfoList UNUSED vcs_list )
467{
468#if !defined(HAVE_LIBCFITSIO)
469 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
470#else // defined(HAVE_LIBCFITSIO)
471
472 int UNUSED status = 0;
473
474 // Check input
475 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
476 XLAL_CHECK_FAIL( file->write, XLAL_EINVAL, "FITS file is not open for writing" );
477 XLAL_CHECK_FAIL( vcs_list != NULL, XLAL_EFAULT );
478
479 // Seek primary HDU
480 CALL_FITS( fits_movabs_hdu, file->ff, 1, NULL );
481
482 // Write VCS information to primary header
483 for ( size_t i = 0; vcs_list[i] != NULL; ++i ) {
484 CHAR keyword[FLEN_KEYWORD];
485 snprintf( keyword, sizeof( keyword ), "%s version", vcs_list[i]->name );
486 XLAL_CHECK_FAIL( XLALFITSHeaderWriteString( file, keyword, vcs_list[i]->version, "version" ) == XLAL_SUCCESS, XLAL_EFUNC );
487 snprintf( keyword, sizeof( keyword ), "%s commit", vcs_list[i]->name );
488 XLAL_CHECK_FAIL( XLALFITSHeaderWriteString( file, keyword, vcs_list[i]->vcsId, "commit ID" ) == XLAL_SUCCESS, XLAL_EFUNC );
489 snprintf( keyword, sizeof( keyword ), "%s status", vcs_list[i]->name );
490 XLAL_CHECK_FAIL( XLALFITSHeaderWriteString( file, keyword, vcs_list[i]->vcsStatus, "repo status" ) == XLAL_SUCCESS, XLAL_EFUNC );
491 }
492
493 return XLAL_SUCCESS;
494
495XLAL_FAIL:
496
497 // Delete FITS file on error
498 if ( file != NULL && file->ff != NULL ) {
499 fits_delete_file( file->ff, &status );
500 file->ff = NULL;
501 }
502
503 return XLAL_FAILURE;
504
505#endif // !defined(HAVE_LIBCFITSIO)
506}
507
509{
510#if !defined(HAVE_LIBCFITSIO)
511 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
512#else // defined(HAVE_LIBCFITSIO)
513
514 int UNUSED status = 0;
515 CHAR *cmd_line = NULL;
516
517 // Check input
518 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
519 XLAL_CHECK_FAIL( file->write, XLAL_EINVAL, "FITS file is not open for writing" );
520
521 // Seek primary HDU
522 CALL_FITS( fits_movabs_hdu, file->ff, 1, NULL );
523
524 // Get UserVar command line in a parseable form
526 XLAL_CHECK_FAIL( cmd_line != NULL, XLAL_EFUNC );
527
528 // Extract and write program name to primary header
529 CHAR *p = cmd_line;
530 CHAR *t = XLALStringToken( &p, "\n", 0 );
531 XLAL_CHECK_FAIL( t != NULL && strlen( t ) > 0, XLAL_EFUNC );
532 CALL_FITS( fits_write_key_longstr, file->ff, "PROGNAME", t, "name of program which created this file" );
533
534 // Extract and write program arguments to primary header
535 t = XLALStringToken( &p, "\n", 0 );
536 while ( t != NULL ) {
537 CHAR *v = strchr( t, '\t' );
538 XLAL_CHECK_FAIL( v != NULL, XLAL_EFAILED );
539 *v++ = '\0';
540 CHAR keyword[FLEN_KEYWORD];
541 snprintf( keyword, sizeof( keyword ), "PROGARG %s", t );
542 CALL_FITS( fits_write_key_longstr, file->ff, keyword, v, "argument to program" );
543 t = XLALStringToken( &p, "\n", 0 );
544 }
545
546 XLALFree( cmd_line );
547 return XLAL_SUCCESS;
548
549XLAL_FAIL:
550
551 // Delete FITS file on error
552 if ( file != NULL && file->ff != NULL ) {
553 fits_delete_file( file->ff, &status );
554 file->ff = NULL;
555 }
556
557 XLALFree( cmd_line );
558 return XLAL_FAILURE;
559
560#endif // !defined(HAVE_LIBCFITSIO)
561}
562
563int XLALFITSHeaderQueryKeyExists( FITSFile UNUSED *file, const CHAR UNUSED *key, BOOLEAN UNUSED *exists )
564{
565#if !defined(HAVE_LIBCFITSIO)
566 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
567#else // defined(HAVE_LIBCFITSIO)
568
569 int UNUSED status = 0;
570
571 // Check input
572 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
573 XLAL_CHECK_FAIL( !file->write, XLAL_EINVAL, "FITS file is not open for reading" );
574 XLAL_CHECK_FAIL( key != NULL, XLAL_EFAULT );
575 XLAL_CHECK_FAIL( exists != NULL, XLAL_EFAULT );
576
577 // Checks if the given key exists in the current HDU
578 CHAR card[FLEN_CARD];
579 CALL_FITS( fits_read_record, file->ff, 0, card );
580 union {
581 const CHAR *cc;
582 CHAR *c;
583 } bad_cast = { .cc = key };
584 CHAR *inclist[] = { bad_cast.c };
585 fits_find_nextkey( file->ff, inclist, XLAL_NUM_ELEM( inclist ), NULL, 0, card, &status );
586 if ( status == KEY_NO_EXIST ) {
587 *exists = 0;
588 } else {
589 CHECK_FITS( fits_find_nextkey );
590 *exists = 1;
591 }
592
593 return XLAL_SUCCESS;
594
595XLAL_FAIL:
596 return XLAL_FAILURE;
597
598#endif // !defined(HAVE_LIBCFITSIO)
599}
600
601int XLALFITSHeaderWriteComment( FITSFile UNUSED *file, const CHAR UNUSED *format, ... )
602{
603#if !defined(HAVE_LIBCFITSIO)
604 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
605#else // defined(HAVE_LIBCFITSIO)
606
607 int UNUSED status = 0;
608
609 // Check input
610 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
611 XLAL_CHECK_FAIL( file->write, XLAL_EINVAL, "FITS file is not open for writing" );
613
614 // Write comment to current header
615 va_list ap;
616 va_start( ap, format );
617 XLAL_CHECK_FAIL( WriteFormattedString( file, format, ap, fits_write_comment ) == XLAL_SUCCESS, XLAL_EFUNC );
618 va_end( ap );
619
620 return XLAL_SUCCESS;
621
622XLAL_FAIL:
623
624 // Delete FITS file on error
625 if ( file != NULL && file->ff != NULL ) {
626 fits_delete_file( file->ff, &status );
627 file->ff = NULL;
628 }
629
630 return XLAL_FAILURE;
631
632#endif // !defined(HAVE_LIBCFITSIO)
633}
634
635int XLALFITSHeaderWriteBOOLEAN( FITSFile UNUSED *file, const CHAR UNUSED *key, const BOOLEAN UNUSED value, const CHAR UNUSED *comment )
636{
637#if !defined(HAVE_LIBCFITSIO)
638 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
639#else // defined(HAVE_LIBCFITSIO)
640
641 int UNUSED status = 0;
642
643 // Check input
644 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
645 XLAL_CHECK_FAIL( file->write, XLAL_EINVAL, "FITS file is not open for writing" );
646 CHAR keyword[FLEN_KEYWORD];
647 XLAL_CHECK_FAIL( CheckFITSKeyword( key, keyword, NULL ) == XLAL_SUCCESS, XLAL_EFUNC );
649
650 // Write boolean value to current header
651 CALL_FITS( fits_write_key_log, file->ff, keyword, value ? 1 : 0, comment );
652
653 return XLAL_SUCCESS;
654
655XLAL_FAIL:
656
657 // Delete FITS file on error
658 if ( file != NULL && file->ff != NULL ) {
659 fits_delete_file( file->ff, &status );
660 file->ff = NULL;
661 }
662
663 return XLAL_FAILURE;
664
665#endif // !defined(HAVE_LIBCFITSIO)
666}
667
668int XLALFITSHeaderReadBOOLEAN( FITSFile UNUSED *file, const CHAR UNUSED *key, BOOLEAN UNUSED *value )
669{
670#if !defined(HAVE_LIBCFITSIO)
671 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
672#else // defined(HAVE_LIBCFITSIO)
673
674 int UNUSED status = 0;
675
676 // Check input
677 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
678 XLAL_CHECK_FAIL( !file->write, XLAL_EINVAL, "FITS file is not open for reading" );
679 CHAR keyword[FLEN_KEYWORD];
680 XLAL_CHECK_FAIL( CheckFITSKeyword( key, keyword, NULL ) == XLAL_SUCCESS, XLAL_EFUNC );
681 XLAL_CHECK_FAIL( value != NULL, XLAL_EFAULT );
682
683 // Read boolean value from current header
684 int val = 0;
685 CHAR comment[FLEN_COMMENT];
686 CALL_FITS( fits_read_key_log, file->ff, keyword, &val, comment );
687 *value = val ? 1 : 0;
688
689 return XLAL_SUCCESS;
690
691XLAL_FAIL:
692 return XLAL_FAILURE;
693
694#endif // !defined(HAVE_LIBCFITSIO)
695}
696
697int XLALFITSHeaderWriteUINT2( FITSFile UNUSED *file, const CHAR UNUSED *key, const UINT2 UNUSED value, const CHAR UNUSED *comment )
698{
699#if !defined(HAVE_LIBCFITSIO)
700 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
701#else // defined(HAVE_LIBCFITSIO)
702
703 int UNUSED status = 0;
704
705 // Check input
706 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
707 XLAL_CHECK_FAIL( file->write, XLAL_EINVAL, "FITS file is not open for writing" );
708 CHAR keyword[FLEN_KEYWORD], unit[FLEN_VALUE];
709 XLAL_CHECK_FAIL( CheckFITSKeyword( key, keyword, unit ) == XLAL_SUCCESS, XLAL_EFUNC );
711
712 // Write 16-bit unsigned integer value to current header
713 LONGLONG val = value;
714 CALL_FITS( fits_write_key_lng, file->ff, keyword, val, comment );
715 CALL_FITS( fits_write_key_unit, file->ff, keyword, unit );
716
717 return XLAL_SUCCESS;
718
719XLAL_FAIL:
720
721 // Delete FITS file on error
722 if ( file != NULL && file->ff != NULL ) {
723 fits_delete_file( file->ff, &status );
724 file->ff = NULL;
725 }
726
727 return XLAL_FAILURE;
728
729#endif // !defined(HAVE_LIBCFITSIO)
730}
731
732int XLALFITSHeaderReadUINT2( FITSFile UNUSED *file, const CHAR UNUSED *key, UINT2 UNUSED *value )
733{
734#if !defined(HAVE_LIBCFITSIO)
735 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
736#else // defined(HAVE_LIBCFITSIO)
737
738 int UNUSED status = 0;
739
740 // Check input
741 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
742 XLAL_CHECK_FAIL( !file->write, XLAL_EINVAL, "FITS file is not open for reading" );
743 CHAR keyword[FLEN_KEYWORD];
744 XLAL_CHECK_FAIL( CheckFITSKeyword( key, keyword, NULL ) == XLAL_SUCCESS, XLAL_EFUNC );
745 XLAL_CHECK_FAIL( value != NULL, XLAL_EFAULT );
746
747 // Read 16-bit unsigned integer value from current header
748 LONGLONG val = 0;
749 CHAR comment[FLEN_COMMENT];
750 CALL_FITS( fits_read_key_lnglng, file->ff, keyword, &val, comment );
751 XLAL_CHECK_FAIL( 0 <= val && ( ( UINT8 ) val ) <= UINT16_MAX, XLAL_ERANGE );
752 *value = val;
753
754 return XLAL_SUCCESS;
755
756XLAL_FAIL:
757 return XLAL_FAILURE;
758
759#endif // !defined(HAVE_LIBCFITSIO)
760}
761
762int XLALFITSHeaderWriteUINT4( FITSFile UNUSED *file, const CHAR UNUSED *key, const UINT4 UNUSED value, const CHAR UNUSED *comment )
763{
764#if !defined(HAVE_LIBCFITSIO)
765 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
766#else // defined(HAVE_LIBCFITSIO)
767
768 int UNUSED status = 0;
769
770 // Check input
771 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
772 XLAL_CHECK_FAIL( file->write, XLAL_EINVAL, "FITS file is not open for writing" );
773 CHAR keyword[FLEN_KEYWORD], unit[FLEN_VALUE];
774 XLAL_CHECK_FAIL( CheckFITSKeyword( key, keyword, unit ) == XLAL_SUCCESS, XLAL_EFUNC );
776
777 // Write 32-bit unsigned integer value to current header
778 LONGLONG val = value;
779 CALL_FITS( fits_write_key_lng, file->ff, keyword, val, comment );
780 CALL_FITS( fits_write_key_unit, file->ff, keyword, unit );
781
782 return XLAL_SUCCESS;
783
784XLAL_FAIL:
785
786 // Delete FITS file on error
787 if ( file != NULL && file->ff != NULL ) {
788 fits_delete_file( file->ff, &status );
789 file->ff = NULL;
790 }
791
792 return XLAL_FAILURE;
793
794#endif // !defined(HAVE_LIBCFITSIO)
795}
796
797int XLALFITSHeaderReadUINT4( FITSFile UNUSED *file, const CHAR UNUSED *key, UINT4 UNUSED *value )
798{
799#if !defined(HAVE_LIBCFITSIO)
800 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
801#else // defined(HAVE_LIBCFITSIO)
802
803 int UNUSED status = 0;
804
805 // Check input
806 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
807 XLAL_CHECK_FAIL( !file->write, XLAL_EINVAL, "FITS file is not open for reading" );
808 CHAR keyword[FLEN_KEYWORD];
809 XLAL_CHECK_FAIL( CheckFITSKeyword( key, keyword, NULL ) == XLAL_SUCCESS, XLAL_EFUNC );
810 XLAL_CHECK_FAIL( value != NULL, XLAL_EFAULT );
811
812 // Read 32-bit unsigned integer value from current header
813 LONGLONG val = 0;
814 CHAR comment[FLEN_COMMENT];
815 CALL_FITS( fits_read_key_lnglng, file->ff, keyword, &val, comment );
816 XLAL_CHECK_FAIL( 0 <= val && ( ( UINT8 ) val ) <= UINT32_MAX, XLAL_ERANGE );
817 *value = val;
818
819 return XLAL_SUCCESS;
820
821XLAL_FAIL:
822 return XLAL_FAILURE;
823
824#endif // !defined(HAVE_LIBCFITSIO)
825}
826
827int XLALFITSHeaderWriteUINT8( FITSFile UNUSED *file, const CHAR UNUSED *key, const UINT8 UNUSED value, const CHAR UNUSED *comment )
828{
829#if !defined(HAVE_LIBCFITSIO)
830 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
831#else // defined(HAVE_LIBCFITSIO)
832
833 int UNUSED status = 0;
834
835 // Check input
836 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
837 XLAL_CHECK_FAIL( file->write, XLAL_EINVAL, "FITS file is not open for writing" );
838 CHAR keyword[FLEN_KEYWORD], unit[FLEN_VALUE];
839 XLAL_CHECK_FAIL( CheckFITSKeyword( key, keyword, unit ) == XLAL_SUCCESS, XLAL_EFUNC );
841
842 // Write 64-bit unsigned integer value to current header
843 XLAL_CHECK_FAIL( value <= LONGLONG_MAX, XLAL_ERANGE );
844 LONGLONG val = value;
845 CALL_FITS( fits_write_key_lng, file->ff, keyword, val, comment );
846 CALL_FITS( fits_write_key_unit, file->ff, keyword, unit );
847
848 return XLAL_SUCCESS;
849
850XLAL_FAIL:
851
852 // Delete FITS file on error
853 if ( file != NULL && file->ff != NULL ) {
854 fits_delete_file( file->ff, &status );
855 file->ff = NULL;
856 }
857
858 return XLAL_FAILURE;
859
860#endif // !defined(HAVE_LIBCFITSIO)
861}
862
863int XLALFITSHeaderReadUINT8( FITSFile UNUSED *file, const CHAR UNUSED *key, UINT8 UNUSED *value )
864{
865#if !defined(HAVE_LIBCFITSIO)
866 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
867#else // defined(HAVE_LIBCFITSIO)
868
869 int UNUSED status = 0;
870
871 // Check input
872 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
873 XLAL_CHECK_FAIL( !file->write, XLAL_EINVAL, "FITS file is not open for reading" );
874 CHAR keyword[FLEN_KEYWORD];
875 XLAL_CHECK_FAIL( CheckFITSKeyword( key, keyword, NULL ) == XLAL_SUCCESS, XLAL_EFUNC );
876 XLAL_CHECK_FAIL( value != NULL, XLAL_EFAULT );
877
878 // Read 64-bit unsigned integer value from current header
879 LONGLONG val = 0;
880 CHAR comment[FLEN_COMMENT];
881 CALL_FITS( fits_read_key_lnglng, file->ff, keyword, &val, comment );
882 XLAL_CHECK_FAIL( 0 <= val && ( ( UINT8 ) val ) <= UINT64_MAX, XLAL_ERANGE );
883 *value = val;
884
885 return XLAL_SUCCESS;
886
887XLAL_FAIL:
888 return XLAL_FAILURE;
889
890#endif // !defined(HAVE_LIBCFITSIO)
891}
892
893int XLALFITSHeaderWriteINT2( FITSFile UNUSED *file, const CHAR UNUSED *key, const INT2 UNUSED value, const CHAR UNUSED *comment )
894{
895#if !defined(HAVE_LIBCFITSIO)
896 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
897#else // defined(HAVE_LIBCFITSIO)
898
899 int UNUSED status = 0;
900
901 // Check input
902 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
903 XLAL_CHECK_FAIL( file->write, XLAL_EINVAL, "FITS file is not open for writing" );
904 CHAR keyword[FLEN_KEYWORD], unit[FLEN_VALUE];
905 XLAL_CHECK_FAIL( CheckFITSKeyword( key, keyword, unit ) == XLAL_SUCCESS, XLAL_EFUNC );
907
908 // Write 16-bit integer value to current header
909 LONGLONG val = value;
910 CALL_FITS( fits_write_key_lng, file->ff, keyword, val, comment );
911 CALL_FITS( fits_write_key_unit, file->ff, keyword, unit );
912
913 return XLAL_SUCCESS;
914
915XLAL_FAIL:
916
917 // Delete FITS file on error
918 if ( file != NULL && file->ff != NULL ) {
919 fits_delete_file( file->ff, &status );
920 file->ff = NULL;
921 }
922
923 return XLAL_FAILURE;
924
925#endif // !defined(HAVE_LIBCFITSIO)
926}
927
928int XLALFITSHeaderReadINT2( FITSFile UNUSED *file, const CHAR UNUSED *key, INT2 UNUSED *value )
929{
930#if !defined(HAVE_LIBCFITSIO)
931 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
932#else // defined(HAVE_LIBCFITSIO)
933
934 int UNUSED status = 0;
935
936 // Check input
937 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
938 XLAL_CHECK_FAIL( !file->write, XLAL_EINVAL, "FITS file is not open for reading" );
939 CHAR keyword[FLEN_KEYWORD];
940 XLAL_CHECK_FAIL( CheckFITSKeyword( key, keyword, NULL ) == XLAL_SUCCESS, XLAL_EFUNC );
941 XLAL_CHECK_FAIL( value != NULL, XLAL_EFAULT );
942
943 // Read 16-bit integer value from current header
944 LONGLONG val = 0;
945 CHAR comment[FLEN_COMMENT];
946 CALL_FITS( fits_read_key_lnglng, file->ff, keyword, &val, comment );
947 XLAL_CHECK_FAIL( INT16_MIN <= val && val <= INT16_MAX, XLAL_ERANGE );
948 *value = val;
949
950 return XLAL_SUCCESS;
951
952XLAL_FAIL:
953 return XLAL_FAILURE;
954
955#endif // !defined(HAVE_LIBCFITSIO)
956}
957
958int XLALFITSHeaderWriteINT4( FITSFile UNUSED *file, const CHAR UNUSED *key, const INT4 UNUSED value, const CHAR UNUSED *comment )
959{
960#if !defined(HAVE_LIBCFITSIO)
961 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
962#else // defined(HAVE_LIBCFITSIO)
963
964 int UNUSED status = 0;
965
966 // Check input
967 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
968 XLAL_CHECK_FAIL( file->write, XLAL_EINVAL, "FITS file is not open for writing" );
969 CHAR keyword[FLEN_KEYWORD], unit[FLEN_VALUE];
970 XLAL_CHECK_FAIL( CheckFITSKeyword( key, keyword, unit ) == XLAL_SUCCESS, XLAL_EFUNC );
972
973 // Write 32-bit integer value to current header
974 LONGLONG val = value;
975 CALL_FITS( fits_write_key_lng, file->ff, keyword, val, comment );
976 CALL_FITS( fits_write_key_unit, file->ff, keyword, unit );
977
978 return XLAL_SUCCESS;
979
980XLAL_FAIL:
981
982 // Delete FITS file on error
983 if ( file != NULL && file->ff != NULL ) {
984 fits_delete_file( file->ff, &status );
985 file->ff = NULL;
986 }
987
988 return XLAL_FAILURE;
989
990#endif // !defined(HAVE_LIBCFITSIO)
991}
992
993int XLALFITSHeaderReadINT4( FITSFile UNUSED *file, const CHAR UNUSED *key, INT4 UNUSED *value )
994{
995#if !defined(HAVE_LIBCFITSIO)
996 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
997#else // defined(HAVE_LIBCFITSIO)
998
999 int UNUSED status = 0;
1000
1001 // Check input
1002 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
1003 XLAL_CHECK_FAIL( !file->write, XLAL_EINVAL, "FITS file is not open for reading" );
1004 CHAR keyword[FLEN_KEYWORD];
1005 XLAL_CHECK_FAIL( CheckFITSKeyword( key, keyword, NULL ) == XLAL_SUCCESS, XLAL_EFUNC );
1006 XLAL_CHECK_FAIL( value != NULL, XLAL_EFAULT );
1007
1008 // Read 32-bit integer value from current header
1009 LONGLONG val = 0;
1010 CHAR comment[FLEN_COMMENT];
1011 CALL_FITS( fits_read_key_lnglng, file->ff, keyword, &val, comment );
1012 XLAL_CHECK_FAIL( INT32_MIN <= val && val <= INT32_MAX, XLAL_ERANGE );
1013 *value = val;
1014
1015 return XLAL_SUCCESS;
1016
1017XLAL_FAIL:
1018 return XLAL_FAILURE;
1019
1020#endif // !defined(HAVE_LIBCFITSIO)
1021}
1022
1023int XLALFITSHeaderWriteINT8( FITSFile UNUSED *file, const CHAR UNUSED *key, const INT8 UNUSED value, const CHAR UNUSED *comment )
1024{
1025#if !defined(HAVE_LIBCFITSIO)
1026 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
1027#else // defined(HAVE_LIBCFITSIO)
1028
1029 int UNUSED status = 0;
1030
1031 // Check input
1032 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
1033 XLAL_CHECK_FAIL( file->write, XLAL_EINVAL, "FITS file is not open for writing" );
1034 CHAR keyword[FLEN_KEYWORD], unit[FLEN_VALUE];
1035 XLAL_CHECK_FAIL( CheckFITSKeyword( key, keyword, unit ) == XLAL_SUCCESS, XLAL_EFUNC );
1037
1038 // Write 64-bit integer value to current header
1039 XLAL_CHECK_FAIL( LONGLONG_MIN <= value && value <= LONGLONG_MAX, XLAL_ERANGE );
1040 LONGLONG val = value;
1041 CALL_FITS( fits_write_key_lng, file->ff, keyword, val, comment );
1042 CALL_FITS( fits_write_key_unit, file->ff, keyword, unit );
1043
1044 return XLAL_SUCCESS;
1045
1046XLAL_FAIL:
1047
1048 // Delete FITS file on error
1049 if ( file != NULL && file->ff != NULL ) {
1050 fits_delete_file( file->ff, &status );
1051 file->ff = NULL;
1052 }
1053
1054 return XLAL_FAILURE;
1055
1056#endif // !defined(HAVE_LIBCFITSIO)
1057}
1058
1059int XLALFITSHeaderReadINT8( FITSFile UNUSED *file, const CHAR UNUSED *key, INT8 UNUSED *value )
1060{
1061#if !defined(HAVE_LIBCFITSIO)
1062 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
1063#else // defined(HAVE_LIBCFITSIO)
1064
1065 int UNUSED status = 0;
1066
1067 // Check input
1068 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
1069 XLAL_CHECK_FAIL( !file->write, XLAL_EINVAL, "FITS file is not open for reading" );
1070 CHAR keyword[FLEN_KEYWORD];
1071 XLAL_CHECK_FAIL( CheckFITSKeyword( key, keyword, NULL ) == XLAL_SUCCESS, XLAL_EFUNC );
1072 XLAL_CHECK_FAIL( value != NULL, XLAL_EFAULT );
1073
1074 // Read 64-bit integer value from current header
1075 LONGLONG val = 0;
1076 CHAR comment[FLEN_COMMENT];
1077 CALL_FITS( fits_read_key_lnglng, file->ff, keyword, &val, comment );
1078 XLAL_CHECK_FAIL( INT64_MIN <= val && val <= INT64_MAX, XLAL_ERANGE );
1079 *value = val;
1080
1081 return XLAL_SUCCESS;
1082
1083XLAL_FAIL:
1084 return XLAL_FAILURE;
1085
1086#endif // !defined(HAVE_LIBCFITSIO)
1087}
1088
1089int XLALFITSHeaderWriteREAL4( FITSFile UNUSED *file, const CHAR UNUSED *key, const REAL4 UNUSED value, const CHAR UNUSED *comment )
1090{
1091#if !defined(HAVE_LIBCFITSIO)
1092 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
1093#else // defined(HAVE_LIBCFITSIO)
1094
1095 int UNUSED status = 0;
1096
1097 // Check input
1098 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
1099 XLAL_CHECK_FAIL( file->write, XLAL_EINVAL, "FITS file is not open for writing" );
1100 CHAR keyword[FLEN_KEYWORD], unit[FLEN_VALUE];
1101 XLAL_CHECK_FAIL( CheckFITSKeyword( key, keyword, unit ) == XLAL_SUCCESS, XLAL_EFUNC );
1103
1104 // Write 32-bit floating-point value to current header
1105 CALL_FITS( fits_write_key_flt, file->ff, keyword, value, FLT_DIG, comment );
1106 CALL_FITS( fits_write_key_unit, file->ff, keyword, unit );
1107
1108 return XLAL_SUCCESS;
1109
1110XLAL_FAIL:
1111
1112 // Delete FITS file on error
1113 if ( file != NULL && file->ff != NULL ) {
1114 fits_delete_file( file->ff, &status );
1115 file->ff = NULL;
1116 }
1117
1118 return XLAL_FAILURE;
1119
1120#endif // !defined(HAVE_LIBCFITSIO)
1121}
1122
1123int XLALFITSHeaderReadREAL4( FITSFile UNUSED *file, const CHAR UNUSED *key, REAL4 UNUSED *value )
1124{
1125#if !defined(HAVE_LIBCFITSIO)
1126 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
1127#else // defined(HAVE_LIBCFITSIO)
1128
1129 int UNUSED status = 0;
1130
1131 // Check input
1132 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
1133 XLAL_CHECK_FAIL( !file->write, XLAL_EINVAL, "FITS file is not open for reading" );
1134 CHAR keyword[FLEN_KEYWORD];
1135 XLAL_CHECK_FAIL( CheckFITSKeyword( key, keyword, NULL ) == XLAL_SUCCESS, XLAL_EFUNC );
1136 XLAL_CHECK_FAIL( value != NULL, XLAL_EFAULT );
1137
1138 // Read 32-bit floating-point value from current header
1139 CHAR comment[FLEN_COMMENT];
1140 CALL_FITS( fits_read_key_flt, file->ff, keyword, value, comment );
1141
1142 return XLAL_SUCCESS;
1143
1144XLAL_FAIL:
1145 return XLAL_FAILURE;
1146
1147#endif // !defined(HAVE_LIBCFITSIO)
1148}
1149
1150int XLALFITSHeaderWriteREAL8( FITSFile UNUSED *file, const CHAR UNUSED *key, const REAL8 UNUSED value, const CHAR UNUSED *comment )
1151{
1152#if !defined(HAVE_LIBCFITSIO)
1153 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
1154#else // defined(HAVE_LIBCFITSIO)
1155
1156 int UNUSED status = 0;
1157
1158 // Check input
1159 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
1160 XLAL_CHECK_FAIL( file->write, XLAL_EINVAL, "FITS file is not open for writing" );
1161 CHAR keyword[FLEN_KEYWORD], unit[FLEN_VALUE];
1162 XLAL_CHECK_FAIL( CheckFITSKeyword( key, keyword, unit ) == XLAL_SUCCESS, XLAL_EFUNC );
1164
1165 // Write 64-bit floating-point value to current header
1166 CALL_FITS( fits_write_key_dbl, file->ff, keyword, value, DBL_DIG, comment );
1167 CALL_FITS( fits_write_key_unit, file->ff, keyword, unit );
1168
1169 return XLAL_SUCCESS;
1170
1171XLAL_FAIL:
1172
1173 // Delete FITS file on error
1174 if ( file != NULL && file->ff != NULL ) {
1175 fits_delete_file( file->ff, &status );
1176 file->ff = NULL;
1177 }
1178
1179 return XLAL_FAILURE;
1180
1181#endif // !defined(HAVE_LIBCFITSIO)
1182}
1183
1184int XLALFITSHeaderReadREAL8( FITSFile UNUSED *file, const CHAR UNUSED *key, REAL8 UNUSED *value )
1185{
1186#if !defined(HAVE_LIBCFITSIO)
1187 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
1188#else // defined(HAVE_LIBCFITSIO)
1189
1190 int UNUSED status = 0;
1191
1192 // Check input
1193 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
1194 XLAL_CHECK_FAIL( !file->write, XLAL_EINVAL, "FITS file is not open for reading" );
1195 CHAR keyword[FLEN_KEYWORD];
1196 XLAL_CHECK_FAIL( CheckFITSKeyword( key, keyword, NULL ) == XLAL_SUCCESS, XLAL_EFUNC );
1197 XLAL_CHECK_FAIL( value != NULL, XLAL_EFAULT );
1198
1199 // Read 64-bit floating-point value from current header
1200 CHAR comment[FLEN_COMMENT];
1201 CALL_FITS( fits_read_key_dbl, file->ff, keyword, value, comment );
1202
1203 return XLAL_SUCCESS;
1204
1205XLAL_FAIL:
1206 return XLAL_FAILURE;
1207
1208#endif // !defined(HAVE_LIBCFITSIO)
1209}
1210
1211int XLALFITSHeaderWriteCOMPLEX8( FITSFile UNUSED *file, const CHAR UNUSED *key, const COMPLEX8 UNUSED value, const CHAR UNUSED *comment )
1212{
1213#if !defined(HAVE_LIBCFITSIO)
1214 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
1215#else // defined(HAVE_LIBCFITSIO)
1216
1217 int UNUSED status = 0;
1218
1219 // Check input
1220 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
1221 XLAL_CHECK_FAIL( file->write, XLAL_EINVAL, "FITS file is not open for writing" );
1222 CHAR keyword[FLEN_KEYWORD], unit[FLEN_VALUE];
1223 XLAL_CHECK_FAIL( CheckFITSKeyword( key, keyword, unit ) == XLAL_SUCCESS, XLAL_EFUNC );
1225
1226 // Write 64-bit complex floating-point value to current header
1227 REAL4 val[2] = {crealf( value ), cimagf( value )};
1228 CALL_FITS( fits_write_key_cmp, file->ff, keyword, val, FLT_DIG, comment );
1229 CALL_FITS( fits_write_key_unit, file->ff, keyword, unit );
1230
1231 return XLAL_SUCCESS;
1232
1233XLAL_FAIL:
1234
1235 // Delete FITS file on error
1236 if ( file != NULL && file->ff != NULL ) {
1237 fits_delete_file( file->ff, &status );
1238 file->ff = NULL;
1239 }
1240
1241 return XLAL_FAILURE;
1242
1243#endif // !defined(HAVE_LIBCFITSIO)
1244}
1245
1246int XLALFITSHeaderReadCOMPLEX8( FITSFile UNUSED *file, const CHAR UNUSED *key, COMPLEX8 UNUSED *value )
1247{
1248#if !defined(HAVE_LIBCFITSIO)
1249 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
1250#else // defined(HAVE_LIBCFITSIO)
1251
1252 int UNUSED status = 0;
1253
1254 // Check input
1255 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
1256 XLAL_CHECK_FAIL( !file->write, XLAL_EINVAL, "FITS file is not open for reading" );
1257 CHAR keyword[FLEN_KEYWORD];
1258 XLAL_CHECK_FAIL( CheckFITSKeyword( key, keyword, NULL ) == XLAL_SUCCESS, XLAL_EFUNC );
1259 XLAL_CHECK_FAIL( value != NULL, XLAL_EFAULT );
1260
1261 // Read 64-bit floating-point value from current header
1262 CHAR comment[FLEN_COMMENT];
1263 REAL4 val[2] = {0, 0};
1264 CALL_FITS( fits_read_key_cmp, file->ff, keyword, val, comment );
1265 *value = crectf( val[0], val[1] );
1266
1267 return XLAL_SUCCESS;
1268
1269XLAL_FAIL:
1270 return XLAL_FAILURE;
1271
1272#endif // !defined(HAVE_LIBCFITSIO)
1273}
1274
1275int XLALFITSHeaderWriteCOMPLEX16( FITSFile UNUSED *file, const CHAR UNUSED *key, const COMPLEX16 UNUSED value, const CHAR UNUSED *comment )
1276{
1277#if !defined(HAVE_LIBCFITSIO)
1278 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
1279#else // defined(HAVE_LIBCFITSIO)
1280
1281 int UNUSED status = 0;
1282
1283 // Check input
1284 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
1285 XLAL_CHECK_FAIL( file->write, XLAL_EINVAL, "FITS file is not open for writing" );
1286 CHAR keyword[FLEN_KEYWORD], unit[FLEN_VALUE];
1287 XLAL_CHECK_FAIL( CheckFITSKeyword( key, keyword, unit ) == XLAL_SUCCESS, XLAL_EFUNC );
1289
1290 // Write 128-bit complex floating-point value to current header
1291 REAL8 val[2] = {creal( value ), cimag( value )};
1292 CALL_FITS( fits_write_key_dblcmp, file->ff, keyword, val, DBL_DIG, comment );
1293 CALL_FITS( fits_write_key_unit, file->ff, keyword, unit );
1294
1295 return XLAL_SUCCESS;
1296
1297XLAL_FAIL:
1298
1299 // Delete FITS file on error
1300 if ( file != NULL && file->ff != NULL ) {
1301 fits_delete_file( file->ff, &status );
1302 file->ff = NULL;
1303 }
1304
1305 return XLAL_FAILURE;
1306
1307#endif // !defined(HAVE_LIBCFITSIO)
1308}
1309
1310int XLALFITSHeaderReadCOMPLEX16( FITSFile UNUSED *file, const CHAR UNUSED *key, COMPLEX16 UNUSED *value )
1311{
1312#if !defined(HAVE_LIBCFITSIO)
1313 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
1314#else // defined(HAVE_LIBCFITSIO)
1315
1316 int UNUSED status = 0;
1317
1318 // Check input
1319 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
1320 XLAL_CHECK_FAIL( !file->write, XLAL_EINVAL, "FITS file is not open for reading" );
1321 CHAR keyword[FLEN_KEYWORD];
1322 XLAL_CHECK_FAIL( CheckFITSKeyword( key, keyword, NULL ) == XLAL_SUCCESS, XLAL_EFUNC );
1323 XLAL_CHECK_FAIL( value != NULL, XLAL_EFAULT );
1324
1325 // Read 128-bit floating-point value from current header
1326 CHAR comment[FLEN_COMMENT];
1327 REAL8 val[2] = {0, 0};
1328 CALL_FITS( fits_read_key_dblcmp, file->ff, keyword, val, comment );
1329 *value = crect( val[0], val[1] );
1330
1331 return XLAL_SUCCESS;
1332
1333XLAL_FAIL:
1334 return XLAL_FAILURE;
1335
1336#endif // !defined(HAVE_LIBCFITSIO)
1337}
1338
1339int XLALFITSHeaderWriteString( FITSFile UNUSED *file, const CHAR UNUSED *key, const CHAR UNUSED *value, const CHAR UNUSED *comment )
1340{
1341#if !defined(HAVE_LIBCFITSIO)
1342 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
1343#else // defined(HAVE_LIBCFITSIO)
1344
1345 int UNUSED status = 0;
1346
1347 // Check input
1348 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
1349 XLAL_CHECK_FAIL( file->write, XLAL_EINVAL, "FITS file is not open for writing" );
1350 CHAR keyword[FLEN_KEYWORD];
1351 XLAL_CHECK_FAIL( CheckFITSKeyword( key, keyword, NULL ) == XLAL_SUCCESS, XLAL_EFUNC );
1352 XLAL_CHECK_FAIL( value != NULL, XLAL_EFAULT );
1354
1355 // Write string value to current header
1356 union {
1357 const CHAR *cc;
1358 CHAR *c;
1359 } bad_cast = { .cc = value };
1360 CALL_FITS( fits_write_key_longstr, file->ff, keyword, bad_cast.c, comment );
1361
1362 return XLAL_SUCCESS;
1363
1364XLAL_FAIL:
1365
1366 // Delete FITS file on error
1367 if ( file != NULL && file->ff != NULL ) {
1368 fits_delete_file( file->ff, &status );
1369 file->ff = NULL;
1370 }
1371
1372 return XLAL_FAILURE;
1373
1374#endif // !defined(HAVE_LIBCFITSIO)
1375}
1376
1377int XLALFITSHeaderReadString( FITSFile UNUSED *file, const CHAR UNUSED *key, CHAR UNUSED **value )
1378{
1379#if !defined(HAVE_LIBCFITSIO)
1380 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
1381#else // defined(HAVE_LIBCFITSIO)
1382
1383 int UNUSED status = 0;
1384 CHAR *val = NULL;
1385
1386 // Check input
1387 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
1388 XLAL_CHECK_FAIL( !file->write, XLAL_EINVAL, "FITS file is not open for reading" );
1389 CHAR keyword[FLEN_KEYWORD];
1390 XLAL_CHECK_FAIL( CheckFITSKeyword( key, keyword, NULL ) == XLAL_SUCCESS, XLAL_EFUNC );
1391 XLAL_CHECK_FAIL( value != NULL, XLAL_EFAULT );
1392
1393 // Read string value from current header
1394 CHAR comment[FLEN_COMMENT];
1395 CALL_FITS( fits_read_key_longstr, file->ff, keyword, &val, comment );
1396 XLAL_CHECK_FAIL( ( *value = XLALStringDuplicate( val ) ) != NULL, XLAL_EFUNC );
1397
1398 if ( val != NULL ) {
1399 fits_free_memory( val, &status );
1400 }
1401 return XLAL_SUCCESS;
1402
1403XLAL_FAIL:
1404 if ( val != NULL ) {
1405 fits_free_memory( val, &status );
1406 }
1407 return XLAL_FAILURE;
1408
1409#endif // !defined(HAVE_LIBCFITSIO)
1410}
1411
1412int XLALFITSHeaderWriteStringVector( FITSFile UNUSED *file, const CHAR UNUSED *key, const LALStringVector UNUSED *values, const CHAR UNUSED *comment )
1413{
1414#if !defined(HAVE_LIBCFITSIO)
1415 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
1416#else // defined(HAVE_LIBCFITSIO)
1417
1418 int UNUSED status = 0;
1419
1420 // Check input
1421 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
1422 XLAL_CHECK_FAIL( file->write, XLAL_EINVAL, "FITS file is not open for writing" );
1423 CHAR keyword[FLEN_KEYWORD];
1424 XLAL_CHECK_FAIL( CheckFITSKeyword( key, keyword, NULL ) == XLAL_SUCCESS, XLAL_EFUNC );
1425 XLAL_CHECK_FAIL( values != NULL, XLAL_EFAULT );
1426 XLAL_CHECK_FAIL( values->length > 0, XLAL_EFAULT );
1428
1429 // Write string values to current header
1430 {
1431 union {
1432 const CHAR *cc;
1433 CHAR *c;
1434 } bad_casts[values->length];
1435 for ( size_t i = 0; i < values->length; ++i ) {
1436 bad_casts[i].cc = comment;
1437 }
1438 CALL_FITS( fits_write_keys_str, file->ff, keyword, 1, values->length, values->data, ( CHAR ** ) &bad_casts[0] );
1439 }
1440
1441 return XLAL_SUCCESS;
1442
1443XLAL_FAIL:
1444
1445 // Delete FITS file on error
1446 if ( file != NULL && file->ff != NULL ) {
1447 fits_delete_file( file->ff, &status );
1448 file->ff = NULL;
1449 }
1450
1451 return XLAL_FAILURE;
1452
1453#endif // !defined(HAVE_LIBCFITSIO)
1454}
1455
1456int XLALFITSHeaderReadStringVector( FITSFile UNUSED *file, const CHAR UNUSED *key, LALStringVector UNUSED **values )
1457{
1458#if !defined(HAVE_LIBCFITSIO)
1459 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
1460#else // defined(HAVE_LIBCFITSIO)
1461
1462 int UNUSED status = 0;
1463
1464 // Check input
1465 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
1466 XLAL_CHECK_FAIL( !file->write, XLAL_EINVAL, "FITS file is not open for reading" );
1467 CHAR keyword[FLEN_KEYWORD];
1468 XLAL_CHECK_FAIL( CheckFITSKeyword( key, keyword, NULL ) == XLAL_SUCCESS, XLAL_EFUNC );
1469 XLAL_CHECK_FAIL( values != NULL, XLAL_EFAULT );
1470 XLAL_CHECK_FAIL( *values == NULL, XLAL_EFAULT );
1471
1472 // Read string values from current header
1473 CHAR vals[FFIO_MAX][FLEN_VALUE], *vals_ptr[FFIO_MAX];
1474 for ( int i = 0; i < FFIO_MAX; ++i ) {
1475 vals_ptr[i] = vals[i];
1476 }
1477 int nfound = 0;
1478 CALL_FITS( fits_read_keys_str, file->ff, keyword, 1, FFIO_MAX, vals_ptr, &nfound );
1479 XLAL_CHECK_FAIL( 0 < nfound, XLAL_EIO, "No items to read into string vector '%s'", keyword );
1480 XLAL_CHECK_FAIL( nfound <= FFIO_MAX, XLAL_EIO, "Too many items to read into string vector '%s'", keyword );
1481 for ( int i = 0; i < nfound; ++i ) {
1482 *values = XLALAppendString2Vector( *values, vals[i] );
1483 XLAL_CHECK_FAIL( *values != NULL, XLAL_EFUNC );
1484 }
1485
1486 return XLAL_SUCCESS;
1487
1488XLAL_FAIL:
1489 return XLAL_FAILURE;
1490
1491#endif // !defined(HAVE_LIBCFITSIO)
1492}
1493
1494int XLALFITSHeaderWriteGPSTime( FITSFile UNUSED *file, const CHAR UNUSED *key, const LIGOTimeGPS UNUSED *value, const CHAR UNUSED *comment )
1495{
1496#if !defined(HAVE_LIBCFITSIO)
1497 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
1498#else // defined(HAVE_LIBCFITSIO)
1499
1500 int UNUSED status = 0;
1501
1502 // Check input
1503 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
1504 XLAL_CHECK_FAIL( file->write, XLAL_EINVAL, "FITS file is not open for writing" );
1505 CHAR keyword[FLEN_KEYWORD];
1506 XLAL_CHECK_FAIL( CheckFITSKeyword( key, keyword, NULL ) == XLAL_SUCCESS, XLAL_EFUNC );
1507 XLAL_CHECK_FAIL( value != NULL, XLAL_EFAULT );
1509
1510 // Ensure GPS time is canonical
1511 LIGOTimeGPS gps;
1512 XLAL_CHECK_FAIL( XLALGPSSet( &gps, value->gpsSeconds, value->gpsNanoSeconds ) != NULL, XLAL_EFUNC );
1513
1514 // Write time in UTC format to current header
1515 struct tm XLAL_INIT_DECL( utc );
1516 XLAL_CHECK_FAIL( XLALGPSToUTC( &utc, gps.gpsSeconds ) != NULL, XLAL_EFUNC );
1517 utc.tm_year += 1900;
1518 utc.tm_mon += 1;
1519 CHAR utc_str[FLEN_VALUE];
1520 CALL_FITS( fits_time2str, utc.tm_year, utc.tm_mon, utc.tm_mday, utc.tm_hour, utc.tm_min, utc.tm_sec + ( gps.gpsNanoSeconds / XLAL_BILLION_REAL8 ), 9, utc_str );
1521 CALL_FITS( fits_write_key_str, file->ff, keyword, utc_str, comment );
1522
1523 // Write time in GPS seconds/nanoseconds format
1524 XLAL_CHECK_FAIL( 4 + strlen( keyword ) < FLEN_KEYWORD, XLAL_EINVAL, "Key '%s' is too long", keyword );
1525 CHAR buf[FLEN_KEYWORD - 4];
1526 strncpy( buf, keyword, sizeof( buf ) );
1527 snprintf( keyword, FLEN_KEYWORD, "%s GPS", buf );
1528 CHAR gps_str[FLEN_VALUE];
1529 XLAL_CHECK_FAIL( XLALGPSToStr( gps_str, &gps ) != NULL, XLAL_EFUNC );
1530 CALL_FITS( fits_write_key_str, file->ff, keyword, gps_str, "UTC value takes precedence" );
1531
1532 return XLAL_SUCCESS;
1533
1534XLAL_FAIL:
1535
1536 // Delete FITS file on error
1537 if ( file != NULL && file->ff != NULL ) {
1538 fits_delete_file( file->ff, &status );
1539 file->ff = NULL;
1540 }
1541
1542 return XLAL_FAILURE;
1543
1544#endif // !defined(HAVE_LIBCFITSIO)
1545}
1546
1547int XLALFITSHeaderReadGPSTime( FITSFile UNUSED *file, const CHAR UNUSED *key, LIGOTimeGPS UNUSED *value )
1548{
1549#if !defined(HAVE_LIBCFITSIO)
1550 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
1551#else // defined(HAVE_LIBCFITSIO)
1552
1553 int UNUSED status = 0;
1554 CHAR *utc_str = NULL;
1555
1556 // Check input
1557 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
1558 XLAL_CHECK_FAIL( !file->write, XLAL_EINVAL, "FITS file is not open for reading" );
1559 CHAR keyword[FLEN_KEYWORD];
1560 XLAL_CHECK_FAIL( CheckFITSKeyword( key, keyword, NULL ) == XLAL_SUCCESS, XLAL_EFUNC );
1561 XLAL_CHECK_FAIL( value != NULL, XLAL_EFAULT );
1562
1563 // Read time in UTC format from current header
1565 struct tm XLAL_INIT_DECL( utc );
1566 double sec = 0, int_sec = 0, frac_sec = 0;
1567 CALL_FITS( fits_str2time, utc_str, &utc.tm_year, &utc.tm_mon, &utc.tm_mday, &utc.tm_hour, &utc.tm_min, &sec );
1568 frac_sec = modf( sec, &int_sec );
1569 utc.tm_year -= 1900;
1570 utc.tm_mon -= 1;
1571 utc.tm_sec = lrint( int_sec );
1572 INT4 gps_sec = XLALUTCToGPS( &utc );
1574 INT4 gps_nsec = lrint( frac_sec * XLAL_BILLION_REAL8 );
1575 XLAL_CHECK_FAIL( XLALGPSSet( value, gps_sec, gps_nsec ) != NULL, XLAL_EFUNC );
1576
1577 XLALFree( utc_str );
1578 return XLAL_SUCCESS;
1579
1580XLAL_FAIL:
1581 XLALFree( utc_str );
1582 return XLAL_FAILURE;
1583
1584#endif // !defined(HAVE_LIBCFITSIO)
1585}
1586
1587int XLALFITSArrayOpenWrite( FITSFile UNUSED *file, const CHAR UNUSED *name, const size_t UNUSED ndim, const size_t UNUSED dims[], const CHAR UNUSED *comment )
1588{
1589#if !defined(HAVE_LIBCFITSIO)
1590 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
1591#else // defined(HAVE_LIBCFITSIO)
1592
1593 int UNUSED status = 0;
1594
1595 // Check input
1596 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
1597 XLAL_CHECK_FAIL( file->write, XLAL_EINVAL, "FITS file is not open for writing" );
1598 XLAL_CHECK_FAIL( name != NULL, XLAL_EFAULT );
1600 XLAL_CHECK_FAIL( dims != NULL, XLAL_EFAULT );
1601
1602 // Set current HDU
1603 file->hdutype = IMAGE_HDU;
1604 strncpy( file->hduname, name, sizeof( file->hduname ) - 1 );
1605 strncpy( file->hducomment, comment, sizeof( file->hducomment ) - 1 );
1606
1607 // Set current HDU data
1608 XLAL_INIT_MEM( file->array );
1609 file->array.bitpix = INT_MAX;
1610 file->array.datatype = INT_MAX;
1611
1612 // Save image dimensions
1613 file->array.naxis = ndim;
1614 for ( int i = 0; i < file->array.naxis; ++i ) {
1615 XLAL_CHECK_FAIL( dims[i] <= LONG_MAX, XLAL_ESIZE );
1616 file->array.naxes[i] = dims[i];
1617 }
1618
1619 return XLAL_SUCCESS;
1620
1621XLAL_FAIL:
1622
1623 // Delete FITS file on error
1624 if ( file != NULL && file->ff != NULL ) {
1625 fits_delete_file( file->ff, &status );
1626 file->ff = NULL;
1627 }
1628
1629 return XLAL_FAILURE;
1630
1631#endif // !defined(HAVE_LIBCFITSIO)
1632}
1633
1634int XLALFITSArrayOpenRead( FITSFile UNUSED *file, const CHAR UNUSED *name, size_t UNUSED *ndim, size_t UNUSED dims[] )
1635{
1636#if !defined(HAVE_LIBCFITSIO)
1637 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
1638#else // defined(HAVE_LIBCFITSIO)
1639
1640 int UNUSED status = 0;
1641
1642 // Check input
1643 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
1644 XLAL_CHECK_FAIL( !file->write, XLAL_EINVAL, "FITS file is not open for reading" );
1645 XLAL_CHECK_FAIL( name != NULL, XLAL_EFAULT );
1646 XLAL_CHECK_FAIL( ndim != NULL, XLAL_EFAULT );
1647 XLAL_CHECK_FAIL( dims != NULL, XLAL_EFAULT );
1648
1649 // Set current HDU
1650 file->hdutype = IMAGE_HDU;
1651 strncpy( file->hduname, name, sizeof( file->hduname ) - 1 );
1652
1653 // Set current HDU data
1654 XLAL_INIT_MEM( file->array );
1655 file->array.bitpix = INT_MAX;
1656 file->array.datatype = INT_MAX;
1657
1658 // Seek image HDU with given name, starting from primary HDU
1659 CALL_FITS( fits_movabs_hdu, file->ff, 1, NULL );
1660 CALL_FITS( fits_movnam_hdu, file->ff, file->hdutype, file->hduname, 0 );
1661
1662 // Get image dimensions
1663 CALL_FITS( fits_get_img_dim, file->ff, &file->array.naxis );
1664 *ndim = file->array.naxis;
1665 XLAL_CHECK_FAIL( *ndim <= FFIO_MAX, XLAL_ESIZE );
1666 CALL_FITS( fits_get_img_size, file->ff, file->array.naxis, file->array.naxes );
1667 for ( int i = 0; i < file->array.naxis; ++i ) {
1668 XLAL_CHECK_FAIL( 0 < file->array.naxes[i] && ( ( size_t ) file->array.naxes[i] ) <= SIZE_MAX, XLAL_ESIZE );
1669 dims[i] = file->array.naxes[i];
1670 }
1671
1672 return XLAL_SUCCESS;
1673
1674XLAL_FAIL:
1675 return XLAL_FAILURE;
1676
1677#endif // !defined(HAVE_LIBCFITSIO)
1678}
1679
1680int XLALFITSArrayOpenWrite1( FITSFile UNUSED *file, const CHAR UNUSED *name, const size_t UNUSED dim0, const CHAR UNUSED *comment )
1681{
1682#if !defined(HAVE_LIBCFITSIO)
1683 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
1684#else // defined(HAVE_LIBCFITSIO)
1685
1686 const size_t dims[1] = { dim0 };
1688 return XLAL_SUCCESS;
1689
1690#endif // !defined(HAVE_LIBCFITSIO)
1691}
1692
1693int XLALFITSArrayOpenRead1( FITSFile UNUSED *file, const CHAR UNUSED *name, size_t UNUSED *dim0 )
1694{
1695#if !defined(HAVE_LIBCFITSIO)
1696 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
1697#else // defined(HAVE_LIBCFITSIO)
1698
1699 size_t ndim = 0, dims[FFIO_MAX];
1701 XLAL_CHECK( ndim == 1, XLAL_EIO );
1702 if ( dim0 != NULL ) {
1703 *dim0 = dims[0];
1704 }
1705 return XLAL_SUCCESS;
1706
1707#endif // !defined(HAVE_LIBCFITSIO)
1708}
1709
1710int XLALFITSArrayOpenWrite2( FITSFile UNUSED *file, const CHAR UNUSED *name, const size_t UNUSED dim0, const size_t UNUSED dim1, const CHAR UNUSED *comment )
1711{
1712#if !defined(HAVE_LIBCFITSIO)
1713 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
1714#else // defined(HAVE_LIBCFITSIO)
1715
1716 const size_t dims[2] = { dim0, dim1 };
1718 return XLAL_SUCCESS;
1719
1720#endif // !defined(HAVE_LIBCFITSIO)
1721}
1722
1723int XLALFITSArrayOpenRead2( FITSFile UNUSED *file, const CHAR UNUSED *name, size_t UNUSED *dim0, size_t UNUSED *dim1 )
1724{
1725#if !defined(HAVE_LIBCFITSIO)
1726 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
1727#else // defined(HAVE_LIBCFITSIO)
1728
1729 size_t ndim = 0, dims[FFIO_MAX];
1731 XLAL_CHECK( ndim == 2, XLAL_EIO );
1732 if ( dim0 != NULL ) {
1733 *dim0 = dims[0];
1734 }
1735 if ( dim1 != NULL ) {
1736 *dim1 = dims[1];
1737 }
1738 return XLAL_SUCCESS;
1739
1740#endif // !defined(HAVE_LIBCFITSIO)
1741}
1742
1743static int UNUSED XLALFITSArrayWrite( FITSFile UNUSED *file, const size_t UNUSED idx[], const int UNUSED bitpix, const int UNUSED datatype, const void UNUSED *elem )
1744{
1745#if !defined(HAVE_LIBCFITSIO)
1746 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
1747#else // defined(HAVE_LIBCFITSIO)
1748
1749 int UNUSED status = 0;
1750
1751 // Check input
1752 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
1753 XLAL_CHECK_FAIL( file->write, XLAL_EINVAL, "FITS file is not open for writing" );
1754 XLAL_CHECK_FAIL( idx != 0, XLAL_EINVAL );
1755 XLAL_CHECK_FAIL( elem != NULL, XLAL_EFAULT );
1756
1757 // Check that we are at an array
1758 XLAL_CHECK_FAIL( file->hdutype == IMAGE_HDU, XLAL_EIO, "Current FITS file HDU is not an array" );
1759
1760 // Check for valid array indexes
1761 for ( int i = 0; i < file->array.naxis; ++i ) {
1762 XLAL_CHECK_FAIL( ( ( long ) idx[i] ) < file->array.naxes[i], XLAL_EDOM, "Array index #%i out of range (%zu >= %li)", i, idx[i], file->array.naxes[i] );
1763 }
1764
1765 // Check for bitpix/datatype consistency
1766 if ( file->array.bitpix == INT_MAX || file->array.datatype == INT_MAX ) {
1767 file->array.bitpix = bitpix;
1768 file->array.datatype = datatype;
1769
1770 // Create a new FITS image to store array
1771 CALL_FITS( fits_create_img, file->ff, bitpix, file->array.naxis, file->array.naxes );
1772 CALL_FITS( fits_write_key_str, file->ff, "HDUNAME", file->hduname, file->hducomment );
1773 CALL_FITS( fits_write_key_str, file->ff, "EXTNAME", file->hduname, file->hducomment ); /* synonym of HDUNAME */
1774
1775 } else {
1776 XLAL_CHECK_FAIL( file->array.bitpix == bitpix && file->array.datatype == datatype, XLAL_EINVAL, "Inconsistent use of %s...() functions", __func__ );
1777 }
1778
1779 // Write array element
1780 long fpixel[FFIO_MAX];
1781 for ( int i = 0; i < file->array.naxis; ++i ) {
1782 fpixel[i] = 1 + idx[i];
1783 }
1784 union {
1785 const void *cv;
1786 CHAR *c;
1787 } bad_cast = { .cv = elem };
1788 CALL_FITS( fits_write_pix, file->ff, file->array.datatype, fpixel, 1, bad_cast.c );
1789
1790 return XLAL_SUCCESS;
1791
1792XLAL_FAIL:
1793
1794 // Delete FITS file on error
1795 if ( file != NULL && file->ff != NULL ) {
1796 fits_delete_file( file->ff, &status );
1797 file->ff = NULL;
1798 }
1799
1800 return XLAL_FAILURE;
1801
1802#endif // !defined(HAVE_LIBCFITSIO)
1803}
1804
1805static int UNUSED XLALFITSArrayRead( FITSFile UNUSED *file, const size_t UNUSED idx[], const int UNUSED bitpix, const int UNUSED datatype, void UNUSED *elem, void UNUSED *nulelem )
1806{
1807#if !defined(HAVE_LIBCFITSIO)
1808 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
1809#else // defined(HAVE_LIBCFITSIO)
1810
1811 int UNUSED status = 0;
1812
1813 // Check input
1814 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
1815 XLAL_CHECK_FAIL( !file->write, XLAL_EINVAL, "FITS file is not open for reading" );
1816 XLAL_CHECK_FAIL( idx != 0, XLAL_EINVAL );
1817 XLAL_CHECK_FAIL( elem != NULL, XLAL_EFAULT );
1818 XLAL_CHECK_FAIL( nulelem != NULL, XLAL_EFAULT );
1819
1820 // Check that we are at an array
1821 XLAL_CHECK_FAIL( file->hdutype == IMAGE_HDU, XLAL_EIO, "Current FITS file HDU is not an array" );
1822
1823 // Check for valid array indexes
1824 for ( int i = 0; i < file->array.naxis; ++i ) {
1825 XLAL_CHECK_FAIL( ( ( long ) idx[i] ) < file->array.naxes[i], XLAL_EDOM, "Array index #%i out of range (%zu >= %li)", i, idx[i], file->array.naxes[i] );
1826 }
1827
1828 // Check for bitpix/datatype consistency
1829 if ( file->array.bitpix == INT_MAX || file->array.datatype == INT_MAX ) {
1830 file->array.bitpix = bitpix;
1831 file->array.datatype = datatype;
1832 } else {
1833 XLAL_CHECK_FAIL( file->array.bitpix == bitpix && file->array.datatype == datatype, XLAL_EINVAL, "Inconsistent use of %s...() functions", __func__ );
1834 }
1835
1836 // Read array elememt
1837 long fpixel[FFIO_MAX];
1838 for ( int i = 0; i < file->array.naxis; ++i ) {
1839 fpixel[i] = 1 + idx[i];
1840 }
1841 int anynul = 0;
1842 CALL_FITS( fits_read_pix, file->ff, datatype, fpixel, 1, nulelem, elem, &anynul );
1843
1844 return XLAL_SUCCESS;
1845
1846XLAL_FAIL:
1847 return XLAL_FAILURE;
1848
1849#endif // !defined(HAVE_LIBCFITSIO)
1850}
1851
1852int XLALFITSArrayWriteUINT2( FITSFile UNUSED *file, const size_t UNUSED idx[], const UINT2 UNUSED elem )
1853{
1854#if !defined(HAVE_LIBCFITSIO)
1855 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
1856#else // defined(HAVE_LIBCFITSIO)
1857
1858 const unsigned short e = elem;
1859 XLAL_CHECK( XLALFITSArrayWrite( file, idx, USHORT_IMG, TUSHORT, &e ) == XLAL_SUCCESS, XLAL_EFUNC );
1860 return XLAL_SUCCESS;
1861
1862#endif // !defined(HAVE_LIBCFITSIO)
1863}
1864
1865int XLALFITSArrayReadUINT2( FITSFile UNUSED *file, const size_t UNUSED idx[], UINT2 UNUSED *elem )
1866{
1867#if !defined(HAVE_LIBCFITSIO)
1868 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
1869#else // defined(HAVE_LIBCFITSIO)
1870
1871 unsigned short e = 0, ne = 0;
1872 XLAL_CHECK( XLALFITSArrayRead( file, idx, USHORT_IMG, TUSHORT, &e, &ne ) == XLAL_SUCCESS, XLAL_EFUNC );
1873 *elem = e;
1874 return XLAL_SUCCESS;
1875
1876#endif // !defined(HAVE_LIBCFITSIO)
1877}
1878
1879int XLALFITSArrayWriteUINT4( FITSFile UNUSED *file, const size_t UNUSED idx[], const UINT4 UNUSED elem )
1880{
1881#if !defined(HAVE_LIBCFITSIO)
1882 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
1883#else // defined(HAVE_LIBCFITSIO)
1884
1885 const unsigned long e = elem;
1886 XLAL_CHECK( XLALFITSArrayWrite( file, idx, ULONG_IMG, TULONG, &e ) == XLAL_SUCCESS, XLAL_EFUNC );
1887 return XLAL_SUCCESS;
1888
1889#endif // !defined(HAVE_LIBCFITSIO)
1890}
1891
1892int XLALFITSArrayReadUINT4( FITSFile UNUSED *file, const size_t UNUSED idx[], UINT4 UNUSED *elem )
1893{
1894#if !defined(HAVE_LIBCFITSIO)
1895 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
1896#else // defined(HAVE_LIBCFITSIO)
1897
1898 unsigned long e = 0, ne = 0;
1899 XLAL_CHECK( XLALFITSArrayRead( file, idx, ULONG_IMG, TULONG, &e, &ne ) == XLAL_SUCCESS, XLAL_EFUNC );
1900 *elem = e;
1901 return XLAL_SUCCESS;
1902
1903#endif // !defined(HAVE_LIBCFITSIO)
1904}
1905
1906int XLALFITSArrayWriteUINT8( FITSFile UNUSED *file, const size_t UNUSED idx[], const UINT8 UNUSED elem )
1907{
1908#if !defined(HAVE_LIBCFITSIO)
1909 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
1910#else // defined(HAVE_LIBCFITSIO)
1911
1912 XLAL_CHECK( elem <= LONGLONG_MAX, XLAL_ERANGE );
1913 const LONGLONG e = elem;
1914 XLAL_CHECK( XLALFITSArrayWrite( file, idx, LONGLONG_IMG, TLONGLONG, &e ) == XLAL_SUCCESS, XLAL_EFUNC );
1915 return XLAL_SUCCESS;
1916
1917#endif // !defined(HAVE_LIBCFITSIO)
1918}
1919
1920int XLALFITSArrayReadUINT8( FITSFile UNUSED *file, const size_t UNUSED idx[], UINT8 UNUSED *elem )
1921{
1922#if !defined(HAVE_LIBCFITSIO)
1923 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
1924#else // defined(HAVE_LIBCFITSIO)
1925
1926 LONGLONG e = 0, ne = 0;
1927 XLAL_CHECK( XLALFITSArrayRead( file, idx, LONGLONG_IMG, TLONGLONG, &e, &ne ) == XLAL_SUCCESS, XLAL_EFUNC );
1928 XLAL_CHECK( 0 <= e && ( ( UINT8 ) e ) <= UINT64_MAX, XLAL_ERANGE );
1929 *elem = e;
1930 return XLAL_SUCCESS;
1931
1932#endif // !defined(HAVE_LIBCFITSIO)
1933}
1934
1935int XLALFITSArrayWriteINT2( FITSFile UNUSED *file, const size_t UNUSED idx[], const INT2 UNUSED elem )
1936{
1937#if !defined(HAVE_LIBCFITSIO)
1938 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
1939#else // defined(HAVE_LIBCFITSIO)
1940
1941 const short e = elem;
1942 XLAL_CHECK( XLALFITSArrayWrite( file, idx, SHORT_IMG, TSHORT, &e ) == XLAL_SUCCESS, XLAL_EFUNC );
1943 return XLAL_SUCCESS;
1944
1945#endif // !defined(HAVE_LIBCFITSIO)
1946}
1947
1948int XLALFITSArrayReadINT2( FITSFile UNUSED *file, const size_t UNUSED idx[], INT2 UNUSED *elem )
1949{
1950#if !defined(HAVE_LIBCFITSIO)
1951 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
1952#else // defined(HAVE_LIBCFITSIO)
1953
1954 short e = 0, ne = 0;
1955 XLAL_CHECK( XLALFITSArrayRead( file, idx, SHORT_IMG, TSHORT, &e, &ne ) == XLAL_SUCCESS, XLAL_EFUNC );
1956 *elem = e;
1957 return XLAL_SUCCESS;
1958
1959#endif // !defined(HAVE_LIBCFITSIO)
1960}
1961
1962int XLALFITSArrayWriteINT4( FITSFile UNUSED *file, const size_t UNUSED idx[], const INT4 UNUSED elem )
1963{
1964#if !defined(HAVE_LIBCFITSIO)
1965 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
1966#else // defined(HAVE_LIBCFITSIO)
1967
1968 const long e = elem;
1969 XLAL_CHECK( XLALFITSArrayWrite( file, idx, LONG_IMG, TLONG, &e ) == XLAL_SUCCESS, XLAL_EFUNC );
1970 return XLAL_SUCCESS;
1971
1972#endif // !defined(HAVE_LIBCFITSIO)
1973}
1974
1975int XLALFITSArrayReadINT4( FITSFile UNUSED *file, const size_t UNUSED idx[], INT4 UNUSED *elem )
1976{
1977#if !defined(HAVE_LIBCFITSIO)
1978 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
1979#else // defined(HAVE_LIBCFITSIO)
1980
1981 long e = 0, ne = 0;
1982 XLAL_CHECK( XLALFITSArrayRead( file, idx, LONG_IMG, TLONG, &e, &ne ) == XLAL_SUCCESS, XLAL_EFUNC );
1983 *elem = e;
1984 return XLAL_SUCCESS;
1985
1986#endif // !defined(HAVE_LIBCFITSIO)
1987}
1988
1989int XLALFITSArrayWriteINT8( FITSFile UNUSED *file, const size_t UNUSED idx[], const INT8 UNUSED elem )
1990{
1991#if !defined(HAVE_LIBCFITSIO)
1992 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
1993#else // defined(HAVE_LIBCFITSIO)
1994
1995 const LONGLONG e = elem;
1996 XLAL_CHECK( XLALFITSArrayWrite( file, idx, LONGLONG_IMG, TLONGLONG, &e ) == XLAL_SUCCESS, XLAL_EFUNC );
1997 return XLAL_SUCCESS;
1998
1999#endif // !defined(HAVE_LIBCFITSIO)
2000}
2001
2002int XLALFITSArrayReadINT8( FITSFile UNUSED *file, const size_t UNUSED idx[], INT8 UNUSED *elem )
2003{
2004#if !defined(HAVE_LIBCFITSIO)
2005 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
2006#else // defined(HAVE_LIBCFITSIO)
2007
2008 LONGLONG e = 0, ne = 0;
2009 XLAL_CHECK( XLALFITSArrayRead( file, idx, LONGLONG_IMG, TLONGLONG, &e, &ne ) == XLAL_SUCCESS, XLAL_EFUNC );
2010 *elem = e;
2011 return XLAL_SUCCESS;
2012
2013#endif // !defined(HAVE_LIBCFITSIO)
2014}
2015
2016int XLALFITSArrayWriteREAL4( FITSFile UNUSED *file, const size_t UNUSED idx[], const REAL4 UNUSED elem )
2017{
2018#if !defined(HAVE_LIBCFITSIO)
2019 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
2020#else // defined(HAVE_LIBCFITSIO)
2021
2022 const float e = elem;
2023 XLAL_CHECK( XLALFITSArrayWrite( file, idx, FLOAT_IMG, TFLOAT, &e ) == XLAL_SUCCESS, XLAL_EFUNC );
2024 return XLAL_SUCCESS;
2025
2026#endif // !defined(HAVE_LIBCFITSIO)
2027}
2028
2029int XLALFITSArrayReadREAL4( FITSFile UNUSED *file, const size_t UNUSED idx[], REAL4 UNUSED *elem )
2030{
2031#if !defined(HAVE_LIBCFITSIO)
2032 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
2033#else // defined(HAVE_LIBCFITSIO)
2034
2035 float e = 0, ne = 0;
2036 XLAL_CHECK( XLALFITSArrayRead( file, idx, FLOAT_IMG, TFLOAT, &e, &ne ) == XLAL_SUCCESS, XLAL_EFUNC );
2037 *elem = e;
2038 return XLAL_SUCCESS;
2039
2040#endif // !defined(HAVE_LIBCFITSIO)
2041}
2042
2043int XLALFITSArrayWriteREAL8( FITSFile UNUSED *file, const size_t UNUSED idx[], const REAL8 UNUSED elem )
2044{
2045#if !defined(HAVE_LIBCFITSIO)
2046 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
2047#else // defined(HAVE_LIBCFITSIO)
2048
2049 const double e = elem;
2050 XLAL_CHECK( XLALFITSArrayWrite( file, idx, DOUBLE_IMG, TDOUBLE, &e ) == XLAL_SUCCESS, XLAL_EFUNC );
2051 return XLAL_SUCCESS;
2052
2053#endif // !defined(HAVE_LIBCFITSIO)
2054}
2055
2056int XLALFITSArrayReadREAL8( FITSFile UNUSED *file, const size_t UNUSED idx[], REAL8 UNUSED *elem )
2057{
2058#if !defined(HAVE_LIBCFITSIO)
2059 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
2060#else // defined(HAVE_LIBCFITSIO)
2061
2062 double e = 0, ne = 0;
2063 XLAL_CHECK( XLALFITSArrayRead( file, idx, DOUBLE_IMG, TDOUBLE, &e, &ne ) == XLAL_SUCCESS, XLAL_EFUNC );
2064 *elem = e;
2065 return XLAL_SUCCESS;
2066
2067#endif // !defined(HAVE_LIBCFITSIO)
2068}
2069
2070int XLALFITSArrayWriteGSLMatrix( FITSFile UNUSED *file, const size_t UNUSED idx[], const gsl_matrix UNUSED *elems )
2071{
2072#if !defined(HAVE_LIBCFITSIO)
2073 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
2074#else // defined(HAVE_LIBCFITSIO)
2075
2076 int UNUSED status = 0;
2077
2078 // Check input
2079 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
2080 XLAL_CHECK_FAIL( file->write, XLAL_EINVAL, "FITS file is not open for writing" );
2081 XLAL_CHECK_FAIL( elems != NULL, XLAL_EFAULT );
2082
2083 // Check that we are at an array of sufficient size
2084 XLAL_CHECK_FAIL( file->hdutype == IMAGE_HDU, XLAL_EIO, "Current FITS file HDU is not an array" );
2085 XLAL_CHECK_FAIL( file->array.naxis >= 2, XLAL_EINVAL, "Array must have at least 2 dimensions" );
2086 XLAL_CHECK_FAIL( elems->size1 == ( size_t ) file->array.naxes[0], XLAL_EINVAL, "Number of 'elems' rows (%zu) does not match array dimension 0 (%li)", elems->size1, file->array.naxes[0] );
2087 XLAL_CHECK_FAIL( elems->size2 == ( size_t ) file->array.naxes[1], XLAL_EINVAL, "Number of 'elems' rows (%zu) does not match array dimension 1 (%li)", elems->size2, file->array.naxes[1] );
2088
2089 // Copy index vector, if given
2090 size_t XLAL_INIT_DECL( i, [FFIO_MAX] );
2091 if ( idx != NULL ) {
2092 memcpy( i, idx, file->array.naxis * sizeof( i[0] ) );
2093 }
2094
2095 // Write GSL matrix elements to first 2 dimensions
2096 for ( i[0] = 0; i[0] < ( size_t ) file->array.naxes[0]; ++i[0] ) {
2097 for ( i[1] = 0; i[1] < ( size_t ) file->array.naxes[1]; ++i[1] ) {
2098 const REAL8 elem = gsl_matrix_get( elems, i[0], i[1] );
2100 }
2101 }
2102
2103 return XLAL_SUCCESS;
2104
2105XLAL_FAIL:
2106
2107 // Delete FITS file on error
2108 if ( file != NULL && file->ff != NULL ) {
2109 fits_delete_file( file->ff, &status );
2110 file->ff = NULL;
2111 }
2112
2113 return XLAL_FAILURE;
2114
2115#endif // !defined(HAVE_LIBCFITSIO)
2116}
2117
2118int XLALFITSArrayReadGSLMatrix( FITSFile UNUSED *file, const size_t UNUSED idx[], gsl_matrix UNUSED **elems )
2119{
2120#if !defined(HAVE_LIBCFITSIO)
2121 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
2122#else // defined(HAVE_LIBCFITSIO)
2123
2124 int UNUSED status = 0;
2125
2126 // Check input
2127 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
2128 XLAL_CHECK_FAIL( !file->write, XLAL_EINVAL, "FITS file is not open for reading" );
2129 XLAL_CHECK_FAIL( elems != NULL, XLAL_EFAULT );
2130 XLAL_CHECK_FAIL( *elems == NULL, XLAL_EINVAL );
2131
2132 // Check that we are at an array of sufficient size
2133 XLAL_CHECK_FAIL( file->hdutype == IMAGE_HDU, XLAL_EIO, "Current FITS file HDU is not an array" );
2134 XLAL_CHECK_FAIL( file->array.naxis >= 2, XLAL_EINVAL, "Array must have at least 2 dimensions" );
2135
2136 // Create GSL matrix
2137 GAMAT( *elems, file->array.naxes[0], file->array.naxes[1] );
2138
2139 // Copy index vector, if given
2140 size_t XLAL_INIT_DECL( i, [FFIO_MAX] );
2141 if ( idx != NULL ) {
2142 memcpy( i, idx, file->array.naxis * sizeof( i[0] ) );
2143 }
2144
2145 // Read GSL matrix elements from first 2 dimensions
2146 for ( i[0] = 0; i[0] < ( size_t ) file->array.naxes[0]; ++i[0] ) {
2147 for ( i[1] = 0; i[1] < ( size_t ) file->array.naxes[1]; ++i[1] ) {
2148 REAL8 elem = 0;
2150 gsl_matrix_set( *elems, i[0], i[1], elem );
2151 }
2152 }
2153
2154 return XLAL_SUCCESS;
2155
2156XLAL_FAIL:
2157 return XLAL_FAILURE;
2158
2159#endif // !defined(HAVE_LIBCFITSIO)
2160}
2161
2162int XLALFITSTableOpenWrite( FITSFile UNUSED *file, const CHAR UNUSED *name, const CHAR UNUSED *comment )
2163{
2164#if !defined(HAVE_LIBCFITSIO)
2165 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
2166#else // defined(HAVE_LIBCFITSIO)
2167
2168 int UNUSED status = 0;
2169
2170 // Check input
2171 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
2172 XLAL_CHECK_FAIL( file->write, XLAL_EINVAL, "FITS file is not open for writing" );
2173 XLAL_CHECK_FAIL( name != NULL, XLAL_EFAULT );
2174
2175 // Set current HDU
2176 file->hdutype = BINARY_TBL;
2177 strncpy( file->hduname, name, sizeof( file->hduname ) - 1 );
2178 strncpy( file->hducomment, comment, sizeof( file->hducomment ) - 1 );
2179
2180 // Set current HDU data
2181 XLAL_INIT_MEM( file->table );
2182
2183 return XLAL_SUCCESS;
2184
2185XLAL_FAIL:
2186
2187 // Delete FITS file on error
2188 if ( file != NULL && file->ff != NULL ) {
2189 fits_delete_file( file->ff, &status );
2190 file->ff = NULL;
2191 }
2192
2193 return XLAL_FAILURE;
2194
2195#endif // !defined(HAVE_LIBCFITSIO)
2196}
2197
2198int XLALFITSTableOpenRead( FITSFile UNUSED *file, const CHAR UNUSED *name, UINT8 UNUSED *nrows )
2199{
2200#if !defined(HAVE_LIBCFITSIO)
2201 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
2202#else // defined(HAVE_LIBCFITSIO)
2203
2204 int UNUSED status = 0;
2205
2206 // Check input
2207 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
2208 XLAL_CHECK_FAIL( !file->write, XLAL_EINVAL, "FITS file is not open for reading" );
2209 XLAL_CHECK_FAIL( name != NULL, XLAL_EFAULT );
2210
2211 // Set current HDU
2212 file->hdutype = BINARY_TBL;
2213 strncpy( file->hduname, name, sizeof( file->hduname ) - 1 );
2214
2215 // Set current HDU data
2216 XLAL_INIT_MEM( file->table );
2217
2218 // Seek table HDU with given name, starting from primary HDU
2219 CALL_FITS( fits_movabs_hdu, file->ff, 1, NULL );
2220 CALL_FITS( fits_movnam_hdu, file->ff, file->hdutype, file->hduname, 0 );
2221
2222 // Get number of table rows
2223 CALL_FITS( fits_get_num_rowsll, file->ff, &file->table.nrows );
2224 if ( nrows != NULL ) {
2225 *nrows = file->table.nrows;
2226 }
2227
2228 return XLAL_SUCCESS;
2229
2230XLAL_FAIL:
2231 return XLAL_FAILURE;
2232
2233#endif // !defined(HAVE_LIBCFITSIO)
2234}
2235
2236static int UNUSED XLALFITSTableColumnAdd( FITSFile UNUSED *file, const CHAR UNUSED *name, const CHAR UNUSED *unit, const size_t UNUSED noffsets, const size_t UNUSED offsets[2], const void UNUSED *record, const size_t UNUSED record_size, const void UNUSED *field, const size_t UNUSED field_size, const size_t UNUSED elem_size, const int UNUSED typechar, const int UNUSED datatype )
2237{
2238#if !defined(HAVE_LIBCFITSIO)
2239 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
2240#else // defined(HAVE_LIBCFITSIO)
2241
2242 int UNUSED status = 0;
2243
2244 // Save previous number of table columns
2245 const int save_tfields = ( file != NULL ) ? file->table.tfields : 0;
2246
2247 // Check input
2248 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
2249 XLAL_CHECK_FAIL( name != NULL, XLAL_EFAULT );
2250 XLAL_CHECK_FAIL( unit != NULL, XLAL_EFAULT );
2251 XLAL_CHECK_FAIL( 0 < noffsets && noffsets <= 2, XLAL_EINVAL );
2252 XLAL_CHECK_FAIL( offsets != NULL, XLAL_EFAULT );
2253 XLAL_CHECK_FAIL( record != NULL, XLAL_EFAULT );
2254 XLAL_CHECK_FAIL( record_size > 0, XLAL_EINVAL );
2255 XLAL_CHECK_FAIL( field != NULL, XLAL_EFAULT );
2256 XLAL_CHECK_FAIL( field_size > 0, XLAL_EINVAL );
2257 XLAL_CHECK_FAIL( ( ( intptr_t ) field ) >= ( ( intptr_t ) record ), XLAL_EINVAL, "Invalid field pointer" );
2258 XLAL_CHECK_FAIL( ( ( intptr_t ) field ) + field_size <= ( ( intptr_t ) record ) + record_size, XLAL_EINVAL, "Invalid field pointer" );
2259 XLAL_CHECK_FAIL( elem_size > 0, XLAL_EINVAL );
2260
2261 // Check that we are at a table
2262 XLAL_CHECK_FAIL( file->hdutype == BINARY_TBL, XLAL_EIO, "Current FITS file HDU is not a table" );
2263
2264 // Move to next column
2265 XLAL_CHECK_FAIL( file->table.tfields <= FFIO_MAX, XLAL_ESIZE );
2266 const int i = file->table.tfields++;
2267
2268 // Store field size
2269 file->table.field_size[i] = field_size;
2270
2271 // Store field offsets
2272 file->table.noffsets[i] = noffsets;
2273 memcpy( file->table.offsets[i], offsets, sizeof( file->table.offsets[i] ) );
2274 file->table.offsets[i][noffsets - 1] = ( size_t )( ( ( intptr_t ) field ) - ( ( intptr_t ) record ) );
2275
2276 // Copy column name
2277 snprintf( file->table.ttype[i], sizeof( file->table.ttype[i] ), "%s", name );
2278
2279 // Copy column unit
2280 snprintf( file->table.tunit[i], sizeof( file->table.tunit[i] ), "%s", unit );
2281
2282 // Create column format
2283 snprintf( file->table.tform[i], sizeof( file->table.tform[i] ), "%zu%c", field_size / elem_size, typechar );
2284
2285 // Store column datatype and number of elements
2286 file->table.datatype[i] = datatype;
2287 file->table.nelements[i] = ( datatype == TSTRING ) ? 1 : field_size / elem_size;
2288
2289 if ( file->write ) {
2290
2291 // Store column index
2292 file->table.colnum[i] = 1 + i;
2293
2294 } else {
2295
2296 // Search for existing column and retrieve column index
2297 CALL_FITS( fits_get_colnum, file->ff, CASEINSEN, file->table.ttype[i], &file->table.colnum[i] );
2298 XLAL_CHECK_FAIL( file->table.colnum[i] > 0, XLAL_EIO );
2299
2300 // Verify existing column format
2301 int datatype_chk = 0;
2302 long repeat_chk = 0, width_chk = 0;
2303 CALL_FITS( fits_get_coltype, file->ff, file->table.colnum[i], &datatype_chk, &repeat_chk, &width_chk );
2304 if ( datatype_chk == TLONG ) {
2305 datatype_chk = TINT;
2306 }
2307 XLAL_CHECK_FAIL( datatype_chk == datatype, XLAL_EIO, "Inconsistent column #%i datatype %i; should be %i", i, datatype_chk, datatype );
2308 const size_t elem_size_chk = ( datatype_chk == TSTRING ) ? 1 : width_chk;
2309 const size_t field_size_chk = repeat_chk * elem_size_chk;
2310 XLAL_CHECK_FAIL( field_size_chk == field_size, XLAL_EIO, "Inconsistent column #%i field size %zu; should be %zu", i, field_size_chk, field_size );
2311 XLAL_CHECK_FAIL( elem_size_chk == elem_size, XLAL_EIO, "Inconsistent column #%i element size %zu; should be %zu", i, elem_size_chk, elem_size );
2312
2313 }
2314
2315 return XLAL_SUCCESS;
2316
2317XLAL_FAIL:
2318
2319 // Restore previous number of table columns
2320 if ( file != NULL ) {
2321 file->table.tfields = save_tfields;
2322 }
2323
2324 return XLAL_FAILURE;
2325
2326#endif // !defined(HAVE_LIBCFITSIO)
2327}
2328
2329int XLALFITSTableColumnAddBOOLEAN( FITSFile UNUSED *file, const CHAR UNUSED *col_name, const size_t UNUSED noffsets, const size_t UNUSED offsets[2], const void UNUSED *record, const size_t UNUSED record_size, const BOOLEAN UNUSED *field, const size_t UNUSED field_size )
2330{
2331#if !defined(HAVE_LIBCFITSIO)
2332 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
2333#else // defined(HAVE_LIBCFITSIO)
2334
2335 XLAL_CHECK( sizeof( *field ) == sizeof( char ), XLAL_ESIZE ); // Double-check that size of LAL type matches that of C type used by CFITSIO in e.g. ffgcv()
2336 XLAL_CHECK( col_name != NULL, XLAL_EFAULT );
2337 XLAL_CHECK( strlen( col_name ) < FLEN_VALUE, XLAL_EINVAL, "Column name '%s' is too long", col_name );
2338 XLAL_CHECK( XLALFITSTableColumnAdd( file, col_name, "", noffsets, offsets, record, record_size, field, field_size, sizeof( *field ), 'L', TLOGICAL ) == XLAL_SUCCESS, XLAL_EFUNC );
2339 return XLAL_SUCCESS;
2340
2341#endif // !defined(HAVE_LIBCFITSIO)
2342}
2343
2344int XLALFITSTableColumnAddUINT2( FITSFile UNUSED *file, const CHAR UNUSED *col_name, const size_t UNUSED noffsets, const size_t UNUSED offsets[2], const void UNUSED *record, const size_t UNUSED record_size, const UINT2 UNUSED *field, const size_t UNUSED field_size )
2345{
2346#if !defined(HAVE_LIBCFITSIO)
2347 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
2348#else // defined(HAVE_LIBCFITSIO)
2349
2350 XLAL_CHECK( sizeof( *field ) == sizeof( unsigned short ), XLAL_ESIZE ); // Double-check that size of LAL type matches that of C type used by CFITSIO in e.g. ffgcv()
2351 XLAL_CHECK( col_name != NULL, XLAL_EFAULT );
2352 XLAL_CHECK( strlen( col_name ) < FLEN_VALUE, XLAL_EINVAL, "Column name '%s' is too long", col_name );
2353 CHAR name[FLEN_VALUE], unit[FLEN_VALUE];
2354 XLAL_CHECK( ExtractUnit( col_name, name, unit ) == XLAL_SUCCESS, XLAL_EINVAL );
2355 XLAL_CHECK( XLALFITSTableColumnAdd( file, name, unit, noffsets, offsets, record, record_size, field, field_size, sizeof( *field ), 'U', TUSHORT ) == XLAL_SUCCESS, XLAL_EFUNC );
2356 return XLAL_SUCCESS;
2357
2358#endif // !defined(HAVE_LIBCFITSIO)
2359}
2360
2361int XLALFITSTableColumnAddUINT4( FITSFile UNUSED *file, const CHAR UNUSED *col_name, const size_t UNUSED noffsets, const size_t UNUSED offsets[2], const void UNUSED *record, const size_t UNUSED record_size, const UINT4 UNUSED *field, const size_t UNUSED field_size )
2362{
2363#if !defined(HAVE_LIBCFITSIO)
2364 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
2365#else // defined(HAVE_LIBCFITSIO)
2366
2367 XLAL_CHECK( sizeof( *field ) == sizeof( unsigned int ), XLAL_ESIZE ); // Double-check that size of LAL type matches that of C type used by CFITSIO in e.g. ffgcv()
2368 XLAL_CHECK( col_name != NULL, XLAL_EFAULT );
2369 XLAL_CHECK( strlen( col_name ) < FLEN_VALUE, XLAL_EINVAL, "Column name '%s' is too long", col_name );
2370 CHAR name[FLEN_VALUE], unit[FLEN_VALUE];
2371 XLAL_CHECK( ExtractUnit( col_name, name, unit ) == XLAL_SUCCESS, XLAL_EINVAL );
2372 XLAL_CHECK( XLALFITSTableColumnAdd( file, name, unit, noffsets, offsets, record, record_size, field, field_size, sizeof( *field ), 'V', TINT ) == XLAL_SUCCESS, XLAL_EFUNC );
2373 return XLAL_SUCCESS;
2374
2375#endif // !defined(HAVE_LIBCFITSIO)
2376}
2377
2378int XLALFITSTableColumnAddUINT8( FITSFile UNUSED *file, const CHAR UNUSED *col_name, const size_t UNUSED noffsets, const size_t UNUSED offsets[2], const void UNUSED *record, const size_t UNUSED record_size, const UINT8 UNUSED *field, const size_t UNUSED field_size )
2379{
2380#if !defined(HAVE_LIBCFITSIO)
2381 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
2382#else // defined(HAVE_LIBCFITSIO)
2383
2384 XLAL_CHECK( sizeof( *field ) == sizeof( LONGLONG ), XLAL_ESIZE ); // Double-check that size of LAL type matches that of C type used by CFITSIO in e.g. ffgcv()
2385 XLAL_CHECK( col_name != NULL, XLAL_EFAULT );
2386 XLAL_CHECK( strlen( col_name ) < FLEN_VALUE, XLAL_EINVAL, "Column name '%s' is too long", col_name );
2387 CHAR name[FLEN_VALUE], unit[FLEN_VALUE];
2388 XLAL_CHECK( ExtractUnit( col_name, name, unit ) == XLAL_SUCCESS, XLAL_EINVAL );
2389 XLAL_CHECK( XLALFITSTableColumnAdd( file, name, unit, noffsets, offsets, record, record_size, field, field_size, sizeof( *field ), 'K', TLONGLONG ) == XLAL_SUCCESS, XLAL_EFUNC );
2390 return XLAL_SUCCESS;
2391
2392#endif // !defined(HAVE_LIBCFITSIO)
2393}
2394
2395int XLALFITSTableColumnAddINT2( FITSFile UNUSED *file, const CHAR UNUSED *col_name, const size_t UNUSED noffsets, const size_t UNUSED offsets[2], const void UNUSED *record, const size_t UNUSED record_size, const INT2 UNUSED *field, const size_t UNUSED field_size )
2396{
2397#if !defined(HAVE_LIBCFITSIO)
2398 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
2399#else // defined(HAVE_LIBCFITSIO)
2400
2401 XLAL_CHECK( sizeof( *field ) == sizeof( short ), XLAL_ESIZE ); // Double-check that size of LAL type matches that of C type used by CFITSIO in e.g. ffgcv()
2402 XLAL_CHECK( col_name != NULL, XLAL_EFAULT );
2403 XLAL_CHECK( strlen( col_name ) < FLEN_VALUE, XLAL_EINVAL, "Column name '%s' is too long", col_name );
2404 CHAR name[FLEN_VALUE], unit[FLEN_VALUE];
2405 XLAL_CHECK( ExtractUnit( col_name, name, unit ) == XLAL_SUCCESS, XLAL_EINVAL );
2406 XLAL_CHECK( XLALFITSTableColumnAdd( file, name, unit, noffsets, offsets, record, record_size, field, field_size, sizeof( *field ), 'I', TSHORT ) == XLAL_SUCCESS, XLAL_EFUNC );
2407 return XLAL_SUCCESS;
2408
2409#endif // !defined(HAVE_LIBCFITSIO)
2410}
2411
2412int XLALFITSTableColumnAddINT4( FITSFile UNUSED *file, const CHAR UNUSED *col_name, const size_t UNUSED noffsets, const size_t UNUSED offsets[2], const void UNUSED *record, const size_t UNUSED record_size, const INT4 UNUSED *field, const size_t UNUSED field_size )
2413{
2414#if !defined(HAVE_LIBCFITSIO)
2415 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
2416#else // defined(HAVE_LIBCFITSIO)
2417
2418 XLAL_CHECK( sizeof( *field ) == sizeof( int ), XLAL_ESIZE ); // Double-check that size of LAL type matches that of C type used by CFITSIO in e.g. ffgcv()
2419 XLAL_CHECK( col_name != NULL, XLAL_EFAULT );
2420 XLAL_CHECK( strlen( col_name ) < FLEN_VALUE, XLAL_EINVAL, "Column name '%s' is too long", col_name );
2421 CHAR name[FLEN_VALUE], unit[FLEN_VALUE];
2422 XLAL_CHECK( ExtractUnit( col_name, name, unit ) == XLAL_SUCCESS, XLAL_EINVAL );
2423 XLAL_CHECK( XLALFITSTableColumnAdd( file, name, unit, noffsets, offsets, record, record_size, field, field_size, sizeof( *field ), 'J', TINT ) == XLAL_SUCCESS, XLAL_EFUNC );
2424 return XLAL_SUCCESS;
2425
2426#endif // !defined(HAVE_LIBCFITSIO)
2427}
2428
2429int XLALFITSTableColumnAddINT8( FITSFile UNUSED *file, const CHAR UNUSED *col_name, const size_t UNUSED noffsets, const size_t UNUSED offsets[2], const void UNUSED *record, const size_t UNUSED record_size, const INT8 UNUSED *field, const size_t UNUSED field_size )
2430{
2431#if !defined(HAVE_LIBCFITSIO)
2432 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
2433#else // defined(HAVE_LIBCFITSIO)
2434
2435 XLAL_CHECK( sizeof( *field ) == sizeof( LONGLONG ), XLAL_ESIZE ); // Double-check that size of LAL type matches that of C type used by CFITSIO in e.g. ffgcv()
2436 XLAL_CHECK( col_name != NULL, XLAL_EFAULT );
2437 XLAL_CHECK( strlen( col_name ) < FLEN_VALUE, XLAL_EINVAL, "Column name '%s' is too long", col_name );
2438 CHAR name[FLEN_VALUE], unit[FLEN_VALUE];
2439 XLAL_CHECK( ExtractUnit( col_name, name, unit ) == XLAL_SUCCESS, XLAL_EINVAL );
2440 XLAL_CHECK( XLALFITSTableColumnAdd( file, name, unit, noffsets, offsets, record, record_size, field, field_size, sizeof( *field ), 'K', TLONGLONG ) == XLAL_SUCCESS, XLAL_EFUNC );
2441 return XLAL_SUCCESS;
2442
2443#endif // !defined(HAVE_LIBCFITSIO)
2444}
2445
2446int XLALFITSTableColumnAddREAL4( FITSFile UNUSED *file, const CHAR UNUSED *col_name, const size_t UNUSED noffsets, const size_t UNUSED offsets[2], const void UNUSED *record, const size_t UNUSED record_size, const REAL4 UNUSED *field, const size_t UNUSED field_size )
2447{
2448#if !defined(HAVE_LIBCFITSIO)
2449 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
2450#else // defined(HAVE_LIBCFITSIO)
2451
2452 XLAL_CHECK( sizeof( *field ) == sizeof( float ), XLAL_ESIZE ); // Double-check that size of LAL type matches that of C type used by CFITSIO in e.g. ffgcv()
2453 XLAL_CHECK( col_name != NULL, XLAL_EFAULT );
2454 XLAL_CHECK( strlen( col_name ) < FLEN_VALUE, XLAL_EINVAL, "Column name '%s' is too long", col_name );
2455 CHAR name[FLEN_VALUE], unit[FLEN_VALUE];
2456 XLAL_CHECK( ExtractUnit( col_name, name, unit ) == XLAL_SUCCESS, XLAL_EINVAL );
2457 XLAL_CHECK( XLALFITSTableColumnAdd( file, name, unit, noffsets, offsets, record, record_size, field, field_size, sizeof( *field ), 'E', TFLOAT ) == XLAL_SUCCESS, XLAL_EFUNC );
2458 return XLAL_SUCCESS;
2459
2460#endif // !defined(HAVE_LIBCFITSIO)
2461}
2462
2463int XLALFITSTableColumnAddREAL8( FITSFile UNUSED *file, const CHAR UNUSED *col_name, const size_t UNUSED noffsets, const size_t UNUSED offsets[2], const void UNUSED *record, const size_t UNUSED record_size, const REAL8 UNUSED *field, const size_t UNUSED field_size )
2464{
2465#if !defined(HAVE_LIBCFITSIO)
2466 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
2467#else // defined(HAVE_LIBCFITSIO)
2468
2469 XLAL_CHECK( sizeof( *field ) == sizeof( double ), XLAL_ESIZE ); // Double-check that size of LAL type matches that of C type used by CFITSIO in e.g. ffgcv()
2470 XLAL_CHECK( col_name != NULL, XLAL_EFAULT );
2471 XLAL_CHECK( strlen( col_name ) < FLEN_VALUE, XLAL_EINVAL, "Column name '%s' is too long", col_name );
2472 CHAR name[FLEN_VALUE], unit[FLEN_VALUE];
2473 XLAL_CHECK( ExtractUnit( col_name, name, unit ) == XLAL_SUCCESS, XLAL_EINVAL );
2474 XLAL_CHECK( XLALFITSTableColumnAdd( file, name, unit, noffsets, offsets, record, record_size, field, field_size, sizeof( *field ), 'D', TDOUBLE ) == XLAL_SUCCESS, XLAL_EFUNC );
2475 return XLAL_SUCCESS;
2476
2477#endif // !defined(HAVE_LIBCFITSIO)
2478}
2479
2480int XLALFITSTableColumnAddCOMPLEX8( FITSFile UNUSED *file, const CHAR UNUSED *col_name, const size_t UNUSED noffsets, const size_t UNUSED offsets[2], const void UNUSED *record, const size_t UNUSED record_size, const COMPLEX8 UNUSED *field, const size_t UNUSED field_size )
2481{
2482#if !defined(HAVE_LIBCFITSIO)
2483 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
2484#else // defined(HAVE_LIBCFITSIO)
2485
2486 XLAL_CHECK( sizeof( *field ) == 2 * sizeof( float ), XLAL_ESIZE ); // Double-check that size of LAL type matches that of C type used by CFITSIO in e.g. ffgcv()
2487 XLAL_CHECK( col_name != NULL, XLAL_EFAULT );
2488 XLAL_CHECK( strlen( col_name ) < FLEN_VALUE, XLAL_EINVAL, "Column name '%s' is too long", col_name );
2489 CHAR name[FLEN_VALUE], unit[FLEN_VALUE];
2490 XLAL_CHECK( ExtractUnit( col_name, name, unit ) == XLAL_SUCCESS, XLAL_EINVAL );
2491 XLAL_CHECK( XLALFITSTableColumnAdd( file, name, unit, noffsets, offsets, record, record_size, field, field_size, sizeof( *field ), 'C', TCOMPLEX ) == XLAL_SUCCESS, XLAL_EFUNC );
2492 return XLAL_SUCCESS;
2493
2494#endif // !defined(HAVE_LIBCFITSIO)
2495}
2496
2497int XLALFITSTableColumnAddCOMPLEX16( FITSFile UNUSED *file, const CHAR UNUSED *col_name, const size_t UNUSED noffsets, const size_t UNUSED offsets[2], const void UNUSED *record, const size_t UNUSED record_size, const COMPLEX16 UNUSED *field, const size_t UNUSED field_size )
2498{
2499#if !defined(HAVE_LIBCFITSIO)
2500 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
2501#else // defined(HAVE_LIBCFITSIO)
2502
2503 XLAL_CHECK( sizeof( *field ) == 2 * sizeof( double ), XLAL_ESIZE ); // Double-check that size of LAL type matches that of C type used by CFITSIO in e.g. ffgcv()
2504 XLAL_CHECK( col_name != NULL, XLAL_EFAULT );
2505 XLAL_CHECK( strlen( col_name ) < FLEN_VALUE, XLAL_EINVAL, "Column name '%s' is too long", col_name );
2506 CHAR name[FLEN_VALUE], unit[FLEN_VALUE];
2507 XLAL_CHECK( ExtractUnit( col_name, name, unit ) == XLAL_SUCCESS, XLAL_EINVAL );
2508 XLAL_CHECK( XLALFITSTableColumnAdd( file, name, unit, noffsets, offsets, record, record_size, field, field_size, sizeof( *field ), 'M', TDBLCOMPLEX ) == XLAL_SUCCESS, XLAL_EFUNC );
2509 return XLAL_SUCCESS;
2510
2511#endif // !defined(HAVE_LIBCFITSIO)
2512}
2513
2514int XLALFITSTableColumnAddCHAR( FITSFile UNUSED *file, const CHAR UNUSED *col_name, const size_t UNUSED noffsets, const size_t UNUSED offsets[2], const void UNUSED *record, const size_t UNUSED record_size, const void UNUSED *field, const size_t UNUSED field_size )
2515{
2516#if !defined(HAVE_LIBCFITSIO)
2517 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
2518#else // defined(HAVE_LIBCFITSIO)
2519
2520 XLAL_CHECK( sizeof( CHAR ) == sizeof( char ), XLAL_ESIZE ); // Double-check that size of LAL type matches that of C type used by CFITSIO in e.g. ffgcv()
2521 XLAL_CHECK( col_name != NULL, XLAL_EFAULT );
2522 XLAL_CHECK( strlen( col_name ) < FLEN_VALUE, XLAL_EINVAL, "Column name '%s' is too long", col_name );
2523 XLAL_CHECK( XLALFITSTableColumnAdd( file, col_name, "", noffsets, offsets, record, record_size, field, field_size, sizeof( CHAR ), 'A', TSTRING ) == XLAL_SUCCESS, XLAL_EFUNC );
2524 return XLAL_SUCCESS;
2525
2526#endif // !defined(HAVE_LIBCFITSIO)
2527}
2528
2529int XLALFITSTableColumnAddGPSTime( FITSFile UNUSED *file, const CHAR UNUSED *col_name, const size_t UNUSED noffsets, const size_t UNUSED offsets[2], const void UNUSED *record, const size_t UNUSED record_size, const LIGOTimeGPS UNUSED *field, const size_t UNUSED field_size )
2530{
2531#if !defined(HAVE_LIBCFITSIO)
2532 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
2533#else // defined(HAVE_LIBCFITSIO)
2534
2535 XLAL_CHECK( sizeof( field->gpsSeconds ) == sizeof( int ), XLAL_ESIZE );
2536 XLAL_CHECK( sizeof( field->gpsNanoSeconds ) == sizeof( int ), XLAL_ESIZE );
2537 XLAL_CHECK( col_name != NULL, XLAL_EFAULT );
2538 XLAL_CHECK( strlen( col_name ) + 3 < FLEN_VALUE, XLAL_EINVAL, "Column name '%s' is too long", col_name );
2539 XLAL_CHECK( field_size == sizeof( LIGOTimeGPS ), XLAL_EINVAL, "Array of GPS times is not supported" );
2540 CHAR name[FLEN_VALUE];
2541 snprintf( name, sizeof( name ), "%s_s", col_name );
2542 XLAL_CHECK( XLALFITSTableColumnAdd( file, name, "s", noffsets, offsets, record, record_size, &( field->gpsSeconds ), sizeof( field->gpsSeconds ), sizeof( field->gpsSeconds ), 'J', TINT ) == XLAL_SUCCESS, XLAL_EFUNC );
2543 snprintf( name, sizeof( name ), "%s_ns", col_name );
2544 XLAL_CHECK( XLALFITSTableColumnAdd( file, name, "ns", noffsets, offsets, record, record_size, &( field->gpsNanoSeconds ), sizeof( field->gpsNanoSeconds ), sizeof( field->gpsNanoSeconds ), 'J', TINT ) == XLAL_SUCCESS, XLAL_EFUNC );
2545 return XLAL_SUCCESS;
2546
2547#endif // !defined(HAVE_LIBCFITSIO)
2548}
2549
2550int XLALFITSTableWriteRow( FITSFile UNUSED *file, const void UNUSED *record )
2551{
2552#if !defined(HAVE_LIBCFITSIO)
2553 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
2554#else // defined(HAVE_LIBCFITSIO)
2555
2556 int UNUSED status = 0;
2557
2558 // Check input
2559 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
2560 XLAL_CHECK_FAIL( file->write, XLAL_EINVAL, "FITS file is not open for writing" );
2561 XLAL_CHECK_FAIL( record != NULL, XLAL_EFAULT );
2562
2563 // Check that we are at a table
2564 XLAL_CHECK_FAIL( file->hdutype == BINARY_TBL, XLAL_EIO, "Current FITS file HDU is not a table" );
2565
2566 // Create new table if required
2567 if ( file->table.irow == 0 ) {
2568 CHAR *ttype_ptr[FFIO_MAX], *tform_ptr[FFIO_MAX], *tunit_ptr[FFIO_MAX];
2569 for ( int i = 0; i < file->table.tfields; ++i ) {
2570 ttype_ptr[i] = file->table.ttype[i];
2571 tform_ptr[i] = file->table.tform[i];
2572 tunit_ptr[i] = file->table.tunit[i];
2573 }
2574 CALL_FITS( fits_create_tbl, file->ff, file->hdutype, 0, file->table.tfields, ttype_ptr, tform_ptr, tunit_ptr, NULL );
2575 CALL_FITS( fits_write_key_str, file->ff, "HDUNAME", file->hduname, file->hducomment );
2576 CALL_FITS( fits_write_key_str, file->ff, "EXTNAME", file->hduname, file->hducomment ); /* synonym of HDUNAME */
2577 }
2578
2579 // Advance to next row
2580 ++file->table.irow;
2581
2582 // Write next table row
2583 for ( int i = 0; i < file->table.tfields; ++i ) {
2584
2585 // Work out pointer to correct place in record
2586 union {
2587 const void *cv;
2588 void *v;
2589 } bad_cast = { .cv = record };
2590 void *value = bad_cast.v;
2591 for ( size_t n = 0; n < file->table.noffsets[i]; ++n ) {
2592 if ( n > 0 ) {
2593 value = *( ( void ** ) value );
2594 }
2595 value = ( void * )( ( ( intptr_t ) value ) + file->table.offsets[i][n] );
2596 }
2597
2598 // Write data in record to table column
2599 {
2600 void *pvalue = ( file->table.datatype[i] == TSTRING ) ? ( void * ) &value : value;
2601 CALL_FITS( fits_write_col, file->ff, file->table.datatype[i], file->table.colnum[i], file->table.irow, 1, file->table.nelements[i], pvalue );
2602 }
2603
2604 }
2605
2606 return XLAL_SUCCESS;
2607
2608XLAL_FAIL:
2609
2610 // Delete FITS file on error
2611 if ( file != NULL && file->ff != NULL ) {
2612 fits_delete_file( file->ff, &status );
2613 file->ff = NULL;
2614 }
2615
2616 return XLAL_FAILURE;
2617
2618#endif // !defined(HAVE_LIBCFITSIO)
2619}
2620
2621int XLALFITSTableReadRow( FITSFile UNUSED *file, void UNUSED *record, UINT8 UNUSED *rem_nrows )
2622{
2623#if !defined(HAVE_LIBCFITSIO)
2624 XLAL_ERROR( XLAL_EFAILED, "CFITSIO is not available" );
2625#else // defined(HAVE_LIBCFITSIO)
2626
2627 int UNUSED status = 0;
2628
2629 // Check input
2630 XLAL_CHECK_FAIL( file != NULL, XLAL_EFAULT );
2631 XLAL_CHECK_FAIL( !file->write, XLAL_EINVAL, "FITS file is not open for reading" );
2632 XLAL_CHECK_FAIL( record != NULL, XLAL_EFAULT );
2633
2634 // Check that we are at a table
2635 XLAL_CHECK_FAIL( file->hdutype == BINARY_TBL, XLAL_EIO, "Current FITS file HDU is not a table" );
2636
2637 // Return if there are no more rows
2638 if ( file->table.irow == file->table.nrows ) {
2639 return XLAL_SUCCESS;
2640 }
2641
2642 // Advance to next row, and return number of remaining rows
2643 ++file->table.irow;
2644 if ( rem_nrows != NULL ) {
2645 *rem_nrows = file->table.nrows - file->table.irow;
2646 }
2647
2648 // Read next table row
2649 for ( int i = 0; i < file->table.tfields; ++i ) {
2650
2651 // Resize temporary buffer, if required
2652 // - Require double the field size to allow for buffer overruns in CFITSIO
2653 const size_t req_buf_size = 2 * file->table.field_size[i];
2654 if ( file->buf_size < req_buf_size ) {
2655 file->buf = XLALRealloc( file->buf, req_buf_size );
2656 XLAL_CHECK( file->buf != NULL, XLAL_ENOMEM );
2657 file->buf_size = req_buf_size;
2658 }
2659 memset( file->buf, 0, req_buf_size );
2660
2661 // Read data from table column into temporary buffer
2662 {
2663 void *pbuf = ( file->table.datatype[i] == TSTRING ) ? ( void * ) &file->buf : file->buf;
2664 CALL_FITS( fits_read_col, file->ff, file->table.datatype[i], file->table.colnum[i], file->table.irow, 1, file->table.nelements[i], NULL, pbuf, NULL );
2665 }
2666
2667 // Work out pointer to correct place in record
2668 void *value = record;
2669 for ( size_t n = 0; n < file->table.noffsets[i]; ++n ) {
2670 if ( n > 0 ) {
2671 value = *( ( void ** ) value );
2672 }
2673 value = ( void * )( ( ( intptr_t ) value ) + file->table.offsets[i][n] );
2674 }
2675
2676 // Copy the required length of the temporary buffer into the record
2677 memcpy( value, file->buf, file->table.field_size[i] );
2678
2679 }
2680
2681 return XLAL_SUCCESS;
2682
2683XLAL_FAIL:
2684 return XLAL_FAILURE;
2685
2686#endif // !defined(HAVE_LIBCFITSIO)
2687}
2688
2689// Local Variables:
2690// c-file-style: "linux"
2691// c-basic-offset: 2
2692// End:
#define __func__
log an I/O error, i.e.
#define XLAL_BILLION_REAL8
int XLALFITSArrayReadINT4(FITSFile UNUSED *file, const size_t UNUSED idx[], INT4 UNUSED *elem)
Definition: FITSFileIO.c:1975
int XLALFITSHeaderReadREAL8(FITSFile UNUSED *file, const CHAR UNUSED *key, REAL8 UNUSED *value)
Definition: FITSFileIO.c:1184
int XLALFITSArrayOpenWrite1(FITSFile UNUSED *file, const CHAR UNUSED *name, const size_t UNUSED dim0, const CHAR UNUSED *comment)
Definition: FITSFileIO.c:1680
int XLALFITSHeaderWriteUINT4(FITSFile UNUSED *file, const CHAR UNUSED *key, const UINT4 UNUSED value, const CHAR UNUSED *comment)
Definition: FITSFileIO.c:762
int XLALFITSArrayOpenWrite(FITSFile UNUSED *file, const CHAR UNUSED *name, const size_t UNUSED ndim, const size_t UNUSED dims[], const CHAR UNUSED *comment)
Definition: FITSFileIO.c:1587
int XLALFITSFileSeekNamedHDU(FITSFile UNUSED *file, const CHAR UNUSED *name)
Definition: FITSFileIO.c:400
int XLALFITSTableWriteRow(FITSFile UNUSED *file, const void UNUSED *record)
Definition: FITSFileIO.c:2550
int XLALFITSHeaderWriteStringVector(FITSFile UNUSED *file, const CHAR UNUSED *key, const LALStringVector UNUSED *values, const CHAR UNUSED *comment)
Definition: FITSFileIO.c:1412
int XLALFITSTableColumnAddCOMPLEX16(FITSFile UNUSED *file, const CHAR UNUSED *col_name, const size_t UNUSED noffsets, const size_t UNUSED offsets[2], const void UNUSED *record, const size_t UNUSED record_size, const COMPLEX16 UNUSED *field, const size_t UNUSED field_size)
Definition: FITSFileIO.c:2497
int XLALFITSFileSeekPrimaryHDU(FITSFile UNUSED *file)
Definition: FITSFileIO.c:378
int XLALFITSHeaderWriteGPSTime(FITSFile UNUSED *file, const CHAR UNUSED *key, const LIGOTimeGPS UNUSED *value, const CHAR UNUSED *comment)
Definition: FITSFileIO.c:1494
int XLALFITSTableColumnAddINT8(FITSFile UNUSED *file, const CHAR UNUSED *col_name, const size_t UNUSED noffsets, const size_t UNUSED offsets[2], const void UNUSED *record, const size_t UNUSED record_size, const INT8 UNUSED *field, const size_t UNUSED field_size)
Definition: FITSFileIO.c:2429
int XLALFITSArrayReadINT2(FITSFile UNUSED *file, const size_t UNUSED idx[], INT2 UNUSED *elem)
Definition: FITSFileIO.c:1948
int XLALFITSHeaderWriteBOOLEAN(FITSFile UNUSED *file, const CHAR UNUSED *key, const BOOLEAN UNUSED value, const CHAR UNUSED *comment)
Definition: FITSFileIO.c:635
int XLALFITSArrayWriteREAL8(FITSFile UNUSED *file, const size_t UNUSED idx[], const REAL8 UNUSED elem)
Definition: FITSFileIO.c:2043
int XLALFITSTableColumnAddUINT2(FITSFile UNUSED *file, const CHAR UNUSED *col_name, const size_t UNUSED noffsets, const size_t UNUSED offsets[2], const void UNUSED *record, const size_t UNUSED record_size, const UINT2 UNUSED *field, const size_t UNUSED field_size)
Definition: FITSFileIO.c:2344
int XLALFITSTableReadRow(FITSFile UNUSED *file, void UNUSED *record, UINT8 UNUSED *rem_nrows)
Definition: FITSFileIO.c:2621
int XLALFITSArrayReadGSLMatrix(FITSFile UNUSED *file, const size_t UNUSED idx[], gsl_matrix UNUSED **elems)
Definition: FITSFileIO.c:2118
int XLALFITSHeaderReadINT2(FITSFile UNUSED *file, const CHAR UNUSED *key, INT2 UNUSED *value)
Definition: FITSFileIO.c:928
int XLALFITSHeaderQueryKeyExists(FITSFile UNUSED *file, const CHAR UNUSED *key, BOOLEAN UNUSED *exists)
Definition: FITSFileIO.c:563
int XLALFITSHeaderReadCOMPLEX16(FITSFile UNUSED *file, const CHAR UNUSED *key, COMPLEX16 UNUSED *value)
Definition: FITSFileIO.c:1310
int XLALFITSHeaderReadBOOLEAN(FITSFile UNUSED *file, const CHAR UNUSED *key, BOOLEAN UNUSED *value)
Definition: FITSFileIO.c:668
int XLALFITSHeaderReadREAL4(FITSFile UNUSED *file, const CHAR UNUSED *key, REAL4 UNUSED *value)
Definition: FITSFileIO.c:1123
int XLALFITSHeaderReadCOMPLEX8(FITSFile UNUSED *file, const CHAR UNUSED *key, COMPLEX8 UNUSED *value)
Definition: FITSFileIO.c:1246
int XLALFITSTableColumnAddCOMPLEX8(FITSFile UNUSED *file, const CHAR UNUSED *col_name, const size_t UNUSED noffsets, const size_t UNUSED offsets[2], const void UNUSED *record, const size_t UNUSED record_size, const COMPLEX8 UNUSED *field, const size_t UNUSED field_size)
Definition: FITSFileIO.c:2480
int XLALFITSArrayWriteINT2(FITSFile UNUSED *file, const size_t UNUSED idx[], const INT2 UNUSED elem)
Definition: FITSFileIO.c:1935
int XLALFITSHeaderReadGPSTime(FITSFile UNUSED *file, const CHAR UNUSED *key, LIGOTimeGPS UNUSED *value)
Definition: FITSFileIO.c:1547
FITSFile * XLALFITSFileOpenWrite(const CHAR UNUSED *file_name)
Definition: FITSFileIO.c:263
int XLALFITSArrayWriteUINT8(FITSFile UNUSED *file, const size_t UNUSED idx[], const UINT8 UNUSED elem)
Definition: FITSFileIO.c:1906
int XLALFITSArrayOpenRead2(FITSFile UNUSED *file, const CHAR UNUSED *name, size_t UNUSED *dim0, size_t UNUSED *dim1)
Definition: FITSFileIO.c:1723
int XLALFITSHeaderReadINT8(FITSFile UNUSED *file, const CHAR UNUSED *key, INT8 UNUSED *value)
Definition: FITSFileIO.c:1059
int XLALFITSHeaderWriteComment(FITSFile UNUSED *file, const CHAR UNUSED *format,...)
Definition: FITSFileIO.c:601
int XLALFITSFileWriteVCSInfo(FITSFile UNUSED *file, const LALVCSInfoList UNUSED vcs_list)
Definition: FITSFileIO.c:466
int XLALFITSArrayReadUINT4(FITSFile UNUSED *file, const size_t UNUSED idx[], UINT4 UNUSED *elem)
Definition: FITSFileIO.c:1892
int XLALFITSFileWriteUVarCmdLine(FITSFile UNUSED *file)
Definition: FITSFileIO.c:508
int XLALFITSTableColumnAddINT2(FITSFile UNUSED *file, const CHAR UNUSED *col_name, const size_t UNUSED noffsets, const size_t UNUSED offsets[2], const void UNUSED *record, const size_t UNUSED record_size, const INT2 UNUSED *field, const size_t UNUSED field_size)
Definition: FITSFileIO.c:2395
int XLALFITSArrayOpenRead(FITSFile UNUSED *file, const CHAR UNUSED *name, size_t UNUSED *ndim, size_t UNUSED dims[])
Definition: FITSFileIO.c:1634
int XLALFITSTableColumnAddUINT4(FITSFile UNUSED *file, const CHAR UNUSED *col_name, const size_t UNUSED noffsets, const size_t UNUSED offsets[2], const void UNUSED *record, const size_t UNUSED record_size, const UINT4 UNUSED *field, const size_t UNUSED field_size)
Definition: FITSFileIO.c:2361
int XLALFITSArrayReadINT8(FITSFile UNUSED *file, const size_t UNUSED idx[], INT8 UNUSED *elem)
Definition: FITSFileIO.c:2002
int XLALFITSHeaderWriteINT2(FITSFile UNUSED *file, const CHAR UNUSED *key, const INT2 UNUSED value, const CHAR UNUSED *comment)
Definition: FITSFileIO.c:893
int XLALFITSHeaderWriteCOMPLEX16(FITSFile UNUSED *file, const CHAR UNUSED *key, const COMPLEX16 UNUSED value, const CHAR UNUSED *comment)
Definition: FITSFileIO.c:1275
int XLALFITSTableOpenWrite(FITSFile UNUSED *file, const CHAR UNUSED *name, const CHAR UNUSED *comment)
Definition: FITSFileIO.c:2162
static int UNUSED XLALFITSArrayRead(FITSFile UNUSED *file, const size_t UNUSED idx[], const int UNUSED bitpix, const int UNUSED datatype, void UNUSED *elem, void UNUSED *nulelem)
Definition: FITSFileIO.c:1805
int XLALFITSArrayWriteUINT2(FITSFile UNUSED *file, const size_t UNUSED idx[], const UINT2 UNUSED elem)
Definition: FITSFileIO.c:1852
static int UNUSED XLALFITSTableColumnAdd(FITSFile UNUSED *file, const CHAR UNUSED *name, const CHAR UNUSED *unit, const size_t UNUSED noffsets, const size_t UNUSED offsets[2], const void UNUSED *record, const size_t UNUSED record_size, const void UNUSED *field, const size_t UNUSED field_size, const size_t UNUSED elem_size, const int UNUSED typechar, const int UNUSED datatype)
Definition: FITSFileIO.c:2236
int XLALFITSArrayWriteUINT4(FITSFile UNUSED *file, const size_t UNUSED idx[], const UINT4 UNUSED elem)
Definition: FITSFileIO.c:1879
int XLALFITSHeaderWriteUINT2(FITSFile UNUSED *file, const CHAR UNUSED *key, const UINT2 UNUSED value, const CHAR UNUSED *comment)
Definition: FITSFileIO.c:697
int XLALFITSArrayWriteREAL4(FITSFile UNUSED *file, const size_t UNUSED idx[], const REAL4 UNUSED elem)
Definition: FITSFileIO.c:2016
FITSFile * XLALFITSFileOpenRead(const CHAR UNUSED *file_name)
Definition: FITSFileIO.c:320
int XLALFITSHeaderWriteINT8(FITSFile UNUSED *file, const CHAR UNUSED *key, const INT8 UNUSED value, const CHAR UNUSED *comment)
Definition: FITSFileIO.c:1023
int XLALFITSArrayReadREAL4(FITSFile UNUSED *file, const size_t UNUSED idx[], REAL4 UNUSED *elem)
Definition: FITSFileIO.c:2029
int XLALFITSHeaderReadINT4(FITSFile UNUSED *file, const CHAR UNUSED *key, INT4 UNUSED *value)
Definition: FITSFileIO.c:993
int XLALFITSArrayOpenRead1(FITSFile UNUSED *file, const CHAR UNUSED *name, size_t UNUSED *dim0)
Definition: FITSFileIO.c:1693
int XLALFITSArrayOpenWrite2(FITSFile UNUSED *file, const CHAR UNUSED *name, const size_t UNUSED dim0, const size_t UNUSED dim1, const CHAR UNUSED *comment)
Definition: FITSFileIO.c:1710
int XLALFITSHeaderWriteUINT8(FITSFile UNUSED *file, const CHAR UNUSED *key, const UINT8 UNUSED value, const CHAR UNUSED *comment)
Definition: FITSFileIO.c:827
int XLALFITSArrayReadUINT2(FITSFile UNUSED *file, const size_t UNUSED idx[], UINT2 UNUSED *elem)
Definition: FITSFileIO.c:1865
int XLALFITSArrayWriteINT8(FITSFile UNUSED *file, const size_t UNUSED idx[], const INT8 UNUSED elem)
Definition: FITSFileIO.c:1989
int XLALFITSHeaderReadUINT2(FITSFile UNUSED *file, const CHAR UNUSED *key, UINT2 UNUSED *value)
Definition: FITSFileIO.c:732
void XLALFITSFileClose(FITSFile UNUSED *file)
Definition: FITSFileIO.c:245
int XLALFITSTableColumnAddREAL8(FITSFile UNUSED *file, const CHAR UNUSED *col_name, const size_t UNUSED noffsets, const size_t UNUSED offsets[2], const void UNUSED *record, const size_t UNUSED record_size, const REAL8 UNUSED *field, const size_t UNUSED field_size)
Definition: FITSFileIO.c:2463
int XLALFITSArrayWriteGSLMatrix(FITSFile UNUSED *file, const size_t UNUSED idx[], const gsl_matrix UNUSED *elems)
Definition: FITSFileIO.c:2070
int XLALFITSTableColumnAddREAL4(FITSFile UNUSED *file, const CHAR UNUSED *col_name, const size_t UNUSED noffsets, const size_t UNUSED offsets[2], const void UNUSED *record, const size_t UNUSED record_size, const REAL4 UNUSED *field, const size_t UNUSED field_size)
Definition: FITSFileIO.c:2446
int XLALFITSHeaderWriteINT4(FITSFile UNUSED *file, const CHAR UNUSED *key, const INT4 UNUSED value, const CHAR UNUSED *comment)
Definition: FITSFileIO.c:958
int XLALFITSTableColumnAddGPSTime(FITSFile UNUSED *file, const CHAR UNUSED *col_name, const size_t UNUSED noffsets, const size_t UNUSED offsets[2], const void UNUSED *record, const size_t UNUSED record_size, const LIGOTimeGPS UNUSED *field, const size_t UNUSED field_size)
Definition: FITSFileIO.c:2529
int XLALFITSHeaderReadStringVector(FITSFile UNUSED *file, const CHAR UNUSED *key, LALStringVector UNUSED **values)
Definition: FITSFileIO.c:1456
int XLALFITSTableColumnAddINT4(FITSFile UNUSED *file, const CHAR UNUSED *col_name, const size_t UNUSED noffsets, const size_t UNUSED offsets[2], const void UNUSED *record, const size_t UNUSED record_size, const INT4 UNUSED *field, const size_t UNUSED field_size)
Definition: FITSFileIO.c:2412
int XLALFITSArrayReadREAL8(FITSFile UNUSED *file, const size_t UNUSED idx[], REAL8 UNUSED *elem)
Definition: FITSFileIO.c:2056
int XLALFITSHeaderWriteREAL4(FITSFile UNUSED *file, const CHAR UNUSED *key, const REAL4 UNUSED value, const CHAR UNUSED *comment)
Definition: FITSFileIO.c:1089
int XLALFITSHeaderWriteREAL8(FITSFile UNUSED *file, const CHAR UNUSED *key, const REAL8 UNUSED value, const CHAR UNUSED *comment)
Definition: FITSFileIO.c:1150
static int UNUSED XLALFITSArrayWrite(FITSFile UNUSED *file, const size_t UNUSED idx[], const int UNUSED bitpix, const int UNUSED datatype, const void UNUSED *elem)
Definition: FITSFileIO.c:1743
int XLALFITSHeaderReadUINT8(FITSFile UNUSED *file, const CHAR UNUSED *key, UINT8 UNUSED *value)
Definition: FITSFileIO.c:863
int XLALFITSHeaderWriteCOMPLEX8(FITSFile UNUSED *file, const CHAR UNUSED *key, const COMPLEX8 UNUSED value, const CHAR UNUSED *comment)
Definition: FITSFileIO.c:1211
int XLALFITSArrayWriteINT4(FITSFile UNUSED *file, const size_t UNUSED idx[], const INT4 UNUSED elem)
Definition: FITSFileIO.c:1962
int XLALFITSTableColumnAddCHAR(FITSFile UNUSED *file, const CHAR UNUSED *col_name, const size_t UNUSED noffsets, const size_t UNUSED offsets[2], const void UNUSED *record, const size_t UNUSED record_size, const void UNUSED *field, const size_t UNUSED field_size)
Definition: FITSFileIO.c:2514
int XLALFITSArrayReadUINT8(FITSFile UNUSED *file, const size_t UNUSED idx[], UINT8 UNUSED *elem)
Definition: FITSFileIO.c:1920
int XLALFITSHeaderReadUINT4(FITSFile UNUSED *file, const CHAR UNUSED *key, UINT4 UNUSED *value)
Definition: FITSFileIO.c:797
int XLALFITSTableColumnAddUINT8(FITSFile UNUSED *file, const CHAR UNUSED *col_name, const size_t UNUSED noffsets, const size_t UNUSED offsets[2], const void UNUSED *record, const size_t UNUSED record_size, const UINT8 UNUSED *field, const size_t UNUSED field_size)
Definition: FITSFileIO.c:2378
int XLALFITSTableColumnAddBOOLEAN(FITSFile UNUSED *file, const CHAR UNUSED *col_name, const size_t UNUSED noffsets, const size_t UNUSED offsets[2], const void UNUSED *record, const size_t UNUSED record_size, const BOOLEAN UNUSED *field, const size_t UNUSED field_size)
Definition: FITSFileIO.c:2329
int XLALFITSTableOpenRead(FITSFile UNUSED *file, const CHAR UNUSED *name, UINT8 UNUSED *nrows)
Definition: FITSFileIO.c:2198
int XLALFITSHeaderReadString(FITSFile UNUSED *file, const CHAR UNUSED *key, CHAR UNUSED **value)
Definition: FITSFileIO.c:1377
int XLALFITSHeaderWriteString(FITSFile UNUSED *file, const CHAR UNUSED *key, const CHAR UNUSED *value, const CHAR UNUSED *comment)
Definition: FITSFileIO.c:1339
int XLALFITSFileWriteHistory(FITSFile UNUSED *file, const CHAR UNUSED *format,...)
Definition: FITSFileIO.c:429
#define c
const char * unit
const char * name
Definition: SearchTiming.c:93
const char * comment
Definition: SearchTiming.c:94
double e
const double u
char * XLALGPSToStr(char *s, const LIGOTimeGPS *t)
#define FFIO_MAX
Maximum possible number of FITS array dimensions, and FITS table columns.
Definition: FITSFileIO.h:49
struct tagFITSFile FITSFile
Representation of a FITS file.
Definition: FITSFileIO.h:54
#define crect(re, im)
unsigned char BOOLEAN
#define XLAL_NUM_ELEM(x)
#define XLAL_INIT_MEM(x)
uint64_t UINT8
double complex COMPLEX16
double REAL8
#define XLAL_INIT_DECL(var,...)
int16_t INT2
int64_t INT8
#define crectf(re, im)
uint16_t UINT2
char CHAR
uint32_t UINT4
float complex COMPLEX8
int32_t INT4
float REAL4
void * XLALCalloc(size_t m, size_t n)
void * XLALRealloc(void *p, size_t n)
void XLALFree(void *p)
char char * XLALStringDuplicate(const char *s)
char * XLALStringAppendFmt(char *s, const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(2
char * XLALStringToken(char **s, const char *delim, int empty)
int XLALStringToUpperCase(char *string)
const LALVCSInfo *const LALVCSInfoList[16]
LALStringVector * XLALAppendString2Vector(LALStringVector *vect, const CHAR *string)
void CHAR * XLALUserVarGetLog(UserVarLogFormat format)
UVAR_LOGFMT_RAWFORM
INT4 XLALUTCToGPS(const struct tm *utc)
struct tm * XLALGPSToUTC(struct tm *utc, INT4 gpssec)
#define XLAL_ERROR_VOID(...)
#define XLAL_ERROR_NULL(...)
#define xlalErrno
#define XLAL_ERROR(...)
#define XLAL_CHECK(assertion,...)
#define XLAL_CHECK_FAIL(assertion,...)
#define XLAL_ERROR_FAIL(...)
XLAL_ENOMEM
XLAL_SUCCESS
XLAL_EFAULT
XLAL_ERANGE
XLAL_ENOENT
XLAL_EFUNC
XLAL_EERR
XLAL_EDOM
XLAL_ESIZE
XLAL_EIO
XLAL_ESYS
XLAL_EINVAL
XLAL_EFAILED
XLAL_FAILURE
LIGOTimeGPS * XLALGPSSet(LIGOTimeGPS *epoch, INT4 gpssec, INT8 gpsnan)
key
size
vals
string url
n
const char * file_name
INT4 gpsNanoSeconds