MIDI Pipeline Reference Manual  2.8.3
createProdDspTrn.c
1 
2 /******************************************************************************
3 *******************************************************************************
4 * European Southern Observatory
5 * VLTI MIDI Maintenance Templates Software
6 *
7 * Module name: createProdDspTrn.c
8 * Description: Contains routines for the product files handling
9 *
10 * History:
11 * 14-Jun-04 (csabet)
12 *******************************************************************************
13 ******************************************************************************/
14 
15 /******************************************************************************
16 * Compiler directives
17 ******************************************************************************/
18 
19 /******************************************************************************
20 * Include files
21 ******************************************************************************/
22 #include <sys/stat.h>
23 #include <stdio.h>
24 #include <cpl.h>
25 #include <time.h>
26 #include "midiGlobal.h"
27 #include "midiLib.h"
28 #include "errorHandling.h"
29 #include "midiFitsUtility.h"
30 #include "fileHandling.h"
31 #include "createProdDspTrn.h"
32 #include "qfits.h"
33 
34 /**********************************************************
35 * Global Variables
36 **********************************************************/
37 
38 /*============================ C O D E A R E A ===========================*/
39 
40 
41 
42 
43 
44 
45 /******************************************************************************
46 * European Southern Observatory
47 * VLTI MIDI Maintenance Templates Software
48 *
49 * Module name: createDspTrnProd
50 * Input/Output: See function arguments to avoid duplication
51 * Description: Creates MIDI product files
52 *
53 * History:
54 * 15-Jun-04 (csabet) Created
55 ******************************************************************************/
56 void createDspTrnProd (
57  MidiFiles *fileNames, // In: Pointer to the file structure
58  ImageFormat *format, // In: Image format
59  DispersiveTrans *trans, // In: Dispersive transmission data structure
60  int *error) // Ou: Error status
61 {
62 
63  /* Local Declarations
64  --------------------*/
65  const char routine[] = "createDspTrnProd";
66  char *classification, *stringTemp;
67  FILE *inFitsBatchPtr;
68  float *dspTrnImage;
69  int i, j, k, l, arraySize;
70  qfitsdumper qdDspTrn;
71 
72  // Algorithm
73  // ---------
74  if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking routine '%s' \n", routine);
75  if (diagnostic > 4) fprintf (midiReportPtr, "Invoking routine '%s' \n", routine);
76 
77  cpl_msg_info(cpl_func,"\nCreating Product files for DSP_TRN from batch %d \n", batchNumber);
78  cpl_msg_info(cpl_func,"--------------------------------------------- \n");
79  fprintf (midiReportPtr, "\nCreating Product for DSP_TRN from batch %d \n", batchNumber);
80  fprintf (midiReportPtr, "--------------------------------------- \n");
81 
82  // Reset status
83  *error = 0;
84  arraySize = 300;
85 
86  // Create the primary header extension
87  createDspTrnPrimHead (fileNames, format, arraySize, trans, error);
88  if (*error)
89  {
90  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot create Primary Header extension");
91  return;
92  }
93 
94  // Allocate memory
95  stringTemp = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
96  classification = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
97  dspTrnImage = (float *) calloc (arraySize * arraySize, sizeof (float));
98 
99  // Convert Transmissivity vector into an image and write into the FITS file
100  for (i = 0; i < 3; i++)
101  {
102  for (j = 0; j < 100; j++)
103  {
104  for (k = 0; k < arraySize; k++)
105  {
106  l = (i * 100 + j) * arraySize + k;
107  dspTrnImage[l] = trans->transmission[i];
108  }
109  }
110  }
111 
112  qdDspTrn.filename = fileNames->outFitsName;
113  qdDspTrn.npix = arraySize * arraySize;
114  qdDspTrn.ptype = PTYPE_FLOAT;
115  qdDspTrn.fbuf = dspTrnImage;
116  qdDspTrn.out_ptype = BPP_IEEE_FLOAT;
117  qfits_pixdump (&qdDspTrn);
118 
119  free (dspTrnImage);
120 
121  // Open the list of files
122  if ((inFitsBatchPtr = fopen (fileNames->inFitsBatch, "r")) == NULL)
123  {
124  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot open input FITS file list");
125  *error = 1;
126  return;
127  }
128 
129 
130  // Read the name of the first file in the list and get it's full path name
131  fgets (stringTemp, MAX_STRING_LENGTH, inFitsBatchPtr);
132  sprintf (classification, "%s", "");
133  sscanf (stringTemp, "%s%s", fileNames->inFitsName, classification);
134 
135  // Copy keywords from the raw FITS file into the QC log
136  createDspTrnQcLog (fileNames->inFitsName, error);
137  if (*error)
138  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot copy keywords to QC log");
139 
140  // Add product info to QC log
141  addProdInfoToDspTrnQcLog (format, fileNames, trans, error);
142 
143  // Close files
144  fclose (inFitsBatchPtr);
145 
146  // Release memory
147  free (classification);
148  free (stringTemp);
149 
150  return;
151 }
152 /*****************************************************************************/
153 
154 
155 /******************************************************************************
156 * European Southern Observatory
157 * VLTI MIDI Data Reduction Software
158 *
159 * Module name: createDspTrnPrimHead
160 * Input/Output: See function arguments to avoid duplication
161 * Description: Creates the primary header
162 *
163 *
164 * History:
165 * 24-Aug-06 (csabet) Created
166 ******************************************************************************/
167 void createDspTrnPrimHead (
168  MidiFiles *fileNames, // In: Pointer to the file structure
169  ImageFormat *format, // In: Image format
170  int arraySize, // In: size of the image
171  DispersiveTrans *trans,// In: Dispersive transmission data structure
172  int *error) // Ou: Error status
173 {
174 
175  // Local Declarations
176  // ------------------
177  const char routine[] = "createDspTrnPrimHead";
178  qfits_header *outFitsHeader;
179  FILE *inFitsBatchPtr=NULL, *outFitsPtr;
180  int i;
181  char *textBuff, *stringQfits, *messageBuffer, *currentTime, *cleanString,
182  *stringTemp, *classification, *sWidthX, *sWidthY, *tech;
183  time_t now;
184  struct tm *newTime;
185  struct stat buf;
186 
187  // Algorithm
188  // ---------
189  if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking routine '%s' \n", routine);
190  if (diagnostic > 4) fprintf(midiReportPtr, "Invoking routine '%s' \n", routine);
191 
192  // Reset parameters
193  *error = 0;
194 
195  // Open list of files
196  if ((inFitsBatchPtr = fopen (fileNames->inFitsBatch, "r")) == NULL)
197  {
198  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot open input FITS file list");
199  *error = 1;
200  return;
201  }
202 
203  // Allocate memory
204  tech = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
205  textBuff = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
206  classification = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
207  stringTemp = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
208  cleanString = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
209  messageBuffer = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
210  currentTime = (char *) calloc (MIN_STRING_LENGTH, sizeof (char));
211  sWidthX = (char *) calloc (MIN_STRING_LENGTH, sizeof (char));
212  sWidthY = (char *) calloc (MIN_STRING_LENGTH, sizeof (char));
213 
214  // Get current time/date
215  now = time(NULL);
216  newTime = gmtime (&now);
217  strftime (currentTime, MIN_STRING_LENGTH, "%a %d %b %Y at %H:%M:%S", newTime);
218 
219  // Read the name of the first file in the list and get it's full path name
220  fgets (stringTemp, MAX_STRING_LENGTH, inFitsBatchPtr);
221  sprintf (classification, "%s", "");
222  sscanf (stringTemp, "%s%s", fileNames->inFitsName, classification);
223 
224  // Copy primary header from the raw file to the output header
225  outFitsHeader = qfits_header_read (fileNames->inFitsName);
226  if (outFitsHeader == NULL)
227  {
228  *error = 1;
229  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot load header from the input FITS file");
230  free (messageBuffer);
231  free (currentTime);
232  free (cleanString);
233  free (stringTemp);
234  free (classification);
235  free (textBuff);
236  free (sWidthX);
237  free (sWidthY);
238  return;
239  }
240 
241  // Write all NAXIS values as character strings
242  sprintf (sWidthY, "%d", arraySize);
243  sprintf (sWidthX, "%d", arraySize);
244 
245  // Updates header for the DetRon output file
246  qfits_header_mod (outFitsHeader, "BITPIX", "-32", "number of bits per pixel");
247  qfits_header_mod (outFitsHeader, "NAXIS", "2", "number of data axes");
248  qfits_header_add (outFitsHeader, "NAXIS1", sWidthX, "", NULL);
249  qfits_header_add (outFitsHeader, "NAXIS2", sWidthY, "", NULL);
250  qfits_header_mod (outFitsHeader, "INSTRUME", "MIDI", "MIDI Raw Data Display FITS created by DRS pipeline" );
251 
252  // Now write all the required product keaywords to the output header
253  // -----------------------------------------------------------------
254  qfits_header_add (outFitsHeader, "HIERARCH ESO PRO TYPE", format->obsType, "MIDI pipeline product type", NULL);
255  qfits_header_add (outFitsHeader, "HIERARCH ESO PRO CATG", "REDUCED_DSPTRN", "Pipeline product category", NULL);
256  qfits_header_add (outFitsHeader, "HIERARCH ESO PRO ARCFILE", fileNames->archFileName, "Arcfile name of first raw file", NULL);
257  qfits_header_add (outFitsHeader, "HIERARCH ESO PRO PIPEDATE", currentTime, "Pipeline run date", "");
258  qfits_header_add (outFitsHeader, "HIERARCH ESO PRO VERSION", MIDI_PIPE_VERSION, "Pipeline version", NULL);
259  qfits_header_add (outFitsHeader, "PIPEFILE", fileNames->pipeFileName, "Pipeline product file name", NULL);
260  qfits_header_add (outFitsHeader, "HIERARCH ESO PRO DID", MIDI_QC_DIC_VERSION, "QC dictionary version", NULL);
261 
262  // Rewind the list of files
263  rewind (inFitsBatchPtr);
264 
265  // Loop through the list of files and write into the primary header
266  i = 0;
267  while (fgets (stringTemp, MAX_STRING_LENGTH, inFitsBatchPtr) != NULL)
268  {
269  sprintf (classification, "%s", "");
270  sscanf (stringTemp, "%s%s", messageBuffer, classification);
271 
272  // Get Technique
273  stringQfits = qfits_query_hdr (messageBuffer, "HIERARCH ESO DPR TECH");
274  if (stringQfits == NULL)
275  {
276  sprintf (tech, "%s", "UNKNOWN");
277  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot get Observation Technique");
278  }
279  else
280  {
281  cleanUpString (stringQfits, cleanString);
282  sprintf (tech, "%s", cleanString);
283  }
284 
285  // If classification is not given get it from the raw file
286  if (strcmp (classification, "") == 0)
287  {
288  stringQfits = qfits_query_hdr (messageBuffer, "HIERARCH ESO DPR CATG");
289  if (stringQfits == NULL)
290  {
291  sprintf (classification, "%s", "UNKNOWN");
292  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot get Observation Category");
293  }
294  else
295  {
296  cleanUpString (stringQfits, cleanString);
297  sprintf (classification, "%s", cleanString);
298  }
299  }
300  removePathName (messageBuffer, midiReportPtr);
301  sprintf (textBuff, "HIERARCH ESO PRO REC1 RAW%d NAME", i+1);
302  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "FITS file name", "");
303  sprintf (textBuff, "HIERARCH ESO PRO REC1 RAW%d CATG", i+1);
304  qfits_header_add (outFitsHeader, textBuff, classification, "Observation Categoty", "");
305  i++;
306  }
307  fclose (inFitsBatchPtr);
308 
309  // Add Image parameters
310  for (i = 0; i < trans->numOfFiles; i++)
311  {
312  if (strcmp (trans->grismId[i], "OPEN") == 0)
313  {
314  sprintf (messageBuffer, "%s", trans->grismId[i]);
315  sprintf (textBuff, "HIERARCH ESO QC TRN F%d IM NAME", i+1);
316  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "Grism Name", "");
317  sprintf (messageBuffer, "%s", trans->filterName[i]);
318  sprintf (textBuff, "HIERARCH ESO QC TRN F%d IM FIL", i+1);
319  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "Filter Name", "");
320  sprintf (messageBuffer, "%0.2f", trans->target[i].xCoord);
321  sprintf (textBuff, "HIERARCH ESO QC TRN F%d IM X", i+1);
322  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "x coordinate", "");
323  sprintf (messageBuffer, "%0.2f", trans->target[i].yCoord);
324  sprintf (textBuff, "HIERARCH ESO QC TRN F%d IM Y", i+1);
325  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "y coordinate", "");
326  sprintf (messageBuffer, "%0.2f", trans->target[i].dxCoord);
327  sprintf (textBuff, "HIERARCH ESO QC TRN F%d IM DX", i+1);
328  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "Shift x coordinate", "");
329  sprintf (messageBuffer, "%0.2f", trans->target[i].dyCoord);
330  sprintf (textBuff, "HIERARCH ESO QC TRN F%d IM DY", i+1);
331  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "Shift y coordinate", "");
332  sprintf (messageBuffer, "%0.4f", trans->integTime[i]);
333  sprintf (textBuff, "HIERARCH ESO QC TRN F%d IM EXT", i+1);
334  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "Integration time", "");
335  sprintf (messageBuffer, "%0.2f", trans->meanFlux[i]);
336  sprintf (textBuff, "HIERARCH ESO QC TRN F%d IM CNT", i+1);
337  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "Mean flux", "");
338  }
339  else if (strcmp (trans->grismId[i], "GRISM") == 0)
340  {
341  sprintf (messageBuffer, "%s", trans->grismId[i]);
342  sprintf (textBuff, "HIERARCH ESO QC TRN F%d GR NAME", i+1);
343  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "Grism Name", "");
344  sprintf (messageBuffer, "%s", trans->filterName[i]);
345  sprintf (textBuff, "HIERARCH ESO QC TRN F%d GR FIL", i+1);
346  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "Filter Name", "");
347  sprintf (messageBuffer, "%0.2f", trans->target[i].xCoord);
348  sprintf (textBuff, "HIERARCH ESO QC TRN F%d GR X", i+1);
349  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "x coordinate", "");
350  sprintf (messageBuffer, "%0.2f", trans->target[i].yCoord);
351  sprintf (textBuff, "HIERARCH ESO QC TRN F%d GR Y", i+1);
352  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "y coordinate", "");
353  sprintf (messageBuffer, "%0.2f", trans->target[i].dxCoord);
354  sprintf (textBuff, "HIERARCH ESO QC TRN F%d GR DX", i+1);
355  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "Shift x coordinate", "");
356  sprintf (messageBuffer, "%0.2f", trans->target[i].dyCoord);
357  sprintf (textBuff, "HIERARCH ESO QC TRN F%d GR DY", i+1);
358  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "Shift y coordinate", "");
359  sprintf (messageBuffer, "%0.4f", trans->integTime[i]);
360  sprintf (textBuff, "HIERARCH ESO QC TRN F%d GR EXT", i+1);
361  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "Integration time", "");
362  sprintf (messageBuffer, "%0.2f", trans->meanFlux[i]);
363  sprintf (textBuff, "HIERARCH ESO QC TRN F%d GR CNT", i+1);
364  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "Mean flux", "");
365  if (i == 3 || i == 4 || i == 5)
366  {
367  sprintf (messageBuffer, "%0.6f", trans->transmission[i-3]);
368  sprintf (textBuff, "HIERARCH ESO QC TRN F%d GR TRANS", i+1);
369  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "Transmissivity", "");
370  }
371  }
372  else if (strcmp (trans->grismId[i], "PRISM") == 0)
373  {
374  sprintf (messageBuffer, "%s", trans->grismId[i]);
375  sprintf (textBuff, "HIERARCH ESO QC TRN F%d PR NAME", i+1);
376  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "Grism Name", "");
377  sprintf (messageBuffer, "%s", trans->filterName[i]);
378  sprintf (textBuff, "HIERARCH ESO QC TRN F%d PR FIL", i+1);
379  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "Filter Name", "");
380  sprintf (messageBuffer, "%0.2f", trans->target[i].xCoord);
381  sprintf (textBuff, "HIERARCH ESO QC TRN F%d PR X", i+1);
382  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "x coordinate", "");
383  sprintf (messageBuffer, "%0.2f", trans->target[i].yCoord);
384  sprintf (textBuff, "HIERARCH ESO QC TRN F%d PR Y", i+1);
385  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "y coordinate", "");
386  sprintf (messageBuffer, "%0.2f", trans->target[i].dxCoord);
387  sprintf (textBuff, "HIERARCH ESO QC TRN F%d PR DX", i+1);
388  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "Shift x coordinate", "");
389  sprintf (messageBuffer, "%0.2f", trans->target[i].dyCoord);
390  sprintf (textBuff, "HIERARCH ESO QC TRN F%d PR DY", i+1);
391  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "Shift y coordinate", "");
392  sprintf (messageBuffer, "%0.4f", trans->integTime[i]);
393  sprintf (textBuff, "HIERARCH ESO QC TRN F%d PR EXT", i+1);
394  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "Integration time", "");
395  sprintf (messageBuffer, "%0.2f", trans->meanFlux[i]);
396  sprintf (textBuff, "HIERARCH ESO QC TRN F%d PR CNT", i+1);
397  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "Mean flux", "");
398  if (i == 3 || i == 4 || i == 5)
399  {
400  sprintf (messageBuffer, "%0.6f", trans->transmission[i-3]);
401  sprintf (textBuff, "HIERARCH ESO QC TRN F%d PR TRANS", i+1);
402  qfits_header_add (outFitsHeader, textBuff, messageBuffer, "Transmissivity", "");
403  }
404  }
405  }
406 
407  // Place Holders
408  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PLACEH1", "TBD", "TBD", "");
409  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PLACEH2", "TBD", "TBD", "");
410  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PLACEH3", "TBD", "TBD", "");
411  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PLACEH4", "TBD", "TBD", "");
412  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PLACEH5", "TBD", "TBD", "");
413  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PLACEH6", "TBD", "TBD", "");
414  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PLACEH7", "TBD", "TBD", "");
415  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PLACEH8", "TBD", "TBD", "");
416  qfits_header_add (outFitsHeader, "HIERARCH ESO QC PLACEH9", "TBD", "TBD", "");
417 
418  // Create the output fits file. If the file exist delete it
419  if (stat (fileNames->outFitsName, &buf) == 0) remove (fileNames->outFitsName);
420 
421  outFitsPtr = fopen (fileNames->outFitsName, "w");
422  if (!outFitsPtr)
423  {
424  *error = 1;
425  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot create output FITS file");
426  free (messageBuffer);
427  free (currentTime);
428  free (cleanString);
429  free (stringTemp);
430  free (classification);
431  free (textBuff);
432  free (sWidthX);
433  free (sWidthY);
434  return;
435  }
436 
437  cpl_msg_info(cpl_func,"Created Product FITS file: %s \n", fileNames->outFitsName);
438  fprintf (midiReportPtr, "Created Product FITS file: %s \n", fileNames->outFitsName);
439 
440  // Write header into the output file
441  qfits_header_sort (&outFitsHeader);
442  qfits_header_dump (outFitsHeader, outFitsPtr);
443  fclose (outFitsPtr);
444  qfits_header_destroy (outFitsHeader);
445 
446  // release memory
447  free (messageBuffer);
448  free (currentTime);
449  free (cleanString);
450  free (stringTemp);
451  free (classification);
452  free (tech);
453  free (textBuff);
454  free (sWidthX);
455  free (sWidthY);
456 
457  return;
458 }
459 /*****************************************************************************/
460 
461 
462 /******************************************************************************
463 * European Southern Observatory
464 * VLTI MIDI Data Reduction Software
465 *
466 * Module name: createDspTrnQcLog
467 * Input/Output: See function arguments to avoid duplication
468 * Description: Copies keywords from the raw input FITS primary header to the
469 * QC log and adds additional product keywords
470 *
471 * History:
472 * 30-Aug-04 (csabet) Created
473 ******************************************************************************/
474 void createDspTrnQcLog (
475  char *inFitsName,
476  int *error)
477 
478 {
479 
480  /* Local Declarations
481  --------------------*/
482  const char routine[] = "createDspTrnQcLog";
483  char *qfitsString, *emptyString, *cleanString;
484 
485  /* Algorithm
486  -----------*/
487  if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking routine '%s' \n", routine);
488  if (diagnostic > 4) fprintf(midiReportPtr, "Invoking routine '%s' \n", routine);
489 
490  /* Reset status */
491  *error = 0;
492 
493  /* Allocate memory */
494  emptyString = (char *) calloc (MIN_STRING_LENGTH, sizeof (char));
495  cleanString = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
496 
497  /* Initialise empty string */
498  strcpy (emptyString, "\"UNKNOWN\"");
499 
500  /* Get all the keywords */
501  qfitsString = qfits_query_hdr (inFitsName, "ARCFILE");
502  if (qfitsString == NULL)
503  fprintf (midiQcLogPtr, "ARCFILE %s \n", emptyString);
504  else {cleanUpString (qfitsString, cleanString);
505  fprintf (midiQcLogPtr, "ARCFILE \"%s\" \n", cleanString);}
506 
507  qfitsString = qfits_query_hdr (inFitsName, "TELESCOP");
508  if (qfitsString == NULL)
509  fprintf (midiQcLogPtr, "TELESCOP %s \n", emptyString);
510  else {cleanUpString (qfitsString, cleanString);
511  fprintf (midiQcLogPtr, "TELESCOP \"%s\" \n", cleanString);}
512 
513  qfitsString = qfits_query_hdr (inFitsName, "INSTRUME");
514  if (qfitsString == NULL)
515  fprintf (midiQcLogPtr, "INSTRUME %s \n", emptyString);
516  else {cleanUpString (qfitsString, cleanString);
517  fprintf (midiQcLogPtr, "INSTRUME \"%s\" \n", cleanString);}
518 
519  qfitsString = qfits_query_hdr (inFitsName, "MJD-OBS");
520  if (qfitsString == NULL)
521  fprintf (midiQcLogPtr, "MJD-OBS %s \n", emptyString);
522  else {cleanUpString (qfitsString, cleanString);
523  fprintf (midiQcLogPtr, "MJD-OBS \"%s\" \n", cleanString);}
524 
525  qfitsString = qfits_query_hdr (inFitsName, "DATE-OBS");
526  if (qfitsString == NULL)
527  fprintf (midiQcLogPtr, "DATE-OBS %s \n", emptyString);
528  else {cleanUpString (qfitsString, cleanString);
529  fprintf (midiQcLogPtr, "DATE-OBS \"%s\" \n", cleanString);}
530 
531  qfitsString = qfits_query_hdr (inFitsName, "UTC");
532  if (qfitsString == NULL)
533  fprintf (midiQcLogPtr, "UTC %s \n", emptyString);
534  else {cleanUpString (qfitsString, cleanString);
535  fprintf (midiQcLogPtr, "UTC %s \n", cleanString);}
536 
537  qfitsString = qfits_query_hdr (inFitsName, "LST");
538  if (qfitsString == NULL)
539  fprintf (midiQcLogPtr, "LST %s \n", emptyString);
540  else {cleanUpString (qfitsString, cleanString);
541  fprintf (midiQcLogPtr, "LST %s \n", cleanString);}
542 
543  qfitsString = qfits_query_hdr (inFitsName, "HIERARCH ESO DET CHIP NX");
544  if (qfitsString == NULL)
545  fprintf (midiQcLogPtr, "DET.CHIP.NX %s \n", emptyString);
546  else {cleanUpString (qfitsString, cleanString);
547  fprintf (midiQcLogPtr, "DET.CHIP.NX %s \n", cleanString);}
548 
549  qfitsString = qfits_query_hdr (inFitsName, "HIERARCH ESO DET CHIP NY");
550  if (qfitsString == NULL)
551  fprintf (midiQcLogPtr, "DET.CHIP.NY %s \n", emptyString);
552  else {cleanUpString (qfitsString, cleanString);
553  fprintf (midiQcLogPtr, "DET.CHIP.NY %s \n", cleanString);}
554 
555  qfitsString = qfits_query_hdr (inFitsName, "HIERARCH ESO DET DIT");
556  if (qfitsString == NULL)
557  fprintf (midiQcLogPtr, "DET.DIT %s \n", emptyString);
558  else {cleanUpString (qfitsString, cleanString);
559  fprintf (midiQcLogPtr, "DET.DIT %s \n", cleanString);}
560 
561  qfitsString = qfits_query_hdr (inFitsName, "HIERARCH ESO DET DITDELAY");
562  if (qfitsString == NULL)
563  fprintf (midiQcLogPtr, "DET.DITDELAY %s \n", emptyString);
564  else {cleanUpString (qfitsString, cleanString);
565  fprintf (midiQcLogPtr, "DET.DITDELAY %s \n", cleanString);}
566 
567  qfitsString = qfits_query_hdr (inFitsName, "HIERARCH ESO DET INT MODE");
568  if (qfitsString == NULL)
569  fprintf (midiQcLogPtr, "DET.INT.MODE %s \n", emptyString);
570  else {cleanUpString (qfitsString, cleanString);
571  fprintf (midiQcLogPtr, "DET.INT.MODE \"%s\" \n", cleanString);}
572 
573  qfitsString = qfits_query_hdr (inFitsName, "HIERARCH ESO DET NDIT");
574  if (qfitsString == NULL)
575  fprintf (midiQcLogPtr, "DET.NDIT %s \n", emptyString);
576  else {cleanUpString (qfitsString, cleanString);
577  fprintf (midiQcLogPtr, "DET.NDIT %s \n", cleanString);}
578 
579  qfitsString = qfits_query_hdr (inFitsName, "HIERARCH ESO DET NRTS MODE");
580  if (qfitsString == NULL)
581  fprintf (midiQcLogPtr, "DET.NRTS.MODE %s \n", emptyString);
582  else {cleanUpString (qfitsString, cleanString);
583  fprintf (midiQcLogPtr, "DET.NRTS.MODE \"%s\" \n", cleanString);}
584 
585  qfitsString = qfits_query_hdr (inFitsName, "HIERARCH ESO DET WIN1 NX");
586  if (qfitsString == NULL)
587  fprintf (midiQcLogPtr, "DET.WIN1.NX %s \n", emptyString);
588  else {cleanUpString (qfitsString, cleanString);
589  fprintf (midiQcLogPtr, "DET.WIN1.NX %s \n", cleanString);}
590 
591  qfitsString = qfits_query_hdr (inFitsName, "HIERARCH ESO DET WIN1 NY");
592  if (qfitsString == NULL)
593  fprintf (midiQcLogPtr, "DET.WIN1.NY %s \n", emptyString);
594  else {cleanUpString (qfitsString, cleanString);
595  fprintf (midiQcLogPtr, "DET.WIN1.NY %s \n", cleanString);}
596 
597  qfitsString = qfits_query_hdr (inFitsName, "HIERARCH ESO DET WIN2 NX");
598  if (qfitsString == NULL)
599  fprintf (midiQcLogPtr, "DET.WIN2.NX %s \n", emptyString);
600  else {cleanUpString (qfitsString, cleanString);
601  fprintf (midiQcLogPtr, "DET.WIN2.NX %s \n", cleanString);}
602 
603  qfitsString = qfits_query_hdr (inFitsName, "HIERARCH ESO DET WIN2 NY");
604  if (qfitsString == NULL)
605  fprintf (midiQcLogPtr, "DET.WIN2.NY %s \n", emptyString);
606  else {cleanUpString (qfitsString, cleanString);
607  fprintf (midiQcLogPtr, "DET.WIN2.NY %s \n", cleanString);}
608 
609  qfitsString = qfits_query_hdr (inFitsName, "HIERARCH ESO DPR CATG");
610  if (qfitsString == NULL)
611  fprintf (midiQcLogPtr, "DPR.CATG %s \n", emptyString);
612  else {cleanUpString (qfitsString, cleanString);
613  fprintf (midiQcLogPtr, "DPR.CATG \"%s\" \n", cleanString);}
614 
615  qfitsString = qfits_query_hdr (inFitsName, "HIERARCH ESO DPR TECH");
616  if (qfitsString == NULL)
617  fprintf (midiQcLogPtr, "DPR.TECH %s \n", emptyString);
618  else {cleanUpString (qfitsString, cleanString);
619  fprintf (midiQcLogPtr, "DPR.TECH \"%s\" \n", cleanString);}
620 
621  qfitsString = qfits_query_hdr (inFitsName, "HIERARCH ESO DPR TYPE");
622  if (qfitsString == NULL)
623  fprintf (midiQcLogPtr, "DPR.TYPE %s \n", emptyString);
624  else {cleanUpString (qfitsString, cleanString);
625  fprintf (midiQcLogPtr, "DPR.TYPE \"%s\" \n", cleanString);}
626 
627  qfitsString = qfits_query_hdr (inFitsName, "HIERARCH ESO INS CAM NAME");
628  if (qfitsString == NULL)
629  fprintf (midiQcLogPtr, "INS.CAM.NAME %s \n", emptyString);
630  else {cleanUpString (qfitsString, cleanString);
631  fprintf (midiQcLogPtr, "INS.CAM.NAME \"%s\" \n", cleanString);}
632 
633  qfitsString = qfits_query_hdr (inFitsName, "HIERARCH ESO INS FIL NAME");
634  if (qfitsString == NULL)
635  fprintf (midiQcLogPtr, "INS.FILT.NAME %s \n", emptyString);
636  else {cleanUpString (qfitsString, cleanString);
637  fprintf (midiQcLogPtr, "INS.FILT.NAME \"%s\" \n", cleanString);}
638 
639  qfitsString = qfits_query_hdr (inFitsName, "HIERARCH ESO INS GRIS NAME");
640  if (qfitsString == NULL)
641  fprintf (midiQcLogPtr, "INS.GRIS.NAME %s \n", emptyString);
642  else {cleanUpString (qfitsString, cleanString);
643  fprintf (midiQcLogPtr, "INS.GRIS.NAME \"%s\" \n", cleanString);}
644 
645  qfitsString = qfits_query_hdr (inFitsName, "HIERARCH ESO INS MODE");
646  if (qfitsString == NULL)
647  fprintf (midiQcLogPtr, "INS.MODE %s \n", emptyString);
648  else {cleanUpString (qfitsString, cleanString);
649  fprintf (midiQcLogPtr, "INS.MODE \"%s\" \n", cleanString);}
650 
651  qfitsString = qfits_query_hdr (inFitsName, "HIERARCH ESO INS OPT1 NAME");
652  if (qfitsString == NULL)
653  fprintf (midiQcLogPtr, "INS.OPT1.NAME %s \n", emptyString);
654  else {cleanUpString (qfitsString, cleanString);
655  fprintf (midiQcLogPtr, "INS.OPT1.NAME \"%s\" \n", cleanString);}
656 
657  qfitsString = qfits_query_hdr (inFitsName, "HIERARCH ESO INS OPT1 TYPE");
658  if (qfitsString == NULL)
659  fprintf (midiQcLogPtr, "INS.OPT1.TYPE %s \n", emptyString);
660  else {cleanUpString (qfitsString, cleanString);
661  fprintf (midiQcLogPtr, "INS.OPT1.TYPE \"%s\" \n", cleanString);}
662 
663  qfitsString = qfits_query_hdr (inFitsName, "HIERARCH ESO INS SHUT NAME");
664  if (qfitsString == NULL)
665  fprintf (midiQcLogPtr, "INS.SHUT.NAME %s \n", emptyString);
666  else {cleanUpString (qfitsString, cleanString);
667  fprintf (midiQcLogPtr, "INS.SHUT.NAME \"%s\" \n", cleanString);}
668 
669  qfitsString = qfits_query_hdr (inFitsName, "HIERARCH ESO INS SLIT NAME");
670  if (qfitsString == NULL)
671  fprintf (midiQcLogPtr, "INS.SLIT.NAME %s \n", emptyString);
672  else {cleanUpString (qfitsString, cleanString);
673  fprintf (midiQcLogPtr, "INS.SLIT.NAME \"%s\" \n", cleanString);}
674 
675  qfitsString = qfits_query_hdr (inFitsName, "HIERARCH ESO OBS ID");
676  if (qfitsString == NULL)
677  fprintf (midiQcLogPtr, "OBS.ID %s \n", emptyString);
678  else {cleanUpString (qfitsString, cleanString);
679  fprintf (midiQcLogPtr, "OBS.ID \"%s\" \n", cleanString);}
680 
681  qfitsString = qfits_query_hdr (inFitsName, "HIERARCH ESO OBS NAME");
682  if (qfitsString == NULL)
683  fprintf (midiQcLogPtr, "OBS.NAME %s \n", emptyString);
684  else {cleanUpString (qfitsString, cleanString);
685  fprintf (midiQcLogPtr, "OBS.NAME \"%s\" \n", cleanString);}
686 
687  qfitsString = qfits_query_hdr (inFitsName, "HIERARCH ESO OBS PI-COI ID");
688  if (qfitsString == NULL)
689  fprintf (midiQcLogPtr, "OBS.PI-COI.ID %s \n", emptyString);
690  else {cleanUpString (qfitsString, cleanString);
691  fprintf (midiQcLogPtr, "OBS.PI-COI.ID \"%s\" \n", cleanString);}
692 
693  qfitsString = qfits_query_hdr (inFitsName, "HIERARCH ESO OBS PI-COI NAME");
694  if (qfitsString == NULL)
695  fprintf (midiQcLogPtr, "OBS.PI-COI.NAME %s \n", emptyString);
696  else {cleanUpString (qfitsString, cleanString);
697  fprintf (midiQcLogPtr, "OBS.PI-COI.NAME \"%s\" \n", cleanString);}
698 
699  qfitsString = qfits_query_hdr (inFitsName, "HIERARCH ESO OBS PROG ID");
700  if (qfitsString == NULL)
701  fprintf (midiQcLogPtr, "OBS.PROG.ID %s \n", emptyString);
702  else {cleanUpString (qfitsString, cleanString);
703  fprintf (midiQcLogPtr, "OBS.PROG.ID \"%s\" \n", cleanString);}
704 
705  qfitsString = qfits_query_hdr (inFitsName, "HIERARCH ESO OBS START");
706  if (qfitsString == NULL)
707  fprintf (midiQcLogPtr, "OBS.START %s \n", emptyString);
708  else {cleanUpString (qfitsString, cleanString);
709  fprintf (midiQcLogPtr, "OBS.START \"%s\" \n", cleanString);}
710 
711  qfitsString = qfits_query_hdr (inFitsName, "HIERARCH ESO OBS TARG NAME");
712  if (qfitsString == NULL)
713  fprintf (midiQcLogPtr, "OBS.TARG.NAME %s \n", emptyString);
714  else {cleanUpString (qfitsString, cleanString);
715  fprintf (midiQcLogPtr, "OBS.TARG.NAME \"%s\" \n", cleanString);}
716 
717  qfitsString = qfits_query_hdr (inFitsName, "HIERARCH ESO OCS EXPO1 FNAME1");
718  if (qfitsString == NULL)
719  fprintf (midiQcLogPtr, "OCS.EXPO1.FNAME1 %s \n", emptyString);
720  else {cleanUpString (qfitsString, cleanString);
721  fprintf (midiQcLogPtr, "OCS.EXPO1.FNAME1 \"%s\" \n", cleanString);}
722 
723  qfitsString = qfits_query_hdr (inFitsName, "HIERARCH ESO TPL ID");
724  if (qfitsString == NULL)
725  fprintf (midiQcLogPtr, "TPL.ID %s \n", emptyString);
726  else {cleanUpString (qfitsString, cleanString);
727  fprintf (midiQcLogPtr, "TPL.ID \"%s\" \n", cleanString);}
728 
729  qfitsString = qfits_query_hdr (inFitsName, "HIERARCH ESO TPL START");
730  if (qfitsString == NULL)
731  fprintf (midiQcLogPtr, "TPL.START %s \n", emptyString);
732  else {cleanUpString (qfitsString, cleanString);
733  fprintf (midiQcLogPtr, "TPL.START \"%s\" \n", cleanString);}
734 
735 
736  /* Release memory */
737  free (emptyString);
738  free (cleanString);
739 
740  return;
741 }
742 /*****************************************************************************/
743 
744 
745 
746 /******************************************************************************
747 * European Southern Observatory
748 * VLTI MIDI Data Reduction Software
749 *
750 * Module name: addProdInfoToDspTrnQcLog
751 * Input/Output: See function arguments to avoid duplication
752 * Description: Adds product information to QC log
753 *
754 *
755 * History:
756 * 16-Jan-04 (csabet) Created
757 ******************************************************************************/
758 void addProdInfoToDspTrnQcLog (
759  ImageFormat *format, // In: Image format
760  MidiFiles *fileNames,
761  DispersiveTrans *trans,// In: Dispersive transmission data structure
762  int *error)
763 {
764 
765  /* Local Declarations
766  --------------------*/
767  const char routine[] = "addProdInfoToDspTrnQcLog";
768  int i;
769  FILE *inFitsBatchPtr;
770  char *stringQfits, *messageBuffer, *currentTime, *textBuff, *cleanString,
771  *stringTemp, *classification;
772  time_t now;
773  struct tm *newTime;
774 
775  /* Algorithm
776  -----------*/
777  if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking routine '%s' \n", routine);
778  if (diagnostic > 4) fprintf (midiReportPtr, "Invoking routine '%s' \n", routine);
779 
780  /* Reset parameters */
781  *error = 0;
782 
783  /* Allocate memory */
784  classification = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
785  stringTemp = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
786  cleanString = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
787  textBuff = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
788  messageBuffer = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
789  currentTime = (char *) calloc (MIN_STRING_LENGTH, sizeof (char));
790 
791  /* Get current time/date */
792  now = time(NULL);
793  newTime = gmtime (&now);
794  strftime (currentTime, MIN_STRING_LENGTH, "%a %d %b %Y at %H:%M:%S", newTime);
795 
796  // Add keyword to QC log file
797  fprintf (midiQcLogPtr, "PRO.TYPE \"%s\" \n", format->obsType);
798  fprintf (midiQcLogPtr, "PRO.CATG \"REDUCED_DSPTRN\" \n");
799  fprintf (midiQcLogPtr, "PRO.ARCFILE \"%s\" \n", fileNames->archFileName);
800  fprintf (midiQcLogPtr, "PRO.PIPEDATE \"%s\" \n", currentTime);
801  fprintf (midiQcLogPtr, "PRO.VERSION \"%s\" \n", MIDI_PIPE_VERSION);
802  fprintf (midiQcLogPtr, "PRO.PIPEFILE \"%s\" \n", fileNames->pipeFileName);
803  fprintf (midiQcLogPtr, "PRO.DID \"%s\" \n", MIDI_QC_DIC_VERSION);
804 
805  /* Open the list of files */
806  if ((inFitsBatchPtr = fopen (fileNames->inFitsBatch, "r")) == NULL)
807  {
808  *error = 1;
809  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot open input FITS file list");
810  free (messageBuffer);
811  free (currentTime);
812  free (cleanString);
813  free (stringTemp);
814  free (classification);
815  free (textBuff);
816  return;
817  }
818 
819  /* Loop through the list of files and write into the QC log */
820  i = 1;
821  while (fgets (stringTemp, MAX_STRING_LENGTH, inFitsBatchPtr) != NULL)
822  {
823  sprintf (classification, "%s", "");
824  sscanf (stringTemp, "%s%s", messageBuffer, classification);
825 
826  /* If classification is not given get it from the raw file */
827  if (strcmp (classification, "") == 0)
828  {
829  stringQfits = qfits_query_hdr (messageBuffer, "HIERARCH ESO DPR CATG");
830  if (stringQfits == NULL)
831  {
832  sprintf (classification, "%s", "UNKNOWN");
833  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot get Observation Category");
834  }
835  else
836  {
837  cleanUpString (stringQfits, cleanString);
838  sprintf (classification, "%s", cleanString);
839  }
840  }
841  removePathName (messageBuffer, midiReportPtr);
842  fprintf (midiQcLogPtr, "PRO.REC1.RAW%d.NAME \"%s\" \n", i, messageBuffer);
843  fprintf (midiQcLogPtr, "PRO.REC1.RAW%d.CATG \"%s\" \n", i++, classification);
844  }
845  fclose (inFitsBatchPtr);
846 
847  for (i = 0; i < trans->numOfFiles; i++)
848  {
849  if (strcmp (trans->grismId[i], "OPEN") == 0)
850  {
851  fprintf (midiQcLogPtr, "QC.TRN.F%d.IM.NAME \"%s\" \n", i+1, trans->grismId[i]);
852  fprintf (midiQcLogPtr, "QC.TRN.F%d.IM.FIL \"%s\" \n", i+1, trans->filterName[i]);
853  fprintf (midiQcLogPtr, "QC.TRN.F%d.IM.X %0.2f \n", i+1, trans->target[i].xCoord);
854  fprintf (midiQcLogPtr, "QC.TRN.F%d.IM.Y %0.2f \n", i+1, trans->target[i].yCoord);
855  fprintf (midiQcLogPtr, "QC.TRN.F%d.IM.DX %0.2f \n", i+1, trans->target[i].dxCoord);
856  fprintf (midiQcLogPtr, "QC.TRN.F%d.IM.DY %0.2f \n", i+1, trans->target[i].dyCoord);
857  fprintf (midiQcLogPtr, "QC.TRN.F%d.IM.EXT %0.4f \n", i+1, trans->integTime[i]);
858  fprintf (midiQcLogPtr, "QC.TRN.F%d.IM.CNT %0.2f \n", i+1, trans->meanFlux[i]);
859  }
860  else if (strcmp (trans->grismId[i], "PRISM") == 0)
861  {
862  fprintf (midiQcLogPtr, "QC.TRN.F%d.PR.NAME \"%s\" \n", i+1, trans->grismId[i]);
863  fprintf (midiQcLogPtr, "QC.TRN.F%d.PR.FIL \"%s\" \n", i+1, trans->filterName[i]);
864  fprintf (midiQcLogPtr, "QC.TRN.F%d.PR.X %0.2f \n", i+1, trans->target[i].xCoord);
865  fprintf (midiQcLogPtr, "QC.TRN.F%d.PR.Y %0.2f \n", i+1, trans->target[i].yCoord);
866  fprintf (midiQcLogPtr, "QC.TRN.F%d.PR.DX %0.2f \n", i+1, trans->target[i].dxCoord);
867  fprintf (midiQcLogPtr, "QC.TRN.F%d.PR.DY %0.2f \n", i+1, trans->target[i].dyCoord);
868  fprintf (midiQcLogPtr, "QC.TRN.F%d.PR.EXT %0.4f \n", i+1, trans->integTime[i]);
869  fprintf (midiQcLogPtr, "QC.TRN.F%d.PR.CNT %0.2f \n", i+1, trans->meanFlux[i]);
870  if (i == 3 || i == 4 || i == 5)
871  fprintf (midiQcLogPtr, "QC.TRN.F%d.PR.TRANS %0.6f \n", i+1, trans->transmission[i-3]);
872  }
873  else if (strcmp (trans->grismId[i], "GRISM") == 0)
874  {
875  fprintf (midiQcLogPtr, "QC.TRN.F%d.GR.NAME \"%s\" \n", i+1, trans->grismId[i]);
876  fprintf (midiQcLogPtr, "QC.TRN.F%d.GR.FIL \"%s\" \n", i+1, trans->filterName[i]);
877  fprintf (midiQcLogPtr, "QC.TRN.F%d.GR.X %0.2f \n", i+1, trans->target[i].xCoord);
878  fprintf (midiQcLogPtr, "QC.TRN.F%d.GR.Y %0.2f \n", i+1, trans->target[i].yCoord);
879  fprintf (midiQcLogPtr, "QC.TRN.F%d.GR.DX %0.2f \n", i+1, trans->target[i].dxCoord);
880  fprintf (midiQcLogPtr, "QC.TRN.F%d.GR.DY %0.2f \n", i+1, trans->target[i].dyCoord);
881  fprintf (midiQcLogPtr, "QC.TRN.F%d.GR.EXT %0.4f \n", i+1, trans->integTime[i]);
882  fprintf (midiQcLogPtr, "QC.TRN.F%d.GR.CNT %0.2f \n", i+1, trans->meanFlux[i]);
883  if (i == 3 || i == 4 || i == 5)
884  fprintf (midiQcLogPtr, "QC.TRN.F%d.GR.TRANS %0.6f \n", i+1, trans->transmission[i-3]);
885  }
886  else
887  {
888  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Unknown Dispersive element");
889  *error = 1;
890  free (messageBuffer);
891  free (currentTime);
892  free (cleanString);
893  free (stringTemp);
894  free (classification);
895  free (textBuff);
896  return;
897  }
898  }
899 
900  /* release memory */
901  free (messageBuffer);
902  free (currentTime);
903  free (textBuff);
904  free (cleanString);
905  free (stringTemp);
906  free (classification);
907 
908  return;
909 }
910 /*****************************************************************************/
911