MIDI Pipeline Reference Manual  2.8.3
createProdFrgUndisp.c
1 /******************************************************************************
2 *******************************************************************************
3 * European Southern Observatory
4 * VLTI MIDI Data Reduction Software
5 *
6 * Module name: createProdFrgUndisp.c
7 * Description: Contains routines for product files handling
8 *
9 * History:
10 * 25-Apr-03 (csabet) Created
11 *******************************************************************************
12 ******************************************************************************/
13 
14 /******************************************************************************
15 * Compiler directives
16 ******************************************************************************/
17 
18 /******************************************************************************
19 * Include files
20 ******************************************************************************/
21 #include <sys/types.h>
22 #include <sys/stat.h>
23 #include <unistd.h>
24 #include <stdio.h>
25 #include <cpl.h>
26 #include <time.h>
27 #include <math.h>
28 #include "midiGlobal.h"
29 #include "midiLib.h"
30 #include "iauWrite.h"
31 #include "midiFitsUtility.h"
32 #include "createProdFrgUndisp.h"
33 #include "geometry.h"
34 #include "memoryHandling.h"
35 #include "errorHandling.h"
36 #include "fileHandling.h"
37 #include "qfits.h"
38 
39 /**********************************************************
40 * Global Variables
41 **********************************************************/
42 
43 /**********************************************************
44 * Constant definitions
45 **********************************************************/
46 
47 /**********************************************************
48 * Function definitions
49 **********************************************************/
50 static void set_fnan(float *f)
51 {
52 
53 #ifndef WORDS_BIGENDIAN
54  static unsigned char fnan_pat[] = {0, 0, 0xc0, 0x7f};
55 #else
56  static unsigned char fnan_pat[] = {0x7f, 0xc0, 0, 0};
57 #endif
58 
59 memcpy(f, fnan_pat, 4);
60 }
61 
62 /*============================ C O D E A R E A ===========================*/
63 
64 
65 
66 
67 /******************************************************************************
68 * European Southern Observatory
69 * VLTI MIDI Data Reduction Software
70 *
71 * Module name: createFrgProdUndisp
72 * Input/Output: See function arguments to avoid duplication
73 * Description: Creates an output fits file and copies keywords from the
74 * input header to the output header
75 *
76 *
77 * History:
78 * 21-Apr-03 (csabet) Created
79 ******************************************************************************/
80 void createFrgProdUndisp (
81  MidiFiles *fileNames,
82  ImageFormat *format,
83  FilterData *filterInfo,
84  RawVisibility *rawVis,
85  TransferFunction *trfFunction,
86  CalibratorParam *calibrator,
87  CalibratedVisibility *calibVis,
88  PhotometryResult *photom,
89  int *error)
90 {
91 
92  /* Local Declarations
93  --------------------*/
94  const char routine[] = "createFrgProdUndisp";
95  int iwave, numOfTelescopes, extNumber;
96  char *stringQfits, *classification, *stringTemp;
97  FILE *inFitsBatchPtr = NULL;
98  IauExchange *iauData;
99  UVW *uvw;
100  float *visAmp, *visSqrd;
101 
102  /* Algorithm
103  -----------*/
104  if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking routine '%s' \n", routine);
105  if (diagnostic > 4) fprintf(midiReportPtr, "Invoking routine '%s' \n", routine);
106 
107  cpl_msg_info(cpl_func,"\nCreating Product files for batch %d \n", batchNumber);
108  cpl_msg_info(cpl_func,"-------------------------------- \n");
109  fprintf (midiReportPtr, "\nCreating Product files for batch %d \n", batchNumber);
110  fprintf (midiReportPtr, "-------------------------------- \n");
111 
112  /* Reset status */
113  *error = 0;
114 
115  /* Allocate memory */
116  stringTemp = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
117  classification = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
118 
119  /* Open the list of files */
120  if ((inFitsBatchPtr = fopen (fileNames->inFitsBatch, "r")) == NULL)
121  {
122  *error = 1;
123  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot open input FITS file list");
124  free (stringTemp);
125  free (classification);
126  return;
127  }
128 
129  /* Read the name of the first file in the list and get it's full path name */
130  fgets (stringTemp, MAX_STRING_LENGTH, inFitsBatchPtr);
131  sprintf (classification, "%s", "");
132  sscanf (stringTemp, "%s%s", fileNames->inFitsName, classification);
133  fclose (inFitsBatchPtr);
134 
135  /* Copy keywords from the raw FITS file into the QC log */
136  createQcLog (fileNames->inFitsName, error);
137  if (*error)
138  {
139  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot copy keywords to QC log");
140  free (stringTemp);
141  free (classification);
142  return;
143  }
144 
145  /* Allocate memory for data structures relating to IAU exchange product FITS file
146  --------------------------------------------------------------------------------*/
147  /* Get number of array elements. Number of telescopes */
148  extNumber = getFitsExtensionNumber (fileNames->inFitsName, "IMAGING_DATA", error);
149  if (*error)
150  {
151  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__,
152  "Cannot get IMAGING_DATA extension number from input FITS file");
153  free (stringTemp);
154  free (classification);
155  return;
156  }
157  stringQfits = qfits_query_ext (fileNames->inFitsName, "MAXTEL", extNumber);
158  if (stringQfits == NULL)
159  {
160  *error = 1;
161  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot read MAXTEL from input FITS file");
162  free (stringTemp);
163  free (classification);
164  return;
165  }
166  else sscanf (stringQfits, "%d", &numOfTelescopes);
167 
168  /* Allocate memory */
169  iauData = callocIauExchange (numOfTelescopes, 1);
170  uvw = (UVW *) calloc (1, sizeof (UVW));
171  visAmp = (float *) calloc (iauData->wavelength->nwave, sizeof (float));
172  visSqrd = (float *) calloc (iauData->wavelength->nwave, sizeof (float));
173 
174  /* Get default visibilities */
175  for (iwave = 0; iwave < iauData->wavelength->nwave; iwave++)
176  {
177  visAmp[iwave] = rawVis->vis;
178  visSqrd[iwave] = rawVis->visSqrd;
179  }
180 
181  /* Overwite if calibrated visibility is available */
182  if ((strcmp (format->obsCatg, "SCIENCE") == 0) && calibVis->exists)
183  {
184  for (iwave = 0; iwave < iauData->wavelength->nwave; iwave++)
185  {
186  visAmp[iwave] = calibVis->vis[iwave];
187  visSqrd[iwave] = calibVis->visSqrd[iwave];
188  }
189  }
190 
191  /* Load output data into the IAU exchange structures */
192  loadFrgOutputDataUndisp (fileNames->inFitsName, filterInfo, visAmp, visSqrd, iauData->array, iauData->targets,
193  iauData->wavelength, iauData->vis, iauData->vis2, uvw, error);
194  if (*error == 1)
195  {
196  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot load data structure");
197  freeIauExchange (iauData);
198  free (uvw);
199  free (visAmp);
200  free (visSqrd);
201  free (stringTemp);
202  free (classification);
203  return;
204  }
205 
206  /* Add product info to QC log */
207  addProdInfoToFrgQcLogUndisp (format, fileNames, rawVis, calibVis, uvw, photom,
208  filterInfo, trfFunction, calibrator, error);
209  if (*error == 1)
210  {
211  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot add product info to QC log");
212  freeIauExchange (iauData);
213  free (uvw);
214  free (visAmp);
215  free (visSqrd);
216  free (stringTemp);
217  free (classification);
218  return;
219  }
220 
221  /* Create the primary header extension */
222  createFrgPrimHeadUndisp (fileNames, format, rawVis, calibVis,
223  uvw, photom, filterInfo, trfFunction, calibrator, error);
224  if (*error == 1)
225  {
226  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot create Primary Header extension");
227  freeIauExchange (iauData);
228  free (uvw);
229  free (visAmp);
230  free (visSqrd);
231  free (stringTemp);
232  free (classification);
233  return;
234  }
235 
236  /* At this stage output FITS file has probably been created with appropriate
237  header. Now we create the tables and write the data in accordance with the IAU exchange */
238  writeFrgFitsFileUndisp (fileNames->outFitsName, iauData->array, iauData->targets, iauData->wavelength,
239  iauData->vis, iauData->vis2, error);
240  if (*error == 1)
241  {
242  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot write product FITS file");
243  freeIauExchange (iauData);
244  free (uvw);
245  free (visAmp);
246  free (visSqrd);
247  free (stringTemp);
248  free (classification);
249  return;
250  }
251 
252  if (diagnostic)cpl_msg_info(cpl_func,"Created Output FITS file: %s \n", fileNames->outFitsName);
253  fprintf (midiReportPtr, "Created Output FITS file: %s \n", fileNames->outFitsName);
254 
255  /* Release memory */
256  freeIauExchange (iauData);
257  free (uvw);
258  free (visAmp);
259  free (visSqrd);
260  free (stringTemp);
261  free (classification);
262 
263  return;
264 }
265 /*****************************************************************************/
266 
267 
268 
269 
270 /******************************************************************************
271 * European Southern Observatory
272 * VLTI MIDI Data Reduction Software
273 *
274 * Module name: createFrgPrimHeadUndisp
275 * Input/Output: See function arguments to avoid duplication
276 * Description: Creates the primary header
277 *
278 *
279 * History:
280 * 02-May-03 (csabet) Created
281 ******************************************************************************/
282 void createFrgPrimHeadUndisp (
283  MidiFiles *fileNames,
284  ImageFormat *format,
285  RawVisibility *rawVis,
286  CalibratedVisibility *calibVis,
287  UVW *uvw,
288  PhotometryResult *photom,
289  FilterData *filterInfo,
290  TransferFunction *trfFunction,
291  CalibratorParam *calibrator,
292  int *error)
293 {
294 
295  /* Local Declarations
296  --------------------*/
297  const char routine[] = "createFrgPrimHeadUndisp";
298  qfits_header *outFitsHeader;
299  FILE *inFitsBatchPtr, *outFitsPtr;
300  int i;
301  char *textBuff, *stringQfits, *messageBuffer, *currentTime, *cleanString,
302  *stringTemp, *classification;
303  unsigned int stringLength;
304  time_t now;
305  struct tm *newTime;
306  struct stat buf;
307 
308  /* Algorithm
309  -----------*/
310  if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking routine '%s' \n", routine);
311  if (diagnostic > 4) fprintf(midiReportPtr, "Invoking routine '%s' \n", routine);
312 
313  *error = 0;
314 
315  /* Allocate memory */
316  textBuff = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
317  classification = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
318  stringTemp = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
319  cleanString = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
320  messageBuffer = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
321  currentTime = (char *) calloc (MIN_STRING_LENGTH, sizeof (char));
322 
323  /* Get current time/date */
324  now = time(NULL);
325  newTime = gmtime (&now);
326  strftime (currentTime, MIN_STRING_LENGTH, "%a %d %b %Y at %H:%M:%S", newTime);
327 
328  /* Copy primary header from the raw file to the output header */
329  outFitsHeader = qfits_header_read (fileNames->inFitsName);
330  if (outFitsHeader == NULL)
331  {
332  *error = 1;
333  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot load header from the input FITS file");
334  free (messageBuffer);
335  free (currentTime);
336  free (cleanString);
337  free (stringTemp);
338  free (classification);
339  free (textBuff);
340  return;
341  }
342 
343  /* Now write all the required product keaywords to the output header
344  -------------------------------------------------------------------*/
345  qfits_header_add (outFitsHeader, "HIERARCH ESO PRO TYPE", format->obsType, "MIDI pipeline product type", "");
346  qfits_header_add (outFitsHeader, "HIERARCH ESO PRO CATG", "REDUCED_UNDISPERSED", "Pipeline product category", NULL);
347  qfits_header_add (outFitsHeader, "HIERARCH ESO PRO ARCFILE", fileNames->archFileName, "Arcfile name of first raw file", "");
348  qfits_header_add (outFitsHeader, "HIERARCH ESO PRO PIPEDATE", currentTime, "Pipeline run date", "");
349  qfits_header_add (outFitsHeader, "HIERARCH ESO PRO VERSION", MIDI_PIPE_VERSION, "Pipeline version", "");
350  qfits_header_add (outFitsHeader, "PIPEFILE", fileNames->pipeFileName, "Pipeline product file name", "");
351  qfits_header_add (outFitsHeader, "HIERARCH ESO PRO DID", MIDI_QC_DIC_VERSION, "QC dictionary version", "");
352 
353  /* Open the list of files */
354  if ((inFitsBatchPtr = fopen (fileNames->inFitsBatch, "r")) == NULL)
355  {
356  *error = 1;
357  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot open input FITS file list");
358  free (messageBuffer);
359  free (currentTime);
360  free (cleanString);
361  free (stringTemp);
362  free (classification);
363  free (textBuff);
364  return;
365  }
366 
367  /* Loop through the list of files and write into the primary header */
368  i = 1;
369  while (fgets (stringTemp, MAX_STRING_LENGTH, inFitsBatchPtr) != NULL)
370  {
371  sprintf (classification, "%s", "");
372  sscanf (stringTemp, "%s%s", messageBuffer, classification);
373 
374  /* If classification is not given get it from the raw file */
375  if (strcmp (classification, "") == 0)
376  {
377  stringQfits = qfits_query_hdr (messageBuffer, "HIERARCH ESO DPR CATG");
378  if (stringQfits == NULL)
379  {
380  sprintf (classification, "%s", "UNKNOWN");
381  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot get Observation Category");
382  }
383  else
384  {
385  cleanUpString (stringQfits, cleanString);
386  sprintf (classification, "%s", cleanString);
387  }
388  }
389  removePathName (messageBuffer, midiReportPtr);
390  sprintf (textBuff, "HIERARCH ESO PRO REC1 RAW%d NAME", i);
391  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "FITS file name", "");
392  sprintf (textBuff, "HIERARCH ESO PRO REC1 RAW%d CATG", i++);
393  qfits_header_add (outFitsHeader, textBuff, classification, "Observation Categoty", "");
394  }
395  fclose (inFitsBatchPtr);
396 
397  /* Write the mask file */
398  sprintf (messageBuffer, "%s", fileNames->maskFileName);
399  removePathName (messageBuffer, midiReportPtr);
400  qfits_header_add (outFitsHeader, "HIERARCH ESO PRO REC2 RAW1 NAME", messageBuffer, "Pipeline Mask File", "");
401 
402  /* Write the transfer function file */
403  if (strcmp (format->obsCatg, "CALIB") == 0) sprintf (messageBuffer, "%s", fileNames->trfNameWrite);
404  else sprintf (messageBuffer, "%s", fileNames->trfNameRead);
405  removePathName (messageBuffer, midiReportPtr);
406  stringLength = strlen (messageBuffer);
407  sprintf (textBuff, "r.");
408  strncat (textBuff, messageBuffer, stringLength-4);
409  sprintf (messageBuffer, "%s_tpl_0001.dummy", textBuff);
410  qfits_header_add (outFitsHeader, "HIERARCH ESO PRO REC2 RAW2 NAME", messageBuffer, "Transfer Function File", "");
411 
412  /* Scan parameters */
413  sprintf (messageBuffer, "%d", format->numOfScansProcessed);
414  qfits_header_add (outFitsHeader, "HIERARCH ESO QC SCN PROCESSED", messageBuffer, "Number of scans processed", "");
415  sprintf (messageBuffer, "%d", format->numOfScansRejected);
416  qfits_header_add (outFitsHeader, "HIERARCH ESO QC SCN REJECTED", messageBuffer, "Number of scans rejected", "");
417 
418  /* Add Filter information */
419  sprintf (messageBuffer, "%f", filterInfo->optFreqLo);
420  qfits_header_add (outFitsHeader, "HIERARCH ESO QC WAVE MIN", messageBuffer, "Filter minimum wavelength in micron", "");
421  sprintf (messageBuffer, "%f", filterInfo->optFreqHi);
422  qfits_header_add (outFitsHeader, "HIERARCH ESO QC WAVE MAX", messageBuffer, "Filter maximum wavelength in micron", "");
423 
424  /* Transfer functions */
425  if (trfFunction->exists)
426  {
427  qfits_header_add (outFitsHeader, "HIERARCH ESO PRO TRF", "AVAILABLE", "Flag for Transfer Function availability", NULL);
428  if (strcmp (format->obsCatg, "CALIB") == 0)
429  {
430  sprintf (messageBuffer, "%f", calibrator->calibVisSqrd);
431  qfits_header_add (outFitsHeader, "HIERARCH ESO QC THEOVIS", messageBuffer, "Theoretical visibility", "");
432  sprintf (messageBuffer, "%f", calibrator->calibVisSqrdErr);
433  qfits_header_add (outFitsHeader, "HIERARCH ESO QC DTHEOVIS", messageBuffer, "(sigma) Error on theoretical visibility", "");
434 
435  sprintf (messageBuffer, "%f", trfFunction->trf[3]);
436  qfits_header_add (outFitsHeader, "HIERARCH ESO QC T0", messageBuffer, "Measured transfer function (ratio of square visibilities)", "");
437  sprintf (messageBuffer, "%f", trfFunction->trf[4]);
438  qfits_header_add (outFitsHeader, "HIERARCH ESO QC T1", messageBuffer, "Measured transfer function (ratio of square visibilities)", "");
439  sprintf (messageBuffer, "%f", trfFunction->trf[5]);
440  qfits_header_add (outFitsHeader, "HIERARCH ESO QC T2", messageBuffer, "Measured transfer function (ratio of square visibilities)", "");
441 
442  sprintf (messageBuffer, "%f", trfFunction->trfErr[3]);
443  qfits_header_add (outFitsHeader, "HIERARCH ESO QC DT0", messageBuffer, "(sigma) Error on measured transfer function", "");
444  sprintf (messageBuffer, "%f", trfFunction->trfErr[4]);
445  qfits_header_add (outFitsHeader, "HIERARCH ESO QC DT1", messageBuffer, "(sigma) Error on measured transfer function", "");
446  sprintf (messageBuffer, "%f", trfFunction->trfErr[5]);
447  qfits_header_add (outFitsHeader, "HIERARCH ESO QC DT2", messageBuffer, "(sigma) Error on measured transfer function", "");
448 
449  sprintf (messageBuffer, "%f", 1.0/trfFunction->trf[3]);
450  qfits_header_add (outFitsHeader, "HIERARCH ESO QC COT0", messageBuffer, "Inverse transfer function", "");
451  sprintf (messageBuffer, "%f", 1.0/trfFunction->trf[4]);
452  qfits_header_add (outFitsHeader, "HIERARCH ESO QC COT1", messageBuffer, "Inverse transfer function", "");
453  sprintf (messageBuffer, "%f", 1.0/trfFunction->trf[5]);
454  qfits_header_add (outFitsHeader, "HIERARCH ESO QC COT2", messageBuffer, "Inverse transfer function", "");
455 
456  sprintf (messageBuffer, "%f", 1.0/trfFunction->trfErr[3]);
457  qfits_header_add (outFitsHeader, "HIERARCH ESO QC DCOT0", messageBuffer, "(sigma) Error on inverse transfer function", "");
458  sprintf (messageBuffer, "%f", 1.0/trfFunction->trfErr[4]);
459  qfits_header_add (outFitsHeader, "HIERARCH ESO QC DCOT1", messageBuffer, "(sigma) Error on inverse transfer function", "");
460  sprintf (messageBuffer, "%f", 1.0/trfFunction->trfErr[5]);
461  qfits_header_add (outFitsHeader, "HIERARCH ESO QC DCOT2", messageBuffer, "(sigma) Error on inverse transfer function", "");
462  }
463  else
464  {
465  sprintf (messageBuffer, "%f", trfFunction->trf[3]);
466  qfits_header_add (outFitsHeader, "HIERARCH ESO QC AT0", messageBuffer, "Applied transfer function", "");
467  sprintf (messageBuffer, "%f", trfFunction->trf[4]);
468  qfits_header_add (outFitsHeader, "HIERARCH ESO QC AT1", messageBuffer, "Applied transfer function", "");
469  sprintf (messageBuffer, "%f", trfFunction->trf[5]);
470  qfits_header_add (outFitsHeader, "HIERARCH ESO QC AT2", messageBuffer, "Applied transfer function", "");
471  sprintf (messageBuffer, "%f", trfFunction->trfErr[3]);
472  qfits_header_add (outFitsHeader, "HIERARCH ESO QC DAT0", messageBuffer, "(sigma) Error on applied transfer function", "");
473  sprintf (messageBuffer, "%f", trfFunction->trfErr[4]);
474  qfits_header_add (outFitsHeader, "HIERARCH ESO QC DAT1", messageBuffer, "(sigma) Error on applied transfer function", "");
475  sprintf (messageBuffer, "%f", trfFunction->trfErr[5]);
476  qfits_header_add (outFitsHeader, "HIERARCH ESO QC DAT2", messageBuffer, "(sigma) Error on applied transfer function", "");
477  }
478  }
479  else
480  qfits_header_add (outFitsHeader, "HIERARCH ESO PRO TRF", UNAV, "Flag for Transfer Function availability", NULL);
481 
482  /* Visibilities */
483  sprintf (messageBuffer, "%f", rawVis->visSqrd);
484  qfits_header_add (outFitsHeader, "HIERARCH ESO QC UNCALV0", messageBuffer, "Uncalibrated square visibility", "");
485  sprintf (messageBuffer, "%f", rawVis->visSqrd1);
486  qfits_header_add (outFitsHeader, "HIERARCH ESO QC UNCALV1", messageBuffer, "Ucalibrated square visibility", "");
487  sprintf (messageBuffer, "%f", rawVis->visSqrd2);
488  qfits_header_add (outFitsHeader, "HIERARCH ESO QC UNCALV2", messageBuffer, "Uncalibrated square visibility", "");
489  sprintf (messageBuffer, "%f", rawVis->visSqrdErr);
490  qfits_header_add (outFitsHeader, "HIERARCH ESO QC DUNCALV0", messageBuffer, "Variance of uncalibrated square visibility", "");
491  sprintf (messageBuffer, "%f", rawVis->visSqrd1Err);
492  qfits_header_add (outFitsHeader, "HIERARCH ESO QC DUNCALV1", messageBuffer, "Variance of uncalibrated square visibility", "");
493  sprintf (messageBuffer, "%f", rawVis->visSqrd2Err);
494  qfits_header_add (outFitsHeader, "HIERARCH ESO QC DUNCALV2", messageBuffer, "Variance of uncalibrated square visibility", "");
495  if (calibVis->exists)
496  {
497  sprintf (messageBuffer, "%f", calibVis->visSqrd[0]);
498  qfits_header_add (outFitsHeader, "HIERARCH ESO QC CALV0", messageBuffer, "Calibrated square visibility", "");
499  sprintf (messageBuffer, "%f", calibVis->visSqrd[1]);
500  qfits_header_add (outFitsHeader, "HIERARCH ESO QC CALV1", messageBuffer, "Calibrated square visibility", "");
501  sprintf (messageBuffer, "%f", calibVis->visSqrd[2]);
502  qfits_header_add (outFitsHeader, "HIERARCH ESO QC CALV2", messageBuffer, "Calibrated square visibility", "");
503  sprintf (messageBuffer, "%f", calibVis->visSqrdErr[0]);
504  qfits_header_add (outFitsHeader, "HIERARCH ESO QC DCALV0", messageBuffer, "Variance of calibrated square visibility", "");
505  sprintf (messageBuffer, "%f", calibVis->visSqrdErr[1]);
506  qfits_header_add (outFitsHeader, "HIERARCH ESO QC DCALV1", messageBuffer, "Variance of calibrated square visibility", "");
507  sprintf (messageBuffer, "%f", calibVis->visSqrdErr[2]);
508  qfits_header_add (outFitsHeader, "HIERARCH ESO QC DCALV2", messageBuffer, "Variance of calibrated square visibility", "");
509  }
510 
511  /* Photometry parameters */
512  sprintf (messageBuffer, "%f", photom->photomA[0]);
513  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PHOTA0", messageBuffer, "Number of photons", "");
514  sprintf (messageBuffer, "%f", photom->photomAErr[0]);
515  qfits_header_add (outFitsHeader, "HIERARCH ESO QC DPHOTA0", messageBuffer, "(sigma) Error in number of photons", "");
516  sprintf (messageBuffer, "%f", photom->photomA[1]);
517  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PHOTA1", messageBuffer, "Number of photons", "");
518  sprintf (messageBuffer, "%f", photom->photomAErr[1]);
519  qfits_header_add (outFitsHeader, "HIERARCH ESO QC DPHOTA1", messageBuffer, "(sigma) Error in number of photons", "");
520  sprintf (messageBuffer, "%f", photom->photomB[0]);
521  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PHOTB0", messageBuffer, "Number of photons", "");
522  sprintf (messageBuffer, "%f", photom->photomBErr[0]);
523  qfits_header_add (outFitsHeader, "HIERARCH ESO QC DPHOTB0", messageBuffer, "(sigma) Error in number of photons", "");
524  sprintf (messageBuffer, "%f", photom->photomB[1]);
525  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PHOTB1", messageBuffer, "Number of photons", "");
526  sprintf (messageBuffer, "%f", photom->photomBErr[1]);
527  qfits_header_add (outFitsHeader, "HIERARCH ESO QC DPHOTB1", messageBuffer, "(sigma) Error in number of photons", "");
528  sprintf (messageBuffer, "%f", photom->ratioPhotomA0toA1);
529  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PHOTA01", messageBuffer, "Ratio of number of photons", "");
530  sprintf (messageBuffer, "%f", photom->ratioPhotomB0toB1);
531  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PHOTB01", messageBuffer, "Ratio of number of photons", "");
532  sprintf (messageBuffer, "%f", photom->chop2ChopAErr[0]);
533  qfits_header_add (outFitsHeader, "HIERARCH ESO QC RMS CHOPA0", messageBuffer, "RMS of chopping cycles", "");
534  sprintf (messageBuffer, "%f", photom->chop2ChopAErr[1]);
535  qfits_header_add (outFitsHeader, "HIERARCH ESO QC RMS CHOPA1", messageBuffer, "RMS of chopping cycles", "");
536  sprintf (messageBuffer, "%f", photom->chop2ChopBErr[0]);
537  qfits_header_add (outFitsHeader, "HIERARCH ESO QC RMS CHOPB0", messageBuffer, "RMS of chopping cycles", "");
538  sprintf (messageBuffer, "%f", photom->chop2ChopBErr[1]);
539  qfits_header_add (outFitsHeader, "HIERARCH ESO QC RMS CHOPB1", messageBuffer, "RMS of chopping cycles", "");
540 
541  /* Add Calibrator keywords */
542  if (strcmp (format->obsCatg, "CALIB") == 0)
543  {
544  qfits_header_add (outFitsHeader, "HIERARCH ESO QC CALIB POS", "UNKNOWN", "Position of the calibrator entry", "");
545  qfits_header_add (outFitsHeader, "HIERARCH ESO QC CALIB NAME", calibrator->calibName, "Name of the calibrator entry", "");
546  sprintf (messageBuffer, "%f", calibrator->calibRA);
547  qfits_header_add (outFitsHeader, "HIERARCH ESO QC CALIB RA", messageBuffer, "Calibrator Right Ascension", "");
548  sprintf (messageBuffer, "%f", calibrator->calibDEC);
549  qfits_header_add (outFitsHeader, "HIERARCH ESO QC CALIB DEC", messageBuffer, "Calibrator Declination", "");
550  sprintf (messageBuffer, "%f", RAD_TO_ARCSEC * calibrator->calibDistance);
551  qfits_header_add (outFitsHeader, "HIERARCH ESO QC CALIB DIST", messageBuffer, "Calibrator Radial Distance in arcsec", "");
552  sprintf (messageBuffer, "%f", calibrator->calibDiameter);
553  qfits_header_add (outFitsHeader, "HIERARCH ESO QC CALIB DIAM", messageBuffer, "Calibrator Diameter in milliarcsec", "");
554  sprintf (messageBuffer, "%f", calibrator->calibDiameterErr);
555  qfits_header_add (outFitsHeader, "HIERARCH ESO QC CALIB DDIAM", messageBuffer, "(sigma) Error on calibrator Diameter in milliarcsec", "");
556  qfits_header_add (outFitsHeader, "HIERARCH ESO QC CALIB FLAG", "UNKNOWN", "Calibrator quality flag", "");
557  sprintf (messageBuffer, "%f", calibrator->calibVisSqrd);
558  qfits_header_add (outFitsHeader, "HIERARCH ESO QC CALIB VIS", messageBuffer, "Calibrator estimated square visibility", "");
559  sprintf (messageBuffer, "%f", calibrator->calibVisSqrdErr);
560  qfits_header_add (outFitsHeader, "HIERARCH ESO QC CALIB DVIS", messageBuffer, "Variance of calibrator estimated square visibility", "");
561  }
562 
563  /* Add Target keywords */
564  qfits_header_add (outFitsHeader, "HIERARCH ESO QC TARG DIAM", "UNKNOWN", "Estimated diameter of the target (mas, Un.Disk model)", "");
565  qfits_header_add (outFitsHeader, "HIERARCH ESO QC TARG DDIAM", "UNKNOWN", "(sigma) Error on estimated target diameter in milliarcsec", "");
566 
567  /* Add UVW. The values of uvw will be added during pipeline execution */
568  sprintf (messageBuffer, "%f", uvw->uCoord);
569  qfits_header_add (outFitsHeader, "HIERARCH ESO QC BL UVW1", messageBuffer, "u component of UVW vector", "");
570  sprintf (messageBuffer, "%f", uvw->vCoord);
571  qfits_header_add (outFitsHeader, "HIERARCH ESO QC BL UVW2", messageBuffer, "v component of UVW vector", "");
572  sprintf (messageBuffer, "%f", uvw->wCoord);
573  qfits_header_add (outFitsHeader, "HIERARCH ESO QC BL UVW3", messageBuffer, "w component of UVW vector", "");
574 
575  /* Baseline parameters */
576  if (trfFunction->exists)
577  {
578  if (strcmp (format->obsCatg, "CALIB") == 0)
579  {
580  sprintf (messageBuffer, "%f", calibrator->calibPblAverage);
581  qfits_header_add (outFitsHeader, "HIERARCH ESO QC BL LENGTH", messageBuffer, "Baseline vector length", "");
582  sprintf (messageBuffer, "%f", calibrator->calibParangAverage);
583  qfits_header_add (outFitsHeader, "HIERARCH ESO QC BL ANGLE", messageBuffer, "Baseline vector angle", "");
584  }
585  }
586 
587  /* Place Holders */
588  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PLACEH1", "TBD", "TBD", "");
589  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PLACEH2", "TBD", "TBD", "");
590  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PLACEH3", "TBD", "TBD", "");
591  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PLACEH4", "TBD", "TBD", "");
592  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PLACEH5", "TBD", "TBD", "");
593  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PLACEH6", "TBD", "TBD", "");
594  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PLACEH7", "TBD", "TBD", "");
595  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PLACEH8", "TBD", "TBD", "");
596  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PLACEH9", "TBD", "TBD", "");
597 
598  /* Create the output fits file */
599  if (stat (fileNames->outFitsName, &buf) == 0) /* If the file exist delete it */
600  remove (fileNames->outFitsName);
601  outFitsPtr = fopen (fileNames->outFitsName, "w");
602  if (!outFitsPtr)
603  {
604  *error = 1;
605  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot create output FITS file");
606  free (messageBuffer);
607  free (currentTime);
608  free (cleanString);
609  free (stringTemp);
610  free (classification);
611  free (textBuff);
612  return;
613  }
614 
615  /* Write header into the output file */
616  qfits_header_sort (&outFitsHeader);
617  qfits_header_dump (outFitsHeader, outFitsPtr);
618  qfits_header_destroy (outFitsHeader);
619  fclose (outFitsPtr);
620 
621  /* release memory */
622  free (messageBuffer);
623  free (currentTime);
624  free (cleanString);
625  free (stringTemp);
626  free (classification);
627  free (textBuff);
628 
629  return;
630 }
631 /*****************************************************************************/
632 
633 
634 
635 
636 /******************************************************************************
637 * European Southern Observatory
638 * VLTI MIDI Data Reduction Software
639 *
640 * Module name: addProdInfoToFrgQcLogUndisp
641 * Input/Output: See function arguments to avoid duplication
642 * Description: Adds product information to QC log
643 *
644 *
645 * History:
646 * 16-Jan-04 (csabet) Created
647 ******************************************************************************/
648 void addProdInfoToFrgQcLogUndisp (
649  ImageFormat *format,
650  MidiFiles *fileNames,
651  RawVisibility *rawVis,
652  CalibratedVisibility *calibVis,
653  UVW *uvw,
654  PhotometryResult *photom,
655  FilterData *filterInfo,
656  TransferFunction *trfFunction,
657  CalibratorParam *calibrator,
658  int *error)
659 {
660 
661  /* Local Declarations
662  --------------------*/
663  const char routine[] = "addProdInfoToFrgQcLogUndisp";
664  int i;
665  FILE *inFitsBatchPtr;
666  char *stringQfits, *messageBuffer, *currentTime, *textBuff, *cleanString,
667  *stringTemp, *classification;
668  unsigned int stringLength;
669  time_t now;
670  struct tm *newTime;
671 
672  /* Algorithm
673  -----------*/
674  if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking routine '%s' \n", routine);
675  if (diagnostic > 4) fprintf (midiReportPtr, "Invoking routine '%s' \n", routine);
676 
677  /* Reset parameters */
678  *error = 0;
679 
680  /* Allocate memory */
681  classification = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
682  stringTemp = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
683  cleanString = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
684  textBuff = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
685  messageBuffer = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
686  currentTime = (char *) calloc (MIN_STRING_LENGTH, sizeof (char));
687 
688  /* Get current time/date */
689  now = time(NULL);
690  newTime = gmtime (&now);
691  strftime (currentTime, MIN_STRING_LENGTH, "%a %d %b %Y at %H:%M:%S", newTime);
692 
693  // Add keyword to QC log file
694  fprintf (midiQcLogPtr, "PRO.TYPE \"%s\" \n", format->obsType);
695  fprintf (midiQcLogPtr, "PRO.CATG \"REDUCED_UNDISPERSED\" \n");
696  fprintf (midiQcLogPtr, "PRO.ARCFILE \"%s\" \n", fileNames->archFileName);
697  fprintf (midiQcLogPtr, "PRO.PIPEDATE \"%s\" \n", currentTime);
698  fprintf (midiQcLogPtr, "PRO.VERSION \"%s\" \n", MIDI_PIPE_VERSION);
699  fprintf (midiQcLogPtr, "PRO.PIPEFILE \"%s\" \n", fileNames->pipeFileName);
700  fprintf (midiQcLogPtr, "PRO.DID \"%s\" \n", MIDI_QC_DIC_VERSION);
701 
702  /* Open the list of files */
703  if ((inFitsBatchPtr = fopen (fileNames->inFitsBatch, "r")) == NULL)
704  {
705  *error = 1;
706  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot open input FITS file list");
707  free (messageBuffer);
708  free (currentTime);
709  free (cleanString);
710  free (stringTemp);
711  free (classification);
712  free (textBuff);
713  return;
714  }
715 
716  /* Loop through the list of files and write into the QC log */
717  i = 1;
718  while (fgets (stringTemp, MAX_STRING_LENGTH, inFitsBatchPtr) != NULL)
719  {
720  sprintf (classification, "%s", "");
721  sscanf (stringTemp, "%s%s", messageBuffer, classification);
722 
723  /* If classification is not given get it from the raw file */
724  if (strcmp (classification, "") == 0)
725  {
726  stringQfits = qfits_query_hdr (messageBuffer, "HIERARCH ESO DPR CATG");
727  if (stringQfits == NULL)
728  {
729  sprintf (classification, "%s", "UNKNOWN");
730  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot get Observation Category");
731  }
732  else
733  {
734  cleanUpString (stringQfits, cleanString);
735  sprintf (classification, "%s", cleanString);
736  }
737  }
738  removePathName (messageBuffer, midiReportPtr);
739  fprintf (midiQcLogPtr, "PRO.REC1.RAW%d.NAME \"%s\" \n", i, messageBuffer);
740  fprintf (midiQcLogPtr, "PRO.REC1.RAW%d.CATG \"%s\" \n", i++, classification);
741  }
742  fclose (inFitsBatchPtr);
743 
744  /* Add name of Mask file to QC log file */
745  sprintf (messageBuffer, "%s", fileNames->maskFileName);
746  removePathName (messageBuffer, midiReportPtr);
747  fprintf (midiQcLogPtr, "PRO.REC2.RAW1.NAME \"%s\" \n", messageBuffer);
748 
749  /* Add name of Transfer Function file to QC log file */
750  if (strcmp (format->obsCatg, "CALIB") == 0) sprintf (messageBuffer, "%s", fileNames->trfNameWrite);
751  else sprintf (messageBuffer, "%s", fileNames->trfNameRead);
752  removePathName (messageBuffer, midiReportPtr);
753  stringLength = strlen (messageBuffer);
754  sprintf (textBuff, "r.");
755  strncat (textBuff, messageBuffer, stringLength-4);
756  sprintf (messageBuffer, "%s_tpl_0001.dummy", textBuff);
757  fprintf (midiQcLogPtr, "PRO.REC2.RAW2.NAME \"%s\" \n", messageBuffer);
758 
759  /* Scan parameters */
760  fprintf (midiQcLogPtr, "QC.SCN.PROCESSED %d \n", format->numOfScansProcessed);
761  fprintf (midiQcLogPtr, "QC.SCN.REJECTED %d \n", format->numOfScansRejected);
762 
763  /* Add keyword to QC log file */
764  fprintf (midiQcLogPtr, "QC.FREQ.MIN %f \n", filterInfo->optFreqLo);
765  fprintf (midiQcLogPtr, "QC.FREQ.MAX %f \n", filterInfo->optFreqHi);
766 
767  /* Transfer functions */
768  if (trfFunction->exists)
769  {
770  if (strcmp (format->obsCatg, "CALIB") == 0)
771  {
772  /* Add QC log */
773  fprintf (midiQcLogPtr, "QC.THEOVIS %f \n", calibrator->calibVisSqrd);
774  fprintf (midiQcLogPtr, "QC.DTHEOVIS %f \n", calibrator->calibVisSqrdErr);
775  fprintf (midiQcLogPtr, "QC.T0 %f \n", trfFunction->trf[3]);
776  fprintf (midiQcLogPtr, "QC.T1 %f \n", trfFunction->trf[4]);
777  fprintf (midiQcLogPtr, "QC.T2 %f \n", trfFunction->trf[5]);
778  fprintf (midiQcLogPtr, "QC.DT0 %f \n", trfFunction->trfErr[3]);
779  fprintf (midiQcLogPtr, "QC.DT1 %f \n", trfFunction->trfErr[4]);
780  fprintf (midiQcLogPtr, "QC.DT2 %f \n", trfFunction->trfErr[5]);
781  fprintf (midiQcLogPtr, "QC.COT0 %f \n", 1.0/trfFunction->trf[3]);
782  fprintf (midiQcLogPtr, "QC.COT1 %f \n", 1.0/trfFunction->trf[4]);
783  fprintf (midiQcLogPtr, "QC.COT2 %f \n", 1.0/trfFunction->trf[5]);
784  fprintf (midiQcLogPtr, "QC.DCOT0 %f \n", 1.0/trfFunction->trfErr[3]);
785  fprintf (midiQcLogPtr, "QC.DCOT1 %f \n", 1.0/trfFunction->trfErr[4]);
786  fprintf (midiQcLogPtr, "QC.DCOT2 %f \n", 1.0/trfFunction->trfErr[5]);
787  }
788  else
789  {
790  /* Add QC log */
791  fprintf (midiQcLogPtr, "QC.AT0 %f \n", trfFunction->trf[3]);
792  fprintf (midiQcLogPtr, "QC.AT1 %f \n", trfFunction->trf[4]);
793  fprintf (midiQcLogPtr, "QC.AT2 %f \n", trfFunction->trf[5]);
794  fprintf (midiQcLogPtr, "QC.DAT0 %f \n", trfFunction->trfErr[3]);
795  fprintf (midiQcLogPtr, "QC.DAT1 %f \n", trfFunction->trfErr[4]);
796  fprintf (midiQcLogPtr, "QC.DAT2 %f \n", trfFunction->trfErr[5]);
797  }
798  }
799 
800  /* Visibilities */
801  fprintf (midiQcLogPtr, "QC.UNCALV0 %f \n", rawVis->visSqrd);
802  fprintf (midiQcLogPtr, "QC.UNCALV1 %f \n", rawVis->visSqrd1);
803  fprintf (midiQcLogPtr, "QC.UNCALV2 %f \n", rawVis->visSqrd2);
804  fprintf (midiQcLogPtr, "QC.DUNCALV0 %f \n", rawVis->visSqrdErr);
805  fprintf (midiQcLogPtr, "QC.DUNCALV1 %f \n", rawVis->visSqrd1Err);
806  fprintf (midiQcLogPtr, "QC.DUNCALV2 %f \n", rawVis->visSqrd2Err);
807  if (calibVis->exists)
808  {
809  fprintf (midiQcLogPtr, "QC.CALV0 %f \n", calibVis->visSqrd[0]);
810  fprintf (midiQcLogPtr, "QC.CALV1 %f \n", calibVis->visSqrd[1]);
811  fprintf (midiQcLogPtr, "QC.CALV2 %f \n", calibVis->visSqrd[2]);
812  fprintf (midiQcLogPtr, "QC.DCALV0 %f \n", calibVis->visSqrdErr[0]);
813  fprintf (midiQcLogPtr, "QC.DCALV1 %f \n", calibVis->visSqrdErr[1]);
814  fprintf (midiQcLogPtr, "QC.DCALV2 %f \n", calibVis->visSqrdErr[2]);
815  }
816 
817  /* Photometry parameters */
818  fprintf (midiQcLogPtr, "QC.PHOTA0 %f \n", photom->photomA[0]);
819  fprintf (midiQcLogPtr, "QC.DPHOTA0 %f \n", photom->photomAErr[0]);
820  fprintf (midiQcLogPtr, "QC.PHOTA1 %f \n", photom->photomA[1]);
821  fprintf (midiQcLogPtr, "QC.DPHOTA1 %f \n", photom->photomAErr[1]);
822  fprintf (midiQcLogPtr, "QC.PHOTB0 %f \n", photom->photomB[0]);
823  fprintf (midiQcLogPtr, "QC.DPHOTB0 %f \n", photom->photomBErr[0]);
824  fprintf (midiQcLogPtr, "QC.PHOTB1 %f \n", photom->photomB[1]);
825  fprintf (midiQcLogPtr, "QC.DPHOTB1 %f \n", photom->photomBErr[1]);
826  fprintf (midiQcLogPtr, "QC.PHOTA01 %f \n", photom->ratioPhotomA0toA1);
827  fprintf (midiQcLogPtr, "QC.PHOTB01 %f \n", photom->ratioPhotomB0toB1);
828  fprintf (midiQcLogPtr, "QC.RMS.CHOPA0 %f \n", photom->chop2ChopAErr[0]);
829  fprintf (midiQcLogPtr, "QC.RMS.CHOPA1 %f \n", photom->chop2ChopAErr[1]);
830  fprintf (midiQcLogPtr, "QC.RMS.CHOPB0 %f \n", photom->chop2ChopBErr[0]);
831  fprintf (midiQcLogPtr, "QC.RMS.CHOPB1 %f \n", photom->chop2ChopBErr[1]);
832 
833  /* Add Calibrator keywords */
834  if (strcmp (format->obsCatg, "CALIB") == 0)
835  {
836  fprintf (midiQcLogPtr, "QC.CALIB.POS \"UNKNOWN\" \n");
837  fprintf (midiQcLogPtr, "QC.CALIB.NAME \"%s\" \n", calibrator->calibName);
838  fprintf (midiQcLogPtr, "QC.CALIB.RA %f \n", calibrator->calibRA);
839  fprintf (midiQcLogPtr, "QC.CALIB.DEC %f \n", calibrator->calibDEC);
840  fprintf (midiQcLogPtr, "QC.CALIB.DIST %f \n", RAD_TO_ARCSEC * calibrator->calibDistance);
841  fprintf (midiQcLogPtr, "QC.CALIB.DIAM %f \n", calibrator->calibDiameter);
842  fprintf (midiQcLogPtr, "QC.CALIB.DDIAM %f \n", calibrator->calibDiameterErr);
843  fprintf (midiQcLogPtr, "QC.CALIB.FLAG \"UNKNOWN\" \n");
844  fprintf (midiQcLogPtr, "QC.CALIB.VIS %f \n", calibrator->calibVisSqrd);
845  fprintf (midiQcLogPtr, "QC.CALIB.DVIS %f \n", calibrator->calibVisSqrdErr);
846  }
847 
848  /* Add Target keywords */
849  fprintf (midiQcLogPtr, "QC.TARG.DIAM \"UNKNOWN\" \n");
850  fprintf (midiQcLogPtr, "QC.TARG.DDIAM \"UNKNOWN\" \n");
851 
852  /* Add UVW. The values of uvw will be added during pipeline execution */
853  fprintf (midiQcLogPtr, "QC.BL.UVW1 %f \n", uvw->uCoord);
854  fprintf (midiQcLogPtr, "QC.BL.UVW2 %f \n", uvw->vCoord);
855  fprintf (midiQcLogPtr, "QC.BL.UVW3 %f \n", uvw->wCoord);
856 
857  /* Baseline parameters */
858  if (trfFunction->exists)
859  {
860  if (strcmp (format->obsCatg, "CALIB") == 0)
861  {
862  fprintf (midiQcLogPtr, "QC.BL.LENGTH %f \n", calibrator->calibPblAverage);
863  fprintf (midiQcLogPtr, "QC.BL.ANGLE %f \n", calibrator->calibParangAverage);
864  }
865  }
866 
867  /* release memory */
868  free (messageBuffer);
869  free (currentTime);
870  free (textBuff);
871  free (cleanString);
872  free (stringTemp);
873  free (classification);
874 
875  return;
876 }
877 /*****************************************************************************/
878 
879 
880 
881 /******************************************************************************
882 * European Southern Observatory
883 * VLTI MIDI Data Reduction Software
884 *
885 * Module name: loadFrgOutputDataUndisp
886 * Input/Output: See function arguments to avoid duplication
887 * Description: Loads MIDI product data into appropriate data structures
888 *
889 *
890 * History:
891 * 04-Nov-03 (csabet) Created
892 ******************************************************************************/
893 void loadFrgOutputDataUndisp (
894  char *fileName,
895  FilterData *filterInfo,
896  float *visAmp,
897  float *visSqrd,
898  OiArray *array,
899  OiTarget *targets,
900  OiWavelength *wave,
901  OiVis *vis,
902  OiVis2 *vis2,
903  UVW *uvw, // Ou: Coordinates of the uvw
904  int *error)
905 {
906  // Local Declarations
907  // ------------------
908  const char routine[] = "loadFrgOutputDataUndisp";
909  int i, irec, iwave, itarg, mjdObs, *selection, extNumber;
910  float effectiveWave, effectiveBand, equinox;
911  char *stringQfits, *emptyString, *buffer, *observationData, *arrayName,
912  *instName, *cleanString;
913  double raEp0, decEp0, integrationTime;
914  qfits_table *arrayGeometry;
915  char *qfitsRow;
916  short *qfitsRow_int, targetId = 1;
917  float *qfitsRow_flt, nullFloat;
918  double *qfitsRow_dbl, utcTime;
919 
920  // Algorithm
921  // ---------
922  *error = 0;
923  if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking routine '%s' \n", routine);
924  if (diagnostic > 4) fprintf(midiReportPtr, "Invoking routine '%s' \n", routine);
925 
926  // Allocate memory
927  cleanString = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
928  emptyString = (char *) calloc (MIN_STRING_LENGTH, sizeof (char));
929  buffer = (char *) calloc (MIN_STRING_LENGTH, sizeof (char));
930  observationData = (char *) calloc (MIN_STRING_LENGTH, sizeof (char));
931  arrayName = (char *) calloc (MIN_STRING_LENGTH, sizeof (char));
932  instName = (char *) calloc (MIN_STRING_LENGTH, sizeof (char));
933 
934  // Initialize values
935  strcpy (emptyString, "NULL");
936  set_fnan (&nullFloat);
937 
938  // Get general parameters from the Header of the input FITS file
939  // -------------------------------------------------------------
940  stringQfits = qfits_query_hdr (fileName, "DATE-OBS");
941  if (stringQfits == NULL)
942  sscanf (emptyString, "%s", observationData);
943  else
944  {
945  cleanUpString (stringQfits, cleanString);
946  sscanf (cleanString, "%s", observationData);
947  }
948 
949 
950  stringQfits = qfits_query_hdr (fileName, "EXPTIME");
951  if (stringQfits == NULL) integrationTime = nullFloat;
952  else sscanf (stringQfits, "%lf", &integrationTime);
953 
954  extNumber = getFitsExtensionNumber (fileName, "ARRAY_GEOMETRY", error);
955  if (*error)
956  {
957  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__,
958  "Cannot get ARRAY_GEOMETRY extension number from input FITS file");
959  free (instName);
960  free (arrayName);
961  free (observationData);
962  free (emptyString);
963  free (buffer);
964  free (cleanString);
965  return;
966  }
967 
968  stringQfits = qfits_query_ext (fileName, "ARRNAME", extNumber);
969  if (stringQfits == NULL)
970  sscanf (emptyString, "%s", arrayName);
971  else
972  {
973  cleanUpString (stringQfits, cleanString);
974  sscanf (cleanString, "%s", arrayName);
975  }
976 
977  stringQfits = qfits_query_hdr (fileName, "INSTRUME");
978  if (stringQfits == NULL)
979  sscanf (emptyString, "%s", instName);
980  else
981  {
982  cleanUpString (stringQfits, cleanString);
983  sscanf (cleanString, "%s", instName);
984  }
985 
986  stringQfits = qfits_query_hdr (fileName, "RA");
987  if (stringQfits == NULL) raEp0 = nullFloat;
988  else sscanf (stringQfits, "%lf", &raEp0);
989 
990  stringQfits = qfits_query_hdr (fileName, "DEC");
991  if (stringQfits == NULL) decEp0 = nullFloat;
992  else sscanf (stringQfits, "%lf", &decEp0);
993 
994  stringQfits = qfits_query_hdr (fileName, "EQUINOX");
995  if (stringQfits == NULL) equinox = nullFloat;
996  else sscanf (stringQfits, "%f", &equinox);
997 
998  stringQfits = qfits_query_hdr (fileName, "MJD-OBS");
999  if (stringQfits == NULL) mjdObs = nullFloat;
1000  else sscanf (stringQfits, "%d", &mjdObs);
1001 
1002  stringQfits = qfits_query_hdr (fileName, "UTC");
1003  if (stringQfits == NULL) utcTime = nullFloat;
1004  else sscanf (stringQfits, "%lf", &utcTime);
1005 
1006  // Load info for OI_ARRAY table
1007  // ----------------------------
1008  if (diagnostic)cpl_msg_info(cpl_func,"Loading oi_array data ... \n");
1009  if (diagnostic) fprintf (midiReportPtr, "Loading oi_array data ... \n");
1010 
1011  // Get the required parameters from the ARRAY_GEOMETRY extension of the input FITS file
1012  sscanf (arrayName, "%s", array->arrname);
1013 
1014  // Get extension number
1015  extNumber = getFitsExtensionNumber (fileName, "ARRAY_GEOMETRY", error);
1016  if (*error)
1017  {
1018  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__,
1019  "Cannot get ARRAY_GEOMETRY extension number from input FITS file");
1020  free (instName);
1021  free (arrayName);
1022  free (observationData);
1023  free (emptyString);
1024  free (buffer);
1025  free (cleanString);
1026  return;
1027  }
1028 
1029  stringQfits = qfits_query_ext (fileName, "FRAME", extNumber);
1030  if (stringQfits == NULL)
1031  sscanf (emptyString, "%s", array->frame);
1032  else
1033  {
1034  cleanUpString (stringQfits, cleanString);
1035  sscanf (cleanString, "%s", array->frame);
1036  }
1037 
1038  stringQfits = qfits_query_ext (fileName, "ARRAYX", extNumber);
1039  if (stringQfits == NULL) array->arrayx = nullFloat;
1040  else sscanf (stringQfits, "%lf", &(array->arrayx));
1041 
1042  stringQfits = qfits_query_ext (fileName, "ARRAYY", extNumber);
1043  if (stringQfits == NULL) array->arrayy = nullFloat;
1044  else sscanf (stringQfits, "%lf", &(array->arrayy));
1045 
1046  stringQfits = qfits_query_ext (fileName, "ARRAYZ", extNumber);
1047  if (stringQfits == NULL) array->arrayz = nullFloat;
1048  else sscanf (stringQfits, "%lf", &(array->arrayz));
1049 
1050  // Open the table
1051  arrayGeometry = qfits_table_open (fileName, extNumber);
1052 
1053  // Load info for OI_ARRAY table
1054  // ----------------------------
1055  selection = (int *) calloc (array->nelement, sizeof (int));
1056  for (i = 0; i < array->nelement; i++)
1057  {
1058  selection[i] = 1;
1059  qfitsRow = (char *) (qfits_query_column (arrayGeometry, 0, selection));
1060  sprintf (array->elem[i].tel_name, "%s", qfitsRow);
1061  free (qfitsRow);
1062 
1063  qfitsRow = (char *) (qfits_query_column (arrayGeometry, 1, selection));
1064  sprintf (array->elem[i].sta_name, "%s", qfitsRow);
1065  free (qfitsRow);
1066 
1067  qfitsRow_int = (short *) (qfits_query_column (arrayGeometry, 2, selection));
1068  array->elem[i].sta_index = qfitsRow_int[0];
1069  free (qfitsRow_int);
1070 
1071  qfitsRow_flt = (float *) (qfits_query_column (arrayGeometry, 3, selection));
1072  array->elem[i].diameter = qfitsRow_flt[0];
1073  free (qfitsRow_flt);
1074 
1075  qfitsRow_dbl = (double *) (qfits_query_column (arrayGeometry, 4, selection));
1076  array->elem[i].staxyz[0] = qfitsRow_dbl[0];
1077  array->elem[i].staxyz[1] = qfitsRow_dbl[1];
1078  array->elem[i].staxyz[2] = qfitsRow_dbl[2];
1079  free (qfitsRow_dbl);
1080 
1081  selection[i] = 0;
1082  }
1083  sprintf (array->revision, "%s", IAUEXCHANGE_VERSION);
1084  free (selection);
1085  qfits_table_close (arrayGeometry);
1086 
1087 
1088  // Load info for OI_TARGET table
1089  // -----------------------------
1090  if (diagnostic)cpl_msg_info(cpl_func,"Loading oi_target data ... \n");
1091  if (diagnostic) fprintf (midiReportPtr, "Loading oi_target data ... \n");
1092 
1093  stringQfits = qfits_query_hdr (fileName, "HIERARCH ESO OBS TARG NAME");
1094  if (stringQfits == NULL)
1095  sscanf (emptyString, "%s", buffer);
1096  else
1097  {
1098  cleanUpString (stringQfits, cleanString);
1099  sscanf (cleanString, "%s", buffer);
1100  }
1101 
1102  for (itarg = 0; itarg < targets->ntarget; itarg++)
1103  {
1104  targets->targ[itarg].target_id = targetId;
1105  sscanf (buffer, "%s", targets->targ[itarg].target);
1106  targets->targ[itarg].raep0 = raEp0;
1107  targets->targ[itarg].decep0 = decEp0;
1108  targets->targ[itarg].equinox = equinox;
1109  targets->targ[itarg].ra_err = nullFloat;
1110  targets->targ[itarg].dec_err = nullFloat;
1111  targets->targ[itarg].sysvel = nullFloat;
1112  sscanf (emptyString, "%s", targets->targ[itarg].veltyp);
1113  sscanf (emptyString, "%s", targets->targ[itarg].veldef);
1114  targets->targ[itarg].pmra = nullFloat;
1115  targets->targ[itarg].pmdec = nullFloat;
1116  targets->targ[itarg].pmra_err = nullFloat;
1117  targets->targ[itarg].pmdec_err = nullFloat;
1118  targets->targ[itarg].parallax = nullFloat;
1119  targets->targ[itarg].para_err = nullFloat;
1120  sscanf (emptyString, "%s", targets->targ[itarg].spectyp);
1121  }
1122  sprintf (targets->revision, "%s", IAUEXCHANGE_VERSION);
1123 
1124 
1125  // Load info for OI_WAVELENGTH table
1126  // ---------------------------------
1127  if (diagnostic)cpl_msg_info(cpl_func,"Loading oi_wavelength data ... \n");
1128  if (diagnostic) fprintf (midiReportPtr, "Loading oi_wavelength data ... \n");
1129 
1130  // Compute the parameters
1131  effectiveWave = 1.e-6 * (SPEED_OF_LIGHT /
1132  (0.5 * (filterInfo->optFreqLo + filterInfo->optFreqHi)));
1133  effectiveBand = 1.e-6 * (SPEED_OF_LIGHT /
1134  (filterInfo->optFreqHi - filterInfo->optFreqLo));
1135 
1136  sscanf (instName, "%s", wave->insname);
1137  for (i = 0; i < wave->nwave; i++)
1138  {
1139  wave->eff_wave[i] = effectiveWave;
1140  wave->eff_band[i] = effectiveBand;
1141  }
1142  sprintf (wave->revision, "%s", IAUEXCHANGE_VERSION);
1143 
1144  // Get the uvw parameters
1145  computeUVW (array->elem[0].staxyz[0], array->elem[0].staxyz[1], array->elem[0].staxyz[2],
1146  array->elem[1].staxyz[0], array->elem[1].staxyz[1], array->elem[1].staxyz[2],
1147  mjdObs, raEp0, decEp0, uvw);
1148 
1149  // Load info for OI_VIS table
1150  // --------------------------
1151  if (diagnostic)cpl_msg_info(cpl_func,"Loading oi_vis data ... \n");
1152  if (diagnostic) fprintf (midiReportPtr, "Loading oi_vis data ... \n");
1153 
1154  // Get the required parameters from the FITS file
1155  sscanf (observationData, "%s", vis->date_obs);
1156  sscanf (arrayName, "%s", vis->arrname);
1157  sscanf (instName, "%s", vis->insname);
1158  for (irec = 0; irec < vis->numrec; irec++)
1159  {
1160  vis->record[irec].target_id = targetId;
1161  vis->record[irec].time = utcTime;
1162  vis->record[irec].mjd = mjdObs;
1163  vis->record[irec].int_time = integrationTime;
1164  vis->record[irec].ucoord = uvw->uCoord;
1165  vis->record[irec].vcoord = uvw->vCoord;
1166  vis->record[irec].sta_index[0] = array->elem[0].sta_index;
1167  vis->record[irec].sta_index[1] = array->elem[1].sta_index;
1168 
1169  for (iwave = 0; iwave < wave->nwave; iwave++)
1170  {
1171  vis->record[irec].visamp[iwave] = visAmp[iwave];
1172  vis->record[irec].visamperr[iwave] = nullFloat;
1173  vis->record[irec].visphi[iwave] = nullFloat;
1174  vis->record[irec].visphierr[iwave] = nullFloat;
1175  }
1176  sprintf (vis->record[irec].flag, "%s", "FALSE");
1177  }
1178  sprintf (vis->revision, "%s", IAUEXCHANGE_VERSION);
1179  vis->nwave = wave->nwave;
1180 
1181 
1182  // Load info for OI_VIS2 table
1183  // ---------------------------
1184  if (diagnostic)cpl_msg_info(cpl_func,"Loading oi_vis2 data ... \n");
1185  if (diagnostic) fprintf (midiReportPtr, "Loading oi_vis2 data ... \n");
1186 
1187  // Get the required parameters from the FITS file
1188  sscanf (observationData, "%s", vis2->date_obs);
1189  sscanf (arrayName, "%s", vis2->arrname);
1190  sscanf (instName, "%s", vis2->insname);
1191  for(irec = 0; irec < vis2->numrec; irec++)
1192  {
1193  vis2->record[irec].target_id = targetId;
1194  vis2->record[irec].time = utcTime;
1195  vis2->record[irec].mjd = mjdObs;
1196  vis2->record[irec].int_time = integrationTime;
1197  vis2->record[irec].ucoord = uvw->uCoord;
1198  vis2->record[irec].vcoord = uvw->vCoord;
1199  vis2->record[irec].sta_index[0] = array->elem[0].sta_index;;
1200  vis2->record[irec].sta_index[1] = array->elem[1].sta_index;;
1201 
1202  for(iwave = 0; iwave < wave->nwave; iwave++)
1203  {
1204  vis2->record[irec].vis2data[iwave] = visSqrd[iwave];
1205  vis2->record[irec].vis2err[iwave] = nullFloat;
1206  }
1207  sprintf (vis2->record[irec].flag, "%s", "FALSE");
1208  }
1209  sprintf (vis2->revision, "%s", IAUEXCHANGE_VERSION);
1210  vis2->nwave = wave->nwave;
1211 
1212 
1213  // Release memory
1214  free (instName);
1215  free (arrayName);
1216  free (observationData);
1217  free (emptyString);
1218  free (buffer);
1219  free (cleanString);
1220 
1221  return;
1222 
1223 }
1224 /*****************************************************************************/
1225 
1226 
1227 
1228 /******************************************************************************
1229 * European Southern Observatory
1230 * VLTI MIDI Data Reduction Software
1231 *
1232 * Module name: writeFrgFitsFileUndisp
1233 * Input/Output: See function arguments to avoid duplication
1234 * Description: Writes and creates appropriate tables into a new fits file in
1235 * accordance with the IAU format
1236 *
1237 * History:
1238 * 02-May-03 (csabet) Created
1239 ******************************************************************************/
1240 void writeFrgFitsFileUndisp (
1241  char *outFitsName,
1242  OiArray *array,
1243  OiTarget *targets,
1244  OiWavelength *wavelength,
1245  OiVis *vis,
1246  OiVis2 *vis2,
1247  int *error)
1248 {
1249  /* Local Declarations
1250  --------------------*/
1251  const char routine[] = "writeFrgFitsFileUndisp";
1252 
1253  /* Algorithm
1254  -----------*/
1255  if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking routine '%s' \n", routine);
1256  if (diagnostic > 4) fprintf(midiReportPtr, "Invoking routine '%s' \n", routine);
1257 
1258  if (diagnostic)cpl_msg_info(cpl_func,"Writing data into the output FITS file \n\n");
1259  if (diagnostic) fprintf (midiReportPtr, "Writing data into the output FITS file \n\n");
1260 
1261  /* Reset parameters */
1262  *error = 0;
1263 
1264  /* Write OiArray table */
1265  writeOiArray (outFitsName, array, error);
1266  if (*error)
1267  {
1268  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__,
1269  "Cannot write OI_ARRAY in the output FITS file");
1270  return;
1271  }
1272 
1273  /* Write OiTarget table */
1274  writeOiTarget (outFitsName, targets, error);
1275  if (*error)
1276  {
1277  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__,
1278  "Cannot write OI_TARGET in the output FITS file");
1279  return;
1280  }
1281 
1282  /* Write OiWavelength table */
1283  writeOiWavelength (outFitsName, wavelength, error);
1284  if (*error)
1285  {
1286  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__,
1287  "Cannot write OI_WAVELENGTH in the output FITS file");
1288  return;
1289  }
1290 
1291  /* Write OiVis table */
1292  writeOiVis (outFitsName, vis, error);
1293  if (*error)
1294  {
1295  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__,
1296  "Cannot write OI_VIS in the output FITS file");
1297  return;
1298  }
1299 
1300  /* Write OiVis2 table */
1301  writeOiVis2 (outFitsName, vis2, error);
1302  if (*error)
1303  {
1304  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__,
1305  "Cannot write OI_VIS2 in the output FITS file");
1306  return;
1307  }
1308 
1309  return;
1310 
1311 }
1312 /*****************************************************************************/
1313