MIDI Pipeline Reference Manual  2.8.3
estimationFrgHSUndisp.c
1 /******************************************************************************
2 *******************************************************************************
3 * European Southern Observatory
4 * VLTI MIDI Data Reduction Software
5 *
6 * Module name: estimationFrgHSUndisp.c
7 * Description: Contains routines for all data preprocessing algorithms
8 *
9 * History:
10 * 12-Jul-03 (csabet) Created. Derived from (jmeisner 03-Feb-03)
11 *******************************************************************************
12 ******************************************************************************/
13 
14 /******************************************************************************
15 * Compiler directives
16 ******************************************************************************/
17 
18 /******************************************************************************
19 * Include files
20 ******************************************************************************/
21 #include <stdio.h>
22 #include <cpl.h>
23 #include <stdlib.h>
24 #include <math.h>
25 #include <string.h>
26 #include "midiGlobal.h"
27 #include "fft.h"
28 #include "complex_midi.h"
29 #include "statistics.h"
30 #include "diagnostics.h"
31 #include "errorHandling.h"
32 #include "midiLib.h"
33 #include "estimationFrgHSUndisp.h"
34 #include "photometry.h"
35 #include "visibility.h"
36 #include "calibration.h"
37 
38 /**********************************************************
39 * Constant definitions
40 **********************************************************/
41 
42 /*============================ C O D E A R E A ===========================*/
43 
44 
45 /******************************************************************************
46 * European Southern Observatory
47 * VLTI MIDI Data Reduction Software
48 *
49 * Module name: estimateFrgHSUndisp
50 * Input/Output: See function arguments to avoid duplication
51 * Description:
52 *
53 *
54 * History:
55 * 10-Jan-04 (csabet) Added several routines and made many modifications
56 * 09-Dec-03 (csabet) Modified the interface to accomodate development of findGoodScanRange
57 * 17-Sep-03 (jmeisner) Completed the code
58 * 21-Jul-03 (csabet) Created routine template
59 ******************************************************************************/
60 void estimateFrgHSUndisp (
61  CompressedData *compressedInterf, // In: Compressed interferometry data
62  CompressedData *compressedPhotA, // In: Compressed photometry data
63  CompressedData *compressedPhotB, // In: Compressed photometry data
64  FilterData *filterInfo, // In: Filter information
65  ImageFormat *formatInterf, // In: Points to the image format
66  ImageFormat *formatPhotomA, // In: Points to the image format
67  ImageFormat *formatPhotomB, // In: Points to the image format
68  RawVisibility *rawVis, // Ou: Result of visibilities
69  PhotometryResult *photometry) // Ou: Result of photometry. Added (csabet 16-Jan-04)
70 {
71 
72  // Local Declarations
73  // ------------------
74  const char routine[] = "estimateFrgHSUndisp";
75  float *accumPS, *accumPS1, *accumPS2;
76  float photomA[2], photomB[2], *photomErrA, *photomErrB;
77  float photomChop2ChopA[2]; // RMS of chop to chop variations.
78  float photomChop2ChopB[2]; // RMS of chop to chop variations.
79  float fractionalBandwidth;
80  int lofreq, hifreq;
81  float ratio_photA0_to_photA1, ratio_errA0_to_photA0, ratio_errA1_to_photA1, ratio_photB0_to_photB1,
82  ratio_errB0_to_photB0, ratio_errB1_to_photB1;
83 
84  // Algorithm
85  // ---------
86  if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking routine '%s'\n", routine);
87  if (diagnostic > 4) fprintf(midiReportPtr, "Invoking routine '%s'\n", routine);
88 
89  cpl_msg_info(cpl_func,"\nComputing Normalized visibilities from batch %d \n", batchNumber);
90  cpl_msg_info(cpl_func,"-------------------------------------------- \n");
91  fprintf(midiReportPtr, "\nComputing Normalized visibilities from batch %d \n", batchNumber);
92  fprintf(midiReportPtr, "-------------------------------------------- \n");
93 
94  /* Allocate memory */
95  photomErrA = (float *) calloc (2, sizeof (float));
96  photomErrB = (float *) calloc (2, sizeof (float));
97 
98  if (diagnostic) cpl_msg_info(cpl_func,"Running photometric files...\n" );
99  fprintf (midiReportPtr, "Running photometric files...\n" );
100  estimatePhotomUndisp (formatPhotomA, compressedPhotA, photomErrA, photomChop2ChopA, photomA);
101  estimatePhotomUndisp (formatPhotomB, compressedPhotB, photomErrB, photomChop2ChopB, photomB);
102 
103  // Singularity checks. (Added, csabet 12-Jan-04)
104  if (photomA[1] != 0.)
105  {
106  ratio_photA0_to_photA1 = photomA[0]/photomA[1];
107  ratio_errA1_to_photA1 = 100.F*photomErrA[1]/photomA[1];
108  }
109  else
110  {
111  ratio_photA0_to_photA1 = NOT_A_NUMBER;
112  ratio_errA1_to_photA1 = NOT_A_NUMBER;
113  }
114 
115  if (photomA[0] != 0.)
116  ratio_errA0_to_photA0 = 100.F*photomErrA[0]/photomA[0];
117  else
118  ratio_errA0_to_photA0 = NOT_A_NUMBER;
119 
120  if (photomB[1] != 0.)
121  {
122  ratio_photB0_to_photB1 = photomB[0]/photomB[1];
123  ratio_errB1_to_photB1 = 100.F*photomErrB[1]/photomB[1];
124  }
125  else
126  {
127  ratio_photB0_to_photB1 = NOT_A_NUMBER;
128  ratio_errB1_to_photB1 = NOT_A_NUMBER;
129  }
130 
131  // Singularity checks. (Added, csabet 12-Jan-04)
132  if (photomB[0] != 0.)
133  ratio_errB0_to_photB0 = 100.F*photomErrB[0]/photomB[0];
134  else
135  ratio_errB0_to_photB0 = NOT_A_NUMBER;
136 
137  if (diagnostic)cpl_msg_info(cpl_func,
138  "\nPhotometric results \n"
139  "------------------- \n"
140  " region0 region1 ratio RMS chop-to-chop net photometric err \n"
141  "Aopen %8.0f %8.0f %5.4f %4.1f%% %4.1f%% %4.1f%% %4.1f%% \n"
142  "Bopen %8.0f %8.0f %5.4f %4.1f%% %4.1f%% %4.1f%% %4.1f%% \n",
143  photomA[0], photomA[1], ratio_photA0_to_photA1, 100.F*photomChop2ChopA[0], 100.F*photomChop2ChopA[1],
144  ratio_errA0_to_photA0, ratio_errA1_to_photA1,
145  photomB[0], photomB[1], ratio_photB0_to_photB1, 100.F*photomChop2ChopB[0], 100.F*photomChop2ChopB[1],
146  ratio_errB0_to_photB0, ratio_errB1_to_photB1);
147 
148  fprintf(midiReportPtr,
149  "\nPhotometric results QCLOG \n"
150  "------------------- QCLOG \n"
151  " region0 region1 ratio RMS chop-to-chop net photometric err QCLOG \n"
152  "Aopen %8.0f %8.0f %5.4f %4.1f%% %4.1f%% %4.1f%% %4.1f%% QCLOG \n"
153  "Bopen %8.0f %8.0f %5.4f %4.1f%% %4.1f%% %4.1f%% %4.1f%% QCLOG \n",
154  photomA[0], photomA[1], ratio_photA0_to_photA1, 100.F*photomChop2ChopA[0], 100.F*photomChop2ChopA[1],
155  ratio_errA0_to_photA0, ratio_errA1_to_photA1,
156  photomB[0], photomB[1], ratio_photB0_to_photB1, 100.F*photomChop2ChopB[0], 100.F*photomChop2ChopB[1],
157  ratio_errB0_to_photB0, ratio_errB1_to_photB1);
158 
159  // Temporarily hand over results and clean up later. Added. csabet 16-Jan-04
160  photometry->photomA[0] = photomA[0];
161  photometry->photomAErr[0] = photomErrA[0];
162  photometry->photomA[1] = photomA[1];
163  photometry->photomAErr[1] = photomErrA[1];
164 
165  photometry->photomB[0] = photomB[0];
166  photometry->photomBErr[0] = photomErrB[0];
167  photometry->photomB[1] = photomB[1];
168  photometry->photomBErr[1] = photomErrB[1];
169 
170  photometry->ratioPhotomA0toA1 = ratio_photA0_to_photA1;
171  photometry->ratioPhotomB0toB1 = ratio_photB0_to_photB1;
172 
173  photometry->chop2ChopAErr[0] = photomChop2ChopA[0];
174  photometry->chop2ChopAErr[1] = photomChop2ChopA[1];
175  photometry->chop2ChopBErr[0] = photomChop2ChopB[0];
176  photometry->chop2ChopBErr[1] = photomChop2ChopB[1];
177 
178  // Added. csabet 12-Jan-04
179  if (photomA[1] == 0. || photomA[0] == 0. || photomB[1] == 0. || photomB[0] == 0.)
180  {
181  sprintf (midiMessage, "A value of %.4f is a reject result. QCLOG", (float)NOT_A_NUMBER);
182  midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
183  }
184 
185  // Preset for the fft algorithm
186  if (diagnostic) cpl_msg_info(cpl_func,"FFT size = %d\n",formatInterf->fftsize);
187  fprintf (midiReportPtr, "FFT size = %d\n",formatInterf->fftsize);
188  SetFFTsize (formatInterf->fftsize);
189 
190  // Allocate 3 arrays for the (differenced) power spectrum accumulated from N scans
191  accumPS = (float *) calloc (formatInterf->fftsize/2, sizeof(float));
192  accumPS1 = (float *) calloc (formatInterf->fftsize/2, sizeof(float));
193  accumPS2 = (float *) calloc (formatInterf->fftsize/2, sizeof(float));
194 
195  // Figure out the bandwidth from the filter description:
196  fractionalBandwidth = 2.0F * (filterInfo->optFreqHi - filterInfo->optFreqLo)/formatInterf->optFreqCal;
197  lofreq = (int) ((0.9F * ((float) formatInterf->fftsize) * filterInfo->optFreqLo)/formatInterf->optFreqCal);
198  hifreq = (int) ((1.1F * ((float) formatInterf->fftsize) * filterInfo->optFreqHi)/formatInterf->optFreqCal);
199 
200  if (hifreq >= (formatInterf->fftsize/2))
201  hifreq = formatInterf->fftsize/2 - 1;
202 
203  if (lofreq >= hifreq)
204  lofreq = hifreq - 1;
205 
206  if (diagnostic)cpl_msg_info(cpl_func,
207  "\nBandwidth used \n"
208  "-------------- \n"
209  "Specified (Min, Max) THz = %6.3f, %6.3f \n"
210  "Integer (Min, Max) = %d, %d \n"
211  "Fractional THz = %6.3f \n"
212  "Folding frequency THz = %6.3f at %2d \n\n",
213  filterInfo->optFreqLo, filterInfo->optFreqHi, lofreq, hifreq,
214  fractionalBandwidth, .5F*formatInterf->optFreqCal, formatInterf->fftsize/2);
215  fprintf (midiReportPtr,
216  "\nBandwidth used QCLOG \n"
217  "-------------- QCLOG \n"
218  "Specified (Min, Max) THz = %6.3f, %6.3f QCLOG \n"
219  "Integer (Min, Max) = %d, %d QCLOG \n"
220  "Fractional THz = %6.3f QCLOG \n"
221  "Folding frequency THz = %6.3f at %2d QCLOG \n\n",
222  filterInfo->optFreqLo, filterInfo->optFreqHi, lofreq, hifreq,
223  fractionalBandwidth, .5F*formatInterf->optFreqCal, formatInterf->fftsize/2);
224 
225  accumulatePowerSpectra (0, formatInterf, compressedInterf->allSpectrum, compressedInterf->badScanList,
226  formatInterf->numOfScansProcessed, accumPS);
227 
228  rawVis->visSqrd = estimateCorrelatedFlux2 (formatInterf, accumPS, fractionalBandwidth,
229  lofreq, hifreq, 0.F);
230 
231  rawVis->vis = estimateCorrelatedFlux (formatInterf, accumPS, lofreq, hifreq, 0.F);
232 
233  accumulatePowerSpectra (1, formatInterf, compressedInterf->allSpectrum, compressedInterf->badScanList,
234  formatInterf->numOfScansProcessed, accumPS1);
235 
236  rawVis->visSqrd1= estimateCorrelatedFlux2 (formatInterf, accumPS1, fractionalBandwidth,
237  lofreq, hifreq, 0.F);
238 
239  rawVis->vis1 = estimateCorrelatedFlux (formatInterf, accumPS1, lofreq, hifreq, 0.F);
240 
241  accumulatePowerSpectra (2, formatInterf, compressedInterf->allSpectrum, compressedInterf->badScanList,
242  formatInterf->numOfScansProcessed, accumPS2);
243 
244  rawVis->visSqrd2 = estimateCorrelatedFlux2 (formatInterf, accumPS2, fractionalBandwidth,
245  lofreq, hifreq, 0.F);
246 
247  rawVis->vis2 = estimateCorrelatedFlux (formatInterf, accumPS2, lofreq, hifreq, 0.F);
248 
249  // This requires all the photometric processing, as well as vis, vis1, vis2
250  normalizeVis (rawVis, photomA, photomB);
251 
252  free (photomErrA);
253  free (photomErrB);
254  free (accumPS);
255  free (accumPS1);
256  free (accumPS2);
257 
258  return;
259 }
260 /*****************************************************************************/
261 
262 
263 /******************************************************************************
264 * European Southern Observatory
265 * VLTI MIDI Data Reduction Software
266 *
267 * Module name: accumulatePowerSpectra
268 * Input/Output: See function arguments to avoid duplication
269 * Description:
270 *
271 * History:
272 * 07-Jan-04 (csabet) Created. Derived from (jmeisner)
273 ******************************************************************************/
274 void accumulatePowerSpectra (
275  int region, // In: region to be processed
276  ImageFormat *imageformat, // In: Points to the image format
277  float *allSpectrum, // In: Pointer to the entire spectra
278  int *badScanList, // In: Scan range mask
279  int numOfScansProcessed, // In: Number of scans processed
280  float *accumPS) // Ou: Points to accumulated power spectra
281 {
282 
283  // Local Declarations
284  // ------------------
285  const char routine[] = "accumulatePowerSpectra";
286  int i, j, fftSizeHalf;
287  float *floatPtr, norm, plotfreqcal;
288 
289 
290  // Algorithm
291  // ---------
292  if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking routine '%s'\n", routine);
293  if (diagnostic > 4) fprintf(midiReportPtr, "Invoking routine '%s'\n", routine);
294 
295  // Initialize
296  fftSizeHalf = 0.5 * imageformat->fftsize;
297  plotfreqcal = imageformat->optFreqCal/((float)imageformat->fftsize);
298  if (imageformat->optFreqCal == 0.F) plotfreqcal = 1.F; // So axis will just say 0,1,2,3....
299 
300  // Accumulate scans. First make signal point to the correct region
301  floatPtr = allSpectrum + (region * imageformat->numOfScans * fftSizeHalf);
302  for (j = 0; j < imageformat->numOfScans; j++)
303  {
304  if (badScanList[j] == 0) // For each good scan
305  {
306  for (i = 0; i < fftSizeHalf; i++) // And for each element of the power spectra
307  accumPS[i] += *floatPtr++; // Add in the element i from spectrum
308  }
309  else
310  {
311  for (i = 0; i < fftSizeHalf; i++)
312  floatPtr++;
313  }
314  }
315 
316  // Normalize (to get average PS)
317  if (numOfScansProcessed > 0) // Check singularity
318  norm = 1.0 / ((float) numOfScansProcessed);
319  else
320  norm = 1.0;
321 
322  for (i = 0; i < fftSizeHalf; i++)
323  accumPS[i] *= norm;
324 
325  // Tabular output in report
326  fprintf (midiReportPtr, "\n--------------------------------------------------------\n"
327  "Region %d incoh power spectral amplitude, including noise\n\n", region);
328  for (i = 0; i < fftSizeHalf; i++)
329  fprintf (midiReportPtr, "%4.1f %8.1f\n", plotfreqcal * ((float)i), sqrtp(accumPS[i]));
330 
331  fprintf (midiReportPtr, "\n--------------------------------------------------------\n\n");
332 
333  return;
334 }
335 /*****************************************************************************/
336 
337 
338 
339 /******************************************************************************
340 * European Southern Observatory
341 * VLTI MIDI Data Reduction Software
342 *
343 * Module name: estimateCorrelatedFlux
344 * Input/Output: See function arguments to avoid duplication
345 * Description: This is the incoherent visibility AMPLITUDE estimator. Currently
346 * does NOT use a correction for weak channels. (which doesn't work well)
347 * History:
348 * 07-Jan-04 (csabet) Created. Derived from (jmeisner)
349 ******************************************************************************/
350 float estimateCorrelatedFlux ( /* Ou: Visibility */
351  ImageFormat *imageFormat, /* In: Points to the image format */
352  float *accumPS, /* In: Points to accumulated power spectra */
353  int loFreq, /* In: Lower limit limit of the bandwidth */
354  int hiFreq, /* In: Higher limit of the bandwidth */
355  float noiselev) /* In: If noiselev ==0, will decide using spectral range above hifreq */
356 {
357 
358  /* Local Declarations
359  --------------------*/
360  const char routine[] = "estimateCorrelatedFlux";
361  int i, fftSizeHalf;
362  float Accum = 0.0, result;
363 
364  /* Algorithm
365  -----------*/
366  if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking routine '%s' \n", routine);
367  if (diagnostic > 4) fprintf(midiReportPtr, "Invoking routine '%s' \n", routine);
368 
369  /* Initialize */
370  fftSizeHalf = 0.5 * imageFormat->fftsize;
371 
372  if (noiselev == 0.0)
373  {
374  for (i = hiFreq; i < fftSizeHalf; i++)
375  Accum += accumPS[i];
376 
377  if ((fftSizeHalf - hiFreq) != 0) /* Check singularity */
378  noiselev = Accum/((float) (fftSizeHalf - hiFreq));
379  else
380  noiselev = Accum/VERY_SMALL_FLOAT;
381 
382  cpl_msg_info(cpl_func,"Estimated noise power level = %f\n", noiselev);
383  fprintf (midiReportPtr, "Estimated noise power level = %f\n", noiselev);
384  }
385 
386  /* Now find the amplitude within specified bandlimits */
387  Accum = 0.0;
388  for (i = loFreq; i <= hiFreq; i++) /* How do you ensure that this range is within the allocated memory for accumPS? csabet 10-Nov-03 */
389  Accum += sqrtp (accumPS[i] - noiselev);
390 
391  result = Accum;
392  cpl_msg_info(cpl_func,"Unnormalized vis amplitude = %7f \n\n", result);
393  fprintf (midiReportPtr, "Unnormalized vis amplitude = %7f \n\n", result);
394 
395  return (result);
396 }
397 /*****************************************************************************/
398 
399 
400 
401 /******************************************************************************
402 * European Southern Observatory
403 * VLTI MIDI Data Reduction Software
404 *
405 * Module name: estimateCorrelatedFlux2
406 * Input/Output: See function arguments to avoid duplication
407 * Description:
408 *
409 *
410 * History:
411 * 07-Jan-04 (csabet) Created. Derived from (jmeisner)
412 ******************************************************************************/
413 float estimateCorrelatedFlux2 ( // Ou: Visibility squared
414  ImageFormat *imageFormat, // In: Points to the image format
415  float *accumPS, // In: Points to accumulated power spectra
416  float bandwidth, // In: Best estimate of effective fractional bandwidth
417  int loFreq, // In: Lower limit limit of the bandwidth
418  int hiFreq, // In: Higher limit of the bandwidth
419  float noiselev) // In: If noiselev ==0, will decide using spectral range above hifreq
420 {
421 
422  /* Local Declarations
423  --------------------*/
424  const char routine[] = "estimateCorrelatedFlux2";
425  int i, fftSizeHalf;
426  float Accum = 0.0, result;
427 
428  /* Algorithm
429  -----------*/
430  if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking routine '%s' \n", routine);
431  if (diagnostic > 4) fprintf(midiReportPtr, "Invoking routine '%s' \n", routine);
432 
433  /* Initialize */
434  fftSizeHalf = 0.5 * imageFormat->fftsize;
435 
436  if(noiselev == 0.0)
437  {
438  for (i = hiFreq; i < fftSizeHalf; i++)
439  Accum += accumPS[i];
440 
441  if ((fftSizeHalf - hiFreq) != 0) /* Check singularity */
442  noiselev = Accum/((float) (fftSizeHalf - hiFreq));
443  else
444  noiselev = Accum/VERY_SMALL_FLOAT;
445 
446  cpl_msg_info(cpl_func,"Estimated noise power level = %f\n", noiselev);
447  fprintf (midiReportPtr, "Estimated noise power level = %f\n", noiselev);
448  }
449 
450  /* Now find the power within specified bandlimits */
451  Accum = 0.0;
452  for (i = loFreq; i <= hiFreq; i++) /* How do you ensure that this range is within the allocated memory region for accumPS? csabet 10-Nov-03 */
453  Accum += accumPS[i];
454 
455  result = 0.5 * ((float) imageFormat->fftsize) * bandwidth * (Accum - noiselev * (hiFreq - loFreq + 1));
456 
457  cpl_msg_info(cpl_func,"Unnormalized vis^2 = %7f \n\n", result);
458  fprintf (midiReportPtr, "Unnormalized vis^2 = %7f \n\n", result);
459 
460  return (result);
461 }
462 /*****************************************************************************/
463