estimationFrgHSUndisp.c

00001 /******************************************************************************
00002 *******************************************************************************
00003 *               European Southern Observatory
00004 *             VLTI MIDI Data Reduction Software
00005 *
00006 * Module name:  estimationFrgHSUndisp.c
00007 * Description:  Contains routines for all data preprocessing algorithms
00008 *
00009 * History:
00010 * 12-Jul-03     (csabet) Created. Derived from (jmeisner 03-Feb-03)
00011 *******************************************************************************
00012 ******************************************************************************/
00013 
00014 /******************************************************************************
00015 *   Compiler directives
00016 ******************************************************************************/
00017 
00018 /******************************************************************************
00019 *   Include files
00020 ******************************************************************************/
00021 #include <stdio.h>
00022 #include <cpl.h>
00023 #include <stdlib.h>
00024 #include <math.h>
00025 #include <string.h>
00026 #include "midiGlobal.h"
00027 #include "fft.h"
00028 #include "complex_midi.h"
00029 #include "statistics.h"
00030 #include "diagnostics.h"
00031 #include "errorHandling.h"
00032 #include "midiLib.h"
00033 #include "estimationFrgHSUndisp.h"
00034 #include "photometry.h"
00035 #include "visibility.h"
00036 #include "calibration.h"
00037 
00038 /**********************************************************
00039 *   Constant definitions
00040 **********************************************************/
00041  
00042 /*============================ C O D E    A R E A ===========================*/
00043  
00044 
00045 /******************************************************************************
00046 *               European Southern Observatory
00047 *            VLTI MIDI Data Reduction Software
00048 *
00049 * Module name:  estimateFrgHSUndisp
00050 * Input/Output: See function arguments to avoid duplication
00051 * Description:
00052 *
00053 *
00054 * History:
00055 * 10-Jan-04     (csabet) Added several routines and made many modifications
00056 * 09-Dec-03     (csabet) Modified the interface to accomodate development of findGoodScanRange
00057 * 17-Sep-03     (jmeisner) Completed the code
00058 * 21-Jul-03     (csabet) Created routine template
00059 ******************************************************************************/
00060 void estimateFrgHSUndisp (
00061     CompressedData        *compressedInterf,    // In: Compressed interferometry data
00062     CompressedData        *compressedPhotA,    // In: Compressed photometry data
00063     CompressedData        *compressedPhotB,    // In: Compressed photometry data
00064     FilterData            *filterInfo,        // In: Filter information
00065     ImageFormat            *formatInterf,        // In: Points to the image format
00066     ImageFormat            *formatPhotomA,        // In: Points to the image format
00067     ImageFormat            *formatPhotomB,        // In: Points to the image format
00068     RawVisibility        *rawVis,            // Ou: Result of visibilities
00069     PhotometryResult    *photometry)        // Ou: Result of photometry. Added (csabet 16-Jan-04)
00070 {
00071 
00072     //    Local Declarations
00073     //    ------------------
00074     const char  routine[] = "estimateFrgHSUndisp";
00075     float        *accumPS, *accumPS1, *accumPS2;
00076     float        photomA[2], photomB[2], *photomErrA, *photomErrB;
00077     float        photomChop2ChopA[2];    // RMS of chop to chop variations.
00078     float        photomChop2ChopB[2];     // RMS of chop to chop variations.
00079     float        fractionalBandwidth;
00080     int            lofreq, hifreq;
00081     float        ratio_photA0_to_photA1, ratio_errA0_to_photA0, ratio_errA1_to_photA1, ratio_photB0_to_photB1,
00082                 ratio_errB0_to_photB0, ratio_errB1_to_photB1;
00083 
00084     //    Algorithm
00085     //    ---------
00086     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s'\n", routine);
00087     if (diagnostic > 4) fprintf(midiReportPtr, "Invoking      routine   '%s'\n", routine);
00088 
00089    cpl_msg_info(cpl_func,"\nComputing Normalized visibilities from batch  %d \n", batchNumber);
00090    cpl_msg_info(cpl_func,"-------------------------------------------- \n");
00091     fprintf(midiReportPtr, "\nComputing Normalized visibilities from batch  %d \n", batchNumber);
00092     fprintf(midiReportPtr, "-------------------------------------------- \n");
00093 
00094     /*  Allocate memory */
00095     photomErrA = (float *) calloc (2, sizeof (float));
00096     photomErrB = (float *) calloc (2, sizeof (float));
00097 
00098     if (diagnostic) cpl_msg_info(cpl_func,"Running photometric files...\n" );
00099     fprintf (midiReportPtr, "Running photometric files...\n" );
00100     estimatePhotomUndisp (formatPhotomA, compressedPhotA, photomErrA, photomChop2ChopA, photomA);
00101     estimatePhotomUndisp (formatPhotomB, compressedPhotB, photomErrB, photomChop2ChopB, photomB);
00102 
00103     //    Singularity checks.    (Added, csabet 12-Jan-04)
00104     if (photomA[1] != 0.)
00105     {
00106         ratio_photA0_to_photA1 = photomA[0]/photomA[1];
00107         ratio_errA1_to_photA1 = 100.F*photomErrA[1]/photomA[1];
00108     }
00109     else
00110     {
00111         ratio_photA0_to_photA1 = NOT_A_NUMBER;
00112         ratio_errA1_to_photA1 = NOT_A_NUMBER;
00113     }
00114 
00115     if (photomA[0] != 0.)
00116         ratio_errA0_to_photA0 = 100.F*photomErrA[0]/photomA[0];
00117     else
00118         ratio_errA0_to_photA0 = NOT_A_NUMBER;
00119 
00120     if (photomB[1] != 0.)
00121     {
00122         ratio_photB0_to_photB1 = photomB[0]/photomB[1];
00123         ratio_errB1_to_photB1 = 100.F*photomErrB[1]/photomB[1];
00124     }
00125     else
00126     {
00127         ratio_photB0_to_photB1 = NOT_A_NUMBER;
00128         ratio_errB1_to_photB1 = NOT_A_NUMBER;
00129     }
00130 
00131     //    Singularity checks.    (Added, csabet 12-Jan-04)
00132     if (photomB[0] != 0.)
00133         ratio_errB0_to_photB0 = 100.F*photomErrB[0]/photomB[0];
00134     else
00135         ratio_errB0_to_photB0 = NOT_A_NUMBER;
00136 
00137     if (diagnostic)cpl_msg_info(cpl_func,
00138         "\nPhotometric results \n"
00139         "------------------- \n"
00140         "          region0    region1   ratio        RMS chop-to-chop    net photometric err \n"
00141         "Aopen   %8.0f   %8.0f    %5.4f        %4.1f%%   %4.1f%%       %4.1f%%   %4.1f%% \n"
00142         "Bopen   %8.0f   %8.0f    %5.4f        %4.1f%%   %4.1f%%       %4.1f%%   %4.1f%% \n",
00143         photomA[0], photomA[1], ratio_photA0_to_photA1, 100.F*photomChop2ChopA[0], 100.F*photomChop2ChopA[1],
00144         ratio_errA0_to_photA0,  ratio_errA1_to_photA1,
00145         photomB[0], photomB[1], ratio_photB0_to_photB1, 100.F*photomChop2ChopB[0], 100.F*photomChop2ChopB[1],
00146         ratio_errB0_to_photB0, ratio_errB1_to_photB1);
00147 
00148     fprintf(midiReportPtr,
00149         "\nPhotometric results                                                                  QCLOG \n"
00150         "-------------------                                                                  QCLOG \n"
00151         "          region0    region1   ratio        RMS chop-to-chop    net photometric err  QCLOG \n"
00152         "Aopen   %8.0f   %8.0f    %5.4f        %4.1f%%   %4.1f%%       %4.1f%%   %4.1f%%      QCLOG \n"
00153         "Bopen   %8.0f   %8.0f    %5.4f        %4.1f%%   %4.1f%%       %4.1f%%   %4.1f%%      QCLOG \n",
00154         photomA[0], photomA[1], ratio_photA0_to_photA1, 100.F*photomChop2ChopA[0], 100.F*photomChop2ChopA[1],
00155         ratio_errA0_to_photA0,  ratio_errA1_to_photA1,
00156         photomB[0], photomB[1], ratio_photB0_to_photB1, 100.F*photomChop2ChopB[0], 100.F*photomChop2ChopB[1],
00157         ratio_errB0_to_photB0, ratio_errB1_to_photB1);
00158 
00159     //    Temporarily hand over results and clean up later. Added. csabet 16-Jan-04
00160     photometry->photomA[0] = photomA[0];
00161     photometry->photomAErr[0] = photomErrA[0];
00162     photometry->photomA[1] = photomA[1];
00163     photometry->photomAErr[1] = photomErrA[1];
00164 
00165     photometry->photomB[0] = photomB[0];
00166     photometry->photomBErr[0] = photomErrB[0];
00167     photometry->photomB[1] = photomB[1];
00168     photometry->photomBErr[1] = photomErrB[1];
00169 
00170     photometry->ratioPhotomA0toA1 = ratio_photA0_to_photA1;
00171     photometry->ratioPhotomB0toB1 = ratio_photB0_to_photB1;
00172 
00173     photometry->chop2ChopAErr[0] = photomChop2ChopA[0];
00174     photometry->chop2ChopAErr[1] = photomChop2ChopA[1];
00175     photometry->chop2ChopBErr[0] = photomChop2ChopB[0];
00176     photometry->chop2ChopBErr[1] = photomChop2ChopB[1];
00177 
00178     //    Added. csabet 12-Jan-04
00179     if (photomA[1] == 0. || photomA[0] == 0. || photomB[1] == 0. || photomB[0] == 0.)
00180     {
00181         sprintf (midiMessage, "A value of  %.4f  is a reject result. QCLOG", (float)NOT_A_NUMBER);
00182         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
00183     }
00184  
00185     //    Preset for the fft algorithm
00186     if (diagnostic) cpl_msg_info(cpl_func,"FFT size = %d\n",formatInterf->fftsize); 
00187     fprintf (midiReportPtr, "FFT size = %d\n",formatInterf->fftsize); 
00188     SetFFTsize (formatInterf->fftsize);
00189     
00190     //    Allocate 3 arrays for the (differenced) power spectrum accumulated from N scans
00191     accumPS = (float *) calloc (formatInterf->fftsize/2, sizeof(float));
00192     accumPS1 = (float *) calloc (formatInterf->fftsize/2, sizeof(float));
00193     accumPS2 = (float *) calloc (formatInterf->fftsize/2, sizeof(float));
00194     
00195     // Figure out the bandwidth from the filter description:
00196     fractionalBandwidth = 2.0F * (filterInfo->optFreqHi - filterInfo->optFreqLo)/formatInterf->optFreqCal;
00197     lofreq = (int) ((0.9F * ((float) formatInterf->fftsize) * filterInfo->optFreqLo)/formatInterf->optFreqCal);
00198     hifreq = (int) ((1.1F * ((float) formatInterf->fftsize) * filterInfo->optFreqHi)/formatInterf->optFreqCal);
00199 
00200     if (hifreq >= (formatInterf->fftsize/2))
00201         hifreq = formatInterf->fftsize/2 - 1;
00202 
00203     if (lofreq >= hifreq)
00204         lofreq = hifreq - 1;
00205 
00206     if (diagnostic)cpl_msg_info(cpl_func,
00207         "\nBandwidth used \n"
00208         "-------------- \n"
00209         "Specified (Min, Max) THz = %6.3f, %6.3f \n"
00210         "Integer   (Min, Max)     = %d,  %d \n"
00211         "Fractional THz           = %6.3f \n"
00212         "Folding frequency THz    = %6.3f at %2d \n\n",
00213         filterInfo->optFreqLo, filterInfo->optFreqHi, lofreq, hifreq,
00214         fractionalBandwidth, .5F*formatInterf->optFreqCal, formatInterf->fftsize/2);
00215     fprintf (midiReportPtr,
00216         "\nBandwidth used                             QCLOG \n"
00217         "--------------                             QCLOG \n"
00218         "Specified (Min, Max) THz = %6.3f, %6.3f    QCLOG \n"
00219         "Integer   (Min, Max)     = %d, %d          QCLOG \n"
00220         "Fractional THz           = %6.3f           QCLOG \n"
00221         "Folding frequency THz    = %6.3f at %2d    QCLOG \n\n",
00222         filterInfo->optFreqLo, filterInfo->optFreqHi, lofreq, hifreq,
00223         fractionalBandwidth, .5F*formatInterf->optFreqCal, formatInterf->fftsize/2);
00224  
00225     accumulatePowerSpectra (0, formatInterf, compressedInterf->allSpectrum, compressedInterf->badScanList,
00226         formatInterf->numOfScansProcessed, accumPS);
00227 
00228     rawVis->visSqrd = estimateCorrelatedFlux2 (formatInterf, accumPS, fractionalBandwidth,
00229         lofreq, hifreq, 0.F);
00230 
00231     rawVis->vis = estimateCorrelatedFlux (formatInterf, accumPS, lofreq, hifreq, 0.F);
00232 
00233     accumulatePowerSpectra (1, formatInterf, compressedInterf->allSpectrum, compressedInterf->badScanList,
00234         formatInterf->numOfScansProcessed, accumPS1);
00235         
00236     rawVis->visSqrd1= estimateCorrelatedFlux2 (formatInterf, accumPS1, fractionalBandwidth,
00237         lofreq, hifreq, 0.F);
00238         
00239     rawVis->vis1 = estimateCorrelatedFlux (formatInterf, accumPS1, lofreq, hifreq, 0.F);
00240 
00241     accumulatePowerSpectra (2, formatInterf, compressedInterf->allSpectrum, compressedInterf->badScanList,
00242         formatInterf->numOfScansProcessed, accumPS2);
00243         
00244     rawVis->visSqrd2 = estimateCorrelatedFlux2 (formatInterf, accumPS2, fractionalBandwidth,
00245         lofreq, hifreq, 0.F);
00246         
00247     rawVis->vis2 = estimateCorrelatedFlux (formatInterf, accumPS2, lofreq, hifreq, 0.F);
00248 
00249     //    This requires all the photometric processing, as well as vis, vis1, vis2
00250     normalizeVis (rawVis, photomA, photomB);
00251 
00252     free (photomErrA);
00253     free (photomErrB);
00254     free (accumPS);
00255     free (accumPS1);
00256     free (accumPS2);
00257 
00258     return;
00259 }
00260 /*****************************************************************************/
00261 
00262 
00263 /******************************************************************************
00264 *               European Southern Observatory
00265 *            VLTI MIDI Data Reduction Software
00266 *
00267 * Module name:  accumulatePowerSpectra
00268 * Input/Output: See function arguments to avoid duplication
00269 * Description:
00270 *
00271 * History:
00272 * 07-Jan-04     (csabet) Created. Derived from (jmeisner)
00273 ******************************************************************************/
00274 void accumulatePowerSpectra (
00275     int            region,                    // In: region to be processed
00276     ImageFormat    *imageformat,            // In: Points to the image format
00277     float        *allSpectrum,            // In: Pointer to the entire spectra
00278     int            *badScanList,            // In: Scan range mask
00279     int            numOfScansProcessed,    // In: Number of scans processed
00280     float        *accumPS)                // Ou: Points to accumulated power spectra
00281 {
00282 
00283     //    Local Declarations
00284     //    ------------------
00285     const char  routine[] = "accumulatePowerSpectra";
00286     int         i, j, fftSizeHalf;
00287     float       *floatPtr, norm, plotfreqcal;
00288  
00289 
00290     //    Algorithm
00291     //    ---------
00292     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s'\n", routine);
00293     if (diagnostic > 4) fprintf(midiReportPtr, "Invoking      routine   '%s'\n", routine);
00294     
00295     //    Initialize
00296     fftSizeHalf = 0.5 * imageformat->fftsize;
00297     plotfreqcal = imageformat->optFreqCal/((float)imageformat->fftsize);
00298     if (imageformat->optFreqCal == 0.F)    plotfreqcal = 1.F;    // So axis will just say 0,1,2,3....
00299 
00300     //    Accumulate scans. First make signal point to the correct region
00301     floatPtr = allSpectrum + (region * imageformat->numOfScans * fftSizeHalf);
00302     for (j = 0; j < imageformat->numOfScans; j++)
00303     {
00304         if (badScanList[j] == 0)    // For each good scan
00305         {
00306             for (i = 0; i < fftSizeHalf; i++)    // And for each element of the power spectra
00307               accumPS[i] += *floatPtr++;        // Add in the element i from spectrum
00308         }
00309         else
00310         {
00311             for (i = 0; i < fftSizeHalf; i++)
00312               floatPtr++;
00313         }
00314     }
00315 
00316     //    Normalize (to get average PS)
00317     if (numOfScansProcessed > 0)    // Check singularity
00318         norm = 1.0 / ((float) numOfScansProcessed);
00319     else
00320         norm = 1.0;
00321 
00322     for (i = 0; i < fftSizeHalf; i++)
00323         accumPS[i] *= norm;
00324 
00325     //    Tabular output in report
00326     fprintf (midiReportPtr, "\n--------------------------------------------------------\n"
00327                             "Region %d incoh power spectral amplitude, including noise\n\n", region);
00328     for (i = 0; i < fftSizeHalf; i++)
00329         fprintf (midiReportPtr, "%4.1f      %8.1f\n", plotfreqcal * ((float)i), sqrtp(accumPS[i]));
00330 
00331     fprintf (midiReportPtr, "\n--------------------------------------------------------\n\n");
00332 
00333     return;
00334 }
00335 /*****************************************************************************/
00336 
00337 
00338 
00339 /******************************************************************************
00340 *               European Southern Observatory
00341 *            VLTI MIDI Data Reduction Software
00342 *
00343 * Module name:  estimateCorrelatedFlux
00344 * Input/Output: See function arguments to avoid duplication
00345 * Description:  This is the incoherent visibility AMPLITUDE estimator. Currently
00346 *               does NOT use a correction for weak channels. (which doesn't work well)
00347 * History:
00348 * 07-Jan-04     (csabet) Created. Derived from (jmeisner)
00349 ******************************************************************************/
00350 float estimateCorrelatedFlux (      /*  Ou: Visibility */
00351     ImageFormat *imageFormat,       /*  In: Points to the image format */
00352     float       *accumPS,           /*  In: Points to accumulated power spectra */
00353     int         loFreq,             /*  In: Lower limit limit of the bandwidth */
00354     int         hiFreq,             /*  In: Higher limit of the bandwidth */
00355     float       noiselev)           /*  In: If noiselev ==0, will decide using spectral range above hifreq */
00356 {
00357 
00358     /*  Local Declarations
00359     --------------------*/
00360     const char  routine[] = "estimateCorrelatedFlux";
00361     int         i, fftSizeHalf;
00362     float       Accum = 0.0, result;
00363 
00364     /*  Algorithm
00365     -----------*/
00366     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s'  \n", routine);
00367     if (diagnostic > 4) fprintf(midiReportPtr, "Invoking      routine   '%s'  \n", routine);    
00368 
00369     /*  Initialize */
00370     fftSizeHalf = 0.5 * imageFormat->fftsize;
00371 
00372     if (noiselev == 0.0)
00373     {
00374         for (i = hiFreq; i < fftSizeHalf; i++)
00375             Accum += accumPS[i];
00376 
00377         if ((fftSizeHalf - hiFreq) != 0)    /*  Check singularity */
00378             noiselev = Accum/((float) (fftSizeHalf - hiFreq));
00379         else
00380             noiselev = Accum/VERY_SMALL_FLOAT;
00381 
00382        cpl_msg_info(cpl_func,"Estimated noise power level = %f\n", noiselev);
00383         fprintf (midiReportPtr, "Estimated noise power level = %f\n", noiselev);
00384     }
00385 
00386     /*  Now find the amplitude within specified bandlimits */
00387     Accum = 0.0;
00388     for (i = loFreq; i <= hiFreq; i++)  /*  How do you ensure that this range is within the allocated memory for  accumPS?  csabet 10-Nov-03 */
00389         Accum += sqrtp (accumPS[i] - noiselev);
00390 
00391     result = Accum;
00392    cpl_msg_info(cpl_func,"Unnormalized vis amplitude  = %7f  \n\n", result);
00393     fprintf (midiReportPtr, "Unnormalized vis amplitude  = %7f  \n\n", result);
00394 
00395     return (result);
00396 }
00397 /*****************************************************************************/
00398 
00399 
00400 
00401 /******************************************************************************
00402 *               European Southern Observatory
00403 *            VLTI MIDI Data Reduction Software
00404 *
00405 * Module name:  estimateCorrelatedFlux2
00406 * Input/Output: See function arguments to avoid duplication
00407 * Description:
00408 *
00409 *
00410 * History:
00411 * 07-Jan-04     (csabet) Created. Derived from (jmeisner)
00412 ******************************************************************************/
00413 float estimateCorrelatedFlux2 (    // Ou: Visibility squared
00414     ImageFormat *imageFormat,    // In: Points to the image format
00415     float       *accumPS,        // In: Points to accumulated power spectra
00416     float       bandwidth,        // In: Best estimate of effective fractional bandwidth
00417     int         loFreq,            // In: Lower limit limit of the bandwidth
00418     int         hiFreq,            // In: Higher limit of the bandwidth
00419     float       noiselev)        // In: If noiselev ==0, will decide using spectral range above hifreq
00420 {
00421 
00422     /*  Local Declarations
00423     --------------------*/
00424     const char  routine[] = "estimateCorrelatedFlux2";
00425     int         i, fftSizeHalf;
00426     float       Accum = 0.0, result;
00427 
00428     /*  Algorithm
00429     -----------*/
00430     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s'  \n", routine);
00431     if (diagnostic > 4) fprintf(midiReportPtr, "Invoking      routine   '%s'  \n", routine);    
00432 
00433     /*  Initialize */
00434     fftSizeHalf = 0.5 * imageFormat->fftsize;
00435 
00436     if(noiselev == 0.0)
00437     {
00438         for (i = hiFreq; i < fftSizeHalf; i++)
00439             Accum += accumPS[i];
00440 
00441         if ((fftSizeHalf - hiFreq) != 0)    /*  Check singularity */
00442             noiselev = Accum/((float) (fftSizeHalf - hiFreq));
00443         else
00444             noiselev = Accum/VERY_SMALL_FLOAT;
00445 
00446        cpl_msg_info(cpl_func,"Estimated noise power level = %f\n", noiselev);
00447         fprintf (midiReportPtr, "Estimated noise power level = %f\n", noiselev);
00448     }
00449 
00450     /* Now find the power within specified bandlimits */
00451     Accum = 0.0;
00452     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 */
00453         Accum += accumPS[i];
00454 
00455     result = 0.5 * ((float) imageFormat->fftsize) * bandwidth * (Accum - noiselev * (hiFreq - loFreq + 1));
00456 
00457    cpl_msg_info(cpl_func,"Unnormalized vis^2          = %7f  \n\n", result);
00458     fprintf (midiReportPtr, "Unnormalized vis^2          = %7f  \n\n", result);
00459 
00460     return (result);
00461 }
00462 /*****************************************************************************/
00463 

Generated on 15 Mar 2012 for MIDI Pipeline Reference Manual by  doxygen 1.6.1