estimationFrg.c

00001 /******************************************************************************
00002 *******************************************************************************
00003 *               European Southern Observatory
00004 *             VLTI MIDI Data Reduction Software
00005 *
00006 * Module name:  estimationFrg.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 "memoryHandling.h"
00032 #include "errorHandling.h"
00033 #include "midiLib.h"
00034 #include "estimationFrg.h"
00035 #include "photometry.h"
00036 #include "visibility.h"
00037 #include "calibration.h"
00038 
00039 /**********************************************************
00040 *   Constant definitions
00041 **********************************************************/
00042  
00043 /*============================ C O D E    A R E A ===========================*/
00044 
00045 
00046 
00047 /******************************************************************************
00048 *               European Southern Observatory
00049 *            VLTI MIDI Data Reduction Software
00050 *
00051 * Module name:  estimateFringe
00052 * Input/Output: See function arguments to avoid duplication
00053 * Description:    Computes DISPERSED fringe and Unnormalized visibility
00054 *
00055 *
00056 * History:
00057 * 16-Jul-04     (csabet) Added Interface specification. Code and further
00058 *                        decomposion shall be carried out by Jeff
00059 * 17-Feb-04     (csabet) Created template
00060 * 22-Jan-05     (csabet) Cleaned up and modified data structures
00061 ******************************************************************************/
00062 void estimateFringe (
00063     MidiFiles        *fileNames,            // In: Pointer to file names
00064     FilterData        *filterInfo,        // In: Filter information
00065     CompressedData    *compressed,        // In: Compressed interferometry data
00066     ImageFormat        *format,            // In: Points to the image format
00067     float           *freqCal,            // IO: If (freqCal[0][0] == 1.0F) then it still needs to be filled in by this function
00068     float            *dispRawVis,        // Ou: Raw unnormalized visibility
00069     float            *dispRawVisErr,        // Ou: Error of Raw unnormalized visibility
00070     int                *error)
00071 {
00072 
00073     /*  Local Declarations
00074     --------------------*/
00075     const     char  routine[] = "estimateFringe";
00076     double    accum = 0.0;
00077     int        region, frame, X, n;   
00078     
00079     /*  Algorithm
00080     -----------*/
00081     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s'\n", routine);
00082     if (diagnostic > 4) fprintf (midiReportPtr, "Invoking      routine   '%s'\n", routine);
00083 
00084    cpl_msg_info(cpl_func,"\nComputing Raw visibilities from batch  %d \n", batchNumber);
00085    cpl_msg_info(cpl_func,"------------------------------------- \n");
00086     fprintf(midiReportPtr, "\nComputing Raw visibilities from batch  %d \n", batchNumber);
00087     fprintf(midiReportPtr, "------------------------------------- \n");
00088 
00089     //    Reset
00090     *error = 0;
00091     
00092     //    Obtain the visibilities^2, and plot the spectra for each freq channel:
00093     ProcessSpectrumEachChannel (fileNames, filterInfo, compressed, format, dispRawVis, 
00094         dispRawVisErr, freqCal, error);
00095     if (*error) return;
00096 
00097     if (plotFile && diagnostic)
00098     {
00099         midiCreatePlotFile2D ("RawVisCombined", "Combined Raw Uncalibrated Visibility", 
00100             "Channel", "Visibility", 0, dispRawVis, 0, format->iXWidth, 1, 0);
00101                 
00102         midiCreatePlotFile2D ("RawVisErrCombined", "Combined Raw Uncalibrated Visibility Error", 
00103             "Channel", "Visibility Error", 0, dispRawVisErr, 0, format->iXWidth, 1, 0);
00104     }
00105     
00106     //    Print results
00107    cpl_msg_info(cpl_func,"\nAverage values of DISPERSED Fringe \n"
00108         "---------------------------------- \n"
00109         "Region     Average values \n");
00110     fprintf (midiReportPtr, "\nAverage values of DISPERSED Fringe \n"
00111         "---------------------------------- \n"
00112         "Region     Average values \n");
00113 
00114     for (region = 0; region < format->numOfRegionsToProcess; region++)
00115     {
00116         accum=0.0;
00117         n = 0;
00118         for (frame = 0; frame < format->numOfFrames; frame++)
00119         {
00120             for (X = 0; X < format->iXWidth; X++)
00121             {
00122                 if (badChannelList[X])
00123                     continue;
00124                     
00125                 accum += (((compressed->iDispFringe)[region])[X])[frame];
00126                 n++;
00127             }
00128         }
00129         
00130         accum /= n;
00131        cpl_msg_info(cpl_func,"%2d      %12.2f \n", region, accum);
00132         fprintf (midiReportPtr, "%2d      %12.2f \n", region, accum);
00133     }
00134 
00135     return;
00136 }
00137 /*****************************************************************************/
00138 
00139 
00140 
00141  
00142 /******************************************************************************
00143 *               European Southern Observatory
00144 *            VLTI MIDI Data Reduction Software
00145 *
00146 * Module name:  ProcessSpectrumEachChannel
00147 * Input/Output: See function arguments to avoid duplication
00148 * Description:
00149 *
00150 *
00151 * History:
00152 * 16-Jul-04     (JM) provided the code
00153 * 20-Jan-05     (csabet) Cleaned up and integrated
00154 ******************************************************************************/
00155 void ProcessSpectrumEachChannel (
00156     MidiFiles        *fileNames,                // In: Pointer to file names
00157     FilterData        *filterInfo,            // In: Filter information
00158     CompressedData    *compressed,            // In: Compressed interferometry data
00159     ImageFormat        *format,                   // In: Points to the image format
00160     float            *dispRawVis,            // Ou: 
00161     float            *dispRawVisErr,            // Ou: 
00162     float           *freqCal,                // Ou: Frequency calibration
00163     int                *error)
00164 {
00165 
00166     //    Local Declarations
00167     //    ------------------
00168     const    char  routine[] = "ProcessSpectrumEachChannel";
00169     int     i, j, X, lowFreqIndex, highFreqIndex, loF, hiF,
00170             freqCalExists, localError, numOfSpectrums;
00171     float     *spectrum, peakval, peakch;
00172     float     calib, **waveCal=NULL;
00173     char    *string, *title, *dataFilePath, *cmdFileName, *argument;
00174     FILE    *cmdFilePtr=NULL, *dataFilePtr=NULL;
00175     float    zero=0.0;
00176     FILE    *wclHistoryPtr=NULL;
00177     float **PeakMatrix;    
00178     int   scan, index;
00179     float *PeakVectorMean;    
00180     char            *fileNamePeak, *titlePeak;
00181 
00182     //    Algorithm
00183     //    ---------
00184     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s'\n", routine);
00185     if (diagnostic > 4) fprintf(midiReportPtr, "Invoking      routine   '%s'\n", routine);
00186 
00187    cpl_msg_info(cpl_func,"\nProcessing each Channel Spectrum from batch %d \n", batchNumber);
00188    cpl_msg_info(cpl_func,"------------------------------------------- \n");
00189     fprintf(midiReportPtr, "\nProcessing each Channel Spectrum from batch %d \n", batchNumber);
00190     fprintf(midiReportPtr, "------------------------------------------- \n");
00191     
00192     //    Initialize
00193     *error = 0;
00194     freqCalExists = 0;
00195 
00196     //    Recalculate FFT size and the frequency indices
00197     if (diagnostic)cpl_msg_info(cpl_func,"FFT size was = %d \n", format->fftsize);
00198     fprintf (midiReportPtr, "FFT size was = %d \n", format->fftsize);
00199     SetFFTsize (format->fftsize);
00200     if (diagnostic)cpl_msg_info(cpl_func,"FFT size is now = %d \n", format->fftsize);
00201     fprintf (midiReportPtr, "FFT size is now = %d \n", format->fftsize);
00202     calib = format->optFreqCal / ((float) format->fftsize);
00203     lowFreqIndex = (int) (filterInfo->optFreqLo / calib);    // Only look at the relevant frequencies
00204     highFreqIndex = (int) (filterInfo->optFreqHi / calib);    // Only look at the relevant frequencies
00205     if (highFreqIndex > (format->fftsize/2)) highFreqIndex = (format->fftsize/2);
00206 
00207     //    Get calibrated channel frequencies
00208     waveCal = callocWaveCalibration (format->numOfDetectorRegions, format);
00209     getCalibratedChWave (fileNames,    format,    waveCal, error);
00210     if (!(*error))
00211     {
00212         freqCalExists = 1;
00213 
00214         //    Open a file for wavelength calibration history
00215         wclHistoryPtr = fopen (fileNames->wclHistoryName, "a");
00216         fprintf (wclHistoryPtr, "Wavelength Calibration \n");
00217         fprintf (wclHistoryPtr, "Grism ID          = %s \n", format->grismId);
00218         fprintf (wclHistoryPtr, "Number of Records = %d \n", format->iXWidth);
00219         fprintf (wclHistoryPtr, "--------------------------------------- \n");
00220         
00221         if (strcmp (format->beamCombiner, "SCI_PHOT") == 0)
00222         {
00223             for (X = 0; X < format->iXWidth; X++) fprintf (wclHistoryPtr, "%f %f %f %f\n", 
00224                 waveCal[0][X], waveCal[1][X], waveCal[2][X], waveCal[3][X]);
00225             fclose (wclHistoryPtr);
00226 
00227             //    Combine channels. Only regions 2 and 3 (Interferometry is used)
00228             for (i = 0; i < format->iXWidth; i++)
00229                 freqCal[i] = (waveCal[1][i] + waveCal[2][i]) * 0.5F; // Average them 
00230         }
00231         else
00232         {
00233             for (X = 0; X < format->iXWidth; X++) fprintf (wclHistoryPtr, "%f %f\n", 
00234                 waveCal[0][X], waveCal[1][X]);
00235             fclose (wclHistoryPtr);
00236 
00237             //    Combine channels
00238             for (i = 0; i < format->iXWidth; i++)
00239                 freqCal[i] = (waveCal[0][i] + waveCal[1][i]) * 0.5F; // Average them 
00240         }
00241 
00242         //    Create plot
00243             if (plotFile) midiCreatePlotFile2D ("WaveCalibCombined", "Combined Wavelength Claibration", 
00244                 "Channel", "Wavelength (micron)", 0, freqCal, 0, format->iXWidth, 1, 0);
00245     }
00246     else
00247     {
00248         //    Readjust
00249         *error = 0;
00250         if (!(highFreqIndex - lowFreqIndex))
00251         {    
00252             *error = 1;
00253             midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "No channels to process");
00254             return;
00255         }
00256     }
00257     freeWaveCalibration (format->numOfDetectorRegions, waveCal);
00258     
00259     if (diagnostic)cpl_msg_info(cpl_func,"\nOptical frequency calibration = %6.2f THz, calibration per FFT resolution = %6.2f THz \n", 
00260         format->optFreqCal, calib);
00261     if (diagnostic)cpl_msg_info(cpl_func,"Low frequency index (for %f THz) = %d \n", filterInfo->optFreqLo, lowFreqIndex);
00262     if (diagnostic)cpl_msg_info(cpl_func,"High frequency index (for %f THz) = %d \n", filterInfo->optFreqHi, highFreqIndex);
00263     if (diagnostic)cpl_msg_info(cpl_func,"With %d frames, and %d frames / scan \n",  format->numOfFrames, format->framesPerScan);
00264     if (diagnostic)cpl_msg_info(cpl_func,"\nProcessing Combined visibility for each channel \n");
00265     
00266     fprintf (midiReportPtr, "\nOptical frequency calibration = %6.2f THz, calibration per fft resolution = %6.2f THz QCLOG \n", 
00267         format->optFreqCal, calib);
00268     fprintf (midiReportPtr, "Low frequency index (for %f THz) = %d QCLOG \n", filterInfo->optFreqLo, lowFreqIndex);
00269     fprintf (midiReportPtr, "High frequency index (for %f THz) = %d QCLOG \n", filterInfo->optFreqHi, highFreqIndex);
00270     fprintf (midiReportPtr, "With %d frames, and %d frames / scan QCLOG \n",  format->numOfFrames, format->framesPerScan);
00271     fprintf (midiReportPtr, "\nProcessing Combined visibility for each channel QCLOG \n");
00272 
00273    cpl_msg_info(cpl_func,"We now carry out Frame, Scan and Channel rejection based on Signal/Noise \n\n");
00274     fprintf(midiReportPtr, "We now carry out Frame, Scan and Channel rejection based on Signal/Noise \n\n");
00275 
00276     if (diagnostic) 
00277        cpl_msg_info(cpl_func,"\nIncoherent visibility results:\n\nChannel   Wavelength (micron)   Log slope   Offset   White noise           Raw vis       Raw vis Error\n");
00278     fprintf (midiReportPtr, 
00279         "\nIncoherent visibility results:\n\nChannel   Wavelength (micron)   Log slope   Offset   White noise           Raw vis       Raw vis Error QCLOG\n");
00280 
00281     //    Prepare header for plots
00282     if (plotFile)
00283     {
00284         //    Allocate memory
00285         dataFilePath = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00286         cmdFileName = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00287         argument = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00288         string = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00289         title = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00290                 
00291         //    Create the plot file
00292         sprintf (string, "3dPowerSpectrumCombinedInterf");
00293         sprintf (title, "Combined Interferometry Power Spectrum");
00294         sprintf (dataFilePath, "%s%s.%s.plt", outFileDir, outRootName, string);
00295         dataFilePtr = fopen (dataFilePath, "w");
00296     }
00297 
00298     //    Allocate memory
00299     spectrum = (float *) calloc (format->fftsize/2, sizeof(float)); 
00300 
00301     //Allocate memory for PeakMatrix:
00302     
00303     PeakMatrix=calloc( format->iXWidth,sizeof (float*) ); 
00304     for(i=0;i<format->iXWidth;i++){
00305        PeakMatrix[i]=calloc(format->numOfScans,sizeof(float));      
00306     }
00307     
00308 
00309     //    Process valid channels only
00310     for (X = 0; X < format->iXWidth; X++)
00311     {
00312         localError = 0;
00313         if (diagnostic)cpl_msg_info(cpl_func,"%3d",  X);
00314         fprintf (midiReportPtr, "%3d",  X);
00315 
00316         if (badChannelList[X])
00317         {
00318             if (diagnostic)cpl_msg_info(cpl_func,"          %5.2f               <-- %s --> \n", freqCal[X], UNAV);
00319             fprintf (midiReportPtr, "          %5.2f               <-- %s -->                     QCLOG \n", freqCal[X], UNAV);
00320             
00321             if (plotFile)
00322             {
00323                 //    Fill in the empty values
00324                 for (j = 0; j < format->fftsize/2; j++)
00325                     fprintf (dataFilePtr, "%f ", zero);
00326                 fprintf (dataFilePtr, "\n");
00327             }
00328             continue;
00329         }
00330         
00331         //    Reset mmory
00332         memset (spectrum, 0, (sizeof(float)) * format->fftsize/2);
00333 
00334         //    Set low and high frequancy index for this channel
00335         if (!freqCalExists)
00336         {
00337             loF = lowFreqIndex - 10;    //    Not sure about this yet. But it's not a likely situation
00338             hiF = highFreqIndex;
00339         }
00340         else                         
00341         {
00342             loF = (int) (((SPEED_OF_LIGHT / freqCal[X])/calib) - 10);
00343             hiF = (int) (((SPEED_OF_LIGHT / freqCal[X])/calib) + 10);
00344         }            
00345         if (loF < 0) loF = 0;
00346         if (hiF > format->fftsize/2) hiF = format->fftsize/2;
00347 
00348 
00349         
00350         //    Get number of spectrums
00351         numOfSpectrums = getChannelSpectrum (X, loF, hiF, compressed->rejectList[X], 
00352                                              (((compressed->iDispFringe)[0])[X]), (((compressed->iDispFringe)[1])[X]), format, spectrum, PeakMatrix[X]);
00353 
00354 
00355         
00356 
00357         //    Check if any spectrums
00358         if (!numOfSpectrums)
00359         {
00360             badChannelList[X] |= BSL_DATA_ERROR;
00361             if (plotFile)
00362             {
00363                 for (j = 0; j < format->fftsize/2; j++)
00364                     fprintf (dataFilePtr, "%f ", zero);
00365                 fprintf (dataFilePtr, "\n");
00366             }
00367             if (diagnostic)cpl_msg_info(cpl_func,"          %5.2f               <-- %s --> \n", freqCal[X], UNAV);
00368             fprintf (midiReportPtr, "          %5.2f               <-- %s -->                     QCLOG \n", freqCal[X], UNAV);
00369             continue;
00370         }
00371         
00372         //    Reject bad spectrums
00373         localError = 0;
00374         for (j = 0; j < format->fftsize/2; j++)
00375         {
00376             if (isnan (spectrum[j]))
00377             {
00378                 localError = 1;
00379                 badChannelList[X] |= BSL_DATA_ERROR;
00380                 break;
00381             }
00382         }
00383         if (localError)
00384         {
00385             if (plotFile)
00386             {
00387                 for (j = 0; j < format->fftsize/2; j++)
00388                     fprintf (dataFilePtr, "%f ", zero);
00389                 fprintf (dataFilePtr, "\n");
00390             }
00391             if (diagnostic)cpl_msg_info(cpl_func,"          %5.2f               <-- %s --> \n", freqCal[X], UNAV);
00392             fprintf (midiReportPtr, "          %5.2f               <-- %s -->                     QCLOG \n", freqCal[X], UNAV);
00393             continue;
00394         }
00395 
00396         //    Write into the plot file
00397         if (plotFile)
00398         {
00399             for (j = 0; j < format->fftsize/2; j++)
00400                 fprintf (dataFilePtr, "%f ", spectrum[j]);
00401             fprintf (dataFilePtr, "\n");
00402         }
00403 
00404         if (!freqCalExists)
00405         {
00406             findSpectralPeak (spectrum, lowFreqIndex, highFreqIndex, &peakch, &peakval);
00407             freqCal[X] = peakch*calib;
00408         }
00409         else                         
00410         {
00411             if (freqCal[X] == 0.0) peakch = 0.0;
00412             else peakch = (SPEED_OF_LIGHT / freqCal[X])/calib;    // lookup from table inputted to this function
00413             peakval = spectrum[(int)(peakch+0.5F)];    // Read out the peak value directly (was for plotting. Not used);
00414         }            
00415             
00416         if (diagnostic)cpl_msg_info(cpl_func,"          %5.2f  ", freqCal[X]);
00417         fprintf (midiReportPtr, "          %5.2f  ", freqCal[X]);
00418  
00419         //    Compute unnormalized visibility estimate from spectrum
00420         if (peakch)    
00421             dispRawVis[X] = analyseSpectrum (format, peakch, spectrum, calib, &(dispRawVisErr[X]));
00422         else 
00423         {
00424             dispRawVis[X] = 0.F;
00425             dispRawVisErr[X] = 0.F;
00426         }
00427         
00428         if (diagnostic)cpl_msg_info(cpl_func,"        %11.4f", dispRawVis[X]);
00429         if (diagnostic)cpl_msg_info(cpl_func,"        %9.4f", dispRawVisErr[X]);
00430         fprintf (midiReportPtr, "        %11.4f", dispRawVis[X]);
00431         fprintf (midiReportPtr, "        %9.4f", dispRawVisErr[X]);
00432             
00433         if (diagnostic)cpl_msg_info(cpl_func,"\n");
00434         fprintf (midiReportPtr,    "   QCLOG\n");
00435     }
00436     //    Release memory
00437     free (spectrum);
00438 
00439 
00440     //Calculate the mean values of the PeakMatrix
00441 
00442     PeakVectorMean=calloc(format->numOfScans,sizeof (float) ); 
00443     
00444 
00445     for (scan = 0; scan < format->numOfScans; scan++)
00446     {
00447        index=0;
00448        for (X = 0; X < format->iXWidth; X++)
00449        {
00450           if(PeakMatrix[X][scan]>0){
00451              PeakVectorMean[scan]+=PeakMatrix[X][scan];
00452              index++;
00453           }
00454        }
00455        PeakVectorMean[scan]=PeakVectorMean[scan]/(float)index;
00456 /*        cpl_msg_info(cpl_func,"PeakVectorMean: %f",PeakVectorMean[scan]); */
00457 /*        cpl_msg_info(cpl_func,"from %d Chanels\n",index);  */
00458     }
00459     
00460     //Write the mean values (averaged over the channel) in a file
00461     fileNamePeak = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00462     titlePeak = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00463     sprintf (fileNamePeak, "PeakScanChannelaveraged");
00464     sprintf (titlePeak, "PeakScanChannelaveraged");
00465 
00466     midiCreatePlotFile2D (fileNamePeak, titlePeak, "Scan", "Peak", 0, PeakVectorMean, 0, format->numOfScans, 1, 0);
00467     free (fileNamePeak);
00468     free (titlePeak);
00469     
00470     
00471     //Free memory 
00472 
00473     free(PeakVectorMean);
00474 
00475     for(i=0;i<format->iXWidth;i++){
00476        free (PeakMatrix[i]);      
00477     }
00478     free (PeakMatrix);
00479 
00480     
00481     //    Fill in the empty values and close dataFilePtr
00482     if (plotFile)
00483         fclose (dataFilePtr);
00484 
00485     //    Display plot file
00486     if (plotFile > 1)
00487     {
00488         //    Create the command file
00489         sprintf (cmdFileName, "plotCmdFile.grb");
00490         cmdFilePtr = fopen (cmdFileName, "w");
00491         fprintf (cmdFilePtr, "set title \'%s\' \n", title);
00492         fprintf (cmdFilePtr, "set xlabel 'Frequency Bin' \n");
00493         fprintf (cmdFilePtr, "set ylabel 'Channel' \n");
00494         fprintf (cmdFilePtr, "set zlabel 'Power Spectrum' \n");
00495         fprintf (cmdFilePtr, "set xrange [0:%d] \n", format->fftsize/2);
00496         fprintf (cmdFilePtr, "set yrange [0:%d] \n", format->iXWidth);
00497         fprintf (cmdFilePtr, "set ticslevel 0 \n");
00498         fprintf (cmdFilePtr, "splot \'%s\' matrix with lines 0 \n", dataFilePath);
00499         if (plotDuration == -1)
00500         {
00501            cpl_msg_info(cpl_func,"\n");
00502             fprintf (cmdFilePtr, "pause %d \"          ***** Hit Return to continue *****\" \n", plotDuration);
00503         }
00504         else
00505             fprintf (cmdFilePtr, "pause %d \n", plotDuration);
00506         
00507         fclose (cmdFilePtr);
00508 
00509         //    Run the command file
00510         sprintf (argument, "gnuplot -title \"MIDI DRS\" -geometry 900x900+0+0 %s", cmdFileName);
00511         system (argument);
00512 
00513         //    Remove temporary files
00514         remove (cmdFileName);
00515     }
00516 
00517     if (plotFile)
00518     {
00519         if (plotFile == 3) remove (dataFilePath);    
00520 
00521         //    Release memory
00522         free (dataFilePath);
00523         free (cmdFileName);
00524         free (argument);
00525         free (string);
00526         free (title);
00527     }
00528 
00529     //    Report
00530     if (!freqCalExists)
00531     {
00532        cpl_msg_info(cpl_func,"\nWavelength Calibration Calculated from Interferometry data \n");
00533        cpl_msg_info(cpl_func,"---------------------------------------------------------- \n");
00534         fprintf (midiReportPtr, "\nWavelength Calibration Calculated from Interferometry data \n");
00535         fprintf (midiReportPtr, "---------------------------------------------------------- \n");
00536         for (X = 0; X < format->iXWidth; X++)
00537         {
00538             if (freqCal[X] == 0.0)
00539             {
00540                cpl_msg_info(cpl_func,"%3d   %7.4f \n", X, zero);
00541                 fprintf (midiReportPtr, "%3d   %7.4f \n", X, zero);
00542             }
00543             else
00544             {
00545                 freqCal[X] = SPEED_OF_LIGHT/freqCal[X];
00546                cpl_msg_info(cpl_func,"%3d   %7.4f \n", X, freqCal[X]);
00547                 fprintf (midiReportPtr, "%3d   %7.4f \n", X, freqCal[X]);
00548             }
00549         }
00550        cpl_msg_info(cpl_func,"\n");
00551         fprintf (midiReportPtr, "\n");
00552 
00553         //    Open a file for wavelength calibration history
00554         wclHistoryPtr = fopen (fileNames->wclHistoryName, "a");
00555         fprintf (wclHistoryPtr, "Wavelength Calibration from Interferometry data \n");
00556         fprintf (wclHistoryPtr, "Grism ID          = %s \n", format->grismId);
00557         fprintf (wclHistoryPtr, "Number of Records = %d \n", format->iXWidth);
00558         fprintf (wclHistoryPtr, "--------------------------------------- \n");
00559         for (X = 0; X < format->iXWidth; X++) fprintf (wclHistoryPtr, "%f \n", freqCal[X]);
00560         fclose (wclHistoryPtr);
00561 
00562         //    Create plot
00563         if (plotFile) midiCreatePlotFile2D ("WaveCalibInterfData", "Wavelength Claibration from Interferometry data", 
00564             "Channel", "Wavelength (micron)", 0, freqCal, 0, format->iXWidth, 1, 0);
00565 
00566         //    Readjust valid channels
00567         for (X = 0; X < format->iXWidth; X++)
00568         {
00569             if (freqCal[X] <= 0.F)
00570                 badChannelList[X] |= BSL_DATA_ERROR;
00571         }
00572     }
00573     
00574     return;
00575 }
00576 /*****************************************************************************/
00577 
00578 
00579  
00580 /******************************************************************************
00581 *               European Southern Observatory
00582 *            VLTI MIDI Data Reduction Software
00583 *
00584 * Module name:  getChannelSpectrum
00585 * Input/Output: See function arguments to avoid duplication
00586 * Description:    This function ALLOCATES fftsize/2 elements for a PS, and returns a 
00587 *                pointer to it
00588 *
00589 * History:
00590 * 16-Jul-04     (JM) provided the initial idea
00591 * 20-Jan-05     (csabet) Cleaned up and extensively modified
00592 ******************************************************************************/
00593 int getChannelSpectrum (
00594     int            X,                // In: Channel number
00595     int            lowFreqIndex,    // In: First index to consider
00596     int            highFreqIndex,    // In: Last index to consider + 1
00597     int            *rejectList,    // In: Pointer to the begining of the bad Frame List for one channel
00598     float        *inData1,        // In: Pointer to position of frame 0
00599     float        *inData2,        // In: Pointer to position of frame 0 of SECOND region. Null if not used
00600     ImageFormat    *format,        // In: Points to the image format.
00601     float        *output,        // Ou: Output spectrum
00602     float        *Peakvector)        // Ou: Output spectrum
00603 
00604 {
00605 
00606     //    Local Declarations
00607     //    ------------------
00608     int                i, k, scan, numOfPs, *badFrame, minFrames, fftSizeHalf, 
00609                     scanFailed, peakIndex;
00610     float            accum, dclevel, scale, lengthAve, *data1, *data2, *spectrum, 
00611                     median, peak, ratio, *spectrumPtr;
00612     struct Complex    *input2ft;
00613     char            *fileName, *title;
00614 /*     char            *titlePeak; */
00615 /*     char            *fileNamePeak; */
00616     
00617     //    Algorithm
00618     //    ---------
00619     minFrames = MIN_FRAMES_PER_SCAN * format->framesPerScan;
00620     fftSizeHalf = (format->fftsize >> 1);
00621     
00622     //    Allocate memory
00623     FFTarray = (struct Complex *) calloc(MAXFFTSIZE, sizeof(struct Complex));
00624     input2ft = (struct Complex *) calloc(format->fftsize, sizeof(struct Complex));
00625     spectrum = (float *) calloc (fftSizeHalf, sizeof (float));
00626 
00627     //    Compute spectrum
00628     numOfPs = 0;
00629     lengthAve = 0.0;
00630 
00631 /*     // Open file for plotting the Peak and the Median as a function of the scan */
00632 
00633 /*     fileNamePeak = (char *) calloc (MAX_STRING_LENGTH, sizeof (char)); */
00634 /*     titlePeak = (char *) calloc (MAX_STRING_LENGTH, sizeof (char)); */
00635 /*     sprintf (fileNamePeak, "PeakSpectrumScanChannel%d", X); */
00636 /*     sprintf (titlePeak, "PeakChannel %d", X); */
00637 
00638 
00639     for (scan = 0; scan < format->numOfScans; scan++)
00640     {
00641         scanFailed = 0;
00642         memset (input2ft, 0, (sizeof(struct Complex)) * format->fftsize);
00643         badFrame = rejectList + scan * format->framesPerScan;    // Set to beginning of this scan
00644         data1 = inData1 + scan * format->framesPerScan;            // Set to beginning of this scan
00645         data2 = inData2 + scan * format->framesPerScan;            // Set to beginning of this scan
00646         
00647         //  Accumulate to the DC level here:
00648         accum =  0.F;
00649         k = 0;
00650         for (i = 0; i < format->framesPerScan; i++)
00651         {
00652             //    Accumulate good frames only
00653             if (!(*badFrame))
00654             {
00655                 accum += *data1 - *data2;
00656 
00657                 //    Also copy to fft input array
00658                 input2ft[k].r = *data1 - *data2;
00659                 k++;
00660             }
00661             data1++;
00662             data2++;
00663             badFrame++;
00664         }
00665         lengthAve += (float) k;
00666 
00667         //    Process this scan if there were enough good frames
00668         if (k > minFrames)
00669         {
00670             // DC level of this scan
00671             dclevel = accum / ((float) k);
00672         
00673             //    Now subtract the dc level from the values we just inputted to the fft input array:
00674             for (i = 0; i < k; i++)
00675                 input2ft[i].r -= dclevel;
00676             
00677             //    Now apply the window function
00678             input2ft[--i].r *= 0.145F;    // Should point to last nonzero element.
00679             input2ft[0].r *= 0.145F;
00680             input2ft[--i].r *= 0.5F;
00681             input2ft[1].r *= 0.5F;
00682             input2ft[--i].r *= 0.855F;
00683             input2ft[2].r *= 0.855F;
00684  
00685             //     Now do the FFT:
00686             FFT (input2ft, FFTlevel);    // Output is waiting in FFTarray
00687 
00688             //    Analyse the scan spectrum
00689             spectrumPtr = spectrum;
00690             for (i = 0; i < fftSizeHalf; i++)
00691                 *spectrumPtr++ = Cmag2(FFTarray[i]);
00692             
00693             peak = signalPeak (spectrum, 0, fftSizeHalf, &peakIndex);
00694             median = signalMedian (spectrum, 0, fftSizeHalf);
00695             ratio = peak/median;
00696 
00697             Peakvector[scan]=peak;            
00698 
00699 
00700             //    Check validity of the peak power
00701             if ((ratio > 10.0) && (peakIndex > lowFreqIndex) && (peakIndex < highFreqIndex))
00702             {
00703                 //     Now add the (sqrd mag) of the fft result to the power spectrum output:
00704                 for (i = 0; i < fftSizeHalf; i++)
00705                     output[i] += spectrum[i];
00706             
00707                 //    Increment number of power spectrums
00708                 numOfPs++;
00709             }
00710             else
00711             {
00712                 scanFailed = 1;
00713                 //    Transfer bad scans to rejection list
00714                 for (i = 0; i < format->framesPerScan; i++)
00715                     rejectList[i + scan * format->framesPerScan] |= BSL_SNR_ERROR;
00716             }
00717 
00718             //    Plot
00719             if (plotFile && diagnostic > 2)
00720             {
00721                 if (scanFailed)cpl_msg_info(cpl_func,"\n    <<ERROR>>: Scan %3d rejected \n\n", scan);
00722                cpl_msg_info(cpl_func,"    Expected low frequency index  = %3d \n", lowFreqIndex);
00723                cpl_msg_info(cpl_func,"    Expected high frequency index = %3d \n", highFreqIndex);
00724                cpl_msg_info(cpl_func,"    Found peak index at           = %3d \n", peakIndex);
00725                cpl_msg_info(cpl_func,"    peak/median                   = %f \n", ratio);
00726                 if (scanFailed) fprintf (midiReportPtr, "\n    <<ERROR>>: Scan %3d rejected \n\n", scan);
00727                 fprintf (midiReportPtr, "    Expected low frequency index  = %3d \n", lowFreqIndex);
00728                 fprintf (midiReportPtr, "    Expected high frequency index = %3d \n", highFreqIndex);
00729                 fprintf (midiReportPtr, "    Found peak index at           = %3d \n", peakIndex);
00730                 fprintf (midiReportPtr, "    peak/median                   = %f \n", ratio);
00731         
00732                 fileName = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00733                 title = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00734                 sprintf (fileName, "SpectrumScan%dChannel%d", scan, X);
00735                 sprintf (title, "Power Spectrum. Scan %d, Channel %d", scan, X);
00736                 midiCreatePlotFile2D (fileName, title, "Frequancy bin", "Power Spectrum", 
00737                     1, spectrum, 0, fftSizeHalf, 1, 0);
00738                 free (fileName);
00739                 free (title);
00740             }           
00741 
00742             
00743         }
00744     }
00745  
00746        
00747 /*     midiCreatePlotFile2D (fileNamePeak, titlePeak, "Scan", "Peak", 0, Peakvector, 0, format->numOfScans, 1, 0); */
00748 /*     free (fileNamePeak); */
00749 /*     free (titlePeak); */
00750     
00751     
00752 
00753     //    All done accumulating. Now normalize:
00754     if (numOfPs > 0)
00755     {
00756         //    Take into account energy in scan after windowed
00757         lengthAve /= ((float) numOfPs);
00758         scale = 4.F * ((float) format->fftsize) / (((float) numOfPs) * (lengthAve - 3.996));    
00759         for (i = 0; i < fftSizeHalf; i++)
00760             output[i] *= scale;
00761     }
00762 
00763     //    Release memory
00764     free (input2ft);
00765     free (spectrum);
00766     free (FFTarray);
00767 
00768     return (numOfPs);
00769 }
00770 /********************************************************************************/
00771  
00772  
00773 /******************************************************************************
00774 *               European Southern Observatory
00775 *            VLTI MIDI Data Reduction Software
00776 *
00777 * Module name:  findSpectralPeak
00778 * Input/Output: See function arguments to avoid duplication
00779 * Description:    Performs a 3-pt interpolation
00780 *
00781 * History:
00782 * 21-Jul-03     (JM)
00783 * 20-Jan-05        (csabet) Integrated
00784 ******************************************************************************/
00785 void findSpectralPeak (
00786     float    *data,            // In: Spectrum input
00787     int        lowFreqIndex,    // In: First index to consider
00788     int        highFreqIndex,    // In: Last index to consider + 1
00789     float    *peakch,        // Ou: Interpolated channel number
00790     float    *peakinterp)    // Ou: Interpolated value at that position
00791 {
00792 
00793     /*  Local Declarations
00794     --------------------*/
00795     int        i, j = lowFreqIndex;
00796     float    peakval = 0.F;
00797 
00798 
00799     /*  Algorithm
00800     -----------*/
00801     for (i = lowFreqIndex; i < highFreqIndex; i++)
00802     {
00803         if (data[i] > peakval)
00804         {
00805             j = i;
00806             peakval = data[i];
00807         }
00808     }
00809 
00810     if ((j == lowFreqIndex) || (j == (highFreqIndex-1)))
00811     {    // basically that means it failed:
00812         *peakch = 0.F;
00813         *peakinterp = 0.F;
00814         return;
00815     }
00816 
00817     //    Do 3-pt interp and return results:     
00818     *peakch = ((float) j) + (data[j-1]-data[j+1])/(2.F*(data[j-1]+data[j+1]-2.F*data[j]));
00819     if (*peakch<0.F)  *peakch = 0.F;    // just in case.....
00820     if (*peakch > ((float) highFreqIndex)) *peakch = ((float) highFreqIndex);
00821     *peakinterp  = data[j] - 0.125F*(data[j+1] - data[j-1]) * (data[j+1] - data[j-1]) / 
00822         (data[j+1] + data[j-1] - 2.F*data[j]);
00823     
00824     return;
00825 }
00826 /*****************************************************************************/
00827  
00828  
00829  
00830  
00831  
00832 /******************************************************************************
00833 *               European Southern Observatory
00834 *            VLTI MIDI Data Reduction Software
00835 *
00836 * Module name:  analyseSpectrum
00837 * Input/Output: See function arguments to avoid duplication
00838 * Description:    Computes unnormalized visibility estimate from spectrum
00839 *
00840 * History:
00841 * 21-Jul-03     (JM)
00842 * 20-Jan-05        (csabet) Cleaned up, added error calculation and Integrated
00843 ******************************************************************************/
00844 float analyseSpectrum (                // Ou: Unnormalized visibility
00845     ImageFormat    *format,            // In: Points to the image format
00846     float        fringeFreq,            // In: Expected optical frequency of fringe, in units of 
00847                                     //     *spectrum (i.e. actualfreq = fringeFreq * optfreqcal/fftsize)
00848     float        *spectrum,            // In: Main input
00849     float        calib,                // In: Optical freq cal, per fft freq point
00850     float        *fringePowerErr)    // Ou: Error of Unnormalized visibility
00851 {
00852 
00853     /*  Local Declarations
00854     --------------------*/
00855     float    fringePower, fringeWidth, slope, offset;
00856     int        fringeLo1,fringeLo2, tenTHz, fringeHi1,fringeHi2, i;
00857     float    *noiseSpec, loPwr, hiPwr;
00858     int     lopt, hipt;
00859     float      whitenoise = 0.F;
00860     int     pass;
00861 
00862     /*  Algorithm
00863     -----------*/
00864  
00865     //    Allocate memory
00866     noiseSpec = (float *) calloc (format->fftsize/2, sizeof(float));
00867  
00868     //    Very crude estimate of the half width of the fringe. (Need to increase when atmospheric OPD velocity is important)
00869     fringeWidth = 1.5 * ((float) format->fftsize) / 
00870         (((float) format->framesPerScan) - 4.F);    // -4 to take windowing into account
00871  
00872     fringeHi1 = (int)(0.5F + fringeFreq + fringeWidth);
00873     fringeHi2 = (int)(0.5F + fringeFreq + 3.F * fringeWidth);
00874     if (fringeHi2 >= (format->fftsize/2 - 5))
00875         fringeHi2 = (format->fftsize/2 - 6);
00876     if (fringeHi1 >= (fringeHi2-1))    // very unlikely
00877         fringeHi1 = fringeHi2-2;
00878  
00879     fringeLo1 = (int)(0.5F + fringeFreq - 3.F*fringeWidth);
00880     fringeLo2 = (int)(0.5F + fringeFreq - fringeWidth);
00881 
00882     //    NEW: Do NOT include anything below 10 THz:
00883     tenTHz = (int) (0.5F + 10.F/calib) ;
00884     if (fringeLo1 < tenTHz)
00885         fringeLo1 = tenTHz;
00886     if (fringeLo1 >= (fringeLo2-1))    // JUST in case
00887         fringeLo1 = fringeLo2-2;
00888  
00889     //    NEW: Do 5 passes, each with updated estimate of whitenoise:
00890     for (pass = 0; pass < 5; pass++) 
00891     {
00892         //    Make est of whitenoise from very highest freqs. First time around, noiseSpec==0
00893         whitenoise = 0.F;    // to accum
00894         for (i = fringeHi2; i < format->fftsize/2; i++)
00895             whitenoise += (spectrum[i] -  noiseSpec[i]);
00896              
00897         whitenoise /= (float) (format->fftsize/2 - fringeHi2);    // Estimate of whitenoise level. Acual noiselevel = noiseSpec[i] + whitenoise
00898               
00899         loPwr = 0.0;    // To accum
00900         for (i = fringeLo1; i < fringeLo2; i++)
00901         {
00902             if (spectrum[i] > (1.05F*whitenoise))
00903                 loPwr += log((double) (spectrum[i] - whitenoise));
00904             else
00905                 loPwr += log((double) (.05F*whitenoise));
00906         }
00907  
00908         loPwr /= (double) (fringeLo2 - fringeLo1);    // Get average
00909 
00910         hiPwr = 0.0;    // To accum
00911         for (i = fringeHi1; i < fringeHi2; i++)
00912         {
00913             if (spectrum[i] > (1.05F*whitenoise))            
00914                 hiPwr += log((double) (spectrum[i] - whitenoise));
00915             else
00916                 hiPwr += log((double) (.05F*whitenoise));
00917         }
00918  
00919         hiPwr /= (double) (fringeHi2 - fringeHi1);    // Get average
00920  
00921         //    Now fit a line to it!
00922         slope = (hiPwr-loPwr)/(log((fringeHi2+fringeHi1-1)*0.5F) - log((fringeLo2 + fringeLo1-1)*0.5F));       
00923         offset = loPwr - slope*log((fringeLo2 + fringeLo1-1)*0.5F);
00924  
00925         //    Now fill in the estimated "noise spectrum":
00926         for (i = 1; i < (format->fftsize/2); i++)
00927             noiseSpec[i] = exp(offset + slope*log(i));
00928         
00929         noiseSpec[0] = noiseSpec[1];
00930     }
00931 
00932     if (diagnostic)cpl_msg_info(cpl_func,"           %6.3f       %7.2f    %8.2f ", slope, offset, whitenoise);
00933     fprintf (midiReportPtr, "           %6.3f       %7.2f    %8.2f ", slope, offset, whitenoise);
00934  
00935     fringePower = 0.F;        // to accum
00936     *fringePowerErr = 0.F;    // Added, csabet 21-Feb-05
00937     lopt = (int)(fringeFreq - fringeWidth);
00938     if (lopt < 0) lopt = 0;
00939         hipt = (int)(fringeFreq + fringeWidth + 1.F);
00940     
00941     if (hipt >= format->fftsize/2) hipt = format->fftsize/2 - 1;
00942     
00943     for (i = lopt; i <= hipt; i++)
00944     {
00945         fringePower += (spectrum[i] - noiseSpec[i] - whitenoise);
00946         *fringePowerErr += (noiseSpec[i] + whitenoise);
00947     }
00948         
00949     //    Release memory
00950     free (noiseSpec);
00951 
00952     return (fringePower);
00953 }
00954 /*****************************************************************************/
00955 

Generated on 11 Feb 2011 for MIDI Pipeline Reference Manual by  doxygen 1.6.1