MIDI Pipeline Reference Manual  2.8.3
transferFunction.c
1 /******************************************************************************
2 *******************************************************************************
3 * European Southern Observatory
4 * VLTI MIDI Data Reduction Software
5 *
6 * Module name: transferFunction.c
7 * Description: Contains routines for all transfer function routines
8 *
9 * History:
10 * 21-Jul-03 (csabet) Created
11 *******************************************************************************
12 ******************************************************************************/
13 
14 /******************************************************************************
15 * Compiler directives
16 ******************************************************************************/
17 #define NEW_PBL_x
18 
19 /******************************************************************************
20 * Include files
21 ******************************************************************************/
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <unistd.h>
25 #include <stdio.h>
26 #include <cpl.h>
27 #include <string.h>
28 #include <math.h>
29 #include "midiGlobal.h"
30 #include "midiLib.h"
31 #include "qfits.h"
32 #include "errorHandling.h"
33 #include "diagnostics.h"
34 #include "fileHandling.h"
35 #include "transferFunction.h"
36 #include "midi_dfs.h"
37 
38 /**********************************************************
39 * Constant definitions
40 **********************************************************/
41 #define START_MIDI_RECORD (173) /* Start line for MIDI record in the calibrator database */
42 #define END_MIDI_RECORD (620) /* End line for MIDI record in the calibrator database */
43 #define CALIB_DB_LEN (30) /* Maximum length of each elements in the calibrator database */
44 #define UNWANTED_ELEMENTS (27) /* Number of unwanted elements in the calibrator database */
45 #define CALIBRATOR_MIN_THRESHOLD (0.000290888) /* Minimum threshold for finding diameter in radians (60 arcsec) */
46 #define DIAMETER_FACTOR (4.848136958e-9) /* Diameter factor = (1.0 / (1000 * 206264.8)) */
47 #define INVERSE_WAVELENGTH (100000.0) /* Inverse Effective wavelength = (1.0 / 10 micron) */
48 
49 /*============================ C O D E A R E A ===========================*/
50 
51 
52 
53 /******************************************************************************
54 * European Southern Observatory
55 * VLTI MIDI Data Reduction Software
56 *
57 * Module name: estimateTransferFunction
58 * Input/Output: See function arguments to avoid duplication
59 * Description: This routine computes the transfer fuction as follows: If the current
60 * observation category is CALIB then the estimate of the uncalibrated
61 * visibility has already been calculated and is given as an input to
62 * this routine. Here we calculate the expected visibility and thereby
63 * the transfer function. The ASCCI file containing the transfer function
64 * is shown below where the first line gives the number of regions and the
65 * subsequent lines give the transfer functions and the errors for each channel
66 *
67 * Record 1 Grism ID
68 * Record 2 Number of Record
69 * Record 3 number_of_combined_regions
70 * Record 4 value_1 value_1_Err ... Value_n value_n_Error
71 * .
72 * .
73 * Record n value_1 value_1_Err ... Value_n value_n_Error
74 *
75 * History:
76 * 07-Feb-05 (csabet) Created
77 ******************************************************************************/
78 void estimateTransferFunction (
79  ImageFormat *formatInterf, // In: Image size of interferometry data
80  MidiFiles *fileNames, // In: Pointer to MIDI file structure
81  DispersedResult *dispResult, // IO: Dispersed result structure
82  CalibratorParam *calibrator, // Ou: Calibrator parameters
83  int *error, // Ou: Error Status
84  cpl_parameterlist *parlist,
85  cpl_frameset *frameset)
86 {
87 
88  // Local Declarations
89  // ------------------
90  const char routine[] = "estimateTransferFunction";
91  FILE * trfPtr, *trfHistoryPtr;
92  int X;
93  struct stat buf;
94  cpl_table * trftable=NULL;
95  cpl_propertylist * qclist=NULL;
96  char * dataname=NULL;
97  char * system_call=NULL;
98 
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,"\nComputing Transfer Functions for batch %d \n", batchNumber);
106  cpl_msg_info(cpl_func,"-------------------------------------- \n");
107  fprintf (midiReportPtr, "\nComputing Transfer Functions for batch %d \n", batchNumber);
108  fprintf (midiReportPtr, "-------------------------------------- \n");
109 
110  // Reset status
111  *error = 0;
112  dispResult->trfExists = 0;
113 
114  // Check if transfer function file exist. If so delete it
115  if (stat (fileNames->trfNameWrite, &buf) == 0) // If the file exist delete it
116  remove (fileNames->trfNameWrite);
117 
118  identifyCalibrator (fileNames, calibrator, error, parlist, frameset);
119  if (*error)
120  {
121  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot identify Calibrator");
122  return;
123  }
124 
125  computeExpectedVis (calibrator, error);
126  if (*error)
127  {
128  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot compute Expected Visibilities");
129  return;
130  }
131 
132  // Compute Transfer Function
133  if (calibrator->calibVis == 0 || calibrator->calibVisSqrd == 0)
134  {
135  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__,
136  "A singularity encountered\n Cannot compute transfer functions");
137  *error = 1;
138  return;
139  }
140  else
141  {
142  // Open the transfer function file for writing
143  if ((trfPtr = fopen (fileNames->trfNameWrite, "w")) == NULL)
144  {
145  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot open file to store transfer functions");
146  *error = 1;
147  return;
148  }
149 
150  // Open a file for transfer function history
151  trfHistoryPtr = fopen (fileNames->trfHistoryName, "a");
152  fprintf (trfHistoryPtr, "Transfer Functions (DISPERSED) for batch %d \n", batchNumber);
153  fprintf (trfHistoryPtr, "---------------------------------------- \n");
154  fprintf (trfHistoryPtr, "Grism ID = %s \n", formatInterf->grismId);
155  fprintf (trfHistoryPtr, "Number of Valid Channels = %d \n", formatInterf->iXWidth);
156 
157  if (diagnostic)cpl_msg_info(cpl_func,"Grism ID = %s \n", formatInterf->grismId);
158  if (diagnostic)cpl_msg_info(cpl_func,"Number of Channels = %d \n", formatInterf->iXWidth);
159 
160  fprintf (midiReportPtr, "\nTransfer Functions (DISPERSED) for batch %d QCLOG \n", batchNumber);
161  fprintf (midiReportPtr, "---------------------------------------- QCLOG \n");
162  fprintf (midiReportPtr, "Grism ID = %s QCLOG \n", formatInterf->grismId);
163  fprintf (midiReportPtr, "Number of Valid Channels = %d QCLOG \n", formatInterf->iXWidth);
164 
165  fprintf (trfPtr, "%s \n", formatInterf->grismId);
166  fprintf (trfPtr, "%d \n", formatInterf->iXWidth);
167 
168  for (X = 0; X < formatInterf->iXWidth; X++)
169  {
170  if (badChannelList[X])
171  {
172  if (diagnostic)cpl_msg_info(cpl_func,"%3d <-- %s --> \n", X, UNAV);
173  fprintf (midiReportPtr, "%3d <-- %s --> QCLOG \n", X, UNAV);
174  fprintf (trfHistoryPtr, "%3d <-- %s --> \n", X, UNAV);
175  fprintf (trfPtr, "%f %f \n", (dispResult->trf)[X], (dispResult->trfErr)[X]);
176  continue;
177  }
178 
179  dispResult->trf[X] = dispResult->normVis2[X] / calibrator->calibVis;
180  dispResult->trfErr[X] = dispResult->normVis2Err[X] / (fabs (calibrator->calibVis)) +
181  calibrator->calibVisErr * (fabs (dispResult->normVis2[X]) /
182  (calibrator->calibVis * calibrator->calibVis));
183 
184  if (diagnostic)cpl_msg_info(cpl_func,"%3d %f %f \n", X, (dispResult->trf)[X], (dispResult->trfErr)[X]);
185  fprintf (midiReportPtr, "%3d %f %f QCLOG \n", X, (dispResult->trf)[X], (dispResult->trfErr)[X]);
186  fprintf (trfHistoryPtr, "%3d %f %f \n", X, (dispResult->trf)[X], (dispResult->trfErr)[X]);
187  fprintf (trfPtr, "%f %f \n", (dispResult->trf)[X], (dispResult->trfErr)[X]);
188  }
189 
190  fclose (trfPtr);
191  fclose (trfHistoryPtr);
192  if (diagnostic)cpl_msg_info(cpl_func,"Created Transfer Function file %s\n", fileNames->trfNameWrite);
193  fprintf (midiReportPtr, "Created Transfer Function file %s\n", fileNames->trfNameWrite);
194  dispResult->trfExists = 1;
195 
196 /* -------------------------------------------------------------------------- */
197 
198 /* Write transfer function in a fits table */
199  trftable=cpl_table_new(formatInterf->iXWidth);
200  cpl_table_new_column(trftable,"CHANNEL",CPL_TYPE_INT);
201  cpl_table_new_column(trftable,"TRF",CPL_TYPE_FLOAT);
202  cpl_table_new_column(trftable,"TRF_ERROR",CPL_TYPE_FLOAT);
203 
204  for (X = 0; X < formatInterf->iXWidth; X++)
205  {
206  cpl_table_set_int(trftable,"CHANNEL",X, X+1);
207  cpl_table_set_float(trftable,"TRF",X, (dispResult->trf)[X]);
208  cpl_table_set_float(trftable,"TRF_ERROR",X, (dispResult->trfErr)[X]);
209  if (badChannelList[X])
210  {
211  cpl_table_set_invalid(trftable, "TRF", X);
212  cpl_table_set_invalid(trftable, "TRF_ERROR", X);
213  }
214  }
215 
216 
217 /* Save the fits table into a fits file */
218 
219  qclist=cpl_propertylist_new();
220 
221  if (strcmp(formatInterf->grismId,"GRISM")==0) {
222  cpl_propertylist_update_string(qclist, CPL_DFS_PRO_CATG, "TRF_GRISM");
223  dataname=cpl_sprintf("MIDI_trf_grism.fits");
224  }
225  if (strcmp(formatInterf->grismId,"PRISM")==0) {
226  cpl_propertylist_update_string(qclist, CPL_DFS_PRO_CATG, "TRF_PRISM");
227  dataname=cpl_sprintf("MIDI_trf_prism.fits");
228  }
229  cpl_propertylist_append_string(qclist, "EXTNAME", "TRANSFER_FUNCTION");
230 
231 
232  cpl_propertylist_update_float(qclist, "ESO QC OBS CAL RA" , calibrator->calibRA);
233  cpl_propertylist_update_float(qclist, "ESO QC OBS CAL DEC" , calibrator->calibDEC);
234  cpl_propertylist_update_float(qclist, "ESO QC OBS AVR PBL " , calibrator->calibPblAverage);
235  cpl_propertylist_update_float(qclist, "ESO QC OBS AVR PARANG" , calibrator->calibParangAverage);
236  cpl_propertylist_update_string(qclist, "ESO QC DB NAME" , calibrator->calibName);
237  cpl_propertylist_update_float(qclist, "ESO QC DB DIAM" , calibrator->calibDiameter);
238  cpl_propertylist_update_float(qclist, "ESO QC DB DIAM ERR " , calibrator->calibDiameterErr);
239  cpl_propertylist_update_float(qclist, "ESO QC DB DIST" , RAD_TO_ARCSEC * calibrator->calibDistance);
240  cpl_propertylist_update_double(qclist, "ESO QC DB MAG NBAND" , calibrator->calibFlux);
241  cpl_propertylist_update_int (qclist, "ESO QC DB FLAG" , calibrator->calibFlag);
242  cpl_propertylist_update_float(qclist, "ESO QC EXP VIS" , calibrator->calibVis);
243  cpl_propertylist_update_float(qclist, "ESO QC EXP VIS ERR" , calibrator->calibVisErr);
244  cpl_propertylist_update_float(qclist, "ESO QC EXP VIS2" , calibrator->calibVisSqrd);
245  cpl_propertylist_update_float(qclist, "ESO QC EXP VIS2 ERR" , calibrator->calibVisSqrdErr);
246 
247  cpl_propertylist_set_comment (qclist, "ESO QC OBS CAL RA" , "Observed Calibrator RA in radians");
248  cpl_propertylist_set_comment (qclist, "ESO QC OBS CAL DEC" , "Observed Calibrator DEC in radians");
249  cpl_propertylist_set_comment (qclist, "ESO QC OBS AVR PBL " , "Observed Calibrator Average PBL in meter");
250  cpl_propertylist_set_comment (qclist, "ESO QC OBS AVR PARANG" , "Observed Calibrator Average PARANG in degrees");
251  cpl_propertylist_set_comment (qclist, "ESO QC DB NAME" , "Closest Calibrator in the database");
252  cpl_propertylist_set_comment (qclist, "ESO QC DB DIAM" , "Calibrator Diameter in marcsec");
253  cpl_propertylist_set_comment (qclist, "ESO QC DB DIAM ERR " , "Calibrator Diameter error in marcsec");
254  cpl_propertylist_set_comment (qclist, "ESO QC DB DIST" , "Computed Distance to Observed Calibrator in arcsec");
255  cpl_propertylist_set_comment (qclist, "ESO QC DB MAG NBAND" , "Calibrator Magnitude in the N-Band");
256  cpl_propertylist_set_comment (qclist, "ESO QC DB FLAG" , "Calibrator Quality Flag");
257  cpl_propertylist_set_comment (qclist, "ESO QC EXP VIS" , "Expected Visibility");
258  cpl_propertylist_set_comment (qclist, "ESO QC EXP VIS ERR" , "Expected Visibility Error");
259  cpl_propertylist_set_comment (qclist, "ESO QC EXP VIS2" , "Expected Squared Visibility");
260  cpl_propertylist_set_comment (qclist, "ESO QC EXP VIS2 ERR" , "Expected Squared Visibility Error");
261 
262 
263  cpl_dfs_save_table(frameset, NULL, parlist, frameset, NULL, trftable,
264  qclist, "midi_fringe_all",
265  qclist, NULL,
266  PACKAGE "/" PACKAGE_VERSION,
267  dataname);
268 
269  /* Now copy the file to tmp to be able to use the files after the
270  originals are renamed by ESOREX
271  */
272  system_call=cpl_sprintf("cp %s /tmp/MIDI_trf.fits", dataname);
273  cpl_msg_info(cpl_func, "Copying the file into the tmp directory ...");
274  cpl_msg_info(cpl_func,system_call);
275  system(system_call);
276 
277  cpl_table_delete(trftable);
278  cpl_propertylist_delete(qclist);
279  cpl_free(dataname);
280  cpl_free(system_call);
281 
282 
283 
284 /* -------------------------------------------------------------------------- */
285 
286  // Compute Binned Tranfer Function
287  computeBinnedTrf (formatInterf, dispResult, error);
288  if (*error)
289  {
290  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot compute Binned Transfer Function");
291  return;
292  }
293 
294 
295  }
296 
297 
298 
299 
300  if (plotFile && diagnostic)
301  {
302  midiCreatePlotFile2D ("TransferFunctionConbined", "Combined Transfer Function",
303  "Channel", "Transfer Function", 0, dispResult->trf, 0, formatInterf->iXWidth, 1, 0);
304 
305  midiCreatePlotFile2D ("TransferFunctionErrConbined", "Combined Transfer Function",
306  "Channel", "Transfer Function Error", 0, dispResult->trfErr, 0, formatInterf->iXWidth, 1, 0);
307  }
308 
309  return;
310 }
311 /*****************************************************************************/
312 
313 
314 /******************************************************************************
315 * European Southern Observatory
316 * VLTI MIDI Data Reduction Software
317 *
318 * Module name: estimateTransferFunctionUndisp
319 * Input/Output: See function arguments to avoid duplication
320 * Description: This routine computes the transfer fuction as follows: If the current
321 * observation category is CALIB then the estimate of the uncalibrated
322 * visibility has already been calculated and is given as an input to
323 * this routine. Here we calculate the expected visibility and thereby
324 * the transfer function. The ASCCI file containing the transfer function
325 * has the following format:
326 *
327 * transfer function region 0
328 * transfer function region 0 Error
329 * transfer function region 1
330 * transfer function region 1 Error
331 * transfer function region 2
332 * transfer function region 2 Error
333 * transfer function squared region 0
334 * transfer function squared region 0 Error
335 * transfer function squared region 1
336 * transfer function squared region 1 Error
337 * transfer function squared region 2
338 * transfer function squared region 2 Error
339 *
340 * History:
341 * 21-Jul-03 (csabet) Created
342 ******************************************************************************/
343 void estimateTransferFunctionUndisp (
344  MidiFiles *fileNames, // In: Pointer to MIDI file structure
345  RawVisibility *measVis, // In: Measured visibilities
346  TransferFunction *trf, // Ou: Transfer Functions
347  CalibratorParam *calibrator, // Ou: Calibrator parameters
348  int *error, // Ou: Status
349  cpl_parameterlist *parlist,
350  cpl_frameset *frameset)
351 {
352 
353  /* Local Declarations
354  --------------------*/
355  const char routine[] = "estimateTransferFunctionUndisp";
356  FILE *trfPtr;
357  int i;
358  FILE *trfHistoryPtr;
359  struct stat buf;
360 
361  /* Algorithm
362  -----------*/
363  if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking routine '%s' \n", routine);
364  if (diagnostic > 4) fprintf(midiReportPtr, "Invoking routine '%s' \n", routine);
365 
366  cpl_msg_info(cpl_func,"\nComputing Transfer Functions for batch %d \n", batchNumber);
367  cpl_msg_info(cpl_func,"-------------------------------------- \n");
368  fprintf (midiReportPtr, "\nComputing Transfer Functions for batch %d \n", batchNumber);
369  fprintf (midiReportPtr, "-------------------------------------- \n");
370 
371  /* Reset status */
372  *error = 0;
373  trf->exists = 0;
374 
375  /* Check if transfer function file exist. If so delete it */
376  if (stat (fileNames->trfNameWrite, &buf) == 0) /* If the file exist delete it */
377  remove (fileNames->trfNameWrite);
378 
379  identifyCalibrator (fileNames, calibrator, error, parlist, frameset);
380  if (*error)
381  {
382  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot identify Calibrator");
383  return;
384  }
385 
386  computeExpectedVis (calibrator, error);
387  if (*error)
388  {
389  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot compute Expected Visibilities");
390  return;
391  }
392 
393  /* Compute Transfer Function */
394  if (calibrator->calibVis == 0 || calibrator->calibVisSqrd == 0)
395  {
396  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__,
397  "A singularity encountered. Cannot compute transfer functions");
398  *error = 1;
399  return;
400  }
401  else
402  {
403  trf->trf[0] = measVis->vis / calibrator->calibVis;
404  trf->trfErr[0] = measVis->visErr / (fabs (calibrator->calibVis)) +
405  calibrator->calibVisErr * (fabs (measVis->vis) / (calibrator->calibVis * calibrator->calibVis));
406 
407  trf->trf[1] = measVis->vis1 / calibrator->calibVis;
408  trf->trfErr[1] = measVis->vis1Err / (fabs (calibrator->calibVis)) +
409  calibrator->calibVisErr * (fabs (measVis->vis1) / (calibrator->calibVis * calibrator->calibVis));
410 
411  trf->trf[2] = measVis->vis2 / calibrator->calibVis;
412  trf->trfErr[2] = measVis->vis2Err / (fabs (calibrator->calibVis)) +
413  calibrator->calibVisErr * (fabs (measVis->vis2) / (calibrator->calibVis * calibrator->calibVis));
414 
415  trf->trf[3] = measVis->visSqrd / calibrator->calibVisSqrd;
416  trf->trfErr[3] = measVis->visSqrdErr / (fabs (calibrator->calibVisSqrd)) +
417  calibrator->calibVisSqrdErr * (fabs (measVis->visSqrd) / (calibrator->calibVisSqrd * calibrator->calibVisSqrd));
418 
419  trf->trf[4] = measVis->visSqrd1 / calibrator->calibVisSqrd;
420  trf->trfErr[4] = measVis->visSqrd1Err / (fabs (calibrator->calibVisSqrd)) +
421  calibrator->calibVisSqrdErr * (fabs (measVis->visSqrd1) / (calibrator->calibVisSqrd * calibrator->calibVisSqrd));
422 
423  trf->trf[5] = measVis->visSqrd2 / calibrator->calibVisSqrd;
424  trf->trfErr[5] = measVis->visSqrd2Err / (fabs (calibrator->calibVisSqrd)) +
425  calibrator->calibVisSqrdErr * (fabs (measVis->visSqrd2) / (calibrator->calibVisSqrd * calibrator->calibVisSqrd));
426  }
427 
428  /* Open the transfer function file for writing */
429  if ((trfPtr = fopen (fileNames->trfNameWrite, "w")) == NULL)
430  {
431  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot open file to store transfer functions");
432  *error = 1;
433  return;
434  }
435  else
436  {
437  cpl_msg_info(cpl_func,"Transfer Function region 0 = %f \n", trf->trf[0]);
438  cpl_msg_info(cpl_func,"Transfer Function region 0 Error = %f \n", trf->trfErr[0]);
439  cpl_msg_info(cpl_func,"Transfer Function region 1 = %f \n", trf->trf[1]);
440  cpl_msg_info(cpl_func,"Transfer Function region 1 Error = %f \n", trf->trfErr[1]);
441  cpl_msg_info(cpl_func,"Transfer Function region 2 = %f \n", trf->trf[2]);
442  cpl_msg_info(cpl_func,"Transfer Function region 2 Error = %f \n", trf->trfErr[2]);
443  cpl_msg_info(cpl_func,"Transfer Function Squared region 0 = %f \n", trf->trf[3]);
444  cpl_msg_info(cpl_func,"Transfer Function Squared region 0 Error = %f \n", trf->trfErr[3]);
445  cpl_msg_info(cpl_func,"Transfer Function Squared region 1 = %f \n", trf->trf[4]);
446  cpl_msg_info(cpl_func,"Transfer Function Squared region 1 Error = %f \n", trf->trfErr[4]);
447  cpl_msg_info(cpl_func,"Transfer Function Squared region 2 = %f \n", trf->trf[5]);
448  cpl_msg_info(cpl_func,"Transfer Function Squared region 2 Error = %f \n", trf->trfErr[5]);
449  fprintf (midiReportPtr, "Transfer Function region 0 = %f (QCLOG)\n", trf->trf[0]);
450  fprintf (midiReportPtr, "Transfer Function region 0 Error = %f (QCLOG)\n", trf->trfErr[0]);
451  fprintf (midiReportPtr, "Transfer Function region 1 = %f (QCLOG)\n", trf->trf[1]);
452  fprintf (midiReportPtr, "Transfer Function region 1 Error = %f (QCLOG)\n", trf->trfErr[1]);
453  fprintf (midiReportPtr, "Transfer Function region 2 = %f (QCLOG)\n", trf->trf[2]);
454  fprintf (midiReportPtr, "Transfer Function region 2 Error = %f (QCLOG)\n", trf->trfErr[2]);
455  fprintf (midiReportPtr, "Transfer Function Squared region 0 = %f (QCLOG)\n", trf->trf[3]);
456  fprintf (midiReportPtr, "Transfer Function Squared region 0 Error = %f (QCLOG)\n", trf->trfErr[3]);
457  fprintf (midiReportPtr, "Transfer Function Squared region 1 = %f (QCLOG)\n", trf->trf[4]);
458  fprintf (midiReportPtr, "Transfer Function Squared region 1 Error = %f (QCLOG)\n", trf->trfErr[4]);
459  fprintf (midiReportPtr, "Transfer Function Squared region 2 = %f (QCLOG)\n", trf->trf[5]);
460  fprintf (midiReportPtr, "Transfer Function Squared region 2 Error = %f (QCLOG)\n", trf->trfErr[5]);
461 
462  /* Write transfer function into the file */
463  for (i = 0; i < 6; i++)
464  {
465  fprintf (trfPtr, "%f\n", trf->trf[i]);
466  fprintf (trfPtr, "%f\n", trf->trfErr[i]);
467  }
468  fclose (trfPtr);
469  if (diagnostic)cpl_msg_info(cpl_func,"Created Transfer Function file %s\n", fileNames->trfNameWrite);
470  fprintf (midiReportPtr, "Created Transfer Function file %s\n", fileNames->trfNameWrite);
471  trf->exists = 1;
472  }
473 
474  /* Open a file for transfer function history */
475  trfHistoryPtr = fopen (fileNames->trfHistoryName, "a");
476  fprintf (trfHistoryPtr, "Transfer Functions (UNDISPERSED) Batch %d \n", batchNumber);
477  fprintf (trfHistoryPtr, "-------------------------------------- \n");
478  for (i = 0; i < 6; i++) fprintf (trfHistoryPtr, "%f %f \n", trf->trf[i], trf->trfErr[i]);
479  fprintf (trfHistoryPtr, "\n");
480  fclose (trfHistoryPtr);
481 
482  return;
483 }
484 /*****************************************************************************/
485 
486 /******************************************************************************
487 * European Southern Observatory
488 * VLTI MIDI Data Reduction Software
489 *
490 * Module name: identifyCalibrator
491 * Input/Output: See function arguments to avoid duplication
492 * Description: This routine identifies the calibrator diameter and computes
493 * the average projected baseline.
494 *
495 * History:
496 * 21-Jul-03 (csabet) Created
497 ******************************************************************************/
498 void identifyCalibrator (
499  MidiFiles *fileNames, // In: Pointer to MIDI file structure
500  CalibratorParam *calibrator, // Ou: Calibrator parameters
501  int *error,
502  cpl_parameterlist *parlist,
503  cpl_frameset *frameset)
504 {
505 
506  /* Local Declarations
507  -------------------*/
508  const char routine[] = "identifyCalibrator";
509  char *fileNameStr, *qfitsString, *cleanString, *stringTemp, *classification;
510  int fileNum;
511  float floatDummy, pblStart, pblEnd, parangStart, parangEnd;
512  FILE *inFitsBatchPtr = NULL;
513 
514  /* Algorithm
515  ----------*/
516  if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking routine '%s' \n", routine);
517  if (diagnostic > 4) fprintf(midiReportPtr, "Invoking routine '%s' \n", routine);
518 
519  /* Initialize parameters */
520  *error = 0;
521  pblStart = 0.0;
522  pblEnd = 0.0;
523  parangStart = 0.0;
524  parangEnd = 0.0;
525  fileNum = 0;
526 
527  /* Allocate memory */
528  classification = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
529  stringTemp = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
530  cleanString = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
531  fileNameStr = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
532 
533  /* Open the list of files */
534  if ((inFitsBatchPtr = fopen (fileNames->inFitsBatch, "r")) == NULL)
535  {
536  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot open input FITS file list");
537  free (cleanString);
538  free (fileNameStr);
539  free (classification);
540  free (stringTemp);
541  *error = 1;
542  return;
543  }
544 
545  /* Extract Projected baseline, RA and DEC for the calibrator */
546  while (fgets (stringTemp, MAX_STRING_LENGTH, inFitsBatchPtr) != NULL)
547  {
548  sprintf (classification, "%s", "");
549  sscanf (stringTemp, "%s%s", fileNameStr, classification);
550 
551  /* Ignore the last empty file */
552  qfitsString = qfits_query_ext (fileNameStr, "HIERARCH ESO DPR TYPE", 0);
553  if (qfitsString == NULL)
554  {
555  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot get DPR TYPE from");
556  *error = 1;
557  free (cleanString);
558  free (fileNameStr);
559  free (classification);
560  free (stringTemp);
561  fclose (inFitsBatchPtr);
562  return;
563  }
564  else
565  {
566  cleanUpString (qfitsString, cleanString);
567  if (strcmp (cleanString, "OTHER") != 0)
568  {
569  fileNum++;
570 
571  /* Get RA and DEC from the first file */
572  if (fileNum == 1)
573  {
574  /* Get RA */
575  qfitsString = qfits_query_ext (fileNameStr, "RA", 0);
576  if (qfitsString == NULL)
577  {
578  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot get RA from");
579  *error = 1;
580  free (cleanString);
581  free (fileNameStr);
582  free (classification);
583  free (stringTemp);
584  fclose (inFitsBatchPtr);
585  return;
586  }
587  else
588  {
589  cleanUpString (qfitsString, cleanString);
590  if (qfits_is_float (cleanString))
591  {
592  sscanf(cleanString, "%f", &(calibrator->calibRA));
593  calibrator->calibRA *= DEG_TO_RAD;
594  }
595  else
596  {
597  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Found non-float RA");
598  *error = 1;
599  free (cleanString);
600  free (fileNameStr);
601  free (classification);
602  free (stringTemp);
603  fclose (inFitsBatchPtr);
604  return;
605  }
606  }
607 
608  /* Get DEC */
609  qfitsString = qfits_query_ext (fileNameStr, "DEC", 0);
610  if (qfitsString == NULL)
611  {
612  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot get DEC");
613  *error = 1;
614  free (cleanString);
615  free (fileNameStr);
616  free (classification);
617  free (stringTemp);
618  fclose (inFitsBatchPtr);
619  return;
620  }
621  else
622  {
623  cleanUpString (qfitsString, cleanString);
624  if (qfits_is_float (cleanString))
625  {
626  sscanf(cleanString, "%f", &(calibrator->calibDEC));
627  calibrator->calibDEC *= DEG_TO_RAD;
628  }
629  else
630  {
631  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Found non-float DEC");
632  *error = 1;
633  free (cleanString);
634  free (fileNameStr);
635  free (classification);
636  free (stringTemp);
637  fclose (inFitsBatchPtr);
638  return;
639  }
640  }
641 
642  /* Get target name */
643  qfitsString = qfits_query_ext (fileNameStr, "HIERARCH ESO OBS TARG NAME", 0);
644  if (qfitsString == NULL)
645  {
646  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot get target name");
647  *error = 1;
648  free (cleanString);
649  free (fileNameStr);
650  free (classification);
651  free (stringTemp);
652  fclose (inFitsBatchPtr);
653  return;
654  }
655  else
656  {
657  cleanUpString (qfitsString, cleanString);
658  sscanf (cleanString, "%s", calibrator->calibName);
659  }
660  }
661 
662  /* Get PBL12 START */
663  qfitsString = qfits_query_ext (fileNameStr, "HIERARCH ESO ISS PBL12 START", 0);
664  if (qfitsString == NULL)
665  {
666  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot get PBL12 START");
667  *error = 1;
668  free (cleanString);
669  free (fileNameStr);
670  free (classification);
671  free (stringTemp);
672  fclose (inFitsBatchPtr);
673  return;
674  }
675  else
676  {
677  cleanUpString (qfitsString, cleanString);
678  if (qfits_is_float (cleanString))
679  {
680  sscanf(cleanString, "%f", &floatDummy);
681  if (floatDummy > 0.0)
682  pblStart += floatDummy;
683  else
684  {
685  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Found non-positive PBL12 START");
686  *error = 1;
687  free (cleanString);
688  free (fileNameStr);
689  free (classification);
690  free (stringTemp);
691  fclose (inFitsBatchPtr);
692  return;
693  }
694  }
695  else
696  {
697  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Found non-float PBL12 START");
698  *error = 1;
699  free (cleanString);
700  free (fileNameStr);
701  free (classification);
702  free (stringTemp);
703  fclose (inFitsBatchPtr);
704  return;
705  }
706  }
707 
708  /* Get PBL12 END */
709  qfitsString = qfits_query_ext (fileNameStr, "HIERARCH ESO ISS PBL12 END", 0);
710  if (qfitsString == NULL)
711  {
712  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot get PBL12 END");
713  *error = 1;
714  free (cleanString);
715  free (fileNameStr);
716  free (classification);
717  free (stringTemp);
718  fclose (inFitsBatchPtr);
719  return;
720  }
721  else
722  {
723  cleanUpString (qfitsString, cleanString);
724  if (qfits_is_float (cleanString))
725  {
726  sscanf(cleanString, "%f", &floatDummy);
727  if (floatDummy > 0.0)
728  pblEnd += floatDummy;
729  else
730  {
731  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Found non-positive PBL12 END");
732  *error = 1;
733  free (cleanString);
734  free (fileNameStr);
735  free (classification);
736  free (stringTemp);
737  fclose (inFitsBatchPtr);
738  return;
739  }
740  }
741  else
742  {
743  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Found non-float PBL12 END");
744  *error = 1;
745  free (cleanString);
746  free (fileNameStr);
747  free (classification);
748  free (stringTemp);
749  fclose (inFitsBatchPtr);
750  return;
751  }
752  }
753 
754  /* Get PARANG START */
755  qfitsString = qfits_query_ext (fileNameStr, "HIERARCH ESO ISS PARANG START", 0);
756  if (qfitsString == NULL)
757  {
758  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot get PARANG START");
759  *error = 1;
760  free (cleanString);
761  free (fileNameStr);
762  free (classification);
763  free (stringTemp);
764  fclose (inFitsBatchPtr);
765  return;
766  }
767  else
768  {
769  cleanUpString (qfitsString, cleanString);
770  if (qfits_is_float (cleanString))
771  {
772  sscanf(cleanString, "%f", &floatDummy);
773  /*if (floatDummy > 0.0)*/
774  parangStart += floatDummy;
775  /*else
776  {
777  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Found non-positive PARANG START");
778  *error = 1;
779  free (cleanString);
780  free (fileNameStr);
781  free (classification);
782  free (stringTemp);
783  fclose (inFitsBatchPtr);
784  return;
785  }*/
786  }
787  else
788  {
789  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Found non-float PARANG START in");
790  *error = 1;
791  free (cleanString);
792  free (fileNameStr);
793  free (classification);
794  free (stringTemp);
795  fclose (inFitsBatchPtr);
796  return;
797  }
798  }
799 
800  /* Get PARANG END */
801  qfitsString = qfits_query_ext (fileNameStr, "HIERARCH ESO ISS PARANG END", 0);
802  if (qfitsString == NULL)
803  {
804  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot get PARANG END");
805  *error = 1;
806  free (cleanString);
807  free (fileNameStr);
808  free (classification);
809  free (stringTemp);
810  fclose (inFitsBatchPtr);
811  return;
812  }
813  else
814  {
815  cleanUpString (qfitsString, cleanString);
816  if (qfits_is_float (cleanString))
817  {
818  sscanf(cleanString, "%f", &floatDummy);
819  /*if (floatDummy > 0.0)*/
820  parangEnd += floatDummy;
821  /*else
822  {
823  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Found non-positive PARANG END");
824  *error = 1;
825  free (cleanString);
826  free (fileNameStr);
827  free (classification);
828  free (stringTemp);
829  fclose (inFitsBatchPtr);
830  return;
831  }*/
832  }
833  else
834  {
835  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Found non-float PARANG END");
836  *error = 1;
837  free (cleanString);
838  free (fileNameStr);
839  free (classification);
840  free (stringTemp);
841  fclose (inFitsBatchPtr);
842  return;
843  }
844  }
845  }
846  }
847  }
848 
849  /* Compute average of projected baselines and angles */
850  pblStart /= fileNum;
851  pblEnd /= fileNum;
852  calibrator->calibPblAverage = 0.5 * (pblStart + pblEnd);
853  parangStart /= fileNum;
854  parangEnd /= fileNum;
855  calibrator->calibParangAverage = 0.5 * (parangStart + parangEnd);
856 
857  cpl_msg_info(cpl_func,"Observed Calibrator = %s \n", calibrator->calibName);
858  cpl_msg_info(cpl_func,"Observed Calibrator RA = %f radians \n", calibrator->calibRA);
859  cpl_msg_info(cpl_func,"Observed Calibrator DEC = %f radians \n", calibrator->calibDEC);
860  cpl_msg_info(cpl_func,"Observed Calibrator Average PBL = %f metres \n", calibrator->calibPblAverage);
861  cpl_msg_info(cpl_func,"Observed Calibrator Average PARANG = %f degrees \n", calibrator->calibParangAverage);
862  fprintf (midiReportPtr, "Observed Calibrator = %s (QCLOG)\n", calibrator->calibName);
863  fprintf (midiReportPtr, "Observed Calibrator RA = %f radians (QCLOG)\n", calibrator->calibRA);
864  fprintf (midiReportPtr, "Observed Calibrator DEC = %f radians (QCLOG)\n", calibrator->calibDEC);
865  fprintf (midiReportPtr, "Observed Calibrator Average PBL = %f metres (QCLOG)\n", calibrator->calibPblAverage);
866  fprintf (midiReportPtr, "Observed Calibrator Average PARANG = %f degrees (QCLOG)\n", calibrator->calibParangAverage);
867 
868  /* Get diameter of the calibrator from the Calibrator database */
869  getCalibratorDiameter (fileNames, calibrator, error, parlist, frameset);
870  if (*error)
871  {
872  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot get Calibrator Diameter");
873  free (cleanString);
874  free (fileNameStr);
875  free (classification);
876  free (stringTemp);
877  fclose (inFitsBatchPtr);
878  return;
879  }
880 
881  /* Release memory and close files */
882  free (fileNameStr);
883  fclose (inFitsBatchPtr);
884  free (cleanString);
885  free (classification);
886  free (stringTemp);
887 
888  return;
889 }
890 /*****************************************************************************/
891 
892 
893 /******************************************************************************
894 * European Southern Observatory
895 * VLTI MIDI Data Reduction Software
896 *
897 * Module name: getCalibratorDiameter
898 * Input/Output: See function arguments to avoid duplication
899 * Description: Searches through the CalibDB and extracts the calibrator
900 * diameter. there are 36 elements in one line. there are
901 * 9 useful elements and UNWANTED_ELEMENTS dummy.
902 *
903 *
904 * History:
905 * 26-Feb-04 (csabet) Created
906 ******************************************************************************/
907 void getCalibratorDiameter (
908  MidiFiles *fileNames,
909  CalibratorParam *calibrator,
910  int *error,
911  cpl_parameterlist *parlist,
912  cpl_frameset *frameset)
913 {
914 
915  /* Local Declarations
916  --------------------*/
917  const char routine[] = "getCalibratorDiameter";
918  int i;
919  double searchRA, searchDEC, diffAngle;
920 
921  cpl_errorstate prestate = cpl_errorstate_get();
922 
923  cpl_frame * cur_frame;
924 
925  cpl_table * table;
926 
927  char ** Name=NULL;
928  int * hourRA=NULL;
929  int * minuteRA=NULL;
930  double * secondRA=NULL;
931  int * signDEC=NULL;
932  int * degreeDEC=NULL;
933  int * minuteDEC=NULL;
934  double * secondDEC=NULL;
935  double * flux=NULL;
936  int * flag=NULL;
937  double * diameter=NULL;
938  double * diameterErr=NULL;
939 
940  int ext_calibrator_data=0;
941  int dimen_calibrator_data=0;
942  char * tag=NULL;
943 
944 
945 
946  /* Algorithm
947  -----------*/
948  if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking routine '%s' \n", routine);
949  if (diagnostic > 4) fprintf(midiReportPtr, "Invoking routine '%s' \n", routine);
950 
951 
952 
953  cur_frame = cpl_frameset_get_first(frameset);
954  if (cur_frame == NULL) {
955  cpl_msg_error(cpl_func, "No frame found in the SOF");
956  *error = 1;
957  return ;
958 
959  }
960 
961  /* Find the calibrator database file in the SOF */
962  while(cur_frame)
963  {
964  /* Check the right tags */
965  tag = (char*)cpl_frame_get_tag(cur_frame);
966  if (strcmp(tag, MIDI_CALIB_DATABASE)) {
967  cur_frame = cpl_frameset_get_next( frameset );
968  continue;
969  }
970  else{
971  cpl_msg_info(cpl_func, "Calibrator database found in the SOF: %s",cpl_frame_get_filename(cur_frame));
972  break;
973  }
974  }
975 
976  if (strcmp(tag, MIDI_CALIB_DATABASE)) {
977  cpl_msg_warning(cpl_func, "No calibrator database file found in the SOF!");
978  cpl_msg_warning(cpl_func, "Transfer function can not be calculated!");
979  *error = 1;
980  return;
981  }
982 
983 
984  /* Load extension CALIBRATOR_DATA */
985 
986  prestate = cpl_errorstate_get();
987 
988  cpl_msg_info(cpl_func, "Reading %s",cpl_frame_get_filename(cur_frame));
989 
990  ext_calibrator_data=cpl_fits_find_extension(cpl_frame_get_filename(cur_frame),"CALIBRATOR_DATA");
991 
992  /* Load extension */
993  if((table = cpl_table_load(cpl_frame_get_filename(cur_frame), ext_calibrator_data, 1))==NULL)
994  {
995  cpl_msg_info(cpl_func, "No siutable table found in the file: %s",cpl_frame_get_filename(cur_frame));
996  cpl_msg_warning(cpl_func, "Transfer function can not be calculated!");
997  cpl_errorstate_set(prestate);
998  *error = 1;
999  return;
1000  }
1001 
1002 
1003  if (cpl_table_has_column(table, "Name" )) {Name =cpl_table_get_data_string(table, "Name" );} else {cpl_msg_warning(cpl_func, "Entry not found: Name" );*error = 1;};
1004  if (cpl_table_has_column(table, "hourRA" )) {hourRA =cpl_table_get_data_int (table, "hourRA" );} else {cpl_msg_warning(cpl_func, "Entry not found: hourRA" );*error = 1;};
1005  if (cpl_table_has_column(table, "minuteRA" )) {minuteRA =cpl_table_get_data_int (table, "minuteRA" );} else {cpl_msg_warning(cpl_func, "Entry not found: minuteRA" );*error = 1;};
1006  if (cpl_table_has_column(table, "secondRA" )) {secondRA =cpl_table_get_data_double (table, "secondRA" );} else {cpl_msg_warning(cpl_func, "Entry not found: secondRA" );*error = 1;};
1007  if (cpl_table_has_column(table, "signDEC" )) {signDEC =cpl_table_get_data_int (table, "signDEC" );} else {cpl_msg_warning(cpl_func, "Entry not found: signDEC" );*error = 1;};
1008  if (cpl_table_has_column(table, "degreeDEC" )) {degreeDEC =cpl_table_get_data_int (table, "degreeDEC" );} else {cpl_msg_warning(cpl_func, "Entry not found: degreeDEC" );*error = 1;};
1009  if (cpl_table_has_column(table, "minuteDEC" )) {minuteDEC =cpl_table_get_data_int (table, "minuteDEC" );} else {cpl_msg_warning(cpl_func, "Entry not found: minuteDEC" );*error = 1;};
1010  if (cpl_table_has_column(table, "secondDEC" )) {secondDEC =cpl_table_get_data_double (table, "secondDEC" );} else {cpl_msg_warning(cpl_func, "Entry not found: secondDEC" );*error = 1;};
1011  if (cpl_table_has_column(table, "N_band" )) {flux =cpl_table_get_data_double(table, "N_band" );} else {cpl_msg_warning(cpl_func, "Entry not found: N_band" );*error = 1;};
1012  if (cpl_table_has_column(table, "flag" )) {flag =cpl_table_get_data_int (table, "flag" );} else {cpl_msg_warning(cpl_func, "Entry not found: flag" );*error = 1;};
1013  if (cpl_table_has_column(table, "diameter" )) {diameter =cpl_table_get_data_double (table, "diameter" );} else {cpl_msg_warning(cpl_func, "Entry not found: diameter" );*error = 1;};
1014  if (cpl_table_has_column(table, "diameterErr")) {diameterErr=cpl_table_get_data_double (table, "diameterErr");} else {cpl_msg_warning(cpl_func, "Entry not found: diameterErr");*error = 1;};
1015 
1016  dimen_calibrator_data=cpl_table_get_nrow(table);
1017 
1018  cpl_msg_info(cpl_func, "Total number of Calibrators in the table: %d", dimen_calibrator_data);
1019 
1020  calibrator->calibDistance =FLT_MAX;
1021 
1022  /* Search for the minimum distance and get the diameter */
1023  for (i=0; i<dimen_calibrator_data;i++)
1024  {
1025 
1026  searchRA = HOUR_TO_RAD * ((double) hourRA[i] + minuteRA[i]/60.0 + secondRA[i]/3600.0);
1027  searchDEC = DEG_TO_RAD * (((double) degreeDEC[i] + minuteDEC[i]/60.0 + secondDEC[i]/3600.0) * signDEC[i]);
1028  diffAngle = acos ( sin(searchDEC) * sin(calibrator->calibDEC) +
1029  cos(searchDEC) * cos(calibrator->calibDEC) * cos(searchRA - calibrator->calibRA) );
1030 
1031  /* cpl_msg_info(cpl_func, " i: %d diffAngle : %f Name: %s", i, diffAngle,Name[i]); */
1032  if (diffAngle < calibrator->calibDistance)
1033  {
1034  calibrator->calibDistance = (float)diffAngle;
1035  calibrator->calibDiameter = (float)diameter[i];
1036  calibrator->calibDiameterErr = (float)diameterErr[i];
1037  strcpy (calibrator->calibName, Name[i]);
1038  calibrator->calibFlux = flux[i]; // Flux in the N-Band (Actually the magnitude)
1039  calibrator->calibFlag = flag[i]; // Quality Parameter/Flag
1040 
1041  }
1042 
1043  }
1044 
1045 
1046  /* Check if minimum angle is within the threshold */
1047  if (calibrator->calibDistance <= CALIBRATOR_MIN_THRESHOLD)
1048  {
1049  cpl_msg_info(cpl_func,"Closest Calibrator in the database = %s \n", calibrator->calibName);
1050  cpl_msg_info(cpl_func,"Calibrator Diameter = %f marcsec \n", calibrator->calibDiameter);
1051  cpl_msg_info(cpl_func,"Calibrator Diameter error = %f marcsec \n", calibrator->calibDiameterErr);
1052  cpl_msg_info(cpl_func,"Computed Distance to Observed Calibrator = %f arcsec \n", RAD_TO_ARCSEC * calibrator->calibDistance);
1053  cpl_msg_info(cpl_func,"Calibrator Flux in the N-Band = %g mag \n", calibrator->calibFlux);
1054  cpl_msg_info(cpl_func,"Calibrator quality flag = %d \n", calibrator->calibFlag);
1055 
1056  fprintf (midiReportPtr, "Closest Calibrator in the database = %s (QCLOG)\n", calibrator->calibName);
1057  fprintf (midiReportPtr, "Calibrator Diameter = %f marcsec (QCLOG)\n", calibrator->calibDiameter);
1058  fprintf (midiReportPtr, "Calibrator Diameter error = %f marcsec (QCLOG)\n", calibrator->calibDiameterErr);
1059  fprintf (midiReportPtr, "Computed Distance to Observed Calibrator = %f arcsec (QCLOG)\n", RAD_TO_ARCSEC * calibrator->calibDistance);
1060  fprintf (midiReportPtr, "Calibrator Flux in the N-Band = %g mag (QCLOG)\n", calibrator->calibFlux);
1061  fprintf (midiReportPtr, "Calibrator quality flag = %d (QCLOG)\n", calibrator->calibFlag);
1062  }
1063  else
1064  {
1065  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot find a close match in the database");
1066  *error = 1;
1067  }
1068 
1069  /* Release memory */
1070  if(table !=NULL) cpl_table_delete(table);
1071 
1072 /* fclose (calibDbPtr); */
1073 /* for (i = 0; i < UNWANTED_ELEMENTS; i++) */
1074 /* free (dummyStr[i]); */
1075 /* free (dummyStr); */
1076 /* free (lineStr); */
1077 
1078  return;
1079 }
1080 /*****************************************************************************/
1081 /* /\****************************************************************************** */
1082 /* * European Southern Observatory */
1083 /* * VLTI MIDI Data Reduction Software */
1084 /* * */
1085 /* * Module name: getCalibratorDiameter */
1086 /* * Input/Output: See function arguments to avoid duplication */
1087 /* * Description: Searches through the CalibDB and extracts the calibrator */
1088 /* * diameter. there are 36 elements in one line. there are */
1089 /* * 9 useful elements and UNWANTED_ELEMENTS dummy. */
1090 /* * */
1091 /* * */
1092 /* * History: */
1093 /* * 26-Feb-04 (csabet) Created */
1094 /* ******************************************************************************\/ */
1095 /* void getCalibratorDiameter ( */
1096 /* MidiFiles *fileNames, */
1097 /* CalibratorParam *calibrator, */
1098 /* int *error, */
1099 /* cpl_parameterlist *parlist, */
1100 /* cpl_frameset *frameset) */
1101 /* { */
1102 
1103 /* /\* Local Declarations */
1104 /* --------------------*\/ */
1105 /* const char routine[] = "getCalibratorDiameter"; */
1106 /* int i, lineNum,flag; */
1107 /* int hourRA, minuteRA, signDEC, degreeDEC, minuteDEC; */
1108 /* float secondRA, secondDEC, diameter, diameterErr; */
1109 /* double flux; */
1110 /* char **dummyStr, *lineStr; */
1111 /* float searchRA, searchDEC, diffAngle; */
1112 /* FILE *calibDbPtr; */
1113 
1114 /* /\* Algorithm */
1115 /* -----------*\/ */
1116 /* if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking routine '%s' \n", routine); */
1117 /* if (diagnostic > 4) fprintf(midiReportPtr, "Invoking routine '%s' \n", routine); */
1118 
1119 /* /\* Allocate memory *\/ */
1120 /* lineStr = (char *) calloc (MAX_STRING_LENGTH, sizeof (char)); */
1121 /* dummyStr = (char **) calloc (UNWANTED_ELEMENTS, sizeof (char *)); */
1122 /* for (i = 0; i < UNWANTED_ELEMENTS; i++) */
1123 /* dummyStr[i] = (char *) calloc (CALIB_DB_LEN, sizeof (char)); */
1124 
1125 /* /\* Reset parameters *\/ */
1126 /* *error = 0; */
1127 /* lineNum = 0; */
1128 
1129 /* /\* Open the calibDB file for reading *\/ */
1130 /* if ((calibDbPtr = fopen (fileNames->calibDbName, "r")) == NULL) */
1131 /* { */
1132 /* midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot open calibrator database"); */
1133 /* *error = 1; */
1134 /* for (i = 0; i < UNWANTED_ELEMENTS; i++) */
1135 /* free (dummyStr[i]); */
1136 /* free (dummyStr); */
1137 /* free (lineStr); */
1138 /* return; */
1139 /* } */
1140 
1141 /* /\* Loop through the calibrator database and identify the closest RA and DEC *\/ */
1142 /* while (fgets (lineStr, MAX_STRING_LENGTH, calibDbPtr) != NULL) */
1143 /* { */
1144 /* sscanf (lineStr, "%s%d%d%f%d%d%d%f%s%s%s%s%s%s%s%s%lg%s%s%s%d%f%f%s%s%s%s%s%s%s%s%s%s%s%s%s", */
1145 /* dummyStr[0], &hourRA, &minuteRA, &secondRA, &signDEC, &degreeDEC, &minuteDEC, &secondDEC, dummyStr[1], dummyStr[2], */
1146 /* dummyStr[3], dummyStr[4], dummyStr[5], dummyStr[6], dummyStr[7], dummyStr[8], &flux, dummyStr[10], */
1147 /* dummyStr[11], dummyStr[12], &flag, &diameter, &diameterErr, dummyStr[14], dummyStr[15], dummyStr[16], */
1148 /* dummyStr[17], dummyStr[18], dummyStr[19], dummyStr[20], dummyStr[21], dummyStr[22], dummyStr[23], dummyStr[24], */
1149 /* dummyStr[25], dummyStr[26]); */
1150 
1151 /* lineNum++; */
1152 
1153 /* /\* Find initial difference *\/ */
1154 /* if (lineNum == START_MIDI_RECORD) */
1155 /* { */
1156 /* searchRA = HOUR_TO_RAD * ((float) hourRA + minuteRA/60.0 + secondRA/3600.0); */
1157 /* searchDEC = DEG_TO_RAD * (((float) degreeDEC + minuteDEC/60.0 + secondDEC/3600.0) * signDEC); */
1158 /* calibrator->calibDistance = acos ( sin(searchDEC) * sin(calibrator->calibDEC) + */
1159 /* cos(searchDEC) * cos(calibrator->calibDEC) * cos(searchRA - calibrator->calibRA) ); */
1160 /* calibrator->calibDiameter = diameter; */
1161 /* calibrator->calibDiameterErr = diameterErr; */
1162 /* sscanf (dummyStr[0], "%s", calibrator->calibName); */
1163 /* } */
1164 
1165 /* /\* Now search for the minimum distance and get the diameter *\/ */
1166 /* if (lineNum > START_MIDI_RECORD && lineNum <= END_MIDI_RECORD) */
1167 /* { */
1168 /* searchRA = HOUR_TO_RAD * ((float) hourRA + minuteRA/60.0 + secondRA/3600.0); */
1169 /* searchDEC = DEG_TO_RAD * (((float) degreeDEC + minuteDEC/60.0 + secondDEC/3600.0) * signDEC); */
1170 /* diffAngle = acos ( sin(searchDEC) * sin(calibrator->calibDEC) + */
1171 /* cos(searchDEC) * cos(calibrator->calibDEC) * cos(searchRA - calibrator->calibRA) ); */
1172 /* if (diffAngle < calibrator->calibDistance) */
1173 /* { */
1174 /* calibrator->calibDistance = diffAngle; */
1175 /* calibrator->calibDiameter = diameter; */
1176 /* calibrator->calibDiameterErr = diameterErr; */
1177 /* sscanf (dummyStr[0], "%s", calibrator->calibName); */
1178 /* calibrator->calibFlux = flux; // Flux in the N-Band */
1179 /* calibrator->calibFlag = flag; // Quality Parameter/Flag */
1180 
1181 
1182 /* } */
1183 /* } */
1184 /* if (lineNum > END_MIDI_RECORD) break; */
1185 /* } */
1186 
1187 /* /\* Check if there was enough record in the file *\/ */
1188 /* if (lineNum < START_MIDI_RECORD) */
1189 /* { */
1190 /* midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Not enough records in database"); */
1191 /* *error = 1; */
1192 /* for (i = 0; i < UNWANTED_ELEMENTS; i++) */
1193 /* free (dummyStr[i]); */
1194 /* free (dummyStr); */
1195 /* free (lineStr); */
1196 /* return; */
1197 /* } */
1198 
1199 /* /\* Check if minimum angle is within the threshold *\/ */
1200 /* if (calibrator->calibDistance <= CALIBRATOR_MIN_THRESHOLD) */
1201 /* { */
1202 /* cpl_msg_info(cpl_func,"Closest Calibrator in the database = %s \n", calibrator->calibName); */
1203 /* cpl_msg_info(cpl_func,"Calibrator Diameter = %f marcsec \n", calibrator->calibDiameter); */
1204 /* cpl_msg_info(cpl_func,"Calibrator Diameter error = %f marcsec \n", calibrator->calibDiameterErr); */
1205 /* cpl_msg_info(cpl_func,"Computed Distance to Observed Calibrator = %f arcsec \n", RAD_TO_ARCSEC * calibrator->calibDistance); */
1206 /* cpl_msg_info(cpl_func,"Calibrator Flux in the N-Band = %g mag \n", calibrator->calibFlux); */
1207 /* cpl_msg_info(cpl_func,"Calibrator quality flag = %d \n", calibrator->calibFlag); */
1208 
1209 /* fprintf (midiReportPtr, "Closest Calibrator in the database = %s (QCLOG)\n", calibrator->calibName); */
1210 /* fprintf (midiReportPtr, "Calibrator Diameter = %f marcsec (QCLOG)\n", calibrator->calibDiameter); */
1211 /* fprintf (midiReportPtr, "Calibrator Diameter error = %f marcsec (QCLOG)\n", calibrator->calibDiameterErr); */
1212 /* fprintf (midiReportPtr, "Computed Distance to Observed Calibrator = %f arcsec (QCLOG)\n", RAD_TO_ARCSEC * calibrator->calibDistance); */
1213 /* fprintf (midiReportPtr, "Calibrator Flux in the N-Band = %g mag (QCLOG)\n", calibrator->calibFlux); */
1214 /* fprintf (midiReportPtr, "Calibrator quality flag = %d (QCLOG)\n", calibrator->calibFlag); */
1215 /* } */
1216 /* else */
1217 /* { */
1218 /* midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot find a close match in the database"); */
1219 /* *error = 1; */
1220 /* } */
1221 
1222 /* /\* Release memory and close file *\/ */
1223 /* fclose (calibDbPtr); */
1224 /* for (i = 0; i < UNWANTED_ELEMENTS; i++) */
1225 /* free (dummyStr[i]); */
1226 /* free (dummyStr); */
1227 /* free (lineStr); */
1228 
1229 /* return; */
1230 /* } */
1231 /*****************************************************************************/
1232 
1233 
1234 
1235 /******************************************************************************
1236 * European Southern Observatory
1237 * VLTI MIDI Data Reduction Software
1238 *
1239 * Module name: computeExpectedVis
1240 * Input/Output: See function arguments to avoid duplication
1241 * Description:
1242 *
1243 *
1244 * History:
1245 * 21-Jul-03 (csabet) Created
1246 ******************************************************************************/
1247 void computeExpectedVis (
1248  CalibratorParam *calibrator, // Ou: Calibrator parameters
1249  int *error) // Ou: Status
1250 {
1251  /* Local Declarations
1252  --------------------*/
1253  const char routine[] = "computeExpectedVis";
1254  double besselK1o1, besselK1o1Err, xArg, xArgErr;
1255 
1256  /* Algorithm
1257  -----------*/
1258  if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking routine '%s' \n", routine);
1259  if (diagnostic > 4) fprintf(midiReportPtr, "Invoking routine '%s' \n", routine);
1260 
1261  /* Reset parameters */
1262  *error = 0;
1263 
1264  /* Compute Bessel function of first kind of order 1
1265  For faster processing most divisions are stated by multiplying factors */
1266  xArg = (double) (MIDI_PI * DIAMETER_FACTOR * calibrator->calibDiameter * calibrator->calibPblAverage * INVERSE_WAVELENGTH);
1267  xArgErr = (double) (MIDI_PI * DIAMETER_FACTOR * calibrator->calibDiameterErr * calibrator->calibPblAverage * INVERSE_WAVELENGTH);
1268  besselK1o1 = computeBesselK1o1 (xArg, xArgErr, &besselK1o1Err);
1269 
1270  /* Compute expected visibilities */
1271  calibrator->calibVis = (float) (2.0 * (besselK1o1 / xArg));
1272  calibrator->calibVisSqrd = calibrator->calibVis * calibrator->calibVis;
1273 
1274  /* Compute errors */
1275  calibrator->calibVisErr = (float) (2.0 * (besselK1o1Err/fabs(xArg) + xArgErr * (fabs(besselK1o1)/(xArg * xArg))));
1276  calibrator->calibVisSqrdErr = 2.0 * (calibrator->calibVisErr * fabs (calibrator->calibVis));
1277 
1278  cpl_msg_info(cpl_func,"Expected Visibility = %f \n", calibrator->calibVis);
1279  cpl_msg_info(cpl_func,"Expected Visibility Error = %f \n", calibrator->calibVisErr);
1280  cpl_msg_info(cpl_func,"Expected Squared Visibility = %f \n", calibrator->calibVisSqrd);
1281  cpl_msg_info(cpl_func,"Expected Squared Visibility Error = %f \n", calibrator->calibVisSqrdErr);
1282  fprintf (midiReportPtr, "Expected Visibility = %f (QCLOG)\n", calibrator->calibVis);
1283  fprintf (midiReportPtr, "Expected Visibility Error = %f (QCLOG)\n", calibrator->calibVisErr);
1284  fprintf (midiReportPtr, "Expected Squared Visibility = %f (QCLOG)\n", calibrator->calibVisSqrd);
1285  fprintf (midiReportPtr, "Expected Squared Visibility Error = %f (QCLOG)\n", calibrator->calibVisSqrdErr);
1286 
1287  return;
1288 }
1289 /*****************************************************************************/
1290 
1291 
1292 /******************************************************************************
1293 * European Southern Observatory
1294 * VLTI MIDI Data Reduction Software
1295 *
1296 * Module name: computeBesselK1o1
1297 * Input/Output: See function arguments to avoid duplication
1298 * Description: Computes bessel function of first kind of order 1 and the
1299 * associated errors.
1300 *
1301 *
1302 * History:
1303 * 01-Mar-04 (csabet) Created
1304 ******************************************************************************/
1305 double computeBesselK1o1 ( /* Ou: Computed Bessel function */
1306  double xArg, /* In: Bessel argument */
1307  double xArgErr, /* In: Error of argument */
1308  double *besselK1o1Err) /* Ou: Error of computed Bessel function */
1309 {
1310  /* Local Declarations
1311  --------------------*/
1312  const char routine[] = "computeBesselK1o1";
1313 
1314  /* Algorithm
1315  -----------*/
1316  if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking routine '%s' \n", routine);
1317  if (diagnostic > 4) fprintf(midiReportPtr, "Invoking routine '%s' \n", routine);
1318 
1319  *besselK1o1Err = (
1320  0.5 * xArgErr +
1321  0.062500000000 * xArgErr * fabs (3.0 * xArg * xArg) +
1322  0.002604166666 * xArgErr * fabs (5.0 * xArg * xArg * xArg * xArg) +
1323  0.000054253472 * xArgErr * fabs (7.0 * xArg * xArg * xArg * xArg * xArg * xArg));
1324 
1325  return (
1326  0.5 * xArg -
1327  0.062500000000 * xArg * xArg * xArg +
1328  0.002604166666 * xArg * xArg * xArg * xArg * xArg -
1329  0.000054253472 * xArg * xArg * xArg * xArg * xArg * xArg * xArg);
1330 }
1331 /*****************************************************************************/
1332 
1333 
1334 /******************************************************************************
1335 * European Southern Observatory
1336 * VLTI MIDI Data Reduction Software
1337 *
1338 * Module name: computeBinnedTrf
1339 * Input/Output: See function arguments to avoid duplication
1340 * Description: This routine computes the transfer function at 5 spectral
1341 * bands as follows:
1342 *
1343 * 1) 8.64 microns (Channels 120 -> 126) PRISM
1344 * (Channels 38 -> 50) GRISM
1345 * 2) 9.00 microns (Channels 113 -> 121) PRISM
1346 * (Channels 52 -> 68) GRISM
1347 * 3) 10.46 microns (Channels 88 -> 99) PRISM
1348 * (Channels 116 -> 136) GRISM
1349 * 4) 11.79 microns (Channels 60 -> 72) PRISM
1350 * (Channels 176 -> 200) GRISM
1351 * 5) 12.80 microns (Channels 36 -> 50) PRISM
1352 * (Channels 217 -> 245) GRISM
1353 *
1354 * History:
1355 * 01-Jul-08 Created
1356 ******************************************************************************/
1357 void computeBinnedTrf (
1358  ImageFormat *format, // In: General data format
1359  DispersedResult *dispResult, // In: Dispersed result structure
1360  int *error) // Ou: Error status
1361 {
1362 
1363  // Local Declarations
1364  // ------------------
1365  const char routine[] = "computeBinnedTrf";
1366  int i, n;
1367 
1368  // Algorithm
1369  // ---------
1370  cpl_msg_info(cpl_func,"\nBinned Transfer Function for batch %d \n", batchNumber);
1371  cpl_msg_info(cpl_func,"------------------------------------------ \n");
1372  fprintf (midiReportPtr, "\nBinned Transfer Function for batch %d QCLOG \n", batchNumber);
1373  fprintf (midiReportPtr, "------------------------------------------ QCLOG \n");
1374 
1375  // Reset parameters
1376  *error = 0;
1377  n = 0;
1378 
1379  dispResult->trfBinned1 = 0.0;
1380  dispResult->trfBinned2 = 0.0;
1381  dispResult->trfBinned3 = 0.0;
1382  dispResult->trfBinned4 = 0.0;
1383  dispResult->trfBinned5 = 0.0;
1384 
1385  if (strcmp(format->grismId, "PRISM") == 0)
1386  {
1387  n = 0;
1388  for (i = 36; i < 51; i++)
1389  {
1390  if (badChannelList[i])
1391  continue;
1392 
1393  dispResult->trfBinned5 += (dispResult->trf)[i];
1394  n++;
1395  }
1396  if(n>0){
1397  dispResult->trfBinned5 /= n;
1398  }
1399  else{
1400  dispResult->trfBinned5= -1.;
1401  }
1402 
1403  n = 0;
1404  for (i = 60; i < 73; i++)
1405  {
1406  if (badChannelList[i])
1407  continue;
1408 
1409  dispResult->trfBinned4 += (dispResult->trf)[i];
1410  n++;
1411  }
1412  if(n>0){
1413  dispResult->trfBinned4 /= n;
1414  }
1415  else{
1416  dispResult->trfBinned4= -1.;
1417  }
1418 
1419  n = 0;
1420  for (i = 88; i < 99; i++)
1421  {
1422  if (badChannelList[i])
1423  continue;
1424 
1425  dispResult->trfBinned3 += (dispResult->trf)[i];
1426  n++;
1427  }
1428  if(n>0){
1429  dispResult->trfBinned3 /= n;
1430  }
1431  else{
1432  dispResult->trfBinned3= -1.;
1433  }
1434 
1435  n = 0;
1436  for (i = 113; i < 122; i++)
1437  {
1438  if (badChannelList[i])
1439  continue;
1440 
1441  dispResult->trfBinned2 += (dispResult->trf)[i];
1442  n++;
1443  }
1444  if(n>0){
1445  dispResult->trfBinned2 /= n;
1446  }
1447  else{
1448  dispResult->trfBinned2= -1.;
1449  }
1450 
1451  n = 0;
1452  for (i = 120; i < 127; i++)
1453  {
1454  if (badChannelList[i])
1455  continue;
1456 
1457  dispResult->trfBinned1 += (dispResult->trf)[i];
1458  n++;
1459  }
1460 
1461  if(n>0){
1462  dispResult->trfBinned1 /= n;
1463  }
1464  else{
1465  dispResult->trfBinned1= -1.;
1466  }
1467  }
1468  else if (strcmp(format->grismId, "GRISM") == 0)
1469  {
1470  n = 0;
1471  for (i = 38; i < 51; i++)
1472  {
1473  if (badChannelList[i])
1474  continue;
1475 
1476  dispResult->trfBinned1 += (dispResult->trf)[i];
1477  n++;
1478  }
1479  if(n>0){
1480  dispResult->trfBinned1 /= n;
1481  }
1482  else{
1483  dispResult->trfBinned1= -1.;
1484  }
1485 
1486  n = 0;
1487  for (i = 52; i < 69; i++)
1488  {
1489  if (badChannelList[i])
1490  continue;
1491 
1492  dispResult->trfBinned2 += (dispResult->trf)[i];
1493  n++;
1494  }
1495  if(n>0){
1496  dispResult->trfBinned2 /= n;
1497  }
1498  else{
1499  dispResult->trfBinned2= -1.;
1500  }
1501 
1502  n = 0;
1503  for (i = 116; i < 137; i++)
1504  {
1505  if (badChannelList[i])
1506  continue;
1507 
1508  dispResult->trfBinned3 += (dispResult->trf)[i];
1509  n++;
1510  }
1511  if(n>0){
1512  dispResult->trfBinned3 /= n;
1513  }
1514  else{
1515  dispResult->trfBinned3= -1.;
1516  }
1517 
1518  n = 0;
1519  for (i = 176; i < 201; i++)
1520  {
1521  if (badChannelList[i])
1522  continue;
1523 
1524  dispResult->trfBinned4 += (dispResult->trf)[i];
1525  n++;
1526  }
1527  if(n>0){
1528  dispResult->trfBinned4 /= n;
1529  }
1530  else{
1531  dispResult->trfBinned4= -1.;
1532  }
1533 
1534  n = 0;
1535  for (i = 217; i < 246; i++)
1536  {
1537  if (badChannelList[i])
1538  continue;
1539 
1540  dispResult->trfBinned5 += (dispResult->trf)[i];
1541  n++;
1542  }
1543  if(n>0){
1544  dispResult->trfBinned5 /= n;
1545  }
1546  else{
1547  dispResult->trfBinned5= -1.;
1548  }
1549  }
1550  else
1551  {
1552  sprintf (midiMessage, "Unknown GRISM ID ... %s", format->grismId);
1553  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
1554  *error = 1;
1555  return;
1556  }
1557 
1558  // Report
1559  cpl_msg_info(cpl_func,"Grism ID: %s \n", format->grismId);
1560  fprintf (midiReportPtr, "Grism ID: %s QCLOG \n", format->grismId);
1561  if (strcmp(format->grismId, "PRISM") == 0)
1562  {
1563  cpl_msg_info(cpl_func," 8.64 micron (Channel 120 -> 126) = %0.4f \n", dispResult->trfBinned1);
1564  cpl_msg_info(cpl_func," 9.00 micron (Channel 113 -> 121) = %0.4f \n", dispResult->trfBinned2);
1565  cpl_msg_info(cpl_func,"10.46 micron (Channel 88 -> 98) = %0.4f \n", dispResult->trfBinned3);
1566  cpl_msg_info(cpl_func,"11.79 micron (Channel 60 -> 72) = %0.4f \n", dispResult->trfBinned4);
1567  cpl_msg_info(cpl_func,"12.80 micron (Channel 36 -> 50) = %0.4f \n", dispResult->trfBinned5);
1568 
1569  fprintf (midiReportPtr, " 8.64 micron (Channel 120 -> 126) = %0.4f QCLOG \n", dispResult->trfBinned1);
1570  fprintf (midiReportPtr, " 9.00 micron (Channel 113 -> 121) = %0.4f QCLOG \n", dispResult->trfBinned2);
1571  fprintf (midiReportPtr, "10.46 micron (Channel 88 -> 98) = %0.4f QCLOG \n", dispResult->trfBinned3);
1572  fprintf (midiReportPtr, "11.79 micron (Channel 60 -> 72) = %0.4f QCLOG \n", dispResult->trfBinned4);
1573  fprintf (midiReportPtr, "12.80 micron (Channel 36 -> 50) = %0.4f QCLOG \n", dispResult->trfBinned5);
1574  }
1575  else
1576  {
1577  cpl_msg_info(cpl_func," 8.64 micron (Channel 38 -> 50) = %0.4f \n", dispResult->trfBinned1);
1578  cpl_msg_info(cpl_func," 9.00 micron (Channel 52 -> 68) = %0.4f \n", dispResult->trfBinned2);
1579  cpl_msg_info(cpl_func,"10.46 micron (Channel 116 -> 136) = %0.4f \n", dispResult->trfBinned3);
1580  cpl_msg_info(cpl_func,"11.79 micron (Channel 176 -> 200) = %0.4f \n", dispResult->trfBinned4);
1581  cpl_msg_info(cpl_func,"12.80 micron (Channel 217 -> 245) = %0.4f \n", dispResult->trfBinned5);
1582 
1583  fprintf (midiReportPtr, " 8.64 micron (Channel 38 -> 50) = %0.4f QCLOG \n", dispResult->trfBinned1);
1584  fprintf (midiReportPtr, " 9.00 micron (Channel 52 -> 68) = %0.4f QCLOG \n", dispResult->trfBinned2);
1585  fprintf (midiReportPtr, "10.46 micron (Channel 116 -> 136) = %0.4f QCLOG \n", dispResult->trfBinned3);
1586  fprintf (midiReportPtr, "11.79 micron (Channel 176 -> 200) = %0.4f QCLOG \n", dispResult->trfBinned4);
1587  fprintf (midiReportPtr, "12.80 micron (Channel 217 -> 245) = %0.4f QCLOG \n", dispResult->trfBinned5);
1588  }
1589 
1590  return;
1591 }
1592 /*****************************************************************************/
1593 
1594 
1595 
1596 
1597 #ifdef NEW_PBL
1598 From: Anders Wallander [awalland@eso.org]
1599 Sent: Wednesday, 12 July, 2006 10:46
1600 To: Isabelle Percheron
1601 Cc: tlicha@eso.org; csabet@eso.org; awalland@eso.org
1602 Subject: Re: VLTI header keyword ISS PBLAxy START/END
1603 
1604 Attachments: VLTSW20060066.PDF
1605 Isabelle at al,
1606 
1607 The keyword still represents the value of projected baseline at the beginning and end of integration.
1608 The format is the same, but the definition of projected baseline is different, hence a new algorithm.
1609 Attached is the change request. The plan is to install this at Paranal end of September.
1610 The point is that pipelines should not break. I am waiting for your comments on this
1611 
1612 Below the 2 different algorithms (GIP is current, RMA is future) to compute PBLA.
1613 
1614 Cheers,
1615 Anders
1616 
1617 double pblaGIP (double alt, double az, double T1[3], double T2[3])
1618 {
1619 
1620  vltDOUBLE star[] = {0.0, 0.0, 0.0};
1621  vltDOUBLE baseline[] = {0.0, 0.0, 0.0};
1622  vltDOUBLE projBaseline[] = {0.0, 0.0, 0.0};
1623  vltDOUBLE sidOpd = 0.0;
1624  vltDOUBLE cosAlt = 0.0;
1625  vltDOUBLE sinAlt = 0.0;
1626  vltDOUBLE cosAz = 0.0;
1627  vltDOUBLE sinAz = 0.0;
1628 
1629  double gip;
1630 
1631  cosAlt = cos(alt * DDEG2RAD);
1632  sinAlt = sin(alt * DDEG2RAD);
1633  cosAz = cos(az * DDEG2RAD);
1634  sinAz = sin(az * DDEG2RAD);
1635 
1636  star[0] = sinAz * cosAlt;
1637  star[1] = (- cosAz) * cosAlt;
1638  star[2] = sinAlt;
1639 
1640  baseline[0] = T2[0] - T1[0];
1641  baseline[1] = T2[1] - T1[1];
1642  baseline[2] = T2[2] - T1[2];
1643 
1644  /* scalar product <star>*<baseline> */
1645  sidOpd = star[0] * baseline[0] + star[1] * baseline[1] + star[2] * baseline[2];
1646  /* projected baseline vector in XYZ coordinate system */
1647  projBaseline[0] = baseline[0] - sidOpd * star[0];
1648  projBaseline[1] = baseline[1] - sidOpd * star[1];
1649  projBaseline[2] = baseline[2] - sidOpd * star[2];
1650 
1651  gip = atan(projBaseline[0]/projBaseline[1]) * DRAD2DEG;
1652 
1653  return gip;
1654 
1655 }
1656 
1657 
1658 double pblaRMA (double alt, double az, double prltic, double T1[3], double T2[3])
1659 {
1660 
1661  vltDOUBLE a, A, A_b, p;
1662  vltDOUBLE sinpsi, cospsi, psi;
1663 
1664  double rma;
1665 
1666  /*
1667  * 1. Compute A, star azimuth, with FITS convention; 0=south, +90 west
1668  * VLT convention is 0=south, +90 east
1669  */
1670  A = (360 - az) * DDEG2RAD;
1671 
1672  /*
1673  * 2. Compute baseline azimuth on the platform
1674  * This is zero if T2 is south of T1 and +90 deg if T2 is west of T1.
1675  * It seems that DLCS applies the convention X pos to west and Y pos to south
1676  * for station coordinates (T vectors).
1677  * In a south-over-west convention for 'A_b' and 'a', the y-component
1678  * of the atan2(y,x) must represent +West and the x-component +South.
1679  * The vector from T1[.] to T2[.] is obtained as T2[.]-T1[.].
1680  */
1681  A_b = atan2( (T2[0] - T1[0]), (T2[1] - T1[1]) );
1682 
1683  /*
1684  * 3. Get a, star elevation
1685  * This is directly given by VLT altitude
1686  */
1687  a = alt * DDEG2RAD;
1688 
1689  /*
1690  * 4. Compute auxiliary angle psi
1691  */
1692  sinpsi = sin(A_b - A);
1693  cospsi = cos(A_b - A) * sin(a);
1694  psi = atan2(sinpsi,cospsi);
1695 
1696  /*
1697  * 5. Get parallactic angle.
1698  * This value is computed by ISS using standard slaPa
1699  */
1700  p = prltic * DDEG2RAD;
1701 
1702  /*
1703  * 6. Compute final angle
1704  *
1705  */
1706  rma = slaDranrm(p + psi + DPI) * DRAD2DEG;
1707 
1708  return rma;
1709 
1710 }
1711 
1712 Isabelle Percheron wrote:
1713 Anders
1714 
1715 I was checking with Cyrus about the uses of the keywords, the pipelines (MIDI
1716 and AMBER for sure) read it and in the case of MIDI uses it, I am stilll not
1717 sure if AMBER pipeline just retrieves it or uses it for other calculations, I
1718 guess they have to retrieve the baseline from somewhere maybe from the stations,
1719 object ...
1720 
1721 So just to be sure, could you confirm if this keyword will still represent the
1722 value of the projected baseline at the beginning of the integration and at the
1723 end. How is the format affected (still the same?). And last could you please
1724 tell us when this is implemented on Paranal for Cyrus to check.
1725 Thanks
1726 Isabelle
1727 
1728 #endif
1729