imageProcessing.c

00001 
00002 /******************************************************************************
00003 *******************************************************************************
00004 *               European Southern Observatory
00005 *          VLTI MIDI Maintenance Templates Software
00006 *
00007 * Module name:  imageProcessing.c
00008 * Description:  Contains routines for image processing
00009 *
00010 * History:      
00011 * 14-Jun-04     (csabet) created
00012 *******************************************************************************
00013 ******************************************************************************/
00014 
00015 /******************************************************************************
00016 *   Compiler directives
00017 ******************************************************************************/
00018 
00019 /******************************************************************************
00020 *   Include files
00021 ******************************************************************************/
00022 #include <sys/stat.h>
00023 #include <math.h>
00024 #include <stdio.h>
00025 #include "qfits.h"
00026 #include "midiGlobal.h"
00027 #include "midiLib.h"
00028 #include "imageProcessing.h"
00029 #include "statistics.h"
00030 #include "errorHandling.h"
00031 #include "diagnostics.h"
00032 #include "cpl_image_io.h"
00033 #include "cpl_image_basic.h"
00034 #include "complex_midi.h"
00035 #include "fft.h"
00036 #include <cpl.h>
00037 
00038 /**********************************************************
00039 *   Constant definitions
00040 **********************************************************/
00041 #define CIRCLE_TO_SQUARE        (0.350)
00042 
00043 /**********************************************************
00044 *   Global Variables 
00045 **********************************************************/
00046 
00047 /*============================ C O D E    A R E A ===========================*/
00048 
00049 
00050 
00051 /******************************************************************************
00052 *               European Southern Observatory
00053 *            VLTI MIDI Data Reduction Software
00054 *
00055 * Module name:  getUndispersedPowerSpectrum
00056 * Input/Output: See function arguments to avoid duplication
00057 * Description:  Creates spectrum for all regions together with the dc levels.
00058 *
00059 * History:
00060 * 17-Sep-03             (JM) Initial code
00061 * 15-Feb-06     (csabet) Completely restructured and also adapted for SCI_PHOT
00062 ******************************************************************************/
00063 void getUndispersedPowerSpectrum (
00064     ImageFormat         *imageFormat,   // In: Pointer to image format
00065     CompressedData      *compressed)    // In: Pointer to the compressed data
00066 {
00067 
00068         //      Local Declarations
00069         //      ------------------
00070         const char              routine[] = "getUndispersedPowerSpectrum";
00071     double                      *inputPtr;
00072     struct Complex      *input2ft;
00073     int                         i, s, R;
00074     float                       accum, *allSpectrumPtr, *dcLevelsPtr;
00075         
00076     //  Algorithm
00077     //  ---------
00078     if (diagnostic > 4) cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
00079     if (diagnostic > 4) fprintf (midiReportPtr, "Invoking      routine   '%s' \n", routine);
00080 
00081         //      Preset FFT
00082     SetFFTsize (imageFormat->fftsize);
00083 
00084         //      Allocate the input array for the FFT:
00085     FFTarray = (struct Complex *) malloc (MAXFFTSIZE * (sizeof(struct Complex)));
00086     input2ft = (struct Complex *) malloc (imageFormat->fftsize * (sizeof(struct Complex)));
00087                  
00088         //      Save pointer etc.
00089         allSpectrumPtr = compressed->allSpectrum;
00090         dcLevelsPtr = compressed->dcLevels;
00091         
00092     for (R = 0; R < REGIONS_UNDISPERSED; R++)
00093     {
00094                 if (R == 0)
00095                         inputPtr = compressed->iFringe;
00096                 else if (R == 1)
00097                         inputPtr = compressed->iFringe1;
00098                 else
00099                         inputPtr = compressed->iFringe2;
00100 
00101                 //      Process each scan in turn:
00102                 for (s = 0; s < imageFormat->numOfScans; s++)
00103                 {
00104                         //      Process good scans only
00105                         if (!(compressed->badScanList[s]))
00106                         {
00107                                 //      Reset
00108                                 memset (input2ft, 0, (sizeof(struct Complex)) * imageFormat->fftsize);
00109                                 accum = 0.F;
00110                                 for (i = 0; i < imageFormat->framesPerScan; i++)
00111                                 {                               
00112                                         //      Accumulate to the DC level here. Process good frames and Ignore Sky if any
00113                                         accum += *inputPtr;
00114 
00115                                         //      Copy to fft input array
00116                                         input2ft[i].r = *inputPtr;
00117                                         inputPtr++;
00118                                 }
00119                         
00120                                 //      DC level of this scan
00121                                 *dcLevelsPtr = accum / ((float) imageFormat->framesPerScan);
00122 
00123                                 //      Now subtract the dc level from the values we just inputted to the fft input array:
00124                                 for (i = 0; i < imageFormat->framesPerScan; i++)
00125                                         input2ft[i].r -= *dcLevelsPtr;
00126                                 
00127                                 //      Increment the pointer
00128                                 dcLevelsPtr++;
00129 
00130                                 //  Now do the FFT. The output will be in FFTarray
00131                                 FFT (input2ft, FFTlevel);
00132                                 
00133                                 //      Now copy the (sqrd mag) of the fft result to the power spectrum output
00134                                 for (i = 0; i < imageFormat->fftsize/2; i++)
00135                                 {
00136                                         *allSpectrumPtr = Cmag2(FFTarray[i]);
00137                                         allSpectrumPtr++;
00138                                 }
00139                         }
00140                         else
00141                         {
00142                                 //      Increment pointers
00143                                 dcLevelsPtr++;
00144                                 for (i = 0; i < imageFormat->framesPerScan; i++)
00145                                         inputPtr++;
00146                                 for (i = 0; i < imageFormat->fftsize/2; i++)
00147                                         allSpectrumPtr++;
00148                         }
00149                 }
00150         }
00151 
00152     //  Create plot data file. For SCI_PHOT it will not be used yet. Not necessary
00153     if (plotFile)
00154     {
00155                 if (strcmp (imageFormat->beamCombiner, "SCI_PHOT") == 0)        
00156                         midiCreatePlotFile2D ("SpectrumCombinedDATA2DATA3", "DATA2-DATA3, DATA2 and DATA3 Spectrum", 
00157                                 "FFT bins for each Scan", "Power Spectrum", 0, compressed->allSpectrum, 0, 
00158                                 imageFormat->allSpectrumLength, 1, 0);
00159                 else
00160                         midiCreatePlotFile2D ("SpectrumCombinedDATA1DATA2", "DATA1-DATA2, DATA1 and DATA2 Spectrum", 
00161                                 "FFT bins for each Scan", "Power Spectrum", 0, compressed->allSpectrum, 0, 
00162                                 imageFormat->allSpectrumLength, 1, 0);
00163         }
00164         
00165         free (input2ft);
00166         free (FFTarray);
00167         
00168         return;
00169 }
00170 //******************************************************************************
00171 
00172 
00173 /******************************************************************************
00174 *               European Southern Observatory
00175 *            VLTI MIDI Data Reduction Software 
00176 *
00177 * Module name:  normalizeSignal
00178 * Input/Output: See function arguments to avoid duplication
00179 * Description:  normalizes the content of an array. For instance eachspectrum, 
00180 *                               to remove large numbers. FV has problems handling large numbers.
00181 *
00182 * History:      
00183 * 11-Nov-03     (csabet) Created
00184 ******************************************************************************/
00185 void normalizeSignal (
00186         int             arraySize,      /*      In:     Length of the array */
00187         float   *signal)        /*      IO:     Pointer to an array */
00188 {
00189 
00190     /*  Local Declarations
00191     --------------------*/
00192     const char  routine[] = "normalizeSignal";
00193         int                     i;
00194         float           maxSignal;
00195         
00196     /*  Algorithm
00197     -----------*/
00198     if (diagnostic > 4) cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
00199     if (diagnostic > 4) fprintf(midiReportPtr, "Invoking      routine   '%s' \n", routine);
00200         
00201         /*      Find maximum. Ignore first two elements */
00202         maxSignal = signal[0];
00203         for (i = 0; i < arraySize; i++)
00204                 if (signal[i] > maxSignal) maxSignal = signal[i];
00205                 
00206         /*      Normalize signal */
00207         for (i = 0; i < arraySize; i++)
00208                 signal[i] /= maxSignal;
00209 
00210     return;
00211 }
00212 /*****************************************************************************/
00213 
00214 
00215 
00216 
00217 /******************************************************************************
00218 *               European Southern Observatory
00219 *          VLTI MIDI Maintenance Templates Software
00220 *
00221 * Module name:  computeFrameFlux
00222 * Input/Output: See function arguments to avoid duplication
00223 * Description:  Computes the total flux in the given frame
00224 *
00225 * History:      
00226 * 26-Aug-04     (csabet) Created
00227 ******************************************************************************/
00228 void computeFrameFlux (
00229         short int       *inData,                //      In:     Pointer to the input data
00230         int                     frame,                  //      In:     Frame number
00231         int                     scalingOffset,  //      In:     Scaling factor
00232     ImageFormat *format,                //      In:     Pointer to the image format
00233         MidiCoords      *target,                //      In:     Region to cover
00234         float           *flux,                  //      Ou:     Computed flux
00235         int                     *pixelCount,    //      Ou      Pixel count
00236     int                 *error)                 //      Ou:     Error status
00237 
00238 {
00239   
00240     //  Local Declarations
00241     //  ------------------
00242         const char  routine[] = "computeFrameFlux";
00243     int                 i, yWin, xWin, fileSpan, frameSpan, subWindowSize;
00244     
00245         //  Algorithm
00246     //  ---------
00247     if (diagnostic > 4) cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
00248     if (diagnostic > 4) fprintf (midiReportPtr, "Invoking      routine   '%s' \n", routine);
00249     
00250     //  Reset status
00251         *error = 0;
00252         *flux = 0.0;
00253         *pixelCount = 0;
00254 
00255         //      Compute flux in the given region
00256         subWindowSize = format->iXWidth * format->iYWidth;
00257         fileSpan = frame * subWindowSize;
00258         for (yWin = 0; yWin < format->iYWidth; yWin++)
00259         {
00260                 frameSpan = yWin * format->iXWidth;
00261                 for (xWin = 0; xWin < format->iXWidth; xWin++)
00262                 {
00263                         //      Compute total flux
00264                         i = fileSpan + frameSpan + xWin;
00265                         if (isnan (inData[i]))
00266                         {
00267                                 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Corrupted data");
00268                                 *error = 1;
00269                                 return;
00270                         }
00271                         if (xWin >= (int) (target->xCoord) && xWin <= (int) (target->dxCoord) &&
00272                                 yWin >= (int) (target->yCoord) && yWin <= (int) (target->dyCoord))
00273                         {
00274                                 *flux += (float) (inData[i] + scalingOffset);
00275                                 (*pixelCount)++;
00276                         }
00277                 }
00278         }
00279 
00280         if (diagnostic)
00281         {
00282                 cpl_msg_info(cpl_func,"\nCoordinates and flux results for frame %d: \n", frame);
00283                 cpl_msg_info(cpl_func,"====================================== \n");
00284                 cpl_msg_info(cpl_func,"   Image coordinates = %f %f %f %f\n", target->xCoord, target->yCoord, target->dxCoord, target->dyCoord);
00285                 cpl_msg_info(cpl_func,"   Flux              = %f\n", *flux);
00286                 cpl_msg_info(cpl_func,"   Pixel count       = %d\n", *pixelCount);
00287                 fprintf (midiReportPtr, "\nCoordinates and flux results for frame %d: \n", frame);
00288                 fprintf (midiReportPtr, "====================================== \n");
00289                 fprintf (midiReportPtr, "   Image coordinates = %f %f %f %f\n", target->xCoord, target->yCoord, target->dxCoord, target->dyCoord);
00290                 fprintf (midiReportPtr, "   Flux              = %f\n", *flux);
00291                 fprintf (midiReportPtr, "   Pixel count       = %d\n", *pixelCount);
00292         }
00293         
00294     return; 
00295 }
00296 //******************************************************************************
00297 
00298         
00299 
00300 
00301 /******************************************************************************
00302 *               European Southern Observatory
00303 *          VLTI MIDI Maintenance Templates Software
00304 *
00305 * Module name:  computeImageFlux
00306 * Input/Output: See function arguments to avoid duplication
00307 * Description:  Computes the total flux in the given image
00308 *
00309 * History:      
00310 * 26-Aug-04     (csabet) Created
00311 ******************************************************************************/
00312 void computeImageFlux (
00313         float           *image,                 //      In:     Pointer to the input data
00314     ImageFormat *format,                //      In:     Pointer to the image format
00315         MidiCoords      *target,                //      In:     Region to cover
00316         float           *flux,                  //      Ou:     Computed flux
00317         int                     *pixelCount,    //      Ou      Pixel count
00318     int                 *error)                 //      Ou:     Error status
00319 
00320 {
00321   
00322     //  Local Declarations
00323     //  ------------------
00324         const char  routine[] = "computeImageFlux";
00325     int                 i, yWin, xWin, frameSpan;
00326     
00327         //  Algorithm
00328     //  ---------
00329     if (diagnostic > 4) cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
00330     if (diagnostic > 4) fprintf (midiReportPtr, "Invoking      routine   '%s' \n", routine);
00331     
00332     //  Reset status
00333         *error = 0;
00334         *flux = 0.0;
00335         *pixelCount = 0;
00336 
00337         //      Compute flux in the given region
00338         for (yWin = 0; yWin < format->iYWidth; yWin++)
00339         {
00340                 frameSpan = yWin * format->iXWidth;
00341                 for (xWin = 0; xWin < format->iXWidth; xWin++)
00342                 {
00343                         //      Compute total flux
00344                         i = frameSpan + xWin;
00345                         if (xWin >= (int) (target->xCoord) && xWin <= (int) (target->dxCoord) &&
00346                                 yWin >= (int) (target->yCoord) && yWin <= (int) (target->dyCoord))
00347                         {
00348                                 *flux += (float) (image[i]);
00349                                 (*pixelCount)++;
00350                         }
00351                 }
00352         }
00353 
00354     return; 
00355 }
00356 //******************************************************************************
00357 
00358 
00359 /******************************************************************************
00360 *               European Southern Observatory
00361 *          VLTI MIDI Maintenance Templates Software
00362 *
00363 * Module name:  createAveragedImage
00364 * Input/Output: See function arguments to avoid duplication
00365 * Description:  Creates an averaged image from the FITS file
00366 *
00367 * History:      
00368 * 18-Aug-04     (csabet) Created
00369 ******************************************************************************/
00370 void createAveragedImage (
00371         short int       *inData,                //      In:     Pointer to the input data
00372         float           scalingOffset,  //      In:     Scaling Offset
00373     ImageFormat *format,                //      In:     Pointer to the image format
00374         float           *image)                 //      Ou:     Output image
00375 
00376 {
00377     //  Local Declarations
00378     //  ------------------
00379     const char  routine[] = "createAveragedImage";
00380     int                 i, count, pixel, frame, subWindowSize;
00381     
00382     //  Algorithm
00383     //  ---------
00384     if (diagnostic > 4) cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
00385     if (diagnostic > 4) fprintf (midiReportPtr, "Invoking      routine   '%s' \n", routine);
00386     
00387     //  Reset status
00388         subWindowSize = format->iXWidth * format->iYWidth;
00389 
00390         for (pixel = 0; pixel < subWindowSize; pixel++)
00391         {
00392                 //      Along the time axis (frame)
00393                 image[pixel] = 0;
00394                 count = 0;
00395                 for (frame = 0; frame < format->numOfFrames; frame++)
00396             {
00397                         //      Load each pixel data along the time axis
00398                         i = frame * subWindowSize + pixel;
00399                         if (isnan (inData[i]))
00400                         {
00401                                 sprintf (midiMessage, "Found bad pixel on frame %d", frame);
00402                                 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
00403                         }
00404                         else
00405                         {
00406                                 count++;
00407                                 image[pixel] += (float) (inData[i] + scalingOffset);
00408                         }
00409                 }
00410 
00411                 //      Compute average image
00412                 image[pixel] /= count;
00413         }
00414         
00415     return; 
00416 }
00417 /*****************************************************************************/
00418 
00419 
00420 
00421 /******************************************************************************
00422 *               European Southern Observatory
00423 *          VLTI MIDI Maintenance Templates Software
00424 *
00425 * Module name:  createFitsImage
00426 * Input/Output: See function arguments to avoid duplication
00427 * Description:  Creates a fits file with the following format:
00428 *                               outFileDir, outRootName, batchNumber, fileNumber
00429 *                               e.g. MIDI_detRon_b1.ai1.fits
00430 *                               Where "ai1" means "Average Image 1"
00431 *
00432 * History:      
00433 * 31-Aug-04     (csabet) Created
00434 ******************************************************************************/
00435 void createFitsImage (
00436         const char    *regionOrFile,  // In: Indicating region or file
00437         const char    *name,                  // In: Name of the image file
00438     char        *inFitsName,    // In: Name of FITS file
00439     int         xLength,                // In: X length
00440     int         yLength,                // In: Y length
00441     float   *image)             // In: Image of the file
00442 {
00443   
00444     //  Local Declarations
00445     //  ------------------
00446     const char  routine[] = "createFitsImage";
00447     qfits_header    *pHeaderOut;
00448     FILE            *imagePtr;
00449     qfitsdumper     qdImage;
00450     char            *sWidthX, *sWidthY, *stringOut;
00451     struct stat         buf;
00452    
00453     //  Algorithm
00454     //  ---------
00455     if (diagnostic > 4) cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
00456     if (diagnostic > 4) fprintf(midiReportPtr, "Invoking      routine   '%s' \n", routine);
00457 
00458         cpl_msg_info(cpl_func,"\nCreating an image from %s for batch  %d \n", regionOrFile, batchNumber);
00459         cpl_msg_info(cpl_func,"----------------------------------- \n");
00460         fprintf (midiReportPtr, "\nCreating an image from %s for batch  %d \n", regionOrFile, batchNumber);
00461         fprintf (midiReportPtr, "----------------------------------- \n");
00462         
00463     //  Allocate memory
00464     stringOut = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00465     sWidthY = (char *) calloc (MIN_STRING_LENGTH, sizeof (char));
00466     sWidthX = (char *) calloc (MIN_STRING_LENGTH, sizeof (char));
00467 
00468     //  Write all NAXIS values as character strings
00469     sprintf (sWidthY, "%d", yLength);
00470     sprintf (sWidthX, "%d", xLength);
00471 
00472     //  Add primary Header
00473     if (diagnostic)cpl_msg_info(cpl_func,"   Extracting primary header from input FITS file   %s \n", inFitsName);
00474     fprintf(midiReportPtr, "   Extracting primary header from input FITS file   %s \n", inFitsName);
00475     pHeaderOut = qfits_header_read (inFitsName);
00476     if (pHeaderOut == NULL)
00477     {
00478                 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot extract primary header from input FITS file");
00479             free (sWidthY);
00480             free (sWidthX);
00481                 free (stringOut);
00482                 return;
00483         }
00484 
00485     //  Updates header for the DetRon output file
00486         qfits_header_mod (pHeaderOut, "BITPIX","-32", "number of bits per pixel"); 
00487     qfits_header_mod (pHeaderOut, "NAXIS", "2", "number of data axes"); 
00488     qfits_header_add (pHeaderOut, "NAXIS1", sWidthX, "", "");
00489     qfits_header_add (pHeaderOut, "NAXIS2", sWidthY, "", "");
00490     
00491 //      qfits_header_mod (pHeaderOut, "HIERARCH ESO DET WIN1 NX", sWidthX, "# of pixels along x");
00492 //      qfits_header_mod (pHeaderOut, "HIERARCH ESO DET WIN1 NY", sWidthY, "# of pixels along y");
00493 //      qfits_header_mod (pHeaderOut, "HIERARCH ESO DET WIN1 STRX", "1", "Lower left pixel in x");
00494 //      qfits_header_mod (pHeaderOut, "HIERARCH ESO DET WIN1 STRY", "1", "Lower left pixel in y");
00495     
00496 //      qfits_header_mod (pHeaderOut, "HIERARCH ESO DET WIN2 NX", sWidthX, "# of pixels along x");
00497 //      qfits_header_mod (pHeaderOut, "HIERARCH ESO DET WIN2 NY", sWidthY, "# of pixels along y");
00498 //      qfits_header_mod (pHeaderOut, "HIERARCH ESO DET WIN2 STRX", "1", "Lower left pixel in x");
00499 //      qfits_header_mod (pHeaderOut, "HIERARCH ESO DET WIN2 STRY", "1", "Lower left pixel in y");
00500     
00501 //      qfits_header_mod (pHeaderOut, "HIERARCH ESO DET CHIP NX", sWidthX, "# of pixels along x");
00502 //      qfits_header_mod (pHeaderOut, "HIERARCH ESO DET CHIP NY", sWidthY, "# of pixels along y");
00503     
00504     qfits_header_mod (pHeaderOut, "INSTRUME", "MIDI", "MIDI Raw Data Display FITS created by DRS pipeline" );  
00505 
00506     //  Create file and dump FITS Header for DetRon output file
00507         sprintf (stringOut, "%s%s.%s.fits", outFileDir, outRootName, name);
00508         if (stat (stringOut, &buf) == 0) remove (stringOut);    //      If the file exist delete it     
00509     if ((imagePtr = fopen (stringOut, "w")) == NULL)
00510     {
00511         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot create Image of the data file");
00512             free (sWidthY);
00513             free (sWidthX);
00514                 free (stringOut);
00515             qfits_header_destroy (pHeaderOut);
00516         return;
00517         }
00518 
00519         cpl_msg_info(cpl_func,"   Created an Image file: %s \n", stringOut);
00520         fprintf (midiReportPtr, "   Created an Image file: %s \n", stringOut);
00521 
00522     qfits_header_dump (pHeaderOut, imagePtr); 
00523     fclose (imagePtr);          
00524 
00525     //  Done writing header, close structure
00526     qfits_header_destroy (pHeaderOut);
00527 
00528     //  Dumps Fringe into the Detector Readout Noise file
00529         qdImage.filename  = stringOut;
00530         qdImage.npix      = xLength * yLength;
00531         qdImage.ptype     = PTYPE_FLOAT;
00532         qdImage.fbuf      = image;
00533         qdImage.out_ptype = BPP_IEEE_FLOAT;
00534 
00535     qfits_pixdump (&qdImage);
00536 
00537     /* Zero-pad the FITS file */
00538     qfits_zeropad((char *)stringOut);
00539 
00540     //  Release memory
00541     free (sWidthY);
00542     free (sWidthX);
00543     free (stringOut);
00544  
00545     return; 
00546 }
00547 /*****************************************************************************/
00548 
00549 
00550 
00551 /******************************************************************************
00552 *               European Southern Observatory
00553 *          VLTI MIDI Maintenance Templates Software
00554 *
00555 * Module name:  midiGaussianFit
00556 * Input/Output: See function arguments to avoid duplication
00557 * Description:  This is a wrapper for the CPL library function
00558 *
00559 * History:      
00560 * 18-Aug-04     (csabet) Created
00561 ******************************************************************************/
00562 void midiGaussianFit (
00563         int             fileNumber,     // In: File number
00564         int             dimension,      // In: Dimensionality
00565         float   *image,         // In: Pointer to an image
00566         int             xImage,         // In: X size of image
00567         int             yImage,         // In: Y size of image
00568         int             xP,                     // In: X coordinate of the central pinhole
00569         int             yP,                     // In: Y coordinate of the central pinhole
00570         int             sizeP,          // In: Search size for the target
00571         double  *xT,            // Ou: X coordinate of the target centroid
00572         double  *yT,            // Ou: Y coordinate of the target centroid
00573         double  *sizeXT,        // Ou: Width of the target
00574         double  *sizeYT,        // Ou: Y-Width of the target
00575     int         *error)         // Ou: Error status
00576 
00577 {
00578   
00579     //  Local Declarations
00580     //  ------------------
00581     const char  routine[] = "midiGaussianFit";
00582     cpl_image   *cplImage;
00583     double              sigX, sigY, norm;
00584         
00585     //  Algorithm
00586     //  ---------
00587     if (diagnostic > 4) cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
00588     if (diagnostic > 4) fprintf (midiReportPtr, "Invoking      routine   '%s' \n", routine);
00589 
00590         //      Reset status
00591         *error = 0;
00592         *xT = 0.0;
00593         *yT = 0.0;
00594         *sizeXT = 0.0;
00595         *sizeYT = 0.0;
00596         
00597         if (dimension == 1)
00598         {
00599                 midiGetFWHM (fileNumber, image, xImage, yImage, sizeP, xT, yT, sizeXT, sizeYT, error);
00600                 if (*error) midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot find centroid");
00601         }
00602         else if (dimension == 2)
00603         {
00604                 //      Using a 2D Gaussian fit find the coordinates of the targets. First build a cpl_image
00605                 cplImage = cpl_image_wrap_float (xImage, yImage, image);
00606                 
00607                 //      There is a memory leak inside "cpl_image_gaussian_fit"
00608                 if (cpl_image_fit_gaussian (cplImage, xP, yP, sizeP, &norm, xT, yT, &sigX, &sigY, NULL, NULL)!=CPL_ERROR_NONE){
00609                    *error = 1;
00610                    midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot find the centroid");
00611                    cpl_image_unwrap (cplImage);
00612                    return;
00613                 }
00614                 
00615                 *sizeXT = 0.5 * (sigX + sigY);
00616                 *sizeYT = 0.5 * (sigX + sigY);
00617 
00618                 cpl_image_unwrap (cplImage);
00619         }
00620         else
00621         {
00622                 *error = 1;
00623                 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Invalid dimensionality");
00624                 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot find centroid");
00625                 return;
00626         }
00627 
00628         //      If all is well print the result
00629         if (!(*error))
00630         {
00631                 cpl_msg_info(cpl_func,"   Target centroid     = (x, y, X-Width, Y-Width) %f %f %f %f\n", 
00632                         *xT, *yT, *sizeXT, *sizeYT);
00633                 fprintf (midiReportPtr, "   Target centroid     = (x, y, X-Width, Y-Width) %f %f %f %f\n", 
00634                         *xT, *yT, *sizeXT, *sizeYT);
00635         }
00636 
00637     return; 
00638 }
00639 //*****************************************************************************
00640 
00641 
00642 /******************************************************************************
00643 *               European Southern Observatory
00644 *          VLTI MIDI Maintenance Templates Software
00645 *
00646 * Module name:  midiGaussian_1d_fit
00647 * Input/Output: See function arguments to avoid duplication
00648 * Description:  This function performs a 1d Gaussian fit
00649 *
00650 * History:      
00651 * 23-Sep-04     (csabet) Created
00652 ******************************************************************************/
00653 void midiGaussian_1d_fit (
00654         float   *array,                 //      In:     Pointer to an array of data
00655         int             length,                 //      In:     length of the array
00656         int             sizeS,                  //      In: Search size for the target
00657         float   *centre,                //      Ou:     Position of the target centroid
00658         float   *sizeT,                 //      Ou:     Size of the target
00659         float   *fluxErr2Min,   //      Ou:     Flux in the search region
00660     int         *error)                 //      Ou:     Error status
00661 
00662 {
00663   
00664     //  Local Declarations
00665     //  ------------------
00666     const char  routine[] = "midiGaussian_1d_fit";
00667     int                 i, j, l, searchLimit, halfGauss;
00668     float               *gaussian, sigma, exponentConst, fluxErr2;
00669     char                *fileString, *title;
00670         
00671     //  Algorithm
00672     //  ---------
00673     if (diagnostic > 4) cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
00674     if (diagnostic > 4) fprintf (midiReportPtr, "Invoking      routine   '%s' \n", routine);
00675 
00676         //      Reset status
00677         *error = 0;
00678         *fluxErr2Min = 0.0;
00679         *centre = 0.0;
00680         *sizeT = 0.0;
00681         sigma = 0.0;
00682 
00683         //      Exception handling. Make sure sizeS is odd
00684         if (diagnostic > 2) cpl_msg_info(cpl_func,"search span before = %d\n", sizeS);
00685         if (!(sizeS & 1)) sizeS += 1;
00686         if (diagnostic > 2) cpl_msg_info(cpl_func,"search span after = %d\n", sizeS);
00687         searchLimit = length - sizeS;
00688         if (searchLimit <= sizeS)
00689         {
00690                 *error = 1;
00691                 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Search window too large");
00692                 return;
00693         }
00694 
00695         //      Allocate memory
00696         gaussian = (float *) calloc (sizeS, sizeof (float));
00697 
00698         //      Determine the symetrical search span
00699         halfGauss = (sizeS >> 1);
00700 
00701         //      Plot the input array
00702         if (diagnostic > 2)
00703                 midiCreatePlotFile2D ("InputArray", "Input Array", "X", "Y", 0, array, 0, length, 1, 0);
00704 
00705         //      Search with different values of Gaussian sigma
00706         for (l = 0; l < GAUSSIAN_SIGMA_SPAN; l++)
00707         {
00708                 //      Define the Normalized Gaussian with a=0
00709                 sigma += 0.25;
00710                 exponentConst = (-0.5) / (sigma * sigma);
00711                 for (i = -halfGauss; i <= halfGauss; i++)
00712                 {
00713                         j = halfGauss+i;
00714                         gaussian[j] = exp (exponentConst * i * i);
00715                         if (plotFile && diagnostic > 2) 
00716                         {
00717                                 fileString = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00718                                 title = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00719                                 sprintf (fileString , "GaussianWithSigma%f", sigma);
00720                                 sprintf (title , "Gaussian with %f Sigma", sigma);
00721                                 midiCreatePlotFile2D (fileString, title, "Span", "Sigma", 0, gaussian, 0, sizeS, 1, 0);
00722                                 free (fileString);
00723                                 free (title);
00724                                 if (diagnostic > 2)
00725                                 {
00726                                         cpl_msg_info(cpl_func,"   Gaussian %d = %8.8f\n", i, gaussian[j]);
00727                                         fprintf (midiReportPtr, "   Gaussian %d = %8.8f\n", i, gaussian[j]);
00728                                 }
00729                         }
00730                 }
00731                         
00732                 //      Find the section where squared error is minimum
00733                 //      -----------------------------------------------
00734                 for (i = 0; i < searchLimit; i++)
00735                 {
00736                         //      Correlate flux
00737                         fluxErr2 = 0.0;
00738                         for (j = 0; j < sizeS; j++)     
00739                                 fluxErr2 += ( (gaussian[j] - array[i+j]) * (gaussian[j] - array[i+j]) );
00740                         
00741                         //      Initialise the mimimum  
00742                         if (l == 0 && i == 0) *fluxErr2Min = fluxErr2;
00743                         else
00744                         {
00745                                 if (fluxErr2 < *fluxErr2Min)
00746                                 {
00747                                         *fluxErr2Min = fluxErr2;
00748                                         *centre = (float) (i + 0.5 * sizeS);
00749                                         *sizeT = (float) (3.0 * sigma);
00750                                 }
00751                         }
00752                 }
00753         }
00754         
00755         //      Release memory
00756         free (gaussian);
00757         
00758     return; 
00759 }
00760 //*****************************************************************************
00761 
00762 
00763 /******************************************************************************
00764 *               European Southern Observatory
00765 *          VLTI MIDI Maintenance Templates Software
00766 *
00767 * Module name:  midiGaussianSmooth
00768 * Input/Output: See function arguments to avoid duplication
00769 * Description:  Using a Gaussian fit computes the refined position of peak
00770 *                               of a pinhole spectra
00771 *
00772 * History:      
00773 * 31-Aug-05     (csabet) Created
00774 ******************************************************************************/
00775 float midiGaussianSmooth (      //      Ou: Refined peak
00776         float   *array,                 //      In:     Pointer to an array of normalised data
00777         int             length,                 //      In:     length of the array
00778         int             peakIn,                 //      In: Approximate peak
00779         int             searchSpan,             //      In:     Search span
00780     int         *error)                 //      Ou:     Error status
00781 
00782 {
00783   
00784     //  Local Declarations
00785     //  ------------------
00786     const char  routine[] = "midiGaussianSmooth";
00787     int                 i, j, l, start, end, halfGauss;
00788     float               *gaussian, sigma, exponentConst, fluxErr2, xCPH, fluxErr2Min;
00789         char            *fileString, *title;
00790                 
00791     //  Algorithm
00792     //  ---------
00793     if (diagnostic > 4) cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
00794     if (diagnostic > 4) fprintf (midiReportPtr, "Invoking      routine   '%s' \n", routine);
00795 
00796         //      Reset status
00797         *error = 0;
00798         fluxErr2Min = 0.0;
00799         sigma = 0.0;
00800         xCPH = 0.0;
00801 
00802         //      Exception handling. Make sure searchSpan is odd
00803         if (diagnostic > 2) cpl_msg_info(cpl_func,"search span before = %d\n", searchSpan);
00804         if (!(searchSpan & 1)) searchSpan += 1;
00805         if (diagnostic > 2) cpl_msg_info(cpl_func,"search span after = %d\n", searchSpan);
00806         halfGauss = (searchSpan >> 1);
00807         start = peakIn - searchSpan;
00808         end = peakIn + searchSpan;
00809         if ((end > length) || (start < 0))
00810         {
00811                 *error = 1;
00812                 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Search window too large");
00813                 return (-1);
00814         }
00815 
00816         //      Allocate memory
00817         gaussian = (float *) calloc (searchSpan, sizeof (float));
00818 
00819         //      Search with different values of Gaussian sigma
00820         for (l = 0; l < GAUSSIAN_SIGMA_SPAN; l++)
00821         {
00822                 //      Define the Normalized Gaussian with a=0
00823                 sigma += 0.25;
00824                 exponentConst = (-0.5) / (sigma * sigma);
00825                 for (i = -halfGauss; i <= halfGauss; i++)
00826                 {
00827                         j = halfGauss+i;
00828                         gaussian[j] = exp (exponentConst * i * i);
00829                         if (plotFile && diagnostic > 2) 
00830                         {
00831                                 fileString = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00832                                 title = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00833                                 sprintf (fileString , "GaussianWithSigma%f", sigma);
00834                                 sprintf (title , "Gaussian with %f Sigma", sigma);
00835                                 midiCreatePlotFile2D (fileString, title, "Span", "Sigma", 0, gaussian, 0, searchSpan, 1, 0);
00836                                 cpl_msg_info(cpl_func,"   Gaussian %d = %8.8f\n", i, gaussian[j]);
00837                                 fprintf (midiReportPtr, "   Gaussian %d = %8.8f\n", i, gaussian[j]);
00838                         }
00839                 }
00840         
00841                 //      Find the section where squared error is minimum
00842                 //      -----------------------------------------------
00843                 for (i = start; i < end; i++)
00844                 {
00845                         //      Correlate flux
00846                         fluxErr2 = 0.0;
00847                         for (j = 0; j < searchSpan; j++)        
00848                                 fluxErr2 += ( (gaussian[j] - array[i+j]) * (gaussian[j] - array[i+j]) );
00849                         
00850                         //      Initialise the mimimum  
00851                         if ((l == 0) && (i == start)) 
00852                                 fluxErr2Min = fluxErr2;
00853                         else
00854                         {
00855                                 if (fluxErr2 < fluxErr2Min)
00856                                 {
00857                                         fluxErr2Min = fluxErr2;
00858                                         xCPH = (float) (i + 0.5 * searchSpan);
00859                                 }
00860                         }
00861                 }
00862         }
00863         
00864         //      Release memory
00865         free (gaussian);
00866         
00867     return (xCPH); 
00868 }
00869 //*****************************************************************************
00870 
00871 
00872 /******************************************************************************
00873 *               European Southern Observatory
00874 *            VLTI MIDI Data Reduction Software
00875 *
00876 * Module name:  getBadScansFromSpectrumUndisp
00877 * Input/Output: See function arguments to avoid duplication
00878 * Description:  Rejecting bad scans based on the signal/noise values
00879 *
00880 * History:
00881 * 14-Mar-06     (csabet) Created
00882 ******************************************************************************/
00883 void getBadScansFromSpectrumUndisp (
00884     FilterData          *filterInfo,    // In: Pointer to filter information
00885     ImageFormat         *format,                // In: Points to the image format
00886         CompressedData  *compressed,    // IO: Pointer to compressed data
00887         int                             *error)                 // Ou: Error status
00888 {
00889     //  Local Declarations
00890     //--------------------
00891     const char  routine[] = "getBadScansFromSpectrumUndisp";
00892         int                     i;
00893         float           *tempArray;
00894 
00895     //  Algorithm
00896     //  ---------
00897     if (diagnostic > 4) cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
00898     if (diagnostic > 4) fprintf(midiReportPtr, "Invoking      routine '%s'  \n", routine);
00899 
00900     cpl_msg_info(cpl_func,"\nRejecting scans based on Signal/Noise \n");
00901     cpl_msg_info(cpl_func,"------------------------------------- \n");
00902     fprintf (midiReportPtr, "\nRejecting scans based on Signal/Noise \n");
00903     fprintf (midiReportPtr, "------------------------------------- \n");
00904 
00905         //      Reset
00906         *error = 0;
00907         
00908         //      Get bad scans due to weak signal/noise
00909         rejectScansOnWeakSNRUndisp (filterInfo, format, compressed, error);
00910                 
00911         //      Now compute number of bad scans 
00912         format->numOfScansRejected = 0;
00913         format->numOfScansProcessed = 0;
00914         for (i = 0; i < format->numOfScans; i++)
00915         {
00916                 if (compressed->badScanList[i])
00917                         format->numOfScansRejected++;
00918         }
00919         format->numOfScansProcessed = format->numOfScans - format->numOfScansRejected;
00920 
00921         //      Create plot file
00922         if (plotFile && diagnostic) 
00923         {
00924                 tempArray = (float *) calloc (format->numOfScans, sizeof (float));
00925                 for (i = 0; i < format->numOfScans; i++)
00926                 {
00927                         if (compressed->badScanList[i] == 0)
00928                                 tempArray[i] = 0.0;
00929                         else
00930                                 tempArray[i] = compressed->badScanList[i];
00931                 }
00932                 midiCreatePlotFile2D ("BadScanList", "Bad Scan List", "Scan", "Failure ID", 
00933                         0, tempArray, 0, format->numOfScans, 1, 0);
00934                 free (tempArray);
00935         }
00936 
00937         //      Report the bad scan list
00938         if (diagnostic) cpl_msg_info(cpl_func,"\nBad Scan List \n");
00939         if (diagnostic) cpl_msg_info(cpl_func,"------------- \n");
00940         fprintf (midiReportPtr, "\nBad Scan List QCLOG \n");
00941         fprintf (midiReportPtr, "-------------   QCLOG \n");
00942         for (i = 0; i < format->numOfScans; i++)
00943         {
00944                 if (diagnostic) cpl_msg_info(cpl_func,"%3d  %3d \n", i, compressed->badScanList[i]);
00945                 fprintf (midiReportPtr, "%3d  %3d     QCLOG \n", i, compressed->badScanList[i]);
00946         }
00947         //      Report the bad scan list
00948         cpl_msg_info(cpl_func,"Number of scans to process = %3d \n", format->numOfScansProcessed);
00949         cpl_msg_info(cpl_func,"Number of scans rejected   = %3d \n", format->numOfScansRejected);
00950         fprintf (midiReportPtr, "Number of scans to process = %3d QCLOG \n", format->numOfScansProcessed);
00951         fprintf (midiReportPtr, "Number of scans rejected   = %3d QCLOG \n", format->numOfScansRejected);
00952         if (diagnostic) 
00953         {
00954                 cpl_msg_info(cpl_func,"Failure ID \n");
00955                 cpl_msg_info(cpl_func,"---------- \n");
00956                 cpl_msg_info(cpl_func,"1    = Bit  1, indicates a TIME error \n");
00957                 cpl_msg_info(cpl_func,"2    = Bit  2, indicates an LOCALOPD error \n");
00958                 cpl_msg_info(cpl_func,"4    = Bit  3, indicates an OPD error \n");
00959                 cpl_msg_info(cpl_func,"8    = Bit  4, indicates a Bad DATA \n");
00960                 cpl_msg_info(cpl_func,"16   = Bit  5, indicates a chopping problem (TARTYPE2) \n");
00961                 cpl_msg_info(cpl_func,"32   = Bit  6, indicates a Delay Line Jump \n");
00962                 cpl_msg_info(cpl_func,"64   = Bit  7, indicates an Unwanted Region \n");
00963                 cpl_msg_info(cpl_func,"128  = Bit  8, indicates a Weak Signal/Noise \n");
00964                 cpl_msg_info(cpl_func,"256  = Bit  9, indicates a SKY Background \n");
00965                 cpl_msg_info(cpl_func,"512  = Bit 10, indicates a TARTYPE Cross error. e.g. region 0 different to region 1 \n");
00966                 cpl_msg_info(cpl_func,"\nHence a number such as 168 indicates bits 4, 6 and 8 were set \n\n");        
00967         }
00968 
00969         fprintf (midiReportPtr, "Failure ID QCLOG \n");
00970         fprintf (midiReportPtr, "---------- QCLOG \n");
00971         fprintf (midiReportPtr, "1    = Bit  1, indicates a TIME error \n");
00972         fprintf (midiReportPtr, "2    = Bit  2, indicates an LOCALOPD error \n");
00973         fprintf (midiReportPtr, "4    = Bit  3, indicates an OPD error \n");
00974         fprintf (midiReportPtr, "8    = Bit  4, indicates a Bad DATA \n");
00975         fprintf (midiReportPtr, "16   = Bit  5, indicates a chopping problem (TARTYPE2) \n");
00976         fprintf (midiReportPtr, "32   = Bit  6, indicates a Delay Line Jump \n");
00977         fprintf (midiReportPtr, "64   = Bit  7, indicates an Unwanted Region \n");
00978         fprintf (midiReportPtr, "128  = Bit  8, indicates a Weak Signal/Noise \n");
00979         fprintf (midiReportPtr, "256  = Bit  9, indicates a SKY Background \n");
00980         fprintf (midiReportPtr, "512  = Bit 10, indicates a TARTYPE Cross error. e.g. region 0 different to region 1 \n");
00981         fprintf (midiReportPtr, "\nHence a number such as 168 indicates bits 4, 6 and 8 were set QCLOG \n\n");
00982         
00983         if (format->numOfScansProcessed < 1)
00984         {
00985                 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "No Scan to process");
00986                 *error = 1;
00987         }
00988         
00989     return;
00990 }
00991 /*****************************************************************************/
00992 
00993 
00994 
00995 
00996 /******************************************************************************
00997 *               European Southern Observatory
00998 *            VLTI MIDI Data Reduction Software
00999 *
01000 * Module name:  rejectScansOnWeakSNRUndisp
01001 * Input/Output: See function arguments to avoid duplication
01002 * Description:  Uses Power Spectrum to get the bad scans. This routine
01003 *                               is used for HIGH_SENS UNDISPERSED processing
01004 *
01005 * History:
01006 * 15-Mar-06     (csabet) Created
01007 ******************************************************************************/
01008 void rejectScansOnWeakSNRUndisp (
01009     FilterData          *filterInfo,    // In: Pointer to filter information
01010     ImageFormat         *format,                // In: Points to the image format
01011         CompressedData  *compressed,    // IO: Pointer to compressed data
01012         int                             *error)                 // Ou: Error status
01013 {
01014     //  Local Declarations
01015     //--------------------
01016     const char  routine[] = "rejectScansOnWeakSNRUndisp";
01017     float       *sigPtr, *spectrum, median, peak, ratio, calib;
01018     int         i, j, fftSizeHalf, peakIndex, loF, hiF;
01019         char            *fileName, *title;
01020         
01021     //  Algorithm
01022     //  ---------
01023     if (diagnostic > 4) cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
01024     if (diagnostic > 4) fprintf(midiReportPtr, "Invoking      routine '%s'  \n", routine);
01025 
01026     //  Initialization
01027         *error = 0;
01028         fftSizeHalf = (format->fftsize >> 1);
01029 
01030         //      Compute indices of the valid frequency range
01031         calib = format->optFreqCal / ((float) format->fftsize);
01032         loF = (int) (filterInfo->optFreqLo / calib);
01033         hiF = (int) (filterInfo->optFreqHi / calib);
01034         if (hiF > format->fftsize/2) hiF = format->fftsize/2;
01035 
01036     //  Allocate memory
01037     spectrum = (float *) calloc (fftSizeHalf, sizeof (float));
01038         
01039         //      Analyse spectrum for each scan
01040     for (i = 0; i < format->numOfScans; i++)
01041     {
01042             sigPtr = compressed->allSpectrum + i * fftSizeHalf;
01043 
01044                 //      Process good scans only
01045                 if (!(compressed->badScanList[i]))
01046                 {
01047                         //      Load spectrum for this scan
01048                 for (j = 0; j < fftSizeHalf; j++)
01049                             spectrum[j] = *sigPtr++;
01050 
01051                         //      Analyse the scan spectrum
01052                         peak = signalPeak (spectrum, 0, fftSizeHalf, &peakIndex);
01053                         median = signalMedian (spectrum, 0, fftSizeHalf);
01054                         ratio = peak/median;
01055                         
01056                         //      Check validity of the peak power
01057                         if ((ratio < 10.0) || (peakIndex < loF) || (peakIndex > hiF))
01058                                 compressed->badScanList[i] |= BSL_SNR_ERROR;
01059 
01060                         //      Plot
01061                         if (plotFile && diagnostic > 2)
01062                         {
01063                                 if (compressed->badScanList[i]) cpl_msg_info(cpl_func,"\n    <<ERROR>>: Scan %3d rejected \n\n", i);
01064                                 cpl_msg_info(cpl_func,"    Expected low frequency index  = %3d \n", loF);
01065                                 cpl_msg_info(cpl_func,"    Expected high frequency index = %3d \n", hiF);
01066                                 cpl_msg_info(cpl_func,"    Found peak index at           = %3d \n", peakIndex);
01067                                 cpl_msg_info(cpl_func,"    peak/median                   = %f \n", ratio);
01068                                 if (compressed->badScanList[i]) fprintf (midiReportPtr, "\n    <<ERROR>>: Scan %3d rejected \n\n", i);
01069                                 fprintf (midiReportPtr, "    Expected low frequency index  = %3d \n", loF);
01070                                 fprintf (midiReportPtr, "    Expected high frequency index = %3d \n", hiF);
01071                                 fprintf (midiReportPtr, "    Found peak index at           = %3d \n", peakIndex);
01072                                 fprintf (midiReportPtr, "    peak/median                   = %f \n", ratio);
01073 
01074                                 fileName = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
01075                                 title = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
01076                                 sprintf (fileName, "SpectrumScan%d", i);
01077                                 sprintf (title, "Power Spectrum. Scan %d", i);
01078                                 midiCreatePlotFile2D (fileName, title, "Frequancy bin", "Power Spectrum", 
01079                                         1, spectrum, 0, fftSizeHalf, 1, 0);
01080                                 free (fileName);
01081                                 free (title);
01082                         }
01083                 }
01084         }
01085 
01086     //  release memory
01087         free (spectrum);
01088 
01089     return;
01090 }
01091 /*****************************************************************************/
01092 
01093 
01094 
01095 
01096 /******************************************************************************
01097 *               European Southern Observatory
01098 *          VLTI MIDI Maintenance Templates Software
01099 *
01100 * Module name:  midiGetFWHM
01101 * Input/Output: See function arguments to avoid duplication
01102 * Description:  This function computes the centre and size of spectroscopic
01103 *                               image. The computation will return the Full Width at 
01104 *                               Half Maximum (FWHM)     of the image. 
01105 *
01106 * History:      
01107 * 23-Sep-04     (csabet) Created
01108 ******************************************************************************/
01109 void midiGetFWHM (
01110         int             imageCount,     // In: Image number or ID
01111         float   *image,         // In: Pointer to an image
01112         int             xImage,         // In: X size of image
01113         int             yImage,         // In: Y size of image
01114         int             sizeP,          // In: Search size for the target
01115         double  *xT,            // Ou: X coordinate of the target centroid
01116         double  *yT,            // Ou: Y coordinate of the target centroid
01117         double  *sizeXT,        // Ou: X-Width of the target
01118         double  *sizeYT,        // Ou: Y-Width of the target
01119     int         *error)         // Ou: Error status
01120 
01121 {
01122   
01123     //  Local Declarations
01124     //  ------------------
01125     const char  routine[] = "midiGetFWHM";
01126     int                 i, j, k, l, length, maxLength, start, end;
01127     float               *arrayData, centre, *centrePositions, *centreFluxErr2Min,
01128                                 fluxErr2Min, *span, siztT, fluxMax, *buffImage, max;
01129     char                *fileName, *title;
01130         
01131     //  Algorithm
01132     //  ---------
01133     if (diagnostic > 4) cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
01134     if (diagnostic > 4) fprintf (midiReportPtr, "Invoking      routine   '%s' \n", routine);
01135 
01136         //      Reset status
01137         *error = 0;
01138                 
01139         //      Allocate memory
01140         length = xImage * yImage;
01141         maxLength = (xImage > yImage) ? xImage : yImage;        // get the largest size
01142         arrayData = (float *) calloc (maxLength, sizeof (float));
01143         centrePositions = (float *) calloc (maxLength, sizeof (float));
01144         centreFluxErr2Min = (float *) calloc (maxLength, sizeof (float));
01145         span = (float *) calloc (maxLength, sizeof (float));
01146         buffImage = (float *) calloc (length, sizeof (float));
01147 
01148         //      Copy image
01149         for (i = 0; i < length; i++)
01150                 buffImage[i] = image[i];
01151                 
01152         //      Normalize image for a better 2D correlation
01153         fluxMax = buffImage[0];
01154         for (i = 0; i < length; i++)
01155                 if (buffImage[i] > fluxMax) fluxMax = buffImage[i];
01156         for (i = 0; i < length; i++)
01157                 buffImage[i] /= fluxMax;
01158 
01159         //      Determine Y and X-Width
01160         //      -----------------------
01161         //      For every row, y = 0, .. yImage
01162         for (i = 0; i < yImage; i++)
01163         {
01164                 //      Load row data, x = 0, .. xImage
01165                 for (j = 0; j < xImage; j++)
01166                 {
01167                         k = j + i * xImage;
01168                         arrayData[j] = buffImage[k];
01169                 }
01170                         
01171                 //      For every row compute centre, size and Error Mean Squared of the Gaussian profile
01172                 midiGaussian_1d_fit (arrayData, xImage, sizeP, &centre, &siztT, &fluxErr2Min, error);
01173                 if (*error)
01174                 {
01175                         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot determine target parameters");
01176                         free (arrayData);
01177                         free (centrePositions);
01178                         free (centreFluxErr2Min);
01179                         free (span);
01180                         free (buffImage);
01181                         return;
01182                 }
01183                 centrePositions[i] = centre;            // Centre positions of the target along Y
01184                 centreFluxErr2Min[i] = fluxErr2Min;     // Graphical presentation of the target centre
01185                 span[i] = siztT;                                        // Variations of Gaussian Span along Y
01186         }
01187 
01188         //      Find optimum Y
01189         *sizeXT = 0;
01190         for (i = 0; i < yImage; i++)
01191         {
01192                 if (span[i] > *sizeXT)
01193                 {
01194                         *yT = i; 
01195                         *sizeXT = span[i];
01196                 }
01197         }
01198 
01199         //      Find FWHM
01200         max = 0.0;
01201         l = *yT * xImage;
01202         for (j = 0; j < xImage; j++)
01203         {
01204                 //      Load row data, x = 0, .. xImage
01205                 k = j + l;
01206                 arrayData[j] = buffImage[k];
01207                 if (arrayData[j] > max) max = arrayData[j];
01208         }
01209         start = 0;
01210         end = 0;
01211         for (j = 0; j < xImage; j++)
01212         {
01213                 if (arrayData[j] > max/2.0)
01214                 {
01215                         start = j;
01216                         break;
01217                 }
01218         }
01219         for (j = xImage-1; j >= 0; j--)
01220         {
01221                 if (arrayData[j] > max/2.0)
01222                 {
01223                         end = j;
01224                         break;
01225                 }
01226         }
01227         *sizeXT = (end - start) * CIRCLE_TO_SQUARE;     // Hopefully taking the central region of the target only
01228         
01229         //      Create plot file
01230         if (plotFile)
01231         {
01232                 fileName = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
01233                 title = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
01234 
01235                 sprintf (fileName, "TargetFluxMinVarX%d", imageCount);
01236                 sprintf (title, "Target Flux Minimum Variance for each Y, beam %d", imageCount);
01237                 midiCreatePlotFile2D (fileName, title, "Y", "Flux", 0, centreFluxErr2Min, 0, yImage, 1, 0);
01238 
01239                 sprintf (fileName, "TargetPositionX%d", imageCount);
01240                 sprintf (title, "Target Centre along Y, beam %d", imageCount);
01241                 midiCreatePlotFile2D (fileName, title, "Y", "X", 0, centrePositions, 0, yImage, 1, 0);
01242 
01243                 sprintf (fileName, "TargetX_WidthAlongY%d", imageCount);
01244                 sprintf (title, "Target X-Width along Y, beam %d", imageCount);
01245                 midiCreatePlotFile2D (fileName, title, "Y", "X-Width", 0, span, 0, yImage, 1, 0);
01246 
01247                 sprintf (fileName, "TargetMaximumProfileAlongY%d", imageCount);
01248                 sprintf (title, "Target Maximum Profile at Y = %f, beam %d", *yT, imageCount);
01249                 midiCreatePlotFile2D (fileName, title, "X", "Flux", 0, arrayData, 0, xImage, 1, 0);
01250         
01251                 //      Release memory
01252                 free (fileName);
01253                 free (title);
01254         }
01255 
01256         //      Determine X and Y-Width
01257         //      ---------------------
01258         //      For every column, x = 0, .. xImage
01259         for (i = 0; i < xImage; i++)
01260         {
01261                 //      Load column data y = 0, .. yImage
01262                 for (j = 0; j < yImage; j++)
01263                 {
01264                         k = i + j * xImage;
01265                         arrayData[j] = buffImage[k];
01266                 }
01267                         
01268                 //      For every column compute centre, size and Error Mean Squared of the Gaussian profile
01269                 midiGaussian_1d_fit (arrayData, yImage, sizeP, &centre, &siztT, &fluxErr2Min, error);
01270                 if (*error)
01271                 {
01272                         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot determine target parameters");
01273                         free (arrayData);
01274                         free (centrePositions);
01275                         free (centreFluxErr2Min);
01276                         free (buffImage);
01277                         free (span);
01278                         return;
01279                 }
01280                 centrePositions[i] = centre;            // Centre positions of the target along X
01281                 centreFluxErr2Min[i] = fluxErr2Min;     // Graphical presentation of the target centre
01282                 span[i] = siztT;                                        // Variations of target Y-Width along X
01283         }
01284 
01285         *sizeYT = 0;
01286         for (i = 0; i < xImage; i++)
01287         {
01288                 if (span[i] > *sizeYT)
01289                 {
01290                         *xT = i; 
01291                         *sizeYT = span[i];
01292                 }
01293         }
01294 
01295         //      Find FWHM
01296         max = 0.0;
01297         for (i = 0; i < yImage; i++)
01298         {
01299                 //      Load column data, y = 0, .. yImage
01300                 k = *xT + i * xImage;
01301                 arrayData[i] = buffImage[k];
01302                 if (arrayData[i] > max) max = arrayData[i];
01303         }
01304         start = 0;
01305         end = 0;
01306         for (j = 0; j < yImage; j++)
01307         {
01308                 if (arrayData[j] > max/2.0)
01309                 {
01310                         start = j;
01311                         break;
01312                 }
01313         }
01314         for (j = yImage-1; j >= 0; j--)
01315         {
01316                 if (arrayData[j] > max/2.0)
01317                 {
01318                         end = j;
01319                         break;
01320                 }
01321         }
01322         *sizeYT = (end - start) * CIRCLE_TO_SQUARE;     // Hopefully taking the central region of the target only
01323 
01324         //      Create plot file
01325         if (plotFile)
01326         {
01327                 fileName = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
01328                 title = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
01329 
01330                 sprintf (fileName, "TargetFluxMinVarY%d", imageCount);
01331                 sprintf (title, "Target Flux Minimum Variance for each X, beam %d", imageCount);
01332                 midiCreatePlotFile2D (fileName, title, "X", "Flux", 0, centreFluxErr2Min, 0, xImage, 1, 0);
01333 
01334                 sprintf (fileName, "TargetPositionY%d", imageCount);
01335                 sprintf (title, "Target Centre along Y, beam %d", imageCount);
01336                 midiCreatePlotFile2D (fileName, title, "X", "Y", 0, centrePositions, 0, xImage, 1, 0);
01337 
01338                 sprintf (fileName, "TargetY_WidthAlongY%d", imageCount);
01339                 sprintf (title, "Target Y-Width along Y, beam %d", imageCount);
01340                 midiCreatePlotFile2D (fileName, title, "X", "Y-Width", 0, span, 0, xImage, 1, 0);
01341 
01342                 sprintf (fileName, "TargetMaximumProfileAlongX%d", imageCount);
01343                 sprintf (title, "Target Maximum Profile at X = %f, beam %d", *xT, imageCount);
01344                 midiCreatePlotFile2D (fileName, title, "Y", "Flux", 0, arrayData, 0, yImage, 1, 0);
01345         
01346                 //      Release memory
01347                 free (fileName);
01348                 free (title);
01349         }
01350 
01351         //      Release memory
01352         free (arrayData);
01353         free (centrePositions);
01354         free (centreFluxErr2Min);
01355         free (span);
01356         free (buffImage);
01357         
01358     return; 
01359 }
01360 //*****************************************************************************
01361 
01362 
01363 /******************************************************************************
01364 *               European Southern Observatory
01365 *            VLTI MIDI Data Reduction Software
01366 *
01367 * Module name:  removeSkyBackground
01368 * Input/Output: See function arguments to avoid duplication
01369 * Description:  Removes sky background.
01370 *
01371 * History:
01372 * 08-Aug-05     (csabet) Created
01373 * 13-Feb-06     (csabet) Completely redesigned
01374 ******************************************************************************/
01375 void removeSkyBackground (
01376     const char                                *shutterId,             // In: AOPEN, BOPEN etc.
01377     enum ProcessingMode processing,             // In: Whether DISP or UNDISP
01378     ImageFormat                 *format,                // In: Format parameters
01379     CompressedData              *compressed,    // Ou: Pointer to the compressed data structure
01380     int                                 *error)                 // Ou: Error status
01381 
01382 {
01383     //  Local Declarations
01384     //  ------------------
01385     const char  routine[] = "removeSkyBackground";
01386         int                     i, j, S, T, R, X, shift, start;
01387         char            lastType;
01388 
01389     //  Algorithm
01390     //  ---------
01391     if (diagnostic > 4) cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
01392     if (diagnostic > 4) fprintf(midiReportPtr, "Invoking      routine   '%s' \n", routine);
01393 
01394         sprintf (midiMessage, "Removing sky background from %s", shutterId);
01395         midiReportInfo (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
01396 
01397         //      Initialise
01398         S = T = 0;
01399         start = 0;
01400         lastType = ' ';
01401         *error = 0;
01402         
01403         //      Compute shift
01404         for (i = 0; i < format->numOfFrames; i++)
01405         {
01406                 if (compressed->tarType[i] == 'T')
01407                 {
01408                         if (lastType == 'U' && T && S)
01409                         {
01410                                 T = 0;
01411                                 S = 0;
01412                         }
01413                         T++;
01414                         if (S)
01415                         {
01416                                 shift = i-start;
01417                                 for (j = start; j < start+S; j++)
01418                                 {
01419                                         if (compressed->tarType[j] != 'U')
01420                                         {
01421                                                 if (diagnostic > 4)
01422                                                 {
01423                                                         cpl_msg_info(cpl_func,"%4d-%4d   %c-%c \n", j+shift, j, 
01424                                                                 compressed->tarType[j+shift], compressed->tarType[j]);
01425                                                         fprintf (midiReportPtr, "%4d-%4d   %c-%c \n", j+shift, j, 
01426                                                                 compressed->tarType[j+shift], compressed->tarType[j]);
01427                                                 }
01428                                                 compressed->iFringe[j] = compressed->iFringe[j+shift] - compressed->iFringe[j];
01429                                                 compressed->iFringe1[j] = compressed->iFringe1[j+shift] - compressed->iFringe1[j];
01430                                                 compressed->iFringe2[j] = compressed->iFringe2[j+shift] - compressed->iFringe2[j];
01431                                                 if (processing == DISPERSED)
01432                                                 {
01433                                                         for (R = 0; R < format->numOfRegionsToProcess; R++)
01434                                                         {
01435                                                                 for (X = 0; X < format->iXWidth; X++)
01436                                                                 {
01437                                                                         (((compressed->iDispFringe)[R])[X])[j] = (((compressed->iDispFringe)[R])[X])[j+shift] - 
01438                                                                                 (((compressed->iDispFringe)[R])[X])[j];
01439                                                                 }
01440                                                         }
01441                                                 }
01442                                         }
01443                                 }
01444                                 i = j+shift-1;
01445                         }
01446                 }
01447                 else if (compressed->tarType[i] == 'S')
01448                 {
01449                         if (lastType == 'U' && T && S)
01450                         {
01451                                 S = 0;
01452                                 T = 0;
01453                         }
01454                         S++;
01455                         if (T)
01456                         {
01457                                 shift = i-start;
01458                                 for (j = start; j < start+T; j++)
01459                                 {
01460                                         if (compressed->tarType[j] != 'U')
01461                                         {
01462                                                 if (diagnostic > 4)
01463                                                 {
01464                                                         cpl_msg_info(cpl_func,"%4d-%4d   %c-%c \n", j, j+shift, 
01465                                                                 compressed->tarType[j], compressed->tarType[j+shift]);
01466                                                         fprintf (midiReportPtr, "%4d-%4d   %c-%c \n", j, j+shift, 
01467                                                                 compressed->tarType[j], compressed->tarType[j+shift]);
01468                                                 }
01469                                                 compressed->iFringe[j] = compressed->iFringe[j] - compressed->iFringe[j+shift];
01470                                                 compressed->iFringe1[j] = compressed->iFringe1[j] - compressed->iFringe1[j+shift];
01471                                                 compressed->iFringe2[j] = compressed->iFringe2[j] - compressed->iFringe2[j+shift];
01472                                                 if (processing == DISPERSED)
01473                                                 {
01474                                                         for (R = 0; R < format->numOfRegionsToProcess; R++)
01475                                                         {
01476                                                                 for (X = 0; X < format->iXWidth; X++)
01477                                                                 {
01478                                                                         (((compressed->iDispFringe)[R])[X])[j] = (((compressed->iDispFringe)[R])[X])[j] - 
01479                                                                                 (((compressed->iDispFringe)[R])[X])[j+shift];
01480                                                                 }
01481                                                         }
01482                                                 }
01483                                         }
01484                                 }
01485                                 i = j+shift-1;
01486                         }
01487                 }
01488                 else
01489                 {
01490                         if (diagnostic > 4)
01491                         {
01492                                 fprintf (midiReportPtr, "%4d %c \n", i, compressed->tarType[i]);
01493                                 cpl_msg_info(cpl_func,"%4d %c \n", i, compressed->tarType[i]);
01494                         }
01495                         lastType = 'U';
01496                         if ((S && T) || (!S && !T))
01497                         {
01498                                 start = i+1;
01499                         }
01500                 }
01501         }
01502 
01503     return;
01504 }
01505 /*****************************************************************************/
01506 
01507 
01508 
01509 /******************************************************************************
01510 *               European Southern Observatory
01511 *             VLTI MIDI Data Reduction Software
01512 *
01513 * Module name:  correctTarType
01514 * Input/Output: See function arguments to avoid duplication
01515 * Description:  Creates a mask from the tarType. Esures number of consecutive 
01516 *                               T and S are equal. Extras should be labled 'U'. New tarType
01517 *                               is then created
01518 *
01519 * History:
01520 * 09-Feb-06     (csabet) Created
01521 ******************************************************************************/
01522 long correctTarType (
01523         const char    *shutterId,
01524         char          *tarType,
01525         float         *TimeStamp,
01526         int            length,
01527         int            *error)
01528 {
01529 
01530     //  Local Declarations
01531     //  ------------------
01532     const char  routine[] = "correctTarType";
01533     int                     i, j, foundT, foundS, S, T, U, start, end, min, newPair;
01534     char            *mask, lastType, lastShot;
01535     long        CounterBad=0;
01536 
01537     //  Algorithm
01538     //  ---------
01539     if (diagnostic > 4) cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
01540     if (diagnostic > 4) fprintf(midiReportPtr, "Invoking      routine   '%s' \n", routine);
01541 
01542         sprintf (midiMessage, "Checking tarType inconsistencies for %s", shutterId);
01543         midiReportInfo (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
01544 
01545         //      Initialise
01546     foundT = foundS = 0;
01547     T = S = U = 0;
01548     start = 0;
01549     lastType = ' ';
01550     lastShot = ' ';
01551     newPair = 0;
01552     *error = 0;
01553     i=0;
01554     j=0 ;
01555     CounterBad=0;
01556         //      Allocate memory
01557     mask = (char *) calloc (length, sizeof (char));
01558 
01559 /*
01560     Check if the time is valid or not. If not, change tarType to 'U'
01561     If a SUS or TUT sequence is caused by this change, set all previous frames
01562     to 'U' until a TUS or a SUT sequence is re-established
01563 */
01564 
01565     for (i = 0; i < length; i++)
01566     {
01567         if(isnan(TimeStamp[i]))
01568         {
01569             cpl_msg_warning(cpl_func,"Corrupted time stamp in table! ");
01570             cpl_msg_warning(cpl_func,"Changing target type of frame %d "
01571                     "from %c to %c", i, tarType[i], 'U');
01572             tarType[i]='U';
01573             CounterBad++;
01574             if(i>0 && i<(length-1) && tarType[i-1]=='S' && tarType[i+1]=='S')
01575             {
01576                 j=i-1;
01577                 while(tarType[j]!='T' && j>=0)
01578                 {
01579                     cpl_msg_warning(cpl_func,"Changing target type of frame %d "
01580                             "from %c to %c", j, tarType[j], 'U');
01581                     tarType[j]='U';
01582                     CounterBad++;
01583                     j--;
01584                 }
01585             }
01586             if(i>0 && i<(length-1) && tarType[i-1]=='T' && tarType[i+1]=='T')
01587             {
01588                 j=i-1;
01589                 while(tarType[j]!='S' && j>=0)
01590                 {
01591                     cpl_msg_warning(cpl_func,"Changing target type of frame %d "
01592                             "from %c to %c", j, tarType[j], 'U');
01593                     tarType[j]='U';
01594                     CounterBad++;
01595                     j--;
01596                 }
01597 
01598             }
01599 
01600         }
01601     }
01602 
01603     for (i = 1; i < length-2; i++)
01604     {
01605         if(tarType[i-1]=='U' && (tarType[i]=='S' || tarType[i]=='T') &&
01606                 tarType[i+1]=='U')
01607         {
01608             cpl_msg_warning(cpl_func,"UTU or USU sequence found, "
01609                     "correcting to UUU");
01610             tarType[i]='U';
01611         }
01612     }
01613 
01614 
01615     for (i = 0; i < length-1; i++)
01616     {
01617         if(tarType[i]=='T' && tarType[i+1]=='S')
01618         {
01619             cpl_msg_warning(cpl_func,"Switching from T to S without U at "
01620                     "frame %d", i);
01621             cpl_msg_warning(cpl_func,"Changing target type of frame %d and %d"
01622                     " to %c", i, i+1, 'U');
01623             tarType[i]='U';
01624             CounterBad++;
01625             tarType[i+1]='U';
01626             CounterBad++;
01627         }
01628 
01629         if(tarType[i]=='S' && tarType[i+1]=='T')
01630         {
01631             cpl_msg_warning(cpl_func,"Switching from S to T without U at "
01632                     "frame %d", i);
01633             cpl_msg_warning(cpl_func,"Changing target type of frame %d and %d"
01634                     " to %c", i, i+1, 'U');
01635             tarType[i]='U';
01636             CounterBad++;
01637             tarType[i+1]='U';
01638             CounterBad++;
01639         }
01640 
01641     }
01642 
01643 
01644         for (i = 0; i < length; i++)
01645         {
01646                 //      Count number of Targets
01647                 if (tarType[i] == 'T')
01648                 {
01649                         if (lastType == 'S')
01650                         {
01651                                 sprintf (midiMessage, "Switching from S to T without U at frame %d. QCLOG", i);
01652                                 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
01653                                 *error = 1;
01654                         }
01655                         if (lastShot == 'T')
01656                         {
01657                                 sprintf (midiMessage, "Switching from T to T without S at frame %d. QCLOG", i);
01658                                 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
01659                                 *error = 1;
01660                         }
01661                         T++;
01662                         mask[i] = 'T';
01663                         lastType = 'T';
01664                         newPair = 0;
01665                 }
01666                 //      Count number of Skys
01667                 else if (tarType[i] == 'S')
01668                 {
01669                         if (lastType == 'T')
01670                         {
01671                                 sprintf (midiMessage, "Switching from T to S without U at frame %d. QCLOG", i);
01672                                 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
01673                                 *error = 1;
01674                         }
01675                         if (lastShot == 'S')
01676                         {
01677                                 sprintf (midiMessage, "Switching from S to S without T at frame %d. QCLOG", i);
01678                                 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
01679                                 *error = 1;
01680                         }
01681                         S++;
01682                         mask[i] = 'S';
01683                         lastType = 'S';
01684                         newPair = 0;
01685                 }
01686                 else
01687                 {
01688                         mask[i] = 'U';
01689                         if (lastType == 'T')
01690                         {
01691                                 lastShot = 'T';
01692                                 foundT = 1;
01693                         }
01694                         if (lastType == 'S')
01695                         {
01696                                 lastShot = 'S';
01697                                 foundS = 1;
01698                         }
01699                         lastType = 'U';
01700                         if (newPair) 
01701                                 start++;
01702                 }
01703                 //      Check sizes and apply corrections
01704                 if ((foundS && foundT) || (foundS && T && (i == length-1)) || (foundT && S && (i == length-1)))
01705                 {
01706                         end = i+1;
01707                         if (S < T) 
01708                                 min = S;
01709                         else 
01710                                 min = T;
01711                                         
01712                         T = S = 0;
01713                         for (j = start; j < end; j++)
01714                         {
01715                                 if (mask[j] == 'T')
01716                                 {
01717                                         T++;
01718                                         if (T > min)
01719                                         {
01720                                                 mask[j] = 'U';
01721                                                 sprintf (midiMessage, "Chopping inconsistency. Found extra 'T' at frame %d. Corrected. QCLOG", j);
01722                                                 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
01723                                         }
01724                                 }
01725                                 else if (mask[j] == 'S')
01726                                 {
01727                                         S++;
01728                                         if (S > min)
01729                                         {
01730                                                 mask[j] = 'U';
01731                                                 sprintf (midiMessage, "Chopping inconsistency. Found extra 'S' at frame %d. Corrected. QCLOG", j);
01732                                                 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
01733                                         }
01734                                 }
01735                         }
01736                         T = S = 0;
01737                         if (foundS && foundT)
01738                         {
01739                                 newPair = 1;
01740                                 start = i;
01741                                 --i;
01742                         }
01743                         foundS = foundT = 0;
01744                 }
01745                 else if ((!foundS && T && (i == length-1)) || (!foundT && S && (i == length-1)))
01746                 {
01747                         for (j = start; j <= i; j++)
01748                         {
01749                                 mask[j] = 'U';
01750                                 sprintf (midiMessage, "Chopping inconsistency. Found extra 'S' or 'T' at frame %d. Corrected. QCLOG", j);
01751                                 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
01752                         }
01753                 }
01754         }
01755 
01756         //      Update tarType
01757         for (i = 0; i < length; i++)
01758                 tarType[i] = mask[i];
01759                 
01760         //      Display new tarType
01761         if (diagnostic > 4)
01762         {
01763                 for (i = 0; i < length; i++)
01764                 {
01765                         cpl_msg_info(cpl_func,"%4d  %c \n", i, tarType[i]);
01766                         fprintf (midiReportPtr, "%4d  %c \n", i, tarType[i]);
01767                 }
01768         }
01769 
01770         //      Release memory
01771         free (mask);
01772         
01773         return CounterBad;
01774 }       
01775 /*****************************************************************************/
01776 

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