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