MIDI Pipeline Reference Manual  2.8.3
createProdFrg.c
1 /******************************************************************************
2 *******************************************************************************
3 * European Southern Observatory
4 * VLTI MIDI Data Reduction Software
5 *
6 * Module name: createProdFrg.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 "createProdFrg.h"
32 #include "midiFitsUtility.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 
63 /*============================ C O D E A R E A ===========================*/
64 
65 
66 
67 
68 /******************************************************************************
69 * European Southern Observatory
70 * VLTI MIDI Data Reduction Software
71 *
72 * Module name: createFrgProd
73 * Input/Output: See function arguments to avoid duplication
74 * Description: Creates all product files for the DISPERSED mode of processing
75 *
76 *
77 * History:
78 * 09-Feb-05 (csabet) Created
79 ******************************************************************************/
80 IauExchange * createFrgProd (
81  MidiFiles *fileNames, // In: File names
82  ImageFormat *imageSizeInterf, // In: Interferometry data parameters
83  float *waveCal, // In: Wavelength array
84  DispersedResult *dispResult, // In: Dispersed result
85  CalibratorParam *calibrator, // In: Calibrator parameters
86  int *error, // Ou: Error Status
87  CorrectedFrames *corrFrames)
88 
89 {
90 
91  // Local Declarations
92  // ------------------
93  const char routine[] = "createFrgProd";
94  int numOfTelescopes, extNumber;
95  char *stringQfits, *classification, *stringTemp;
96  FILE *inFitsBatchPtr = NULL;
97  IauExchange *iauData;
98  UVW *uvw;
99 
100  // Algorithm
101  // ---------
102  if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking routine '%s' \n", routine);
103  if (diagnostic > 4) fprintf(midiReportPtr, "Invoking routine '%s' \n", routine);
104 
105  cpl_msg_info(cpl_func,"\nCreating Product files for batch %d \n", batchNumber);
106  cpl_msg_info(cpl_func,"-------------------------------- \n");
107  fprintf (midiReportPtr, "\nCreating Product files for batch %d \n", batchNumber);
108  fprintf (midiReportPtr, "-------------------------------- \n");
109 
110  // Reset status
111  *error = 0;
112 
113  // Allocate memory
114  stringTemp = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
115  classification = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
116 
117  // Open the list of files
118  if ((inFitsBatchPtr = fopen (fileNames->inFitsBatch, "r")) == NULL)
119  {
120  *error = 1;
121  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot open input FITS file list");
122  free (stringTemp);
123  free (classification);
124  return NULL;
125  }
126 
127  // Read the name of the first file in the list and get it's full path name
128  fgets (stringTemp, MAX_STRING_LENGTH, inFitsBatchPtr);
129  sprintf (classification, "%s", "");
130  sscanf (stringTemp, "%s%s", fileNames->inFitsName, classification);
131  fclose (inFitsBatchPtr);
132 
133  // Copy keywords from the raw FITS file into the QC log
134  createQcLog (fileNames->inFitsName, error);
135  if (*error)
136  {
137  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot copy keywords to QC log");
138  free (stringTemp);
139  free (classification);
140  return NULL;
141  }
142 
143  // Get number of array elements. Number of telescopes
144  extNumber = getFitsExtensionNumber (fileNames->inFitsName, "IMAGING_DATA", error);
145  stringQfits = qfits_query_ext (fileNames->inFitsName, "MAXTEL", extNumber);
146  if (stringQfits == NULL)
147  {
148  *error = 1;
149  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot read MAXTEL from input FITS file");
150  free (stringTemp);
151  free (classification);
152  return NULL;
153  }
154  else sscanf (stringQfits, "%d", &numOfTelescopes);
155 
156  // Allocate memory for data structures relating to IAU exchange product FITS file
157  iauData = callocIauExchange (numOfTelescopes, imageSizeInterf->iXWidth);
158  uvw = (UVW *) calloc (1, sizeof (UVW));
159 
160  // Load output data into the IAU exchange structures
161  loadFrgOutputData (imageSizeInterf->obsCatg, fileNames->inFitsName, waveCal, dispResult, iauData, uvw, error);
162  if (*error)
163  {
164  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot load data structure");
165  freeIauExchange (iauData);
166  free (uvw);
167  free (stringTemp);
168  free (classification);
169  return NULL;
170  }
171 
172  // Add product info to QC log
173  addProdInfoToFrgQcLog (fileNames, imageSizeInterf, dispResult, uvw, waveCal, calibrator, error, corrFrames);
174  if (*error)
175  {
176  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot add product info to QC log");
177  freeIauExchange (iauData);
178  free (uvw);
179  free (stringTemp);
180  free (classification);
181  return NULL;
182  }
183 
184  // Create the primary header extension
185  createFrgPrimHead (fileNames, imageSizeInterf, dispResult, uvw, waveCal,
186  calibrator, error, corrFrames);
187  if (*error)
188  {
189  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot create Primary Header extension");
190  freeIauExchange (iauData);
191  free (uvw);
192  free (stringTemp);
193  free (classification);
194  return NULL;
195  }
196 
197  // At this stage output FITS file has probably been created with appropriate
198  // header. Now we create the tables and write the data in accordance with the IAU exchange
199  writeFrgFitsFile (fileNames->outFitsName, iauData, error);
200  if (*error)
201  {
202  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot write product FITS file");
203  freeIauExchange (iauData);
204  free (uvw);
205  free (stringTemp);
206  free (classification);
207  return NULL;
208  }
209 
210  if (diagnostic)cpl_msg_info(cpl_func,"Created Output FITS file: %s \n", fileNames->outFitsName);
211  fprintf (midiReportPtr, "Created Output FITS file: %s \n", fileNames->outFitsName);
212 
213  // Release memory
214 
215  /* Has to be free'ed by the caller */
216  /*freeIauExchange (iauData);*/
217 
218  free (uvw);
219  free (stringTemp);
220  free (classification);
221 
222  return iauData;
223 }
224 /*****************************************************************************/
225 
226 
227 
228 /******************************************************************************
229 * European Southern Observatory
230 * VLTI MIDI Data Reduction Software
231 *
232 * Module name: createFrgPrimHead
233 * Input/Output: See function arguments to avoid duplication
234 * Description: Creates the primary header
235 *
236 *
237 * History:
238 * 10-Feb-05 (csabet) Created
239 ******************************************************************************/
240 void createFrgPrimHead (
241  MidiFiles *fileNames,
242  ImageFormat *sizeInterf,
243  DispersedResult *dispResult,
244  UVW *uvw,
245  float *waveCal,
246  CalibratorParam *calibrator,
247  int *error,
248  CorrectedFrames *corrFrames)
249 {
250 
251  // Local Declarations
252  // ------------------
253  const char routine[] = "createFrgPrimHead";
254  qfits_header *outFitsHeader;
255  FILE *inFitsBatchPtr, *outFitsPtr;
256  int X;
257  char *textBuff, *stringQfits, *messageBuffer, *currentTime, *cleanString,
258  *stringTemp, *classification;
259 /* unsigned int stringLength;*/
260  time_t now;
261  struct tm *newTime;
262  struct stat buf;
263  float photA=0.0, photAErr=0.0, photB=0.0, photBErr=0.0, photI=0.0, photIErr=0.0,
264  photNet2=0.0, photNet2Err=0.0;
265 
266  // Algorithm
267  // ---------
268  if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking routine '%s' \n", routine);
269  if (diagnostic > 4) fprintf(midiReportPtr, "Invoking routine '%s' \n", routine);
270 
271  *error = 0;
272 
273  // Allocate memory
274  textBuff = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
275  classification = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
276  stringTemp = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
277  cleanString = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
278  messageBuffer = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
279  currentTime = (char *) calloc (MIN_STRING_LENGTH, sizeof (char));
280 
281  // Get current time/date
282  now = time(NULL);
283  newTime = gmtime (&now);
284  strftime (currentTime, MIN_STRING_LENGTH, "%a %d %b %Y at %H:%M:%S", newTime);
285 
286  // Copy primary header from the raw file to the output header
287  outFitsHeader = qfits_header_read (fileNames->inFitsName);
288  if (outFitsHeader == NULL)
289  {
290  *error = 1;
291  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot load header from the input FITS file");
292  free (messageBuffer);
293  free (currentTime);
294  free (cleanString);
295  free (stringTemp);
296  free (classification);
297  free (textBuff);
298  return;
299  }
300 
301  // Now write all the required product keaywords to the output header
302  // -----------------------------------------------------------------
303  qfits_header_add (outFitsHeader, "HIERARCH ESO PRO TYPE", sizeInterf->obsType, "MIDI pipeline product type", "");
304 
305  if ((strcmp (batchTemplate, "SCI_PHOT_CALIB") == 0) || (strcmp (batchTemplate, "SCI_PHOT_SCIENCE") == 0))
306  qfits_header_add (outFitsHeader, "HIERARCH ESO PRO CATG", "REDUCED_DISPERSED_SCIPHOT", "Pipeline product category", NULL);
307  else
308  qfits_header_add (outFitsHeader, "HIERARCH ESO PRO CATG", "REDUCED_DISPERSED", "Pipeline product category", NULL);
309 
310  qfits_header_add (outFitsHeader, "HIERARCH ESO PRO ARCFILE", fileNames->archFileName, "Arcfile name of first raw file", "");
311  qfits_header_add (outFitsHeader, "HIERARCH ESO PRO PIPEDATE", currentTime, "Pipeline run date", "");
312  qfits_header_add (outFitsHeader, "HIERARCH ESO PRO VERSION", MIDI_PIPE_VERSION, "Pipeline version", "");
313  qfits_header_add (outFitsHeader, "PIPEFILE", fileNames->pipeFileName, "Pipeline product file name", "");
314  qfits_header_add (outFitsHeader, "HIERARCH ESO PRO DID", MIDI_QC_DIC_VERSION, "QC dictionary version", "");
315 
316  // Open the list of files
317  if ((inFitsBatchPtr = fopen (fileNames->inFitsBatch, "r")) == NULL)
318  {
319  *error = 1;
320  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot open input FITS file list");
321  free (messageBuffer);
322  free (currentTime);
323  free (cleanString);
324  free (stringTemp);
325  free (classification);
326  free (textBuff);
327  return;
328  }
329 
330  // Loop through the list of files and write into the primary header
331  X = 1;
332  while (fgets (stringTemp, MAX_STRING_LENGTH, inFitsBatchPtr) != NULL)
333  {
334  sprintf (classification, "%s", "");
335  sscanf (stringTemp, "%s%s", messageBuffer, classification);
336 
337  // If classification is not given get it from the raw file
338  if (strcmp (classification, "") == 0)
339  {
340  stringQfits = qfits_query_hdr (messageBuffer, "HIERARCH ESO DPR CATG");
341  if (stringQfits == NULL)
342  {
343  sprintf (classification, "%s", "UNKNOWN");
344  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot get Observation Category");
345  }
346  else
347  {
348  cleanUpString (stringQfits, cleanString);
349  sprintf (classification, "%s", cleanString);
350  }
351  }
352  removePathName (messageBuffer, midiReportPtr);
353  sprintf (textBuff, "HIERARCH ESO PRO REC1 RAW%d NAME", X);
354  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "FITS file name", "");
355  sprintf (textBuff, "HIERARCH ESO PRO REC1 RAW%d CATG", X++);
356  qfits_header_add (outFitsHeader, textBuff, classification, "Observation Categoty", "");
357  }
358  fclose (inFitsBatchPtr);
359 
360 /*
361  * Not anymore needed as properly inserted in the SOF and inherited by the cpl
362  * saving functions
363  // Write the mask file
364  sprintf (messageBuffer, "%s", fileNames->maskFileName);
365  removePathName (messageBuffer, midiReportPtr);
366  qfits_header_add (outFitsHeader, "HIERARCH ESO PRO REC2 RAW1 NAME", messageBuffer, "Pipeline Mask File", "");
367 
368  // Write the transfer function file
369  if (strcmp (sizeInterf->obsCatg, "CALIB") == 0) sprintf (messageBuffer, "%s", fileNames->trfNameWrite);
370  else sprintf (messageBuffer, "%s", fileNames->trfNameRead);
371  removePathName (messageBuffer, midiReportPtr);
372  stringLength = strlen (messageBuffer);
373  sprintf (textBuff, "r.");
374  strncat (textBuff, messageBuffer, stringLength-4);
375  sprintf (messageBuffer, "%s_tpl_0001.dummy", textBuff);
376  qfits_header_add (outFitsHeader, "HIERARCH ESO PRO REC2 RAW2 NAME", messageBuffer, "Transfer Function File", "");
377 */
378 
379  // Scan parameters
380  sprintf (messageBuffer, "%d", sizeInterf->numOfChannelsProcessed);
381  qfits_header_add (outFitsHeader, "HIERARCH ESO QC CH PROCESSED", messageBuffer, "Number of chnnels processed", "");
382  sprintf (messageBuffer, "%d", sizeInterf->numOfChannelsRejected);
383  qfits_header_add (outFitsHeader, "HIERARCH ESO QC CH REJECTED", messageBuffer, "Number of channels rejected", "");
384 
385  // Add Wavelengths
386  for (X = 0; X < sizeInterf->iXWidth; X++)
387  {
388  if (badChannelList[X])
389  {
390  sprintf (textBuff, "HIERARCH ESO QC LAMBDA%d", X);
391  sprintf (messageBuffer, "%s", UNAV);
392  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "Calibrated wavelength", "");
393  continue;
394  }
395 
396  sprintf (textBuff, "HIERARCH ESO QC LAMBDA%d", X);
397  sprintf (messageBuffer, "%f", waveCal[X]);
398  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "Calibrated wavelength", "");
399  }
400 
401  // Transfer functions
402  if (dispResult->trfExists)
403  {
404  qfits_header_add (outFitsHeader, "HIERARCH ESO PRO TRF", "AVAILABLE", "Flag for Transfer Function availability", NULL);
405  if (strcmp (sizeInterf->obsCatg, "CALIB") == 0)
406  {
407  sprintf (messageBuffer, "%f", calibrator->calibVisSqrd);
408  qfits_header_add (outFitsHeader, "HIERARCH ESO QC THEOVIS", messageBuffer, "Theoretical visibility", "");
409  sprintf (messageBuffer, "%f", calibrator->calibVisSqrdErr);
410  qfits_header_add (outFitsHeader, "HIERARCH ESO QC DTHEOVIS", messageBuffer, "(sigma) Error on theoretical visibility", "");
411  qfits_header_add (outFitsHeader, "HIERARCH ESO QC CALIB POS", "UNKNOWN", "Position of the calibrator entry", "");
412  qfits_header_add (outFitsHeader, "HIERARCH ESO QC CALIB NAME", calibrator->calibName, "Name of the calibrator entry", "");
413  sprintf (messageBuffer, "%f", calibrator->calibRA);
414  qfits_header_add (outFitsHeader, "HIERARCH ESO QC CALIB RA", messageBuffer, "Calibrator Right Ascension", "");
415  sprintf (messageBuffer, "%f", calibrator->calibDEC);
416  qfits_header_add (outFitsHeader, "HIERARCH ESO QC CALIB DEC", messageBuffer, "Calibrator Declination", "");
417  sprintf (messageBuffer, "%f", RAD_TO_ARCSEC * calibrator->calibDistance);
418  qfits_header_add (outFitsHeader, "HIERARCH ESO QC CALIB DIST", messageBuffer, "Calibrator Radial Distance in arcsec", "");
419  sprintf (messageBuffer, "%f", calibrator->calibDiameter);
420  qfits_header_add (outFitsHeader, "HIERARCH ESO QC CALIB DIAM", messageBuffer, "Calibrator Diameter in milliarcsec", "");
421  sprintf (messageBuffer, "%f", calibrator->calibDiameterErr);
422  qfits_header_add (outFitsHeader, "HIERARCH ESO QC CALIB DDIAM", messageBuffer, "(sigma) Error on calibrator Diameter in milliarcsec", "");
423  sprintf (messageBuffer, "%d", calibrator->calibFlag);
424  qfits_header_add (outFitsHeader, "HIERARCH ESO QC CALIB FLAG", messageBuffer, "Calibrator quality flag", "");
425  sprintf (messageBuffer, "%g", calibrator->calibFlux);
426  qfits_header_add (outFitsHeader, "HIERARCH ESO QC CALIB FLUX", messageBuffer, "Calibrator N-band flux", "");
427  sprintf (messageBuffer, "%f", calibrator->calibPblAverage);
428  qfits_header_add (outFitsHeader, "HIERARCH ESO QC BL LENGTH", messageBuffer, "Baseline vector length", "");
429  sprintf (messageBuffer, "%f", calibrator->calibParangAverage);
430  qfits_header_add (outFitsHeader, "HIERARCH ESO QC BL ANGLE", messageBuffer, "Baseline vector angle", "");
431 
432  if (strcmp(sizeInterf->grismId, "PRISM") == 0)
433  {
434  sprintf (messageBuffer, "%0.4f", dispResult->trfBinned1);
435  qfits_header_add (outFitsHeader, "HIERARCH ESO QC TRF BINNED1", messageBuffer,
436  "Binned transfer function at 8.64 micron (Ch 120-126)", "");
437  sprintf (messageBuffer, "%0.4f", dispResult->trfBinned2);
438  qfits_header_add (outFitsHeader, "HIERARCH ESO QC TRF BINNED2", messageBuffer,
439  "Binned transfer function at 9.00 micron (Ch 113-121)", "");
440  sprintf (messageBuffer, "%0.4f", dispResult->trfBinned3);
441  qfits_header_add (outFitsHeader, "HIERARCH ESO QC TRF BINNED3", messageBuffer,
442  "Binned transfer function at 10.46 micron (Ch 88-98)", "");
443  sprintf (messageBuffer, "%0.4f", dispResult->trfBinned4);
444  qfits_header_add (outFitsHeader, "HIERARCH ESO QC TRF BINNED4", messageBuffer,
445  "Binned transfer function at 11.79 micron (Ch 60-72)", "");
446  sprintf (messageBuffer, "%0.4f", dispResult->trfBinned5);
447  qfits_header_add (outFitsHeader, "HIERARCH ESO QC TRF BINNED5", messageBuffer,
448  "Binned transfer function at 12.80 micron (Ch 36-50)", "");
449  }
450  else
451  {
452  sprintf (messageBuffer, "%0.4f", dispResult->trfBinned1);
453  qfits_header_add (outFitsHeader, "HIERARCH ESO QC TRF BINNED1", messageBuffer,
454  "Binned transfer function at 8.64 micron (Ch 38-50)", "");
455  sprintf (messageBuffer, "%0.4f", dispResult->trfBinned2);
456  qfits_header_add (outFitsHeader, "HIERARCH ESO QC TRF BINNED2", messageBuffer,
457  "Binned transfer function at 9.00 micron (Ch 52-68)", "");
458  sprintf (messageBuffer, "%0.4f", dispResult->trfBinned3);
459  qfits_header_add (outFitsHeader, "HIERARCH ESO QC TRF BINNED3", messageBuffer,
460  "Binned transfer function at 10.46 micron (Ch 116-136)", "");
461  sprintf (messageBuffer, "%0.4f", dispResult->trfBinned4);
462  qfits_header_add (outFitsHeader, "HIERARCH ESO QC TRF BINNED4", messageBuffer,
463  "Binned transfer function at 11.79 micron (Ch 176-200)", "");
464  sprintf (messageBuffer, "%0.4f", dispResult->trfBinned5);
465  qfits_header_add (outFitsHeader, "HIERARCH ESO QC TRF BINNED5", messageBuffer,
466  "Binned transfer function at 12.80 micron (Ch 217-245)", "");
467  }
468 
469 
470  for (X = 0; X < sizeInterf->iXWidth; X++)
471  {
472  if (badChannelList[X])
473  {
474  sprintf (textBuff, "HIERARCH ESO QC T%d", X);
475  sprintf (messageBuffer, "%s", UNAV);
476  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "Measured transfer function", "");
477 
478  sprintf (textBuff, "HIERARCH ESO QC DT%d", X);
479  sprintf (messageBuffer, "%s", UNAV);
480  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "(sigma) Error on measured transfer function", "");
481 
482  sprintf (textBuff, "HIERARCH ESO QC COT%d", X);
483  sprintf (messageBuffer, "%s", UNAV);
484  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "Inverse transfer function", "");
485 
486  sprintf (textBuff, "HIERARCH ESO QC DCOT%d", X);
487  sprintf (messageBuffer, "%s", UNAV);
488  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "(sigma) Error on inverse transfer function", "");
489  }
490  else
491  {
492  sprintf (textBuff, "HIERARCH ESO QC T%d", X);
493  sprintf (messageBuffer, "%f", (dispResult->trf)[X]);
494  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "Measured transfer function", "");
495 
496  sprintf (textBuff, "HIERARCH ESO QC DT%d", X);
497  sprintf (messageBuffer, "%f", (dispResult->trfErr)[X]);
498  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "(sigma) Error on measured transfer function", "");
499 
500  sprintf (textBuff, "HIERARCH ESO QC COT%d", X);
501  sprintf (messageBuffer, "%f", 1.0/(dispResult->trf)[X]);
502  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "Inverse transfer function", "");
503 
504  sprintf (textBuff, "HIERARCH ESO QC DCOT%d", X);
505  sprintf (messageBuffer, "%f", 1.0/(dispResult->trfErr)[X]);
506  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "(sigma) Error on inverse transfer function", "");
507  }
508  }
509  }
510  else
511  {
512  // Add Applied Transfer Functions
513  for (X = 0; X < sizeInterf->iXWidth; X++)
514  {
515  if (badChannelList[X])
516  {
517  sprintf (textBuff, "HIERARCH ESO QC AT%d", X);
518  sprintf (messageBuffer, "%s", UNAV);
519  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "Applied transfer function", "");
520 
521  sprintf (textBuff, "HIERARCH ESO QC DAT%d", X);
522  sprintf (messageBuffer, "%s", UNAV);
523  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "(sigma) Error on applied transfer function", "");
524  }
525  else
526  {
527  sprintf (textBuff, "HIERARCH ESO QC AT%d", X);
528  sprintf (messageBuffer, "%f", (dispResult->trf)[X]);
529  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "Applied transfer function", "");
530 
531  sprintf (textBuff, "HIERARCH ESO QC DAT%d", X);
532  sprintf (messageBuffer, "%f", (dispResult->trfErr)[X]);
533  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "(sigma) Error on applied transfer function", "");
534  }
535  }
536  }
537  }
538  else
539  {
540  qfits_header_add (outFitsHeader, "HIERARCH ESO PRO TRF", UNAV, "Flag for Transfer Function availability", NULL);
541  if (strcmp (sizeInterf->obsCatg, "CALIB") == 0)
542  {
543  sprintf (messageBuffer, "%f", calibrator->calibPblAverage);
544  qfits_header_add (outFitsHeader, "HIERARCH ESO QC BL LENGTH", messageBuffer, "Baseline vector length", "");
545  sprintf (messageBuffer, "%f", calibrator->calibParangAverage);
546  qfits_header_add (outFitsHeader, "HIERARCH ESO QC BL ANGLE", messageBuffer, "Baseline vector angle", "");
547 
548  }
549  }
550 
551  // Add uncalibrated Normal Visibilities
552  for (X = 0; X < sizeInterf->iXWidth; X++)
553  {
554  if (badChannelList[X])
555  {
556  sprintf (textBuff, "HIERARCH ESO QC UNCALV%d", X);
557  sprintf (messageBuffer, "%s", UNAV);
558  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "Uncalibrated Normal Visibility", "");
559 
560  sprintf (textBuff, "HIERARCH ESO QC DUNCALV%d", X);
561  sprintf (messageBuffer, "%s", UNAV);
562  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "(sigma) Error of uncalibrated Normal Visibility", "");
563  }
564  else
565  {
566  sprintf (textBuff, "HIERARCH ESO QC UNCALV%d", X);
567  sprintf (messageBuffer, "%f", (dispResult->normVis2)[X]);
568  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "Uncalibrated Normal Visibility", "");
569 
570  sprintf (textBuff, "HIERARCH ESO QC DUNCALV%d", X);
571  sprintf (messageBuffer, "%f", (dispResult->normVis2Err)[X]);
572  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "(sigma) Error of uncalibrated Normal Visibility", "");
573  }
574  }
575 
576 
577  // Add Photometry parameters
578  for (X = 0; X < sizeInterf->iXWidth; X++)
579  {
580  if (!(badChannelList[X]))
581  {
582  photA += (dispResult->photomA)[0][X];
583  photAErr += (dispResult->photomAErr)[0][X];
584  photB += (dispResult->photomB)[0][X];
585  photBErr += (dispResult->photomBErr)[0][X];
586  photI += (dispResult->photomI)[0][X];
587  photIErr += (dispResult->photomIErr)[0][X];
588  photNet2 += (dispResult->photomNet2)[X];
589  photNet2Err += (dispResult->photomNet2Err)[X];
590  }
591  }
592  if (sizeInterf->numOfChannelsProcessed)
593  {
594  photA /= sizeInterf->numOfChannelsProcessed;
595  photAErr /= sizeInterf->numOfChannelsProcessed;
596  photB /= sizeInterf->numOfChannelsProcessed;
597  photBErr /= sizeInterf->numOfChannelsProcessed;
598  photI /= sizeInterf->numOfChannelsProcessed;
599  photIErr /= sizeInterf->numOfChannelsProcessed;
600  photNet2 /= sizeInterf->numOfChannelsProcessed;
601  photNet2Err /= sizeInterf->numOfChannelsProcessed;
602  }
603  sprintf (textBuff, "HIERARCH ESO QC AV PHOTA");
604  sprintf (messageBuffer, "%f", photA);
605  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "Average photometry", "");
606  sprintf (textBuff, "HIERARCH ESO QC AV DPHOTA");
607  sprintf (messageBuffer, "%f", photAErr);
608  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "(sigma) Error of Average photometry", "");
609  sprintf (textBuff, "HIERARCH ESO QC AV PHOTB");
610  sprintf (messageBuffer, "%f", photB);
611  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "Average photometry", "");
612  sprintf (textBuff, "HIERARCH ESO QC AV DPHOTB");
613  sprintf (messageBuffer, "%f", photBErr);
614  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "(sigma) Error of Average photometry", "");
615  sprintf (textBuff, "HIERARCH ESO QC AV PHOTI");
616  sprintf (messageBuffer, "%f", photI);
617  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "Average photometry", "");
618  sprintf (textBuff, "HIERARCH ESO QC AV DPHOTI");
619  sprintf (messageBuffer, "%f", photIErr);
620  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "(sigma) Error of Average photometry", "");
621  sprintf (textBuff, "HIERARCH ESO QC AV PHOTN");
622  sprintf (messageBuffer, "%f", photNet2);
623  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "Average photometry", "");
624  sprintf (textBuff, "HIERARCH ESO QC AV DPHOTN");
625  sprintf (messageBuffer, "%f", photNet2Err);
626  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "(sigma) Error of Average photometry", "");
627 
628 
629  // Add Calibrated Visibilities
630  if (dispResult->calibVisExists)
631  {
632  for (X = 0; X < sizeInterf->iXWidth; X++)
633  {
634  if (badChannelList[X])
635  {
636  sprintf (textBuff, "HIERARCH ESO QC CALV%d", X);
637  sprintf (messageBuffer, "%s", UNAV);
638  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "Calibrated Visibility", "");
639 
640  sprintf (textBuff, "HIERARCH ESO QC DCALV%d", X);
641  sprintf (messageBuffer, "%s", UNAV);
642  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "(sigma) Error of calibrated Visibility", "");
643  }
644  else
645  {
646  sprintf (textBuff, "HIERARCH ESO QC CALV%d", X);
647  sprintf (messageBuffer, "%f", (dispResult->calibVis2)[X]);
648  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "Calibrated Visibility", "");
649 
650  sprintf (textBuff, "HIERARCH ESO QC DCALV%d", X);
651  sprintf (messageBuffer, "%f", (dispResult->calibVis2Err)[X]);
652  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "(sigma) Error of calibrated Visibility", "");
653  }
654  }
655  }
656 
657 
658  // Add Target keywords
659  qfits_header_add (outFitsHeader, "HIERARCH ESO QC TARG DIAM", "UNKNOWN", "Estimated diameter of the target (mas, Un.Disk model)", "");
660  qfits_header_add (outFitsHeader, "HIERARCH ESO QC TARG DDIAM", "UNKNOWN", "(sigma) Error on estimated target diameter in milliarcsec", "");
661 
662  // Add UVW. The values of uvw will be added during pipeline execution
663  sprintf (messageBuffer, "%f", uvw->uCoord);
664  qfits_header_add (outFitsHeader, "HIERARCH ESO QC BL UVW1", messageBuffer, "u component of UVW vector", "");
665  sprintf (messageBuffer, "%f", uvw->vCoord);
666  qfits_header_add (outFitsHeader, "HIERARCH ESO QC BL UVW2", messageBuffer, "v component of UVW vector", "");
667  sprintf (messageBuffer, "%f", uvw->wCoord);
668  qfits_header_add (outFitsHeader, "HIERARCH ESO QC BL UVW3", messageBuffer, "w component of UVW vector", "");
669 
670  // Add binned photometry measurements
671  if ((strcmp(sizeInterf->grismId, "PRISM") == 0) && (strcmp(sizeInterf->beamCombiner, "HIGH_SENS") == 0))
672  {
673  sprintf (messageBuffer, "%0.2f", dispResult->photomATarg1);
674  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PHOTA TARG1", messageBuffer, "PhotA Targ1 Ch 113 - 121", "");
675  sprintf (messageBuffer, "%0.2f", dispResult->photomBTarg1);
676  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PHOTB TARG1", messageBuffer, "PhotB Targ1 Ch 113 - 121", "");
677 
678  sprintf (messageBuffer, "%0.2f", dispResult->photomATarg2);
679  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PHOTA TARG2", messageBuffer, "PhotA Targ2 Ch 88 - 98", "");
680  sprintf (messageBuffer, "%0.2f", dispResult->photomBTarg2);
681  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PHOTB TARG2", messageBuffer, "PhotB Targ2 Ch 88 - 98", "");
682 
683  sprintf (messageBuffer, "%0.2f", dispResult->photomATarg3);
684  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PHOTA TARG3", messageBuffer, "PhotA Targ3 Ch 36 - 50", "");
685  sprintf (messageBuffer, "%0.2f", dispResult->photomBTarg3);
686  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PHOTB TARG3", messageBuffer, "PhotB Targ3 Ch 36 - 50", "");
687 
688  sprintf (messageBuffer, "%0.2f", dispResult->photomATotal1);
689  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PHOTA TOTAL1", messageBuffer, "PhotA Total1 Ch 113 - 121", "");
690  sprintf (messageBuffer, "%0.2f", dispResult->photomBTotal1);
691  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PHOTB TOTAL1", messageBuffer, "PhotB Total1 Ch 113 - 121", "");
692 
693  sprintf (messageBuffer, "%0.2f", dispResult->photomATotal2);
694  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PHOTA TOTAL2", messageBuffer, "PhotA Total2 Ch 88 - 98", "");
695  sprintf (messageBuffer, "%0.2f", dispResult->photomBTotal2);
696  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PHOTB TOTAL2", messageBuffer, "PhotB Total2 Ch 88 - 98", "");
697 
698  sprintf (messageBuffer, "%0.2f", dispResult->photomATotal3);
699  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PHOTA TOTAL3", messageBuffer, "PhotA Total3 Ch 36 - 50", "");
700  sprintf (messageBuffer, "%0.2f", dispResult->photomBTotal3);
701  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PHOTB TOTAL3", messageBuffer, "PhotB Total3 Ch 36 - 50", "");
702  }
703  else
704  {
705  sprintf (messageBuffer, "%0.2f", dispResult->photomATarg1);
706  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PHOTA TARG1", messageBuffer, "PhotA Targ1 Ch 52 - 68", "");
707  sprintf (messageBuffer, "%0.2f", dispResult->photomBTarg1);
708  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PHOTB TARG1", messageBuffer, "PhotB Targ1 Ch 52 - 68", "");
709 
710  sprintf (messageBuffer, "%0.2f", dispResult->photomATarg2);
711  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PHOTA TARG2", messageBuffer, "PhotA Targ2 Ch 116 - 136", "");
712  sprintf (messageBuffer, "%0.2f", dispResult->photomBTarg2);
713  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PHOTB TARG2", messageBuffer, "PhotB Targ2 Ch 116 - 136", "");
714 
715  sprintf (messageBuffer, "%0.2f", dispResult->photomATarg3);
716  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PHOTA TARG3", messageBuffer, "PhotA Targ3 Ch 217 - 244", "");
717  sprintf (messageBuffer, "%0.2f", dispResult->photomBTarg3);
718  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PHOTB TARG3", messageBuffer, "PhotB Targ3 Ch 217 - 244", "");
719 
720  sprintf (messageBuffer, "%0.2f", dispResult->photomATotal1);
721  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PHOTA TOTAL1", messageBuffer, "PhotA Total1 Ch 52 - 68", "");
722  sprintf (messageBuffer, "%0.2f", dispResult->photomBTotal1);
723  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PHOTB TOTAL1", messageBuffer, "PhotB Total1 Ch 52 - 68", "");
724 
725  sprintf (messageBuffer, "%0.2f", dispResult->photomATotal2);
726  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PHOTA TOTAL2", messageBuffer, "PhotA Total2 Ch 116 - 136", "");
727  sprintf (messageBuffer, "%0.2f", dispResult->photomBTotal2);
728  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PHOTB TOTAL2", messageBuffer, "PhotB Total2 Ch 116 - 136", "");
729 
730  sprintf (messageBuffer, "%0.2f", dispResult->photomATotal3);
731  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PHOTA TOTAL3", messageBuffer, "PhotA Total3 Ch 217 - 244", "");
732  sprintf (messageBuffer, "%0.2f", dispResult->photomBTotal3);
733  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PHOTB TOTAL3", messageBuffer, "PhotB Total3 Ch 217 - 244", "");
734  }
735 
736  // Add binned uncalibrated visibilities
737  if (strcmp(sizeInterf->grismId, "PRISM") == 0)
738  {
739  sprintf (messageBuffer, "%0.4f", dispResult->uncalVisBinned1);
740  qfits_header_add (outFitsHeader, "HIERARCH ESO QC UNCAL BINNED1", messageBuffer,
741  "Binned uncal vis at 8.64 micron (Ch 120-126)", "");
742  sprintf (messageBuffer, "%0.4f", dispResult->uncalVisBinned2);
743  qfits_header_add (outFitsHeader, "HIERARCH ESO QC UNCAL BINNED2", messageBuffer,
744  "Binned uncal vis at 9.00 micron (Ch 113-121)", "");
745  sprintf (messageBuffer, "%0.4f", dispResult->uncalVisBinned3);
746  qfits_header_add (outFitsHeader, "HIERARCH ESO QC UNCAL BINNED3", messageBuffer,
747  "Binned uncal vis at 10.46 micron (Ch 88-98)", "");
748  sprintf (messageBuffer, "%0.4f", dispResult->uncalVisBinned4);
749  qfits_header_add (outFitsHeader, "HIERARCH ESO QC UNCAL BINNED4", messageBuffer,
750  "Binned uncal vis at 11.79 micron (Ch 60-72)", "");
751  sprintf (messageBuffer, "%0.4f", dispResult->uncalVisBinned5);
752  qfits_header_add (outFitsHeader, "HIERARCH ESO QC UNCAL BINNED5", messageBuffer,
753  "Binned uncal vis at 12.80 micron (Ch 36-50)", "");
754  }
755  else
756  {
757  sprintf (messageBuffer, "%0.4f", dispResult->uncalVisBinned1);
758  qfits_header_add (outFitsHeader, "HIERARCH ESO QC UNCAL BINNED1", messageBuffer,
759  "Binned uncal vis at 8.64 micron (Ch 38-50)", "");
760  sprintf (messageBuffer, "%0.4f", dispResult->uncalVisBinned2);
761  qfits_header_add (outFitsHeader, "HIERARCH ESO QC UNCAL BINNED2", messageBuffer,
762  "Binned uncal vis at 9.00 micron (Ch 52-68)", "");
763  sprintf (messageBuffer, "%0.4f", dispResult->uncalVisBinned3);
764  qfits_header_add (outFitsHeader, "HIERARCH ESO QC UNCAL BINNED3", messageBuffer,
765  "Binned uncal vis at 10.46 micron (Ch 116-136)", "");
766  sprintf (messageBuffer, "%0.4f", dispResult->uncalVisBinned4);
767  qfits_header_add (outFitsHeader, "HIERARCH ESO QC UNCAL BINNED4", messageBuffer,
768  "Binned uncal vis at 11.79 micron (Ch 176-200)", "");
769  sprintf (messageBuffer, "%0.4f", dispResult->uncalVisBinned5);
770  qfits_header_add (outFitsHeader, "HIERARCH ESO QC UNCAL BINNED5", messageBuffer,
771  "Binned uncal vis at 12.80 micron (Ch 217-245)", "");
772  }
773 
774  sprintf (messageBuffer, "%ld", corrFrames->CorrInterf);
775  qfits_header_add (outFitsHeader, "HIERARCH ESO QC TARTYPE INTERF CHANGED", messageBuffer,
776  "Number of type-modified frames", "");
777 
778  sprintf (messageBuffer, "%ld", corrFrames->CorrPhotomA);
779  qfits_header_add (outFitsHeader, "HIERARCH ESO QC TARTYPE PHOTOMA CHANGED", messageBuffer,
780  "Number of type-modified frames", "");
781 
782  sprintf (messageBuffer, "%ld", corrFrames->CorrPhotomB);
783  qfits_header_add (outFitsHeader, "HIERARCH ESO QC TARTYPE PHOTOMB CHANGED", messageBuffer,
784  "Number of type-modified frames", "");
785 
786  // Place Holders
787  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PLACEH1", "TBD", "TBD", "");
788  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PLACEH2", "TBD", "TBD", "");
789  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PLACEH3", "TBD", "TBD", "");
790  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PLACEH4", "TBD", "TBD", "");
791  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PLACEH5", "TBD", "TBD", "");
792  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PLACEH6", "TBD", "TBD", "");
793  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PLACEH7", "TBD", "TBD", "");
794  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PLACEH8", "TBD", "TBD", "");
795  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PLACEH9", "TBD", "TBD", "");
796 
797  // Create the output fits file
798  if (stat (fileNames->outFitsName, &buf) == 0) // If the file exist delete it
799  remove (fileNames->outFitsName);
800  outFitsPtr = fopen (fileNames->outFitsName, "w");
801  if (!outFitsPtr)
802  {
803  *error = 1;
804  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot create output FITS file");
805  free (messageBuffer);
806  free (currentTime);
807  free (cleanString);
808  free (stringTemp);
809  free (classification);
810  free (textBuff);
811  return;
812  }
813 
814  // Write header into the output file
815  qfits_header_sort (&outFitsHeader);
816  qfits_header_dump (outFitsHeader, outFitsPtr);
817  qfits_header_destroy (outFitsHeader);
818  fclose (outFitsPtr);
819 
820  // release memory
821  free (messageBuffer);
822  free (currentTime);
823  free (cleanString);
824  free (stringTemp);
825  free (classification);
826  free (textBuff);
827 
828  return;
829 }
830 /*****************************************************************************/
831 
832 
833 
834 
835 /******************************************************************************
836 * European Southern Observatory
837 * VLTI MIDI Data Reduction Software
838 *
839 * Module name: addProdInfoToFrgQcLog
840 * Input/Output: See function arguments to avoid duplication
841 * Description: Adds product information to QC log
842 *
843 *
844 * History:
845 * 09-Feb-05 (csabet) Created
846 ******************************************************************************/
847 void addProdInfoToFrgQcLog (
848  MidiFiles *fileNames, // In: File names
849  ImageFormat *sizeInterf, // In: Interferometry data parameters
850  DispersedResult *dispResult, // In: Dispersed result
851  UVW *uvw, // In: UVW coordinates
852  float *freqCal, // In: Frequency array
853  CalibratorParam *calibrator, // In: Calibrator parameters
854  int *error, // Ou: Error status
855  CorrectedFrames *corrFrames)
856 {
857 
858  // Local Declarations
859  // ------------------
860  const char routine[] = "addProdInfoToFrgQcLog";
861  int X;
862  FILE *inFitsBatchPtr;
863  char *stringQfits, *messageBuffer, *currentTime, *textBuff, *cleanString,
864  *stringTemp, *classification;
865  unsigned int stringLength;
866  time_t now;
867  struct tm *newTime;
868  float photA=0.0, photAErr=0.0, photB=0.0, photBErr=0.0, photI=0.0, photIErr=0.0,
869  photNet2=0.0, photNet2Err=0.0;
870 
871  // Algorithm
872  // ---------
873  if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking routine '%s' \n", routine);
874  if (diagnostic > 4) fprintf (midiReportPtr, "Invoking routine '%s' \n", routine);
875 
876  // Reset parameters
877  *error = 0;
878 
879  // Allocate memory
880  classification = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
881  stringTemp = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
882  cleanString = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
883  textBuff = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
884  messageBuffer = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
885  currentTime = (char *) calloc (MIN_STRING_LENGTH, sizeof (char));
886 
887  // Get current time/date
888  now = time(NULL);
889  newTime = gmtime (&now);
890  strftime (currentTime, MIN_STRING_LENGTH, "%a %d %b %Y at %H:%M:%S", newTime);
891 
892  // Add keyword to QC log file
893  fprintf (midiQcLogPtr, "PRO.TYPE \"%s\" \n", sizeInterf->obsType);
894 
895  if ((strcmp (batchTemplate, "SCI_PHOT_CALIB") == 0) || (strcmp (batchTemplate, "SCI_PHOT_SCIENCE") == 0))
896  fprintf (midiQcLogPtr, "PRO.CATG \"REDUCED_DISPERSED_SCIPHOT\" \n");
897  else
898  fprintf (midiQcLogPtr, "PRO.CATG \"REDUCED_DISPERSED\" \n");
899 
900  fprintf (midiQcLogPtr, "PRO.ARCFILE \"%s\" \n", fileNames->archFileName);
901  fprintf (midiQcLogPtr, "PRO.PIPEDATE \"%s\" \n", currentTime);
902  fprintf (midiQcLogPtr, "PRO.VERSION \"%s\" \n", MIDI_PIPE_VERSION);
903  fprintf (midiQcLogPtr, "PRO.PIPEFILE \"%s\" \n", fileNames->pipeFileName);
904  fprintf (midiQcLogPtr, "PRO.DID \"%s\" \n", MIDI_QC_DIC_VERSION);
905 
906  // Open the list of files
907  if ((inFitsBatchPtr = fopen (fileNames->inFitsBatch, "r")) == NULL)
908  {
909  *error = 1;
910  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot open input FITS file list");
911  free (messageBuffer);
912  free (currentTime);
913  free (cleanString);
914  free (stringTemp);
915  free (classification);
916  free (textBuff);
917  return;
918  }
919 
920  // Loop through the list of files and write into the QC log
921  X = 1;
922  while (fgets (stringTemp, MAX_STRING_LENGTH, inFitsBatchPtr) != NULL)
923  {
924  sprintf (classification, "%s", "");
925  sscanf (stringTemp, "%s%s", messageBuffer, classification);
926 
927  // If classification is not given get it from the raw file
928  if (strcmp (classification, "") == 0)
929  {
930  stringQfits = qfits_query_hdr (messageBuffer, "HIERARCH ESO DPR CATG");
931  if (stringQfits == NULL)
932  {
933  sprintf (classification, "%s", "UNKNOWN");
934  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot get Observation Category");
935  }
936  else
937  {
938  cleanUpString (stringQfits, cleanString);
939  sprintf (classification, "%s", cleanString);
940  }
941  }
942  removePathName (messageBuffer, midiReportPtr);
943  fprintf (midiQcLogPtr, "PRO.REC1.RAW%d.NAME \"%s\" \n", X, messageBuffer);
944  fprintf (midiQcLogPtr, "PRO.REC1.RAW%d.CATG \"%s\" \n", X++, classification);
945  }
946  fclose (inFitsBatchPtr);
947 
948  // Add name of Mask file to QC log file
949  sprintf (messageBuffer, "%s", fileNames->maskFileName);
950  removePathName (messageBuffer, midiReportPtr);
951  fprintf (midiQcLogPtr, "PRO.REC2.RAW1.NAME \"%s\" \n", messageBuffer);
952 
953  // Add name of Transfer Function file to QC log file
954  if (strcmp (sizeInterf->obsCatg, "CALIB") == 0) sprintf (messageBuffer, "%s", fileNames->trfNameWrite);
955  else sprintf (messageBuffer, "%s", fileNames->trfNameRead);
956  removePathName (messageBuffer, midiReportPtr);
957  stringLength = strlen (messageBuffer);
958  sprintf (textBuff, "r.");
959  strncat (textBuff, messageBuffer, stringLength-4);
960  sprintf (messageBuffer, "%s_tpl_0001.dummy", textBuff);
961  fprintf (midiQcLogPtr, "PRO.REC2.RAW2.NAME \"%s\" \n", messageBuffer);
962 
963  // Scan parameters
964  fprintf (midiQcLogPtr, "QC.CH.PROCESSED %d \n", sizeInterf->numOfChannelsProcessed);
965  fprintf (midiQcLogPtr, "QC.CH.REJECTED %d \n", sizeInterf->numOfChannelsRejected);
966 
967  // Add Wavelengths
968  for (X = 0; X < sizeInterf->iXWidth; X++)
969  {
970  if (badChannelList[X])
971  {
972  fprintf (midiQcLogPtr, "QC.LAMBDA%d %s \n", X, UNAV);
973  continue;
974  }
975 
976  fprintf (midiQcLogPtr, "QC.LAMBDA%d %f \n", X, freqCal[X]);
977  }
978 
979  // Transfer functions
980  if (dispResult->trfExists)
981  {
982  if (strcmp (sizeInterf->obsCatg, "CALIB") == 0)
983  {
984  // Add Calibrator keywords
985  fprintf (midiQcLogPtr, "QC.THEOVIS %f \n", calibrator->calibVisSqrd);
986  fprintf (midiQcLogPtr, "QC.DTHEOVIS %f \n", calibrator->calibVisSqrdErr);
987  fprintf (midiQcLogPtr, "QC.CALIB.POS \"UNKNOWN\" \n");
988  fprintf (midiQcLogPtr, "QC.CALIB.NAME \"%s\" \n", calibrator->calibName);
989  fprintf (midiQcLogPtr, "QC.CALIB.RA %f \n", calibrator->calibRA);
990  fprintf (midiQcLogPtr, "QC.CALIB.DEC %f \n", calibrator->calibDEC);
991  fprintf (midiQcLogPtr, "QC.CALIB.DIST %f \n", RAD_TO_ARCSEC * calibrator->calibDistance);
992  fprintf (midiQcLogPtr, "QC.CALIB.DIAM %f \n", calibrator->calibDiameter);
993  fprintf (midiQcLogPtr, "QC.CALIB.DDIAM %f \n", calibrator->calibDiameterErr);
994  fprintf (midiQcLogPtr, "QC.CALIB.FLAG %d \n", calibrator->calibFlag);
995  fprintf (midiQcLogPtr, "QC.CALIB.FLUX %g \n", calibrator->calibFlux);
996  fprintf (midiQcLogPtr, "QC.BL.LENGTH %f \n", calibrator->calibPblAverage);
997  fprintf (midiQcLogPtr, "QC.BL.ANGLE %f \n", calibrator->calibParangAverage);
998 
999  // Add binned Transfer Function
1000  fprintf (midiQcLogPtr, "QC.TRF.BINNED1 %0.4f \n", dispResult->trfBinned1);
1001  fprintf (midiQcLogPtr, "QC.TRF.BINNED2 %0.4f \n", dispResult->trfBinned2);
1002  fprintf (midiQcLogPtr, "QC.TRF.BINNED3 %0.4f \n", dispResult->trfBinned3);
1003  fprintf (midiQcLogPtr, "QC.TRF.BINNED4 %0.4f \n", dispResult->trfBinned4);
1004  fprintf (midiQcLogPtr, "QC.TRF.BINNED5 %0.4f \n", dispResult->trfBinned5);
1005 
1006 
1007  for (X = 0; X < sizeInterf->iXWidth; X++)
1008  {
1009  if (badChannelList[X])
1010  {
1011  fprintf (midiQcLogPtr, "QC.T%d %s \n", X, UNAV);
1012  fprintf (midiQcLogPtr, "QC.DT%d %s \n", X, UNAV);
1013  fprintf (midiQcLogPtr, "QC.COT%d %s \n", X, UNAV);
1014  fprintf (midiQcLogPtr, "QC.DCOT%d %s \n", X, UNAV);
1015  continue;
1016  }
1017 
1018  fprintf (midiQcLogPtr, "QC.T%d %f \n", X, (dispResult->trf)[X]);
1019  fprintf (midiQcLogPtr, "QC.DT%d %f \n", X, (dispResult->trfErr)[X]);
1020  fprintf (midiQcLogPtr, "QC.COT%d %f \n", X, 1.0/(dispResult->trf)[X]);
1021  fprintf (midiQcLogPtr, "QC.DCOT%d %f \n", X, 1.0/(dispResult->trfErr)[X]);
1022  }
1023  }
1024  else
1025  {
1026  // Add Applied Transfer Functions
1027  for (X = 0; X < sizeInterf->iXWidth; X++)
1028  {
1029  if (badChannelList[X])
1030  {
1031  fprintf (midiQcLogPtr, "QC.AT%d %s \n", X, UNAV);
1032  fprintf (midiQcLogPtr, "QC.DAT%d %s \n", X, UNAV);
1033  }
1034  else
1035  {
1036  fprintf (midiQcLogPtr, "QC.AT%d %f \n", X, (dispResult->trf)[X]);
1037  fprintf (midiQcLogPtr, "QC.DAT%d %f \n", X, (dispResult->trfErr)[X]);
1038  }
1039  }
1040  }
1041  }
1042 
1043  // Add uncalibrated Normal Visibilities
1044  for (X = 0; X < sizeInterf->iXWidth; X++)
1045  {
1046  if (badChannelList[X])
1047  {
1048  fprintf (midiQcLogPtr, "QC.UNCALV%d %s \n", X, UNAV);
1049  fprintf (midiQcLogPtr, "QC.DUNCALV%d %s \n", X, UNAV);
1050  }
1051  else
1052  {
1053  fprintf (midiQcLogPtr, "QC.UNCALV%d %f \n", X, (dispResult->normVis2)[X]);
1054  fprintf (midiQcLogPtr, "QC.DUNCALV%d %f \n", X, (dispResult->normVis2Err)[X]);
1055  }
1056  }
1057 
1058  // Add Photometry parameters
1059  for (X = 0; X < sizeInterf->iXWidth; X++)
1060  {
1061  if (!(badChannelList[X]))
1062  {
1063  photA += (dispResult->photomA)[0][X];
1064  photAErr += (dispResult->photomAErr)[0][X];
1065  photB += (dispResult->photomB)[0][X];
1066  photBErr += (dispResult->photomBErr)[0][X];
1067  photI += (dispResult->photomI)[0][X];
1068  photIErr += (dispResult->photomIErr)[0][X];
1069  photNet2 += (dispResult->photomNet2)[X];
1070  photNet2Err += (dispResult->photomNet2Err)[X];
1071  }
1072  }
1073  if (sizeInterf->numOfChannelsProcessed)
1074  {
1075  photA /= sizeInterf->numOfChannelsProcessed;
1076  photAErr /= sizeInterf->numOfChannelsProcessed;
1077  photB /= sizeInterf->numOfChannelsProcessed;
1078  photBErr /= sizeInterf->numOfChannelsProcessed;
1079  photI /= sizeInterf->numOfChannelsProcessed;
1080  photIErr /= sizeInterf->numOfChannelsProcessed;
1081  photNet2 /= sizeInterf->numOfChannelsProcessed;
1082  photNet2Err /= sizeInterf->numOfChannelsProcessed;
1083  }
1084  fprintf (midiQcLogPtr, "QC.AV.PHOTA %f \n", photA);
1085  fprintf (midiQcLogPtr, "QC.AV.DPHOTA %f \n", photAErr);
1086  fprintf (midiQcLogPtr, "QC.AV.PHOTB %f \n", photB);
1087  fprintf (midiQcLogPtr, "QC.AV.DPHOTB %f \n", photBErr);
1088  fprintf (midiQcLogPtr, "QC.AV.PHOTI %f \n", photI);
1089  fprintf (midiQcLogPtr, "QC.AV.DPHOTI %f \n", photIErr);
1090  fprintf (midiQcLogPtr, "QC.AV.PHOTN %f \n", photNet2);
1091  fprintf (midiQcLogPtr, "QC.AV.DPHOTN %f \n", photNet2Err);
1092 
1093  // Add Calibrated Visibilities
1094  if (dispResult->calibVisExists)
1095  {
1096  for (X = 0; X < sizeInterf->iXWidth; X++)
1097  {
1098  if (badChannelList[X])
1099  {
1100  fprintf (midiQcLogPtr, "QC.CALV%d %s \n", X, UNAV);
1101  fprintf (midiQcLogPtr, "QC.DCALV%d %s \n", X, UNAV);
1102  }
1103  else
1104  {
1105  fprintf (midiQcLogPtr, "QC.CALV%d %f \n", X, (dispResult->calibVis2)[X]);
1106  fprintf (midiQcLogPtr, "QC.DCALV%d %f \n", X, (dispResult->calibVis2Err)[X]);
1107  }
1108  }
1109  }
1110 
1111  // Add Target keywords
1112  fprintf (midiQcLogPtr, "QC.TARG.DIAM \"UNKNOWN\" \n");
1113  fprintf (midiQcLogPtr, "QC.TARG.DDIAM \"UNKNOWN\" \n");
1114 
1115  // Add UVW. The values of uvw will be added during pipeline execution
1116  fprintf (midiQcLogPtr, "QC.BL.UVW1 %f \n", uvw->uCoord);
1117  fprintf (midiQcLogPtr, "QC.BL.UVW2 %f \n", uvw->vCoord);
1118  fprintf (midiQcLogPtr, "QC.BL.UVW3 %f \n", uvw->wCoord);
1119 
1120  // Add binned photometry measurements
1121  if (strcmp(sizeInterf->beamCombiner, "HIGH_SENS") == 0)
1122  {
1123  fprintf (midiQcLogPtr, "QC.PHOTA.TARG1 %0.2f \n", dispResult->photomATarg1);
1124  fprintf (midiQcLogPtr, "QC.PHOTB.TARG1 %0.2f \n", dispResult->photomBTarg1);
1125 
1126  fprintf (midiQcLogPtr, "QC.PHOTA.TARG2 %0.2f \n", dispResult->photomATarg2);
1127  fprintf (midiQcLogPtr, "QC.PHOTB.TARG2 %0.2f \n", dispResult->photomBTarg2);
1128 
1129  fprintf (midiQcLogPtr, "QC.PHOTA.TARG3 %0.2f \n", dispResult->photomATarg3);
1130  fprintf (midiQcLogPtr, "QC.PHOTB.TARG3 %0.2f \n", dispResult->photomBTarg3);
1131 
1132  fprintf (midiQcLogPtr, "QC.PHOTA.TOTAL1 %0.2f \n", dispResult->photomATotal1);
1133  fprintf (midiQcLogPtr, "QC.PHOTB.TOTAL1 %0.2f \n", dispResult->photomBTotal1);
1134 
1135  fprintf (midiQcLogPtr, "QC.PHOTA.TOTAL2 %0.2f \n", dispResult->photomATotal2);
1136  fprintf (midiQcLogPtr, "QC.PHOTB.TOTAL2 %0.2f \n", dispResult->photomBTotal2);
1137 
1138  fprintf (midiQcLogPtr, "QC.PHOTA.TOTAL3 %0.2f \n", dispResult->photomATotal3);
1139  fprintf (midiQcLogPtr, "QC.PHOTB.TOTAL3 %0.2f \n", dispResult->photomBTotal3);
1140  }
1141 
1142  // Add binned uncalibrated visibilities
1143  fprintf (midiQcLogPtr, "QC.UNCAL.BINNED1 %0.4f \n", dispResult->uncalVisBinned1);
1144  fprintf (midiQcLogPtr, "QC.UNCAL.BINNED2 %0.4f \n", dispResult->uncalVisBinned2);
1145  fprintf (midiQcLogPtr, "QC.UNCAL.BINNED3 %0.4f \n", dispResult->uncalVisBinned3);
1146  fprintf (midiQcLogPtr, "QC.UNCAL.BINNED4 %0.4f \n", dispResult->uncalVisBinned4);
1147  fprintf (midiQcLogPtr, "QC.UNCAL.BINNED5 %0.4f \n", dispResult->uncalVisBinned5);
1148 
1149  // Add number of changed target types
1150  fprintf (midiQcLogPtr, "QC.TARTYPE.INTERF.CHANGED %ld \n", corrFrames->CorrInterf );
1151  fprintf (midiQcLogPtr, "QC.TARTYPE.PHOTOMA.CHANGED %ld \n", corrFrames->CorrPhotomA );
1152  fprintf (midiQcLogPtr, "QC.TARTYPE.PHOTOMB.CHANGED %ld \n", corrFrames->CorrPhotomB );
1153 
1154 
1155  // Release memory
1156  free (messageBuffer);
1157  free (currentTime);
1158  free (textBuff);
1159  free (cleanString);
1160  free (stringTemp);
1161  free (classification);
1162 
1163  return;
1164 }
1165 /*****************************************************************************/
1166 
1167 
1168 
1169 /******************************************************************************
1170 * European Southern Observatory
1171 * VLTI MIDI Data Reduction Software
1172 *
1173 * Module name: loadFrgOutputData
1174 * Input/Output: See function arguments to avoid duplication
1175 * Description: Loads MIDI product data into appropriate data structures
1176 *
1177 *
1178 * History:
1179 * 11-Feb-05 (csabet) Created
1180 ******************************************************************************/
1181 void loadFrgOutputData (
1182  char *obsCategory, // In: Observation category
1183  char *fileName, // In: Input file name
1184  float *waveCal, // In: array of frequencies
1185  DispersedResult *dispResult, // In: Dispersed result
1186  IauExchange *iauData, // Ou: IAU Exchange data structure
1187  UVW *uvw, // Ou: Coordinates of the uvw
1188  int *error)
1189 
1190 {
1191  // Local Declarations
1192  // ------------------
1193  const char routine[] = "loadFrgOutputData";
1194  int i, irec, iwave, itarg, mjdObs, *selection, extNumber;
1195  float equinox;
1196  char *stringQfits, *emptyString, *buffer, *observationData, *arrayName,
1197  *instName, *cleanString;
1198  double raEp0, decEp0, integrationTime;
1199  qfits_table *arrayGeometry;
1200 /* char *qfitsRow=NULL; */
1201  short *qfitsRow_int, targetId = 1;
1202  float *qfitsRow_flt, nullFloat;
1203  double *qfitsRow_dbl, utcTime;
1204 
1205  cpl_table * table =NULL;
1206  char ** tel_name =NULL;
1207  char ** sta_name =NULL;
1208 
1209 
1210 
1211  // Algorithm
1212  // ---------
1213  *error = 0;
1214  if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking routine '%s' \n", routine);
1215  if (diagnostic > 4) fprintf(midiReportPtr, "Invoking routine '%s' \n", routine);
1216 
1217  // Allocate memory
1218  cleanString = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
1219  emptyString = (char *) calloc (MIN_STRING_LENGTH, sizeof (char));
1220  buffer = (char *) calloc (MIN_STRING_LENGTH, sizeof (char));
1221  observationData = (char *) calloc (MIN_STRING_LENGTH, sizeof (char));
1222  arrayName = (char *) calloc (MIN_STRING_LENGTH, sizeof (char));
1223  instName = (char *) calloc (MIN_STRING_LENGTH, sizeof (char));
1224 
1225  // Initialize values
1226  strcpy (emptyString, "NULL");
1227  set_fnan (&nullFloat);
1228 
1229  // Get general parameters from the Header of the input FITS file
1230  // -------------------------------------------------------------
1231  stringQfits = qfits_query_hdr (fileName, "DATE-OBS");
1232  if (stringQfits == NULL)
1233  sscanf (emptyString, "%s", observationData);
1234  else
1235  {
1236  cleanUpString (stringQfits, cleanString);
1237  sscanf (cleanString, "%s", observationData);
1238  }
1239 
1240  stringQfits = qfits_query_hdr (fileName, "EXPTIME");
1241  if (stringQfits == NULL) integrationTime = nullFloat;
1242  else sscanf (stringQfits, "%lf", &integrationTime);
1243 
1244  extNumber = getFitsExtensionNumber (fileName, "ARRAY_GEOMETRY", error);
1245  stringQfits = qfits_query_ext (fileName, "ARRNAME", extNumber);
1246  if (stringQfits == NULL)
1247  sscanf (emptyString, "%s", arrayName);
1248  else
1249  {
1250  cleanUpString (stringQfits, cleanString);
1251  sscanf (cleanString, "%s", arrayName);
1252  }
1253 
1254  stringQfits = qfits_query_hdr (fileName, "INSTRUME");
1255  if (stringQfits == NULL)
1256  sscanf (emptyString, "%s", instName);
1257  else
1258  {
1259  cleanUpString (stringQfits, cleanString);
1260  sscanf (cleanString, "%s", instName);
1261  }
1262 
1263  stringQfits = qfits_query_hdr (fileName, "RA");
1264  if (stringQfits == NULL) raEp0 = nullFloat;
1265  else sscanf (stringQfits, "%lf", &raEp0);
1266 
1267  stringQfits = qfits_query_hdr (fileName, "DEC");
1268  if (stringQfits == NULL) decEp0 = nullFloat;
1269  else sscanf (stringQfits, "%lf", &decEp0);
1270 
1271  stringQfits = qfits_query_hdr (fileName, "EQUINOX");
1272  if (stringQfits == NULL) equinox = nullFloat;
1273  else sscanf (stringQfits, "%f", &equinox);
1274 
1275  stringQfits = qfits_query_hdr (fileName, "MJD-OBS");
1276  if (stringQfits == NULL) mjdObs = nullFloat;
1277  else sscanf (stringQfits, "%d", &mjdObs);
1278 
1279  stringQfits = qfits_query_hdr (fileName, "UTC");
1280  if (stringQfits == NULL) utcTime = nullFloat;
1281  else sscanf (stringQfits, "%lf", &utcTime);
1282 
1283  // Load info for OI_ARRAY table
1284  // ----------------------------
1285  if (diagnostic)cpl_msg_info(cpl_func,"Loading OI_ARRAY data ... \n");
1286  if (diagnostic) fprintf (midiReportPtr, "Loading OI_ARRAY data ... \n");
1287 
1288  // Get the required parameters from the ARRAY_GEOMETRY extension of the input FITS file
1289  sscanf (arrayName, "%s", iauData->array->arrname);
1290 
1291  // Get extension number
1292  extNumber = getFitsExtensionNumber (fileName, "ARRAY_GEOMETRY", error);
1293 
1294  stringQfits = qfits_query_ext (fileName, "FRAME", extNumber);
1295  if (stringQfits == NULL)
1296  sscanf (emptyString, "%s", iauData->array->frame);
1297  else
1298  {
1299  cleanUpString (stringQfits, cleanString);
1300  sscanf (cleanString, "%s", iauData->array->frame);
1301  }
1302 
1303  stringQfits = qfits_query_ext (fileName, "ARRAYX", extNumber);
1304  if (stringQfits == NULL) iauData->array->arrayx = nullFloat;
1305  else sscanf (stringQfits, "%lf", &(iauData->array->arrayx));
1306 
1307  stringQfits = qfits_query_ext (fileName, "ARRAYY", extNumber);
1308  if (stringQfits == NULL) iauData->array->arrayy = nullFloat;
1309  else sscanf (stringQfits, "%lf", &(iauData->array->arrayy));
1310 
1311  stringQfits = qfits_query_ext (fileName, "ARRAYZ", extNumber);
1312  if (stringQfits == NULL) iauData->array->arrayz = nullFloat;
1313  else sscanf (stringQfits, "%lf", &(iauData->array->arrayz));
1314 
1315  // Open the table
1316  arrayGeometry = qfits_table_open (fileName, extNumber);
1317 
1318 
1319  table = cpl_table_load(fileName, extNumber, 1);
1320 
1321  if (cpl_table_has_column(table, "TEL_NAME")) tel_name=cpl_table_get_data_string(table, "TEL_NAME");
1322  if (cpl_table_has_column(table, "STA_NAME")) sta_name=cpl_table_get_data_string(table, "STA_NAME");
1323 
1324 
1325 /* for (i=0; i<cpl_table_get_nrow(table);i++){ */
1326 /* cpl_msg_info(cpl_func, "tel_name: %s sta_name: %s",tel_name[i], sta_name[i]); */
1327 /* } */
1328 
1329 
1330 
1331 
1332 
1333  // Load info for OI_ARRAY table
1334  // ----------------------------
1335  selection = (int *) calloc (iauData->array->nelement, sizeof (int));
1336  for (i = 0; i < iauData->array->nelement; i++)
1337  {
1338  selection[i] = 1;
1339  sprintf ((iauData->array->elem)[i].tel_name, "%s", tel_name[i]);
1340  sprintf ((iauData->array->elem)[i].sta_name, "%s", sta_name[i]);
1341  if (diagnostic > 2){
1342  cpl_msg_info(cpl_func,"iauData->array->elem)[i].tel_name: %s tel_name[i] %s", (iauData->array->elem)[i].tel_name,tel_name[i]);
1343  cpl_msg_info(cpl_func,"iauData->array->elem)[i].sta_name: %s sta_name[i] %s", (iauData->array->elem)[i].sta_name,sta_name[i]);
1344  }
1345 
1346 
1347 /* qfitsRow = (char *) (qfits_query_column (arrayGeometry, 0, selection)); */
1348 /* if (diagnostic > 2)cpl_msg_info(cpl_func,"qfitsRow = %s \n", qfitsRow); */
1349 /* removeNewLine (qfitsRow, cleanString); */
1350 /* if (diagnostic > 2)cpl_msg_info(cpl_func,"cleanString = %s \n", cleanString); */
1351 /* sprintf ((iauData->array->elem)[i].tel_name, "%s", cleanString); */
1352 /* free (qfitsRow); */
1353 
1354 
1355 /* qfitsRow = (char *) (qfits_query_column (arrayGeometry, 1, selection)); */
1356 /* removeNewLine (qfitsRow, cleanString); */
1357 /* sprintf ((iauData->array->elem)[i].sta_name, "%s", cleanString); */
1358 /* free (qfitsRow); */
1359 
1360 
1361  qfitsRow_int = (short *) (qfits_query_column (arrayGeometry, 2, selection));
1362  (iauData->array->elem)[i].sta_index = qfitsRow_int[0];
1363  free (qfitsRow_int);
1364 
1365  qfitsRow_flt = (float *) (qfits_query_column (arrayGeometry, 3, selection));
1366  (iauData->array->elem)[i].diameter = qfitsRow_flt[0];
1367  free (qfitsRow_flt);
1368 
1369  qfitsRow_dbl = (double *) (qfits_query_column (arrayGeometry, 4, selection));
1370  (iauData->array->elem)[i].staxyz[0] = qfitsRow_dbl[0];
1371  (iauData->array->elem)[i].staxyz[1] = qfitsRow_dbl[1];
1372  (iauData->array->elem)[i].staxyz[2] = qfitsRow_dbl[2];
1373  free (qfitsRow_dbl);
1374 
1375  selection[i] = 0;
1376  }
1377 /* Free table memory */
1378  cpl_table_delete(table);
1379 
1380  sprintf (iauData->array->revision, "%s", IAUEXCHANGE_VERSION);
1381  free (selection);
1382  qfits_table_close (arrayGeometry);
1383 
1384  // Load info for OI_TARGET table
1385  // -----------------------------
1386  if (diagnostic)cpl_msg_info(cpl_func,"Loading OI_TARGET data ... \n");
1387  if (diagnostic) fprintf (midiReportPtr, "Loading OI_TARGET data ... \n");
1388 
1389  stringQfits = qfits_query_hdr (fileName, "HIERARCH ESO OBS TARG NAME");
1390  if (stringQfits == NULL)
1391  sscanf (emptyString, "%s", buffer);
1392  else
1393  {
1394  cleanUpString (stringQfits, cleanString);
1395  sscanf (cleanString, "%s", buffer);
1396  }
1397 
1398  for (itarg = 0; itarg < iauData->targets->ntarget; itarg++)
1399  {
1400  (iauData->targets->targ)[itarg].target_id = targetId;
1401  sscanf (buffer, "%s", (iauData->targets->targ)[itarg].target);
1402  (iauData->targets->targ)[itarg].raep0 = raEp0;
1403  (iauData->targets->targ)[itarg].decep0 = decEp0;
1404  (iauData->targets->targ)[itarg].equinox = equinox;
1405  (iauData->targets->targ)[itarg].ra_err = nullFloat;
1406  (iauData->targets->targ)[itarg].dec_err = nullFloat;
1407  (iauData->targets->targ)[itarg].sysvel = nullFloat;
1408  sscanf (emptyString, "%s", (iauData->targets->targ)[itarg].veltyp);
1409  sscanf (emptyString, "%s", (iauData->targets->targ)[itarg].veldef);
1410  (iauData->targets->targ)[itarg].pmra = nullFloat;
1411  (iauData->targets->targ)[itarg].pmdec = nullFloat;
1412  (iauData->targets->targ)[itarg].pmra_err = nullFloat;
1413  (iauData->targets->targ)[itarg].pmdec_err = nullFloat;
1414  (iauData->targets->targ)[itarg].parallax = nullFloat;
1415  (iauData->targets->targ)[itarg].para_err = nullFloat;
1416  sscanf (emptyString, "%s", (iauData->targets->targ)[itarg].spectyp);
1417  }
1418  sprintf (iauData->targets->revision, "%s", IAUEXCHANGE_VERSION);
1419 
1420 
1421  // Load info for OI_WAVELENGTH table
1422  // ---------------------------------
1423  if (diagnostic)cpl_msg_info(cpl_func,"Loading OI_WAVELENGTH data ... \n");
1424  if (diagnostic) fprintf (midiReportPtr, "Loading OI_WAVELENGTH data ... \n");
1425 
1426  // Compute the parameters
1427  sscanf (instName, "%s", iauData->wavelength->insname);
1428  for (i = 0; i < (iauData->wavelength->nwave-1); i++)
1429  {
1430  (iauData->wavelength->eff_wave)[i] = 1.e-6 * waveCal[i];
1431  (iauData->wavelength->eff_band)[i] = 1.e-6 * fabs ((waveCal[1+i] - waveCal[i]));
1432  }
1433  // Final row
1434  (iauData->wavelength->eff_wave)[iauData->wavelength->nwave-1] = 1.e-6 *
1435  waveCal[iauData->wavelength->nwave-1];
1436  (iauData->wavelength->eff_band)[iauData->wavelength->nwave-1] =
1437  (iauData->wavelength->eff_band)[iauData->wavelength->nwave-2];
1438  sprintf (iauData->wavelength->revision, "%s", IAUEXCHANGE_VERSION);
1439 
1440  // Get the uvw parameters
1441  computeUVW ((iauData->array->elem)[0].staxyz[0], (iauData->array->elem)[0].staxyz[1], (iauData->array->elem)[0].staxyz[2],
1442  (iauData->array->elem)[1].staxyz[0], (iauData->array->elem)[1].staxyz[1], (iauData->array->elem)[1].staxyz[2],
1443  mjdObs, raEp0, decEp0, uvw);
1444 
1445  // Load info for OI_VIS table
1446  // --------------------------
1447  if (diagnostic)cpl_msg_info(cpl_func,"Loading OI_VIS data ... \n");
1448  if (diagnostic) fprintf (midiReportPtr, "Loading OI_VIS data ... \n");
1449 
1450  // Get the required parameters from the FITS file
1451  sscanf (observationData, "%s", iauData->vis->date_obs);
1452  sscanf (arrayName, "%s", iauData->vis->arrname);
1453  sscanf (instName, "%s", iauData->vis->insname);
1454  for (irec = 0; irec < iauData->vis->numrec; irec++)
1455  {
1456  (iauData->vis->record)[irec].target_id = targetId;
1457  (iauData->vis->record)[irec].time = utcTime;
1458  (iauData->vis->record)[irec].mjd = mjdObs;
1459  (iauData->vis->record)[irec].int_time = integrationTime;
1460  (iauData->vis->record)[irec].ucoord = uvw->uCoord;
1461  (iauData->vis->record)[irec].vcoord = uvw->vCoord;
1462  (iauData->vis->record)[irec].sta_index[0] = (iauData->array->elem)[0].sta_index;
1463  (iauData->vis->record)[irec].sta_index[1] = (iauData->array->elem)[1].sta_index;
1464 
1465  if ((strcmp (obsCategory, "SCIENCE") == 0) && dispResult->calibVisExists)
1466  {
1467  for (iwave = 0; iwave < iauData->wavelength->nwave; iwave++)
1468  {
1469  if (badChannelList[iwave])
1470  {
1471  (iauData->vis->record)[irec].visamp[iwave] = nullFloat;
1472  (iauData->vis->record)[irec].visamperr[iwave] = nullFloat;
1473  }
1474  else
1475  {
1476  (iauData->vis->record)[irec].visamp[iwave] = sqrt ((dispResult->calibVis2)[iwave]);
1477  (iauData->vis->record)[irec].visamperr[iwave] = sqrt ((dispResult->calibVis2Err)[iwave]);
1478  }
1479  (iauData->vis->record)[irec].visphi[iwave] = nullFloat;
1480  (iauData->vis->record)[irec].visphierr[iwave] = nullFloat;
1481  }
1482  }
1483  else
1484  {
1485  for (iwave = 0; iwave < iauData->wavelength->nwave; iwave++)
1486  {
1487  if (badChannelList[iwave])
1488  {
1489  (iauData->vis->record)[irec].visamp[iwave] = nullFloat;
1490  (iauData->vis->record)[irec].visamperr[iwave] = nullFloat;
1491  }
1492  else
1493  {
1494  (iauData->vis->record)[irec].visamp[iwave] = sqrt ((dispResult->normVis2)[iwave]);
1495  (iauData->vis->record)[irec].visamperr[iwave] = sqrt ((dispResult->normVis2Err)[iwave]);
1496  }
1497  (iauData->vis->record)[irec].visphi[iwave] = nullFloat;
1498  (iauData->vis->record)[irec].visphierr[iwave] = nullFloat;
1499  }
1500  }
1501  sprintf ((iauData->vis->record)[irec].flag, "%s", "FALSE");
1502  }
1503  sprintf (iauData->vis->revision, "%s", IAUEXCHANGE_VERSION);
1504  iauData->vis->nwave = iauData->wavelength->nwave;
1505 
1506 
1507  // Load info for OI_VIS2 table
1508  // ---------------------------
1509  if (diagnostic)cpl_msg_info(cpl_func,"Loading OI_VIS2 data ... \n");
1510  if (diagnostic) fprintf (midiReportPtr, "Loading OI_VIS2 data ... \n");
1511 
1512  // Get the required parameters from the FITS file
1513  sscanf (observationData, "%s", iauData->vis2->date_obs);
1514  sscanf (arrayName, "%s", iauData->vis2->arrname);
1515  sscanf (instName, "%s", iauData->vis2->insname);
1516  for(irec = 0; irec < iauData->vis2->numrec; irec++)
1517  {
1518  (iauData->vis2->record)[irec].target_id = targetId;
1519  (iauData->vis2->record)[irec].time = utcTime;
1520  (iauData->vis2->record)[irec].mjd = mjdObs;
1521  (iauData->vis2->record)[irec].int_time = integrationTime;
1522  (iauData->vis2->record)[irec].ucoord = uvw->uCoord;
1523  (iauData->vis2->record)[irec].vcoord = uvw->vCoord;
1524  (iauData->vis2->record)[irec].sta_index[0] = (iauData->array->elem)[0].sta_index;;
1525  (iauData->vis2->record)[irec].sta_index[1] = (iauData->array->elem)[1].sta_index;;
1526 
1527  if ((strcmp (obsCategory, "SCIENCE") == 0) && dispResult->calibVisExists)
1528  {
1529  for (iwave = 0; iwave < iauData->wavelength->nwave; iwave++)
1530  {
1531  if (badChannelList[iwave])
1532  {
1533  (iauData->vis2->record)[irec].vis2data[iwave] = nullFloat;
1534  (iauData->vis2->record)[irec].vis2err[iwave] = nullFloat;
1535  }
1536  else
1537  {
1538  (iauData->vis2->record)[irec].vis2data[iwave] = (dispResult->calibVis2)[iwave];
1539  (iauData->vis2->record)[irec].vis2err[iwave] = (dispResult->calibVis2Err)[iwave];
1540  }
1541  }
1542  }
1543  else
1544  {
1545  for (iwave = 0; iwave < iauData->wavelength->nwave; iwave++)
1546  {
1547  if (badChannelList[iwave])
1548  {
1549  (iauData->vis2->record)[irec].vis2data[iwave] = nullFloat;
1550  (iauData->vis2->record)[irec].vis2err[iwave] = nullFloat;
1551  }
1552  else
1553  {
1554  (iauData->vis2->record)[irec].vis2data[iwave] = (dispResult->normVis2)[iwave];
1555  (iauData->vis2->record)[irec].vis2err[iwave] = (dispResult->normVis2Err)[iwave];
1556  }
1557  }
1558  }
1559  sprintf ((iauData->vis2->record)[irec].flag, "%s", "FALSE");
1560  }
1561  sprintf (iauData->vis2->revision, "%s", IAUEXCHANGE_VERSION);
1562  iauData->vis2->nwave = iauData->wavelength->nwave;
1563 
1564  // Release memory
1565  free (instName);
1566  free (arrayName);
1567  free (observationData);
1568  free (emptyString);
1569  free (buffer);
1570  free (cleanString);
1571 
1572  return;
1573 
1574 }
1575 /*****************************************************************************/
1576 
1577 
1578 
1579 
1580 /******************************************************************************
1581 * European Southern Observatory
1582 * VLTI MIDI Data Reduction Software
1583 *
1584 * Module name: writeFrgFitsFile
1585 * Input/Output: See function arguments to avoid duplication
1586 * Description: Writes and creates appropriate tables into a new fits file in
1587 * accordance with the IAU format
1588 *
1589 * History:
1590 * 11-Feb-05 (csabet) Created
1591 ******************************************************************************/
1592 void writeFrgFitsFile (
1593  char *outFitsName,
1594  IauExchange *iauData,
1595  int *error)
1596 {
1597  // Local Declarations
1598  // ------------------
1599  const char routine[] = "writeFrgFitsFile";
1600 
1601  // Algorithm
1602  // ---------
1603  if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking routine '%s' \n", routine);
1604  if (diagnostic > 4) fprintf(midiReportPtr, "Invoking routine '%s' \n", routine);
1605 
1606  if (diagnostic)cpl_msg_info(cpl_func,"Writing data into the output FITS file \n\n");
1607  if (diagnostic) fprintf (midiReportPtr, "Writing data into the output FITS file \n\n");
1608 
1609  // Reset parameters
1610  *error = 0;
1611 
1612  // Write OI_ARRAY table
1613  writeOiArray (outFitsName, iauData->array, error);
1614  if (*error)
1615  {
1616  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot write OI_ARRAY in the output FITS file");
1617  return;
1618  }
1619 
1620  // Write OI_TARGET table
1621  writeOiTarget (outFitsName, iauData->targets, error);
1622  if (*error)
1623  {
1624  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot write OI_TARGET in the output FITS file");
1625  return;
1626  }
1627 
1628  // Write OI_WAVELENGTH table
1629  writeOiWavelength (outFitsName, iauData->wavelength, error);
1630  if (*error)
1631  {
1632  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot write OI_WAVELENGTH in the output FITS file");
1633  return;
1634  }
1635 
1636  // Write OI_VIS table
1637  writeOiVis (outFitsName, iauData->vis, error);
1638  if (*error)
1639  {
1640  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot write OI_VIS in the output FITS file");
1641  return;
1642  }
1643 
1644  // Write OI_VIS2 table
1645  writeOiVis2 (outFitsName, iauData->vis2, error);
1646  if (*error)
1647  {
1648  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot write OI_VIS2 in the output FITS file");
1649  return;
1650  }
1651 
1652  return;
1653 
1654 }
1655 /*****************************************************************************/
1656