LALPulsar  6.1.0.1-fe68b98
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
45 int 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
92 struct 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 ///
126 static 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 );
133  XLAL_CHECK_FAIL( format != 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 
160 XLAL_FAIL:
161  return XLAL_FAILURE;
162 
163 }
164 
165 ///
166 /// Extract unit from a keyword or column name
167 ///
168 static 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 
197 XLAL_FAIL:
198  return XLAL_FAILURE;
199 
200 }
201 
202 ///
203 /// Format and check a FITS keyword
204 ///
205 static 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 
238 XLAL_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 
263 FITSFile *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 
304 XLAL_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 
320 FITSFile *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 
360 XLAL_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 
394 XLAL_FAIL:
395  return XLAL_FAILURE;
396 
397 #endif // !defined(HAVE_LIBCFITSIO)
398 }
399 
400 int 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 
423 XLAL_FAIL:
424  return XLAL_FAILURE;
425 
426 #endif // !defined(HAVE_LIBCFITSIO)
427 }
428 
429 int 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" );
440  XLAL_CHECK_FAIL( format != NULL, XLAL_EFAULT );
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 
453 XLAL_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 
466 int 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 
495 XLAL_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 
549 XLAL_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 
563 int 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 
595 XLAL_FAIL:
596  return XLAL_FAILURE;
597 
598 #endif // !defined(HAVE_LIBCFITSIO)
599 }
600 
601 int 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" );
612  XLAL_CHECK_FAIL( format != NULL, XLAL_EFAULT );
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 
622 XLAL_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 
635 int 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 );
648  XLAL_CHECK_FAIL( comment != NULL, XLAL_EFAULT );
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 
655 XLAL_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 
668 int 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 
691 XLAL_FAIL:
692  return XLAL_FAILURE;
693 
694 #endif // !defined(HAVE_LIBCFITSIO)
695 }
696 
697 int 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 );
710  XLAL_CHECK_FAIL( comment != NULL, XLAL_EFAULT );
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 
719 XLAL_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 
732 int 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 
756 XLAL_FAIL:
757  return XLAL_FAILURE;
758 
759 #endif // !defined(HAVE_LIBCFITSIO)
760 }
761 
762 int 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 );
775  XLAL_CHECK_FAIL( comment != NULL, XLAL_EFAULT );
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 
784 XLAL_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 
797 int 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 
821 XLAL_FAIL:
822  return XLAL_FAILURE;
823 
824 #endif // !defined(HAVE_LIBCFITSIO)
825 }
826 
827 int 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 );
840  XLAL_CHECK_FAIL( comment != NULL, XLAL_EFAULT );
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 
850 XLAL_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 
863 int 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 
887 XLAL_FAIL:
888  return XLAL_FAILURE;
889 
890 #endif // !defined(HAVE_LIBCFITSIO)
891 }
892 
893 int 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 );
906  XLAL_CHECK_FAIL( comment != NULL, XLAL_EFAULT );
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 
915 XLAL_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 
928 int 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 
952 XLAL_FAIL:
953  return XLAL_FAILURE;
954 
955 #endif // !defined(HAVE_LIBCFITSIO)
956 }
957 
958 int 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 );
971  XLAL_CHECK_FAIL( comment != NULL, XLAL_EFAULT );
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 
980 XLAL_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 
993 int 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 
1017 XLAL_FAIL:
1018  return XLAL_FAILURE;
1019 
1020 #endif // !defined(HAVE_LIBCFITSIO)
1021 }
1022 
1023 int 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 );
1036  XLAL_CHECK_FAIL( comment != NULL, XLAL_EFAULT );
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 
1046 XLAL_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 
1059 int 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 
1083 XLAL_FAIL:
1084  return XLAL_FAILURE;
1085 
1086 #endif // !defined(HAVE_LIBCFITSIO)
1087 }
1088 
1089 int 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 );
1102  XLAL_CHECK_FAIL( comment != NULL, XLAL_EFAULT );
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 
1110 XLAL_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 
1123 int 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 
1144 XLAL_FAIL:
1145  return XLAL_FAILURE;
1146 
1147 #endif // !defined(HAVE_LIBCFITSIO)
1148 }
1149 
1150 int 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 );
1163  XLAL_CHECK_FAIL( comment != NULL, XLAL_EFAULT );
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 
1171 XLAL_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 
1184 int 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 
1205 XLAL_FAIL:
1206  return XLAL_FAILURE;
1207 
1208 #endif // !defined(HAVE_LIBCFITSIO)
1209 }
1210 
1211 int 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 );
1224  XLAL_CHECK_FAIL( comment != NULL, XLAL_EFAULT );
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 
1233 XLAL_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 
1246 int 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 
1269 XLAL_FAIL:
1270  return XLAL_FAILURE;
1271 
1272 #endif // !defined(HAVE_LIBCFITSIO)
1273 }
1274 
1275 int 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 );
1288  XLAL_CHECK_FAIL( comment != NULL, XLAL_EFAULT );
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 
1297 XLAL_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 
1310 int 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 
1333 XLAL_FAIL:
1334  return XLAL_FAILURE;
1335 
1336 #endif // !defined(HAVE_LIBCFITSIO)
1337 }
1338 
1339 int 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 );
1353  XLAL_CHECK_FAIL( comment != 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 
1364 XLAL_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 
1377 int 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 
1403 XLAL_FAIL:
1404  if ( val != NULL ) {
1405  fits_free_memory( val, &status );
1406  }
1407  return XLAL_FAILURE;
1408 
1409 #endif // !defined(HAVE_LIBCFITSIO)
1410 }
1411 
1412 int 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 );
1427  XLAL_CHECK_FAIL( comment != NULL, 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 
1443 XLAL_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 
1456 int 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 
1488 XLAL_FAIL:
1489  return XLAL_FAILURE;
1490 
1491 #endif // !defined(HAVE_LIBCFITSIO)
1492 }
1493 
1494 int 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 );
1508  XLAL_CHECK_FAIL( comment != 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 
1534 XLAL_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 
1547 int 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 
1580 XLAL_FAIL:
1581  XLALFree( utc_str );
1582  return XLAL_FAILURE;
1583 
1584 #endif // !defined(HAVE_LIBCFITSIO)
1585 }
1586 
1587 int 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 );
1599  XLAL_CHECK_FAIL( ndim <= FFIO_MAX, XLAL_ESIZE );
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 
1621 XLAL_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 
1634 int 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 
1674 XLAL_FAIL:
1675  return XLAL_FAILURE;
1676 
1677 #endif // !defined(HAVE_LIBCFITSIO)
1678 }
1679 
1680 int 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 
1693 int 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 
1710 int 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 
1723 int 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 
1743 static 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 
1792 XLAL_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 
1805 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 )
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 
1846 XLAL_FAIL:
1847  return XLAL_FAILURE;
1848 
1849 #endif // !defined(HAVE_LIBCFITSIO)
1850 }
1851 
1852 int 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 
1865 int 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 
1879 int 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 
1892 int 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 
1906 int 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 
1920 int 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 
1935 int 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 
1948 int 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 
1962 int 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 
1975 int 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 
1989 int 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 
2002 int 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 
2016 int 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 
2029 int 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 
2043 int 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 
2056 int 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 
2070 int 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 
2105 XLAL_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 
2118 int 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 
2156 XLAL_FAIL:
2157  return XLAL_FAILURE;
2158 
2159 #endif // !defined(HAVE_LIBCFITSIO)
2160 }
2161 
2162 int 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 
2185 XLAL_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 
2198 int 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 
2230 XLAL_FAIL:
2231  return XLAL_FAILURE;
2232 
2233 #endif // !defined(HAVE_LIBCFITSIO)
2234 }
2235 
2236 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 )
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 
2317 XLAL_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 
2329 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 )
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 
2344 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 )
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 
2361 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 )
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 
2378 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 )
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 
2395 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 )
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 
2412 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 )
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 
2429 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 )
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 
2446 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 )
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 
2463 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 )
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 
2480 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 )
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 
2497 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 )
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 
2514 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 )
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 
2529 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 )
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 
2550 int 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 
2608 XLAL_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 
2621 int 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 
2683 XLAL_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
FITSFile * XLALFITSFileOpenWrite(const CHAR UNUSED *file_name)
Definition: FITSFileIO.c:263
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
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
FITSFile * XLALFITSFileOpenRead(const CHAR UNUSED *file_name)
Definition: FITSFileIO.c:320
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
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
int XLALStringToUpperCase(char *string)
char * XLALStringToken(char **s, const char *delim, int empty)
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