MIDI Pipeline Reference Manual  2.8.3
iauWrite.c
1 /******************************************************************************
2 *******************************************************************************
3 * European Southern Observatory
4 * VLTI MIDI Data Reduction Software
5 *
6 * Module name: iauWrite.c
7 * Description: Routines to write MIDI product data in accordance with the IAU
8 * Exchange format
9 *
10 * History:
11 * 01-Jun-06 (csabet) Removed static memory allocation
12 * 10-Jul-03 (csabet) Created. Derived from John Young <jsy1001@cam.ac.uk>
13 *******************************************************************************
14 ******************************************************************************/
15 
16 /******************************************************************************
17 * Compiler directives
18 ******************************************************************************/
19 
20 /******************************************************************************
21 * Include files
22 ******************************************************************************/
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <cpl.h>
26 #include <string.h>
27 #include "iauExchange.h"
28 #include "iauWrite.h"
29 #include "midiGlobal.h"
30 #include "qfits.h"
31 #include "qfits_header.h"
32 
33 /******************************************************************************
34 * Global Variables
35 ******************************************************************************/
36 
37 /******************************************************************************
38 * Local Prototypes
39 ******************************************************************************/
40 
41 /*============================ C O D E A R E A ===========================*/
42 
43 
44 /******************************************************************************
45 * European Southern Observatory
46 * VLTI MIDI Data Reduction Software
47 *
48 * Module name: writeOiArray
49 * Input/Output: See function arguments to avoid duplication
50 * Description: Writes OI_ARRAY fits binary table
51 *
52 *
53 * History:
54 * 15-Apr-04 (csabet) Converted to qfits
55 * 10-Jul-03 (csabet) Created. Derived from John Young <jsy1001@cam.ac.uk>
56 ******************************************************************************/
57 void writeOiArray (
58  char *outFitsName, // In: Name of output FITS file
59  OiArray *array, // In: Pointer to the OiArray structure
60  int *status) // IO: Error status
61 {
62 
63  // Local Declarations
64  // ------------------
65  const char routine[] = "writeOiArray";
66  FILE *outFitsPtr;
67  qfits_table *oiArrayTable;
68  int tableWidth, numOfColumns, numOfRows, numOfElemStaIndex,
69  numOfElemStaName, numOfElemTelName, numOfElemDiameter, numOfElemStaxyz;
70  qfits_col *colPtr;
71  qfits_header *oiArrayHeader;
72  const void **outArrayPtr;
73  char *telName, *staName, *telPtr, *staPtr;
74  char *tempString;
75  int i, j, k, arrayStatus;
76  float *diameter;
77  double *staxyz;
78  short *staIndex;
79 
80 
81  // Algorithm
82  // ---------
83 
84  // Reset status and set table parameters
85  *status = 0;
86  arrayStatus = 0;
87  numOfRows = array->nelement;
88  numOfColumns = 5;
89  tableWidth = -1;
90  numOfElemTelName = 16;
91  numOfElemStaName = 16;
92  numOfElemStaIndex = 1;
93  numOfElemDiameter = 1;
94  numOfElemStaxyz = 3;
95 
96  // Allocate memory
97  tempString = (char *) calloc ( MAX_STRING_LENGTH, sizeof (char));
98 
99  // Open the output FITS file for writing
100  outFitsPtr = fopen (outFitsName, "a");
101  if (outFitsPtr == NULL)
102  {
103  *status = 1;
104  cpl_msg_info(cpl_func,"<<Warning>> from '%s'. Cannot open output FITS file for writing %s\n", routine, outFitsName);
105  free (tempString);
106  return;
107  }
108 
109  // Create a new table
110  oiArrayTable = qfits_table_new (outFitsName, QFITS_BINTABLE, tableWidth, numOfColumns, numOfRows);
111  if (!oiArrayTable)
112  {
113  *status = 1;
114  cpl_msg_info(cpl_func,"<<Warning>> from '%s'. Cannot create OI_ARRAY table \n", routine);
115  free (tempString);
116  fclose (outFitsPtr);
117  remove (outFitsName);
118  return;
119  }
120 
121  // Fill in the column information
122  colPtr = oiArrayTable->col;
123  qfits_col_fill (colPtr, numOfElemTelName, 0, sizeof(char), TFITS_BIN_TYPE_A, "TEL_NAME", " ", " ", " ",
124  0, 0.0, 0, 0.0, 0);
125  colPtr++;
126  qfits_col_fill (colPtr, numOfElemStaName, 0, sizeof(char), TFITS_BIN_TYPE_A, "STA_NAME", " ", " ", " ",
127  0, 0.0, 0, 0.0, 0);
128  colPtr++;
129  qfits_col_fill (colPtr, numOfElemStaIndex, 0, sizeof(short), TFITS_BIN_TYPE_I, "STA_INDEX", " ", " ", " ",
130  0, 0.0, 0, 0.0, 0);
131  colPtr++;
132  qfits_col_fill (colPtr, numOfElemDiameter, 0, sizeof(float), TFITS_BIN_TYPE_E, "DIAMETER", "m", " ", " ",
133  0, 0.0, 0, 0.0, 0);
134  colPtr++;
135  qfits_col_fill (colPtr, numOfElemStaxyz, 0, sizeof(double), TFITS_BIN_TYPE_D, "STAXYZ", "m", " ", " ",
136  0, 0.0, 0, 0.0, 0);
137 
138  // Create OI_ARRAY header
139  oiArrayHeader = qfits_table_ext_header_default (oiArrayTable);
140  qfits_header_add (oiArrayHeader, "EXTNAME", "OI_ARRAY", "Name of this binary table extension", "");
141  qfits_header_add (oiArrayHeader, "OI_REVN", array->revision, "Revision number of the table definition", "");
142  qfits_header_add (oiArrayHeader, "ARRNAME", array->arrname, "Array name", "");
143  qfits_header_add (oiArrayHeader, "FRAME", array->frame, "Coordinate frame", "");
144  sprintf (tempString, "%f", array->arrayx);
145  qfits_header_add (oiArrayHeader, "ARRAYX", tempString, "Array centre x coordinate", "");
146  sprintf (tempString, "%f", array->arrayy);
147  qfits_header_add (oiArrayHeader, "ARRAYY", tempString, "Array centre y coordinate", "");
148  sprintf (tempString, "%f", array->arrayz);
149  qfits_header_add (oiArrayHeader, "ARRAYZ", tempString, "Array centre z coordinate", "");
150 
151  // Diagnostics
152  if (diagnostic > 2) qfits_header_dump (oiArrayHeader, midiReportPtr);
153 
154  // Allocate space for the array of data
155  outArrayPtr = (const void **) calloc (numOfColumns, sizeof(const void *));
156  telName = (char *) calloc (numOfRows * MAX_STRING_LENGTH, sizeof(char));
157  staName = (char *) calloc (numOfRows * MAX_STRING_LENGTH, sizeof(char));
158  staIndex = (short *) calloc (numOfRows, sizeof(short));
159  diameter = (float *) calloc (numOfRows, sizeof(float));
160  staxyz = (double *) calloc (numOfRows * numOfElemStaxyz, sizeof(double));
161 
162  // Load buffer
163  telPtr = telName;
164  for (i = 0; i < numOfRows; i++)
165  {
166  sprintf (telPtr, "%s", array->elem[i].tel_name);
167  telPtr += numOfElemTelName;
168  }
169 
170  staPtr = staName;
171  for (i = 0; i < numOfRows; i++)
172  {
173  sprintf (staPtr, "%s", array->elem[i].sta_name);
174  staPtr += numOfElemStaName;
175  }
176 
177  k = 0;
178  for (i = 0; i < numOfRows; i++)
179  {
180  staIndex[i] = array->elem[i].sta_index;
181  diameter[i] = array->elem[i].diameter;
182  for (j = 0; j < numOfElemStaxyz; j++)
183  {
184  staxyz[k++] = array->elem[i].staxyz[j];
185  }
186  }
187 
188  // Point to the correct elements
189  outArrayPtr[0] = (void *) telName;
190  outArrayPtr[1] = (void *) staName;
191  outArrayPtr[2] = (void *) staIndex;
192  outArrayPtr[3] = (void *) diameter;
193  outArrayPtr[4] = (void *) staxyz;
194 
195  arrayStatus = qfits_table_append_xtension_hdr (outFitsPtr, oiArrayTable, outArrayPtr, oiArrayHeader);
196  if (arrayStatus == - 1)
197  {
198  *status = 1;
199  cpl_msg_info(cpl_func,"<<Warning>> from '%s'. Cannot write into OI_ARRAY table \n", routine);
200  remove (outFitsName);
201  }
202 
203  // Close files and release memory
204  qfits_header_destroy (oiArrayHeader);
205  qfits_table_close (oiArrayTable);
206  free (tempString);
207  free (outArrayPtr);
208  fclose (outFitsPtr);
209  free (telName);
210  free (staName);
211  free (staIndex);
212  free (diameter);
213  free (staxyz);
214 
215  return;
216 }
217 /*****************************************************************************/
218 
219 /******************************************************************************
220 * European Southern Observatory
221 * VLTI MIDI Data Reduction Software
222 *
223 * Module name: writeOiTarget
224 * Input/Output: See function arguments to avoid duplication
225 * Description: Write OI_TARGET fits binary table
226 *
227 *
228 * History:
229 * 13-May-04 (csabet) Converted to qfits
230 * 10-Jul-03 (csabet) Created. Derived from John Young <jsy1001@cam.ac.uk>
231 ******************************************************************************/
232 void writeOiTarget (
233  char *outFitsName, // In: Name of output FITS file
234  OiTarget *targets, // In: Pointer to OiTarget
235  int *status) // IO: Error status
236 {
237 
238  // Local Declaration
239  // -----------------
240  const char routine[] = "writeOiTarget";
241  FILE *outFitsPtr;
242  qfits_table *oiTargetTable;
243  int tableWidth, numOfColumns, numOfRows, numOfElements, numOfElemTargetName,
244  numOfElemVeltyp, numOfElemVeldef, numOfElemSpectyp, arrayStatus;
245  qfits_col *colPtr;
246  qfits_header *oiTargetHeader;
247  const void **outTargetPtr;
248  char *tempString;
249 
250  // Algorithm
251  // ---------
252 
253  // Reset status and set table parameters
254  *status = 0;
255  arrayStatus = 0;
256  numOfRows = targets->ntarget;
257  numOfColumns = 17;
258  tableWidth = -1;
259  numOfElements = 1;
260  numOfElemTargetName = 16;
261  numOfElemVeltyp = 8;
262  numOfElemVeldef = 8;
263  numOfElemSpectyp = 16;
264 
265  // Allocate memory
266  tempString = (char *) calloc ( MAX_STRING_LENGTH, sizeof (char));
267 
268  // Open the output FITS file for writing
269  outFitsPtr = fopen (outFitsName, "a");
270  if (outFitsPtr == NULL)
271  {
272  *status = 1;
273  cpl_msg_info(cpl_func,"<<Warning>> from '%s'. Cannot open output FITS file for writing %s\n", routine, outFitsName);
274  free (tempString);
275  return;
276  }
277 
278  // Create a new table
279  oiTargetTable = qfits_table_new (outFitsName, QFITS_BINTABLE, tableWidth, numOfColumns, numOfRows);
280  if (!oiTargetTable)
281  {
282  *status = 1;
283  cpl_msg_info(cpl_func,"<<Warning>> from '%s'. Cannot create OI_TARGET table \n", routine);
284  free (tempString);
285  fclose (outFitsPtr);
286  remove (outFitsName);
287  return;
288  }
289 
290  // Fill in the column information
291  colPtr = oiTargetTable->col;
292  qfits_col_fill (colPtr, numOfElements, 0, sizeof(short), TFITS_BIN_TYPE_I, "TARGET_ID", " ", " ", " ",
293  0, 0.0, 0, 0.0, 0);
294  colPtr++;
295  qfits_col_fill (colPtr, numOfElemTargetName, 0, sizeof(char), TFITS_BIN_TYPE_A, "TARGET", " ", " ", " ",
296  0, 0.0, 0, 0.0, 0);
297  colPtr++;
298  qfits_col_fill (colPtr, numOfElements, 0, sizeof(double), TFITS_BIN_TYPE_D, "RAEP0", "deg", " ", " ",
299  0, 0.0, 0, 0.0, 0);
300  colPtr++;
301  qfits_col_fill (colPtr, numOfElements, 0, sizeof(double), TFITS_BIN_TYPE_D, "DECEP0", "deg", " ", " ",
302  0, 0.0, 0, 0.0, 0);
303  colPtr++;
304  qfits_col_fill (colPtr, numOfElements, 0, sizeof(float), TFITS_BIN_TYPE_E, "EQUINOX", "year", " ", " ",
305  0, 0.0, 0, 0.0, 0);
306  colPtr++;
307  qfits_col_fill (colPtr, numOfElements, 0, sizeof(double), TFITS_BIN_TYPE_D, "RA_ERR", "deg", " ", " ",
308  0, 0.0, 0, 0.0, 0);
309  colPtr++;
310  qfits_col_fill (colPtr, numOfElements, 0, sizeof(double), TFITS_BIN_TYPE_D, "DEC_ERR", "deg", " ", " ",
311  0, 0.0, 0, 0.0, 0);
312  colPtr++;
313  qfits_col_fill (colPtr, numOfElements, 0, sizeof(double), TFITS_BIN_TYPE_D, "SYSVEL", "m/s", " ", " ",
314  0, 0.0, 0, 0.0, 0);
315  colPtr++;
316  qfits_col_fill (colPtr, numOfElemVeltyp, 0, sizeof(char), TFITS_BIN_TYPE_A, "VELTYP", " ", " ", " ",
317  0, 0.0, 0, 0.0, 0);
318  colPtr++;
319  qfits_col_fill (colPtr, numOfElemVeldef, 0, sizeof(char), TFITS_BIN_TYPE_A, "VELDEF", " ", " ", " ",
320  0, 0.0, 0, 0.0, 0);
321  colPtr++;
322  qfits_col_fill (colPtr, numOfElements, 0, sizeof(double), TFITS_BIN_TYPE_D, "PMRA", "deg/year", " ", " ",
323  0, 0.0, 0, 0.0, 0);
324  colPtr++;
325  qfits_col_fill (colPtr, numOfElements, 0, sizeof(double), TFITS_BIN_TYPE_D, "PMDEC", "deg/year", " ", " ",
326  0, 0.0, 0, 0.0, 0);
327  colPtr++;
328  qfits_col_fill (colPtr, numOfElements, 0, sizeof(double), TFITS_BIN_TYPE_D, "PMRA_ERR", "deg/year", " ", " ",
329  0, 0.0, 0, 0.0, 0);
330  colPtr++;
331  qfits_col_fill (colPtr, numOfElements, 0, sizeof(double), TFITS_BIN_TYPE_D, "PMDEC_ERR", "deg/year", " ", " ",
332  0, 0.0, 0, 0.0, 0);
333  colPtr++;
334  qfits_col_fill (colPtr, numOfElements, 0, sizeof(float), TFITS_BIN_TYPE_E, "PARALLAX", "deg", " ", " ",
335  0, 0.0, 0, 0.0, 0);
336  colPtr++;
337  qfits_col_fill (colPtr, numOfElements, 0, sizeof(float), TFITS_BIN_TYPE_E, "PARA_ERR", "deg", " ", " ",
338  0, 0.0, 0, 0.0, 0);
339  colPtr++;
340  qfits_col_fill (colPtr, numOfElemSpectyp, 0, sizeof(char), TFITS_BIN_TYPE_A, "SPECTYP", " ", " ", " ",
341  0, 0.0, 0, 0.0, 0);
342 
343  // Create OI_RARGET header
344  oiTargetHeader = qfits_table_ext_header_default (oiTargetTable);
345  qfits_header_add (oiTargetHeader, "EXTNAME", "OI_TARGET", "Name of this binary table extension", "");
346  qfits_header_add (oiTargetHeader, "OI_REVN", targets->revision, "Revision number of the table definition", "");
347 
348  // Diagnostics
349  if (diagnostic > 2) qfits_header_dump (oiTargetHeader, midiReportPtr);
350 
351  // Allocate space for the array of data
352  outTargetPtr = (const void **) calloc (numOfColumns, sizeof(const void *));
353 
354  // Point to the correct elements
355  outTargetPtr[0] = (void *) &(targets->targ->target_id);
356  outTargetPtr[1] = (void *) targets->targ->target;
357  outTargetPtr[2] = (void *) &(targets->targ->raep0);
358  outTargetPtr[3] = (void *) &(targets->targ->decep0);
359  outTargetPtr[4] = (void *) &(targets->targ->equinox);
360  outTargetPtr[5] = (void *) &(targets->targ->ra_err);
361  outTargetPtr[6] = (void *) &(targets->targ->dec_err);
362  outTargetPtr[7] = (void *) &(targets->targ->sysvel);
363  outTargetPtr[8] = (void *) targets->targ->veltyp;
364  outTargetPtr[9] = (void *) targets->targ->veldef;
365  outTargetPtr[10] = (void *) &(targets->targ->pmra);
366  outTargetPtr[11] = (void *) &(targets->targ->pmdec);
367  outTargetPtr[12] = (void *) &(targets->targ->pmra_err);
368  outTargetPtr[13] = (void *) &(targets->targ->pmdec_err);
369  outTargetPtr[14] = (void *) &(targets->targ->parallax);
370  outTargetPtr[15] = (void *) &(targets->targ->para_err);
371  outTargetPtr[16] = (void *) targets->targ->spectyp;
372 
373  arrayStatus = qfits_table_append_xtension_hdr (outFitsPtr, oiTargetTable, outTargetPtr, oiTargetHeader);
374  if (arrayStatus == - 1)
375  {
376  *status = 1;
377  cpl_msg_info(cpl_func,"<<Warning>> from '%s'. Cannot write into OI_TARGET table \n", routine);
378  remove (outFitsName);
379  }
380 
381  // Close files and release memory
382  qfits_header_destroy (oiTargetHeader);
383  qfits_table_close (oiTargetTable);
384  free (tempString);
385  free (outTargetPtr);
386  fclose (outFitsPtr);
387 
388  return;
389 }
390 /*****************************************************************************/
391 
392 /******************************************************************************
393 * European Southern Observatory
394 * VLTI MIDI Data Reduction Software
395 *
396 * Module name: writeOiWavelength
397 * Input/Output: See function arguments to avoid duplication
398 * Description: Write OI_WAVELENGTH fits binary table
399 *
400 *
401 * History:
402 * 13-May-04 (csabet) Converted to qfits
403 * 10-Jul-03 (csabet) Created. Derived from John Young <jsy1001@cam.ac.uk>
404 ******************************************************************************/
405 void writeOiWavelength (
406  char *outFitsName, // In: Name of output FITS file
407  OiWavelength *wave, // In: Pointer to OiWavelength
408  int *status) // IO: Status
409 {
410 
411  // Local Declarations
412  // ------------------
413  const char routine[] = "writeOiWavelength";
414  FILE *outFitsPtr;
415  qfits_table *oiWaveTable;
416  int i, tableWidth, numOfColumns, numOfRows, numOfElements, arrayStatus;
417  qfits_col *colPtr;
418  qfits_header *oiWaveHeader;
419  const void **outWavePtr;
420  char *tempString;
421  float *effWave, *effBand;
422 
423  // Algorithm
424  // ---------
425 
426  // Reset status and set table parameters
427  *status = 0;
428  arrayStatus = 0;
429  numOfRows = wave->nwave;
430  numOfColumns = 2;
431  tableWidth = -1;
432  numOfElements = 1;
433 
434  // Allocate memory
435  tempString = (char *) calloc ( MAX_STRING_LENGTH, sizeof (char));
436 
437  // Open the output FITS file for writing
438  outFitsPtr = fopen (outFitsName, "a");
439  if (outFitsPtr == NULL)
440  {
441  *status = 1;
442  cpl_msg_info(cpl_func,"<<Warning>> from '%s'. Cannot open output FITS file for writing %s\n", routine, outFitsName);
443  free (tempString);
444  return;
445  }
446 
447  // Create a new table
448  oiWaveTable = qfits_table_new (outFitsName, QFITS_BINTABLE, tableWidth, numOfColumns, numOfRows);
449  if (!oiWaveTable)
450  {
451  *status = 1;
452  cpl_msg_info(cpl_func,"<<Warning>> from '%s'. Cannot create OI_WAVELENGTH table \n", routine);
453  free (tempString);
454  fclose (outFitsPtr);
455  remove (outFitsName);
456  return;
457  }
458 
459  // Fill in the column information
460  colPtr = oiWaveTable->col;
461  qfits_col_fill (colPtr, numOfElements, 0, sizeof(float), TFITS_BIN_TYPE_E, "EFF_WAVE", "m", " ", " ",
462  0, 0.0, 0, 0.0, 0);
463  colPtr++;
464  qfits_col_fill (colPtr, numOfElements, 0, sizeof(float), TFITS_BIN_TYPE_E, "EFF_BAND", "m", " ", " ",
465  0, 0.0, 0, 0.0, 0);
466 
467  // Create OI_WAVELENGTH header
468  oiWaveHeader = qfits_table_ext_header_default (oiWaveTable);
469  qfits_header_add (oiWaveHeader, "EXTNAME", "OI_WAVELENGTH", "Name of this binary table extension", "");
470  qfits_header_add (oiWaveHeader, "OI_REVN", wave->revision, "Revision number of the table definition", "");
471  qfits_header_add (oiWaveHeader, "INSNAME", wave->insname, "Detector name", "");
472 
473  // Diagnostics
474  if (diagnostic > 2) qfits_header_dump (oiWaveHeader, midiReportPtr);
475 
476  // Allocate space for the array of data
477  outWavePtr = (const void **) calloc (numOfColumns, sizeof(const void *));
478  effWave = (float *) calloc (numOfRows * numOfElements, sizeof(float));
479  effBand = (float *) calloc (numOfRows * numOfElements, sizeof(float));
480 
481  // Load data
482  for (i = 0; i < numOfRows; i++)
483  {
484  effWave[i] = wave->eff_wave[i];
485  effBand[i] = wave->eff_band[i];
486  }
487 
488  // Point to the correct elements
489  outWavePtr[0] = (void *) effWave;
490  outWavePtr[1] = (void *) effBand;
491 
492  arrayStatus = qfits_table_append_xtension_hdr (outFitsPtr, oiWaveTable, outWavePtr, oiWaveHeader);
493  if (arrayStatus == - 1)
494  {
495  *status = 1;
496  cpl_msg_info(cpl_func,"<<Warning>> from '%s'. Cannot write into OI_TARGET table \n", routine);
497  remove (outFitsName);
498  }
499 
500  // Close files and release memory
501  qfits_header_destroy (oiWaveHeader);
502  qfits_table_close (oiWaveTable);
503  free (tempString);
504  free (effWave);
505  free (effBand);
506  free (outWavePtr);
507  fclose (outFitsPtr);
508 
509  return;
510 }
511 /*****************************************************************************/
512 
513 
514 /******************************************************************************
515 * European Southern Observatory
516 * VLTI MIDI Data Reduction Software
517 *
518 * Module name: writeOiVis
519 * Input/Output: See function arguments to avoid duplication
520 * Description: Write OI_VIS fits binary table
521 *
522 *
523 * History:
524 * 14-May-04 (csabet) Converted to qfits
525 * 10-Jul-03 (csabet) Created. Derived from John Young <jsy1001@cam.ac.uk>
526 ******************************************************************************/
527 void writeOiVis ( // Ou: On error, returns non-zero cfitsio error code, and sets status
528  char *outFitsName, // In: Name of output FITS file
529  OiVis *vis, // In: Pointer to OiVis structure
530  int *status) // IO: Status
531 {
532 
533  // Local Declarations
534  // ------------------
535  const char routine[] = "writeOiVis";
536  FILE *outFitsPtr;
537  qfits_table *oiVisTable;
538  int tableWidth, numOfColumns, numOfRows, numOfElements, numOfElemStaIndex, numOfElemVis;
539  qfits_col *colPtr;
540  qfits_header *oiVisHeader;
541  const void **outVisPtr;
542  char *tempString, *flag, *stringPtr;
543  int i, j, k, l, m, *targetId, arrayStatus;
544  double *time, *mjd, *integTime, *visAmp, *visAmapErr, *visPhi, *visPhiErr,
545  *uCoord, *vCoord;
546  short *staIndex;
547 
548  // Algorithm
549  // ---------
550 
551  // Reset status and set table parameters
552  *status = 0;
553  arrayStatus = 0;
554  numOfRows = vis->numrec;
555  numOfColumns = 12;
556  tableWidth = -1;
557  numOfElements = 1;
558  numOfElemStaIndex = 2;
559  numOfElemVis = vis->nwave;
560 
561  // Allocate memory
562  tempString = (char *) calloc ( MAX_STRING_LENGTH, sizeof (char));
563 
564  // Open the output FITS file for writing
565  outFitsPtr = fopen (outFitsName, "a");
566  if (outFitsPtr == NULL)
567  {
568  *status = 1;
569  cpl_msg_info(cpl_func,"<<Warning>> from '%s'. Cannot open output FITS file for writing %s\n", routine, outFitsName);
570  free (tempString);
571  return;
572  }
573 
574  // Create a new table
575  oiVisTable = qfits_table_new (outFitsName, QFITS_BINTABLE, tableWidth, numOfColumns, numOfRows);
576  if (!oiVisTable)
577  {
578  *status = 1;
579  cpl_msg_info(cpl_func,"<<Warning>> from '%s'. Cannot create OI_VIS table \n", routine);
580  free (tempString);
581  fclose (outFitsPtr);
582  remove (outFitsName);
583  return;
584  }
585 
586  // Fill in the column information
587  colPtr = oiVisTable->col;
588  qfits_col_fill (colPtr, numOfElements, 0, sizeof(short), TFITS_BIN_TYPE_I, "TARGET_ID", " ", " ", " ",
589  0, 0.0, 0, 0.0, 0);
590  colPtr++;
591  qfits_col_fill (colPtr, numOfElements, 0, sizeof(double), TFITS_BIN_TYPE_D, "TIME", "s", " ", " ",
592  0, 0.0, 0, 0.0, 0);
593  colPtr++;
594  qfits_col_fill (colPtr, numOfElements, 0, sizeof(double), TFITS_BIN_TYPE_D, "MJD", "day", " ", " ",
595  0, 0.0, 0, 0.0, 0);
596  colPtr++;
597  qfits_col_fill (colPtr, numOfElements, 0, sizeof(double), TFITS_BIN_TYPE_D, "INT_TIME", "s", " ", " ",
598  0, 0.0, 0, 0.0, 0);
599  colPtr++;
600  qfits_col_fill (colPtr, numOfElemVis, 0, sizeof(double), TFITS_BIN_TYPE_D, "VISAMP", " ", " ", " ",
601  0, 0.0, 0, 0.0, 0);
602  colPtr++;
603  qfits_col_fill (colPtr, numOfElemVis, 0, sizeof(double), TFITS_BIN_TYPE_D, "VISAMPERR", " ", " ", " ",
604  0, 0.0, 0, 0.0, 0);
605  colPtr++;
606  qfits_col_fill (colPtr, numOfElemVis, 0, sizeof(double), TFITS_BIN_TYPE_D, "VISPHI", "deg", " ", " ",
607  0, 0.0, 0, 0.0, 0);
608  colPtr++;
609  qfits_col_fill (colPtr, numOfElemVis, 0, sizeof(double), TFITS_BIN_TYPE_D, "VISPHIERR", "deg", " ", " ",
610  0, 0.0, 0, 0.0, 0);
611  colPtr++;
612  qfits_col_fill (colPtr, numOfElements, 0, sizeof(double), TFITS_BIN_TYPE_D, "UCOORD", "m", " ", " ",
613  0, 0.0, 0, 0.0, 0);
614  colPtr++;
615  qfits_col_fill (colPtr, numOfElements, 0, sizeof(double), TFITS_BIN_TYPE_D, "VCOORD", "m", " ", " ",
616  0, 0.0, 0, 0.0, 0);
617  colPtr++;
618  qfits_col_fill (colPtr, numOfElemStaIndex, 0, sizeof(short), TFITS_BIN_TYPE_I, "STA_INDEX", " ", " ", " ",
619  0, 0.0, 0, 0.0, 0);
620  colPtr++;
621  qfits_col_fill (colPtr, numOfElemVis, 0, sizeof(char), TFITS_BIN_TYPE_L, "FLAG", " ", " ", " ",
622  0, 0.0, 0, 0.0, 0);
623  colPtr++;
624 
625  // Create OI_VIS header
626  oiVisHeader = qfits_table_ext_header_default (oiVisTable);
627  qfits_header_add (oiVisHeader, "EXTNAME", "OI_VIS", "Name of this binary table extension", "");
628  qfits_header_add (oiVisHeader, "OI_REVN", vis->revision, "Revision number of the table definition", "");
629  qfits_header_add (oiVisHeader, "DATE-OBS", vis->date_obs, "UTC start date of observations", "");
630  if (strlen(vis->arrname) > 0)
631  qfits_header_add (oiVisHeader, "ARRNAME", vis->arrname, "Array name", "");
632 
633  qfits_header_add (oiVisHeader, "INSNAME", vis->insname, "Detector name", "");
634 
635  // Diagnostics
636  if (diagnostic > 2) qfits_header_dump (oiVisHeader, midiReportPtr);
637 
638  // Allocate space for the array of data
639  outVisPtr = (const void **) calloc (numOfColumns, sizeof(const void *));
640  targetId = (int *) calloc (numOfRows * numOfElements, sizeof (int));
641  time = (double *) calloc (numOfRows * numOfElements, sizeof (double));
642  mjd = (double *) calloc (numOfRows * numOfElements, sizeof (double));
643  integTime = (double *) calloc (numOfRows * numOfElements, sizeof (double));
644  visAmp = (double *) calloc (numOfRows * numOfElemVis, sizeof (double));
645  visAmapErr = (double *) calloc (numOfRows * numOfElemVis, sizeof (double));
646  visPhi = (double *) calloc (numOfRows * numOfElemVis, sizeof (double));
647  visPhiErr = (double *) calloc (numOfRows * numOfElemVis, sizeof (double));
648  uCoord = (double *) calloc (numOfRows * numOfElements, sizeof (double));
649  vCoord = (double *) calloc (numOfRows * numOfElements, sizeof (double));
650  staIndex = (short *) calloc (numOfRows * numOfElemStaIndex, sizeof (short));
651  flag = (char *) calloc (numOfRows * numOfElemVis+1, sizeof (char));
652 
653  // Load the data
654  k = 0;
655  l = 0;
656  m = 0;
657  stringPtr = flag;
658  for (i = 0; i < numOfRows; i++)
659  {
660  for (j = 0; j < numOfElements; j++)
661  {
662  targetId[k] = vis->record[j].target_id;
663  time[k] = vis->record[j].time;
664  mjd[k] = vis->record[j].mjd;
665  integTime[k] = vis->record[j].int_time;
666  uCoord[k] = vis->record[j].ucoord;
667  vCoord[k++] = vis->record[j].vcoord;
668  }
669 
670 
671 
672  for (j = 0; j < numOfElemVis; j++)
673  {
674  visAmp[l] = vis->record[i].visamp[j];
675  visAmapErr[l] = vis->record[i].visamperr[j];
676  visPhi[l] = vis->record[i].visphi[j];
677  visPhiErr[l++] = vis->record[i].visphierr[j];
678 
679  if (strcmp (vis->record[i].flag, "FALSE") == 0)
680  sprintf (stringPtr, "%s", "F");
681  else
682  sprintf (stringPtr, "%s", "T");
683  stringPtr += numOfElements;
684 
685  }
686 /* stringPtr += numOfElements; */
687 
688  for (j = 0; j < numOfElemStaIndex; j++)
689  {
690  staIndex[m++] = vis->record[i].sta_index[j];
691  }
692  }
693 
694  // Point to the correct elements
695  outVisPtr[0] = (void *) targetId;
696  outVisPtr[1] = (void *) time;
697  outVisPtr[2] = (void *) mjd;
698  outVisPtr[3] = (void *) integTime;
699  outVisPtr[4] = (void *) visAmp;
700  outVisPtr[5] = (void *) visAmapErr;
701  outVisPtr[6] = (void *) visPhi;
702  outVisPtr[7] = (void *) visPhiErr;
703  outVisPtr[8] = (void *) uCoord;
704  outVisPtr[9] = (void *) vCoord;
705  outVisPtr[10] = (void *) staIndex;
706  outVisPtr[11] = (void *) flag;
707 
708  arrayStatus = qfits_table_append_xtension_hdr (outFitsPtr, oiVisTable, outVisPtr, oiVisHeader);
709  if (arrayStatus == - 1)
710  {
711  *status = 1;
712  cpl_msg_info(cpl_func,"<<Warning>> from '%s'. Cannot write into OI_VIS table \n", routine);
713  remove (outFitsName);
714  }
715 
716  // Close files and release memory
717  qfits_header_destroy (oiVisHeader);
718  qfits_table_close (oiVisTable);
719  free (tempString);
720  free (outVisPtr);
721  fclose (outFitsPtr);
722  free (targetId);
723  free (time);
724  free (mjd);
725  free (integTime);
726  free (visAmp);
727  free (visAmapErr);
728  free (visPhi);
729  free (visPhiErr);
730  free (uCoord);
731  free (vCoord);
732  free (staIndex);
733  free (flag);
734 
735  return;
736 }
737 /*****************************************************************************/
738 
739 
740 /******************************************************************************
741 * European Southern Observatory
742 * VLTI MIDI Data Reduction Software
743 *
744 * Module name: writeOiVis2
745 * Input/Output: See function arguments to avoid duplication
746 * Description: Write OI_VIS2 fits binary table
747 *
748 *
749 * History:
750 * 14-May-04 (csabet) Converted to qfits
751 * 10-Jul-03 (csabet) Created. Derived from John Young <jsy1001@cam.ac.uk>
752 ******************************************************************************/
753 void writeOiVis2 ( // Ou: On error, returns non-zero cfitsio error code, and sets status
754  char *outFitsName, // In: Name of output FITS file
755  OiVis2 *vis2, // In: Pointer to OiVis2 structure
756  int *status) // IO: Status
757 {
758 
759 
760  // Local Declarations
761  // ------------------
762  const char routine[] = "writeOiVis2";
763  FILE *outFitsPtr;
764  qfits_table *oiVis2Table;
765  int tableWidth, numOfColumns, numOfRows, numOfElements, numOfElemStaIndex, numOfElemVis2;
766  qfits_col *colPtr;
767  qfits_header *oiVis2Header;
768  const void **outVis2Ptr;
769  char *tempString, *flag, *stringPtr;
770  int i, j, k, l, m, *targetId, arrayStatus;
771  double *time, *mjd, *integTime, *vis2Data, *vis2Err, *uCoord, *vCoord;
772  short *staIndex;
773 
774  // Algorithm
775  // ---------
776 
777  // Reset status and set table parameters
778  *status = 0;
779  arrayStatus = 0;
780  numOfRows = vis2->numrec;
781  numOfColumns = 10;
782  tableWidth = -1;
783  numOfElements = 1;
784  numOfElemStaIndex = 2;
785  numOfElemVis2 = vis2->nwave;
786 
787  // Allocate memory
788  tempString = (char *) calloc ( MAX_STRING_LENGTH, sizeof (char));
789 
790  // Open the output FITS file for writing
791  outFitsPtr = fopen (outFitsName, "a");
792  if (outFitsPtr == NULL)
793  {
794  *status = 1;
795  cpl_msg_info(cpl_func,"<<Warning>> from '%s'. Cannot open output FITS file for writing %s\n", routine, outFitsName);
796  free (tempString);
797  return;
798  }
799 
800  // Create a new table
801  oiVis2Table = qfits_table_new (outFitsName, QFITS_BINTABLE, tableWidth, numOfColumns, numOfRows);
802  if (!oiVis2Table)
803  {
804  *status = 1;
805  cpl_msg_info(cpl_func,"<<Warning>> from '%s'. Cannot create OI_VIS2 table \n", routine);
806  free (tempString);
807  fclose (outFitsPtr);
808  remove (outFitsName);
809  return;
810  }
811 
812  // Fill in the column information
813  colPtr = oiVis2Table->col;
814  qfits_col_fill (colPtr, numOfElements, 0, sizeof(short), TFITS_BIN_TYPE_I, "TARGET_ID", " ", " ", " ",
815  0, 0.0, 0, 0.0, 0);
816  colPtr++;
817  qfits_col_fill (colPtr, numOfElements, 0, sizeof(double), TFITS_BIN_TYPE_D, "TIME", "s", " ", " ",
818  0, 0.0, 0, 0.0, 0);
819  colPtr++;
820  qfits_col_fill (colPtr, numOfElements, 0, sizeof(double), TFITS_BIN_TYPE_D, "MJD", "day", " ", " ",
821  0, 0.0, 0, 0.0, 0);
822  colPtr++;
823  qfits_col_fill (colPtr, numOfElements, 0, sizeof(double), TFITS_BIN_TYPE_D, "INT_TIME", "s", " ", " ",
824  0, 0.0, 0, 0.0, 0);
825  colPtr++;
826  qfits_col_fill (colPtr, numOfElemVis2, 0, sizeof(double), TFITS_BIN_TYPE_D, "VIS2DATA", " ", " ", " ",
827  0, 0.0, 0, 0.0, 0);
828  colPtr++;
829  qfits_col_fill (colPtr, numOfElemVis2, 0, sizeof(double), TFITS_BIN_TYPE_D, "VIS2ERR", " ", " ", " ",
830  0, 0.0, 0, 0.0, 0);
831  colPtr++;
832  qfits_col_fill (colPtr, numOfElements, 0, sizeof(double), TFITS_BIN_TYPE_D, "UCOORD", "m", " ", " ",
833  0, 0.0, 0, 0.0, 0);
834  colPtr++;
835  qfits_col_fill (colPtr, numOfElements, 0, sizeof(double), TFITS_BIN_TYPE_D, "VCOORD", "m", " ", " ",
836  0, 0.0, 0, 0.0, 0);
837  colPtr++;
838  qfits_col_fill (colPtr, numOfElemStaIndex, 0, sizeof(short), TFITS_BIN_TYPE_I, "STA_INDEX", " ", " ", " ",
839  0, 0.0, 0, 0.0, 0);
840  colPtr++;
841  qfits_col_fill (colPtr, numOfElemVis2, 0, sizeof(char), TFITS_BIN_TYPE_L, "FLAG", " ", " ", " ",
842  0, 0.0, 0, 0.0, 0);
843  colPtr++;
844 
845  // Create OI_VIS header
846  oiVis2Header = qfits_table_ext_header_default (oiVis2Table);
847  qfits_header_add (oiVis2Header, "EXTNAME", "OI_VIS2", "Name of this binary table extension", "");
848  qfits_header_add (oiVis2Header, "OI_REVN", vis2->revision, "Revision number of the table definition", "");
849  qfits_header_add (oiVis2Header, "DATE-OBS", vis2->date_obs, "UTC start date of observations", "");
850  if (strlen(vis2->arrname) > 0)
851  qfits_header_add (oiVis2Header, "ARRNAME", vis2->arrname, "Array name", "");
852 
853  qfits_header_add (oiVis2Header, "INSNAME", vis2->insname, "Detector name", "");
854 
855  // Diagnostics. Comment out later
856  if (diagnostic > 2) qfits_header_dump (oiVis2Header, midiReportPtr);
857 
858  // Allocate space for the array of data
859  outVis2Ptr = (const void **) calloc (numOfColumns, sizeof(const void *));
860  targetId = (int *) calloc (numOfRows * numOfElements, sizeof (int));
861  time = (double *) calloc (numOfRows * numOfElements, sizeof (double));
862  mjd = (double *) calloc (numOfRows * numOfElements, sizeof (double));
863  integTime = (double *) calloc (numOfRows * numOfElements, sizeof (double));
864  vis2Data = (double *) calloc (numOfRows * numOfElemVis2, sizeof (double));
865  vis2Err = (double *) calloc (numOfRows * numOfElemVis2, sizeof (double));
866  uCoord = (double *) calloc (numOfRows * numOfElements, sizeof (double));
867  vCoord = (double *) calloc (numOfRows * numOfElements, sizeof (double));
868  staIndex = (short *) calloc (numOfRows * numOfElemStaIndex, sizeof (short));
869  flag = (char *) calloc (numOfRows * numOfElemVis2+1, sizeof (char));
870 
871  // Load the data
872  k = 0;
873  l = 0;
874  m = 0;
875  stringPtr = flag;
876  for (i = 0; i < numOfRows; i++)
877  {
878  for (j = 0; j < numOfElements; j++)
879  {
880  targetId[k] = vis2->record[j].target_id;
881  time[k] = vis2->record[j].time;
882  mjd[k] = vis2->record[j].mjd;
883  integTime[k] = vis2->record[j].int_time;
884  uCoord[k] = vis2->record[j].ucoord;
885  vCoord[k++] = vis2->record[j].vcoord;
886  }
887 
888 
889  for (j = 0; j < numOfElemVis2; j++)
890  {
891  vis2Data[l] = vis2->record[i].vis2data[j];
892  vis2Err[l++] = vis2->record[i].vis2err[j];
893 
894  if (strcmp (vis2->record[i].flag, "FALSE") == 0)
895  sprintf (stringPtr, "%s", "F");
896  else
897  sprintf (stringPtr, "%s", "T");
898  stringPtr += numOfElements;
899 
900  }
901 
902  for (j = 0; j < numOfElemStaIndex; j++)
903  {
904  staIndex[m++] = vis2->record[i].sta_index[j];
905  }
906  }
907 
908  // Point to the correct elements
909  outVis2Ptr[0] = (void *) targetId;
910  outVis2Ptr[1] = (void *) time;
911  outVis2Ptr[2] = (void *) mjd;
912  outVis2Ptr[3] = (void *) integTime;
913  outVis2Ptr[4] = (void *) vis2Data;
914  outVis2Ptr[5] = (void *) vis2Err;
915  outVis2Ptr[6] = (void *) uCoord;
916  outVis2Ptr[7] = (void *) vCoord;
917  outVis2Ptr[8] = (void *) staIndex;
918  outVis2Ptr[9] = (void *) flag;
919 
920  arrayStatus = qfits_table_append_xtension_hdr (outFitsPtr, oiVis2Table, outVis2Ptr, oiVis2Header);
921  if (arrayStatus == - 1)
922  {
923  *status = 1;
924  cpl_msg_info(cpl_func,"<<Warning>> from '%s'. Cannot write into OI_VIS2 table \n", routine);
925  remove (outFitsName);
926  }
927 
928  // Close files and release memory
929  qfits_header_destroy (oiVis2Header);
930  qfits_table_close (oiVis2Table);
931  free (tempString);
932  free (outVis2Ptr);
933  fclose (outFitsPtr);
934  free (targetId);
935  free (time);
936  free (mjd);
937  free (integTime);
938  free (vis2Data);
939  free (vis2Err);
940  free (uCoord);
941  free (vCoord);
942  free (staIndex);
943  free (flag);
944 
945  return;
946 }
947 /*****************************************************************************/
948 
949 
950 /******************************************************************************
951 * European Southern Observatory
952 * VLTI MIDI Data Reduction Software
953 *
954 * Module name: writeOiT3
955 * Input/Output: See function arguments to avoid duplication
956 * Description: Write OI_T3 fits binary table
957 *
958 * Warning: This routine is not tested as it is not used in the MIDI
959 * History:
960 * 14-May-04 (csabet) Converted to qfits
961 * 10-Jul-03 (csabet) Created. Derived from John Young <jsy1001@cam.ac.uk>
962 ******************************************************************************/
963 void writeOiT3 ( // Ou: On error, returns non-zero cfitsio error code, and sets status
964  char *outFitsName, // In: Name of output FITS file
965  OiT3 *t3, // In: Pointer to OiT3 structure
966  int *status) // IO: Status
967 {
968 
969  // Local Declarations
970  // ------------------
971  const char routine[] = "writeOiT3";
972  FILE *outFitsPtr;
973  qfits_table *oiT3Table;
974  int tableWidth, numOfColumns, numOfRows, numOfElements, numOfElemStaIndex, numOfElemT3;
975  qfits_col *colPtr;
976  qfits_header *oiT3Header;
977  const void **outT3Ptr;
978  char *tempString, *flag, *stringPtr;
979  int i, j, k, l, m, *targetId, *staIndex;
980  double *time, *mjd, *integTime, *t3Amp, *t3AmpErr, *t3Phi, *t3PhiErr,
981  *u1Coord, *v1Coord, *u2Coord, *v2Coord;
982 
983  // Algorithm
984  // ---------
985 
986  // Reset status and set table parameters
987  *status = 0;
988  numOfRows = t3->numrec;
989  numOfColumns = 14;
990  tableWidth = -1;
991  numOfElements = 1;
992  numOfElemStaIndex = 1;
993  numOfElemT3 = t3->nwave;
994 
995  // Allocate memory
996  tempString = (char *) calloc ( MAX_STRING_LENGTH, sizeof (char));
997 
998  // Open the output FITS file for writing
999  outFitsPtr = fopen (outFitsName, "a");
1000  if (outFitsPtr == NULL)
1001  {
1002  *status = 1;
1003  cpl_msg_info(cpl_func,"<<Warning>> from '%s'. Cannot open output FITS file for writing %s\n", routine, outFitsName);
1004  free (tempString);
1005  return;
1006  }
1007 
1008  // Create a new table
1009  oiT3Table = qfits_table_new (outFitsName, QFITS_BINTABLE, tableWidth, numOfColumns, numOfRows);
1010  if (!oiT3Table)
1011  {
1012  *status = 1;
1013  cpl_msg_info(cpl_func,"<<Warning>> from '%s'. Cannot create OI_T3 table \n", routine);
1014  free (tempString);
1015  fclose (outFitsPtr);
1016  remove (outFitsName);
1017  return;
1018  }
1019 
1020  // Fill in the column information
1021  colPtr = oiT3Table->col;
1022  qfits_col_fill (colPtr, numOfElements, 0, sizeof(short), TFITS_BIN_TYPE_I, "TARGET_ID", " ", " ", " ",
1023  0, 0.0, 0, 0.0, 0);
1024  colPtr++;
1025  qfits_col_fill (colPtr, numOfElements, 0, sizeof(double), TFITS_BIN_TYPE_D, "TIME", "s", " ", " ",
1026  0, 0.0, 0, 0.0, 0);
1027  colPtr++;
1028  qfits_col_fill (colPtr, numOfElements, 0, sizeof(double), TFITS_BIN_TYPE_D, "MJD", "day", " ", " ",
1029  0, 0.0, 0, 0.0, 0);
1030  colPtr++;
1031  qfits_col_fill (colPtr, numOfElements, 0, sizeof(double), TFITS_BIN_TYPE_D, "INT_TIME", "s", " ", " ",
1032  0, 0.0, 0, 0.0, 0);
1033  colPtr++;
1034  qfits_col_fill (colPtr, numOfElemT3, 0, sizeof(double), TFITS_BIN_TYPE_D, "T3AMP", " ", " ", " ",
1035  0, 0.0, 0, 0.0, 0);
1036  colPtr++;
1037  qfits_col_fill (colPtr, numOfElemT3, 0, sizeof(double), TFITS_BIN_TYPE_D, "T3AMPERR", " ", " ", " ",
1038  0, 0.0, 0, 0.0, 0);
1039  colPtr++;
1040  qfits_col_fill (colPtr, numOfElemT3, 0, sizeof(double), TFITS_BIN_TYPE_D, "T3PHI", " ", " ", " ",
1041  0, 0.0, 0, 0.0, 0);
1042  colPtr++;
1043  qfits_col_fill (colPtr, numOfElemT3, 0, sizeof(double), TFITS_BIN_TYPE_D, "T3PHIERR", " ", " ", " ",
1044  0, 0.0, 0, 0.0, 0);
1045  colPtr++;
1046  qfits_col_fill (colPtr, numOfElements, 0, sizeof(double), TFITS_BIN_TYPE_D, "U1COORD", "m", " ", " ",
1047  0, 0.0, 0, 0.0, 0);
1048  colPtr++;
1049  qfits_col_fill (colPtr, numOfElements, 0, sizeof(double), TFITS_BIN_TYPE_D, "V1COORD", "m", " ", " ",
1050  0, 0.0, 0, 0.0, 0);
1051  colPtr++;
1052  qfits_col_fill (colPtr, numOfElements, 0, sizeof(double), TFITS_BIN_TYPE_D, "U2COORD", "m", " ", " ",
1053  0, 0.0, 0, 0.0, 0);
1054  colPtr++;
1055  qfits_col_fill (colPtr, numOfElements, 0, sizeof(double), TFITS_BIN_TYPE_D, "V2COORD", "m", " ", " ",
1056  0, 0.0, 0, 0.0, 0);
1057  colPtr++;
1058  qfits_col_fill (colPtr, numOfElemStaIndex, 0, sizeof(short), TFITS_BIN_TYPE_I, "STA_INDEX", " ", " ", " ",
1059  0, 0.0, 0, 0.0, 0);
1060  colPtr++;
1061  qfits_col_fill (colPtr, numOfElements, 0, sizeof(char), TFITS_BIN_TYPE_A, "FLAG", " ", " ", " ",
1062  0, 0.0, 0, 0.0, 0);
1063  colPtr++;
1064 
1065  // Create OI_VIS header
1066  oiT3Header = qfits_table_ext_header_default (oiT3Table);
1067  qfits_header_add (oiT3Header, "EXTNAME", "OI_T3", "Name of this binary table extension", "");
1068  qfits_header_add (oiT3Header, "OI_REVN", t3->revision, "Revision number of the table definition", "");
1069  qfits_header_add (oiT3Header, "DATE-OBS", t3->date_obs, "UTC start date of observations", "");
1070  if (strlen(t3->arrname) > 0)
1071  qfits_header_add (oiT3Header, "ARRNAME", t3->arrname, "Array name", "");
1072 
1073  qfits_header_add (oiT3Header, "INSNAME", t3->insname, "Detector name", "");
1074 
1075  // Diagnostics. Comment out later
1076  if (diagnostic > 2) qfits_header_dump (oiT3Header, midiReportPtr);
1077 
1078  // Allocate space for the array of data
1079  outT3Ptr = (const void **) calloc (numOfColumns, sizeof(const void *));
1080  targetId = (int *) calloc (numOfRows * numOfElements, sizeof (int));
1081  time = (double *) calloc (numOfRows * numOfElements, sizeof (double));
1082  mjd = (double *) calloc (numOfRows * numOfElements, sizeof (double));
1083  integTime = (double *) calloc (numOfRows * numOfElements, sizeof (double));
1084  t3Amp = (double *) calloc (numOfRows * numOfElemT3, sizeof (double));
1085  t3AmpErr = (double *) calloc (numOfRows * numOfElemT3, sizeof (double));
1086  t3Phi = (double *) calloc (numOfRows * numOfElemT3, sizeof (double));
1087  t3PhiErr = (double *) calloc (numOfRows * numOfElemT3, sizeof (double));
1088  u1Coord = (double *) calloc (numOfRows * numOfElements, sizeof (double));
1089  v1Coord = (double *) calloc (numOfRows * numOfElements, sizeof (double));
1090  u2Coord = (double *) calloc (numOfRows * numOfElements, sizeof (double));
1091  v2Coord = (double *) calloc (numOfRows * numOfElements, sizeof (double));
1092  staIndex = (int *) calloc (numOfRows * numOfElemStaIndex, sizeof (int));
1093  flag = (char *) calloc (numOfRows * MAX_STRING_LENGTH, sizeof (char));
1094 
1095  // Load the data
1096  k = 0;
1097  l = 0;
1098  m = 0;
1099  stringPtr = flag;
1100  for (i = 0; i < numOfRows; i++)
1101  {
1102  for (j = 0; j < numOfElements; j++)
1103  {
1104  targetId[k] = t3->record[j].target_id;
1105  time[k] = t3->record[j].time;
1106  mjd[k] = t3->record[j].mjd;
1107  integTime[k] = t3->record[j].int_time;
1108  u1Coord[k] = t3->record[j].u1coord;
1109  v1Coord[k++] = t3->record[j].v1coord;
1110  u2Coord[k] = t3->record[j].u2coord;
1111  v2Coord[k++] = t3->record[j].v2coord;
1112  }
1113 
1114  cpl_msg_info(cpl_func,"flag = %s\n", t3->record[i].flag);
1115  if (strcmp (t3->record[i].flag, "FALSE") == 0)
1116  sprintf (stringPtr, "%s", "F");
1117  else
1118  sprintf (stringPtr, "%s", "T");
1119  stringPtr += numOfElements;
1120 
1121  for (j = 0; j < numOfElemT3; j++)
1122  {
1123  t3Amp[l] = t3->record[i].t3amp[j];
1124  t3AmpErr[l] = t3->record[i].t3amperr[j];
1125  t3Phi[l] = t3->record[i].t3phi[j];
1126  t3PhiErr[l] = t3->record[i].t3phierr[j];
1127  }
1128 
1129  for (j = 0; j < numOfElemStaIndex; j++)
1130  {
1131  staIndex[m++] = t3->record[i].sta_index[j];
1132  }
1133  }
1134 
1135  // Point to the correct elements
1136  outT3Ptr[0] = (void *) targetId;
1137  outT3Ptr[1] = (void *) time;
1138  outT3Ptr[2] = (void *) mjd;
1139  outT3Ptr[3] = (void *) integTime;
1140  outT3Ptr[4] = (void *) t3Amp;
1141  outT3Ptr[5] = (void *) t3AmpErr;
1142  outT3Ptr[6] = (void *) t3Phi;
1143  outT3Ptr[7] = (void *) t3PhiErr;
1144  outT3Ptr[8] = (void *) u1Coord;
1145  outT3Ptr[9] = (void *) v1Coord;
1146  outT3Ptr[10] = (void *) u2Coord;
1147  outT3Ptr[11] = (void *) v2Coord;
1148  outT3Ptr[12] = (void *) staIndex;
1149  outT3Ptr[13] = (void *) flag;
1150 
1151  if (qfits_table_append_xtension_hdr (outFitsPtr, oiT3Table, outT3Ptr, oiT3Header) == -1)
1152  {
1153  *status = 1;
1154  cpl_msg_info(cpl_func,"<<Warning>> from '%s'. Cannot write into OI_T3 table \n", routine);
1155  remove (outFitsName);
1156  }
1157 
1158  // Close files and release memory
1159  qfits_header_destroy (oiT3Header);
1160  qfits_table_close (oiT3Table);
1161  free (tempString);
1162  free (outT3Ptr);
1163  fclose (outFitsPtr);
1164  free (targetId);
1165  free (time);
1166  free (mjd);
1167  free (integTime);
1168  free (t3Amp);
1169  free (t3AmpErr);
1170  free (t3Phi);
1171  free (t3PhiErr);
1172  free (u1Coord);
1173  free (v1Coord);
1174  free (u2Coord);
1175  free (v2Coord);
1176  free (staIndex);
1177  free (flag);
1178 
1179  return;
1180 }
1181 /*****************************************************************************/