procDetLin.c

00001 
00002 /******************************************************************************
00003 *******************************************************************************
00004 *               European Southern Observatory
00005 *          VLTI MIDI Maintenance Templates Software
00006 *
00007 * Module name:  procDetLin.c
00008 * Description:  Contains routines for processing the templates
00009 *
00010 * History:      
00011 * 16-Jun-04     (csabet) created
00012 *******************************************************************************
00013 ******************************************************************************/
00014 
00015 /******************************************************************************
00016 *   Compiler directives
00017 ******************************************************************************/
00018 
00019 /******************************************************************************
00020 *   Include files
00021 ******************************************************************************/
00022 #include <math.h>
00023 #include <stdio.h>
00024 #include <cpl.h>
00025 #include "midiGlobal.h"
00026 #include "midiLib.h"
00027 #include "imageProcessing.h"
00028 #include "memoryHandling.h"
00029 #include "errorHandling.h"
00030 #include "createProdDetLin.h"
00031 #include "midiFitsUtility.h"
00032 #include "fitsAnalysisTec.h"
00033 #include "procDetLin.h"
00034 #include "statistics.h"
00035 #include "diagnostics.h"
00036 #include "cpl_polynomial.h"
00037 #include "qfits.h"
00038 #include "midi_cplutils.h"
00039 
00040 /**********************************************************
00041 *   Constant definitions
00042 **********************************************************/
00043 
00044 /**********************************************************
00045 *   Global Variables 
00046 **********************************************************/
00047 
00048 /*============================ C O D E    A R E A ===========================*/
00049 
00050 
00051 
00052 /******************************************************************************
00053 *               European Southern Observatory
00054 *          VLTI MIDI Maintenance Templates Software
00055 *
00056 * Module name:  procDetLin
00057 * Input/Output: See function arguments to avoid duplication
00058 * Description:  Computes the detector linearity. This is the main routine for this
00059 *                application.
00060 *
00061 * History:      
00062 * 03-May-05     (csabet) Created
00063 * 09-May-06     (csabet) Modified to characterise each pixel
00064 ******************************************************************************/
00065 void procDetLin (
00066     MidiFiles    *fileNames,    // In: Pointer to file names
00067     int            *error)        // Ou: Error status
00068 {
00069 
00070     //    Local Declarations
00071     //    ------------------
00072     const char      routine[] = "procDetLin";
00073     ImageFormat        *format=NULL;
00074     DetLinearity     *linearity=NULL;
00075     int                numOfFiles;
00076     FILE            *signaturePtr=NULL;
00077     
00078     //    Algorithm
00079     //    ---------
00080     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
00081     if (diagnostic > 4) fprintf (midiReportPtr, "Invoking      routine   '%s' \n", routine);
00082 
00083     //    Write a signature
00084     signaturePtr = fopen ("MIDI_sig_lin.log", "w");
00085     fclose (signaturePtr);
00086 
00087     //    Reset status
00088     *error = 0;
00089     numOfFiles = 0;
00090     
00091     //    Allocate memory
00092     format = callocImageFormat ();
00093     
00094     analyseFitsDetLin (fileNames, format, &numOfFiles, error);
00095     if (*error)
00096     {
00097         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot analyse DETLIN");
00098         freeImageFormat (format);
00099         return;
00100     }
00101     
00102     linearity = callocDetLin (numOfFiles, format);
00103     computeDetLin (numOfFiles, fileNames, format, linearity, error);
00104     if (*error)
00105     {
00106         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot process DETLIN");
00107         freeDetLin (linearity);
00108         freeImageFormat (format);
00109         return;
00110     }
00111     
00112     createDetLinProd (fileNames, format, numOfFiles, linearity, error);
00113     if (*error)    midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot create DETLIN products");
00114 
00115     //    Release memory
00116     freeDetLin (linearity);
00117     freeImageFormat (format);
00118 
00119     return; 
00120 }
00121 /*****************************************************************************/
00122 
00123 
00124 /******************************************************************************
00125 *               European Southern Observatory
00126 *          VLTI MIDI Maintenance Templates Software
00127 *
00128 * Module name:  computeDetLin
00129 * Input/Output: See function arguments to avoid duplication
00130 * Description:  Computes the detector linearity. 
00131 *                Compute average flux for each pixel in a given file. Exclude saturated pixels.
00132 *                Find coefficients of a polynomial describing the linearity over the integration 
00133 *                time.
00134 *
00135 * History:      
00136 * 15-Jun-04     (csabet) Created
00137 * 09-May-06     (csabet) Modified to characterise each pixel
00138 ******************************************************************************/
00139 void computeDetLin (
00140     int                numOfFiles,    // In: Number of data files
00141     MidiFiles        *fileNames,    // In: Pointer to the MIDI file structure
00142     ImageFormat        *format,    // In: Data format
00143     DetLinearity     *linearity,    // Ou: Pointer to the detector linearity data structure
00144     int                *error)        // Ou: Error status
00145 {
00146 
00147     //    Local Declarations
00148     //    ------------------
00149     const char  routine[] = "computeDetLin";
00150     char        *fileTemp, *classification, *firstFitsFile;
00151     FILE        *inFitsBatchPtr;
00152     ImageFormat    *formatLocal;
00153     int            localError, fileNumber, extNumOfImagingDataFile;
00154     
00155     //    Algorithm
00156     //    ---------
00157     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
00158     if (diagnostic > 4) fprintf (midiReportPtr, "Invoking      routine   '%s' \n", routine);
00159 
00160     //    Allocate memory
00161     classification = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00162     firstFitsFile = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00163     fileTemp = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00164     formatLocal = callocImageFormat ();
00165 
00166     //    Reset status
00167     *error = 0;
00168     localError = 0;
00169     fileNumber = 0;
00170     linearity->exists = 0;
00171     formatLocal->hasData = 0;
00172             
00173     //    Open the list of files
00174     if ((inFitsBatchPtr = fopen (fileNames->inFitsBatch, "r")) == NULL)
00175     {
00176         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, 
00177             "Cannot open input FITS file list\n                 No compression has been carried out for this batch");
00178         freeImageFormat (formatLocal);
00179         free (fileTemp);
00180         free (classification);
00181         *error = 1;
00182         return;
00183     }
00184 
00185     //    Loop through the files and analyse
00186     while (fgets (fileTemp, MAX_STRING_LENGTH, inFitsBatchPtr) != NULL)
00187     {
00188         sprintf (classification, "%s", "");
00189         sscanf (fileTemp, "%s%s", fileNames->inFitsName, classification);
00190         if (diagnostic)cpl_msg_info(cpl_func,"\n   Processing file   %s \n", fileNames->inFitsName);
00191         fprintf(midiReportPtr, "\n   Processing file   %s \n", fileNames->inFitsName);
00192 
00193         //    Get 'extNumOfImagingDataFile' extension number of IMAGING_DATA in input file
00194         extNumOfImagingDataFile  = findImagingDataExtension (fileNames->inFitsName, TAB_IMAGING_DATA, &localError);
00195         if (localError) 
00196         {
00197             *error = 1;
00198             break;
00199         }
00200 
00201         //    Get Image Format parameters
00202         if (extNumOfImagingDataFile > 0)
00203         {
00204             getImageFormat (fileNames->inFitsName, extNumOfImagingDataFile, formatLocal, &localError);
00205             if (localError) 
00206             {
00207                 *error = 1;
00208                 break;
00209             }
00210         }
00211         else formatLocal->hasData = 0;
00212 
00213         //    Check if the file has data
00214         if (formatLocal->hasData)
00215         {
00216             //    Check Categ, Tech and Type and then compute the image size
00217             if ((strcmp (formatLocal->obsCatg, "CALIB") == 0) &&
00218                 ((strcmp (formatLocal->obsTech, "IMAGE") == 0) || 
00219                 (strcmp (formatLocal->obsTech, "SPECTRUM") == 0)) &&
00220                 (strcmp (formatLocal->obsType, "FLAT") == 0))
00221             {
00222                 //    Save grism ID
00223                 sprintf (linearity->grismId, "%s", formatLocal->grismId);
00224                 if (diagnostic)cpl_msg_info(cpl_func,"   Grism ID for file %d           = %s\n", fileNumber+1, formatLocal->grismId);
00225                 fprintf (midiReportPtr, "   Grism ID for file %d           = %s\n", fileNumber+1, formatLocal->grismId);
00226                 
00227                 //    Create and display averaged images
00228                 createAndDisplayImageDetLin (fileNumber, fileNames->inFitsName, extNumOfImagingDataFile, 
00229                     format, linearity, &localError);
00230                 if (localError) *error = 1;
00231                     
00232                 //    Calculate mean of counts. Ignore this file if pixels are saturated
00233                 getIntegrationTime (fileNumber, fileNames->inFitsName, linearity, &localError);
00234                 if (localError) *error = 1;
00235                         
00236                 //    Set the flags
00237                 linearity->exists = 1;
00238 
00239                 //    Increment file number but make sure it is not greater than the allocated
00240                 fileNumber++;
00241                 if (fileNumber > numOfFiles)
00242                 {
00243                     *error = 1;
00244                     break;
00245                 }
00246                 
00247                 //    Save name of the first FITS file
00248                 if (fileNumber == 1) sprintf (firstFitsFile, "%s", fileNames->inFitsName);
00249             }
00250             else
00251                 midiReportInfo (midiReportPtr, routine, __FILE__, __LINE__, "The above file is not suitable for this task");
00252         }
00253         else
00254         {
00255             if (diagnostic)
00256             {
00257                 sprintf (midiMessage, "No data tables in %s. Not processed", fileNames->inFitsName);
00258                 midiReportInfo (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
00259             }
00260         }
00261     }
00262 
00263     
00264     //    Check if processing has been carried out
00265     if ((linearity->exists) && !(*error) && (fileNumber == numOfFiles))
00266     {
00267        cpl_msg_info(cpl_func,"\nDetector Linearity Inventry: \n");
00268        cpl_msg_info(cpl_func,"=========================== \n");
00269        cpl_msg_info(cpl_func,"   Expected number of data files  = %d\n", numOfFiles);
00270        cpl_msg_info(cpl_func,"   Number of data files processed = %d\n", fileNumber);
00271        cpl_msg_info(cpl_func,"\n");
00272 
00273         fprintf (midiReportPtr, "\nDetector Linearity Inventry: \n");
00274         fprintf (midiReportPtr, "=========================== \n");
00275         fprintf (midiReportPtr, "   Expected number of data files  = %d\n", numOfFiles);
00276         fprintf (midiReportPtr, "   Number of data files processed = %d\n", fileNumber);
00277         fprintf (midiReportPtr, "\n");
00278 
00279         //    Assess linerity
00280         //    ---------------
00281         assessLinearity (format, firstFitsFile, linearity, error);
00282     }
00283 
00284     if (*error || localError)
00285         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot assess Detector Linearity");
00286 
00287     //    Close the file list
00288     fclose (inFitsBatchPtr);
00289     
00290     //    Release memory
00291     freeImageFormat (formatLocal);
00292     free (fileTemp);
00293     free (classification);
00294     free (firstFitsFile);
00295 
00296     return; 
00297 }
00298 /*****************************************************************************/
00299 
00300 
00301 /******************************************************************************
00302 *               European Southern Observatory
00303 *          VLTI MIDI Maintenance Templates Software
00304 *
00305 * Module name:  createAndDisplayImageDetLin
00306 * Input/Output: See function arguments to avoid duplication
00307 * Description:  Creates averaged images for display and later processing
00308 *                purposes.
00309 *
00310 * History:      
00311 * 08-May-06     (csabet) Created
00312 ******************************************************************************/
00313 void createAndDisplayImageDetLin ( 
00314     int                fileNumber,            // In: File number
00315     char            *fileName,            // In: Name of file to process
00316     int                extensionNumber,    // In: Extension number of the IMAGE_DATA
00317     ImageFormat        *format,            // In: Pointer to the image format
00318     DetLinearity     *linearity,            // Ou: Pointer to the detector linearity data structure
00319     int                *error)                // Ou: Error status
00320 
00321 {
00322   
00323     //    Local Declarations
00324     //    ------------------
00325     const char  routine[] = "createAndDisplayImageDetLin";
00326     qfits_table *pTable  = NULL;
00327     short int   *inData;
00328     char        *tempStr, *string, *title, *dataName;
00329     int         i, foundData = 0, scalingOffset, 
00330                 indexData;
00331        
00332     //    Algorithm
00333     //    ---------
00334     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
00335     if (diagnostic > 4) fprintf (midiReportPtr, "Invoking      routine   '%s' \n", routine);
00336     
00337     //    Reset status
00338     *error = 0;
00339     linearity->saturated[fileNumber] = 0;
00340     
00341     //    Open IMAGING_DATA = INDEX 2
00342     pTable = qfits_table_open (fileName, extensionNumber);
00343     if (!pTable)
00344     {
00345         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot load IMAGING_DATA");
00346         *error = 1;
00347         return;
00348     }
00349         
00350     //    Get data table information
00351     for (i = 0; i < pTable->nc; i++)
00352     {
00353         if (strcmp (pTable->col[i].tlabel, "DATA1") == 0)
00354         {
00355             foundData = 1;
00356             indexData = i;
00357         }
00358     }
00359     if (foundData == 0)
00360     {
00361         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot find requested columns in data FITS file");
00362         qfits_table_close (pTable);
00363         *error = 1;
00364         return;
00365     }
00366 
00367     //    Read column DATA
00368     inData = (short int*) qfits_query_column (pTable, indexData, NULL); 
00369 
00370     //    Get the scaling offset
00371     dataName = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00372     for (i = 14; i < 25; i++)
00373     {
00374         sprintf (dataName, "TZERO%d", i);
00375         tempStr = qfits_query_ext (fileName, dataName, extensionNumber);
00376         if (tempStr != NULL)
00377         {
00378             if (diagnostic)cpl_msg_info(cpl_func,"Scaling Offset = %s\n", tempStr);
00379             if (diagnostic) fprintf (midiReportPtr, "Scaling Offset = %s\n", tempStr);
00380             sscanf (tempStr, "%d", &scalingOffset);
00381             break;
00382         }
00383     }
00384     if (tempStr == NULL)
00385     {
00386         scalingOffset = 0;
00387         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot read Scaling Offset. It is set to 0");
00388     }
00389     free (dataName);
00390     
00391     //    Create averaged image for the whole file. This also allows a check on existence of a target
00392     createAveragedImage (inData, scalingOffset,    format, linearity->aveImage[fileNumber]);
00393 
00394     //    Create an image FITS file
00395     title = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00396     string = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00397     sprintf (title, "AveImg%d", fileNumber+1);
00398     sprintf (string, "file %d", fileNumber+1);
00399     createFitsImage (string, title, fileName, format->iXWidth, format->iYWidth, linearity->aveImage[fileNumber]);
00400 
00401     //    Create plot file
00402     if (plotFile)
00403     {
00404         sprintf (string, "3dAveImg%d", fileNumber+1);
00405         sprintf (title, "Averaged Image, file %d", fileNumber+1);
00406         midiCreatePlotFile3D (string, title, "X", "Y", "Flux", 
00407             0, linearity->aveImage[fileNumber], format->iXWidth, format->iYWidth, "lines", "3");
00408     }
00409 
00410     //    Create an averaged image. This time excluding the saturated pixels
00411     checkSaturationDetLin (inData, scalingOffset, format, linearity->aveImage[fileNumber], 
00412         &(linearity->saturated[fileNumber]));
00413 
00414     //    Create plot file excluding saturated pixels
00415     if (diagnostic > 2)
00416     {
00417         sprintf (string, "3dAveImgClean%d", fileNumber+1);
00418         sprintf (title, "Averaged Image. Excluding saturated pixels, file %d", fileNumber+1);
00419         if (plotFile) midiCreatePlotFile3D (string, title, "X", "Y", "Flux", 
00420             0, linearity->aveImage[fileNumber], format->iXWidth, format->iYWidth, "lines", "3");
00421     }
00422     free (title);
00423     free (string);
00424     
00425     //    Release memory
00426     qfits_table_close (pTable);
00427     free (inData);
00428 
00429     return; 
00430 }
00431 /*****************************************************************************/
00432 
00433 
00434 /******************************************************************************
00435 *               European Southern Observatory
00436 *          VLTI MIDI Maintenance Templates Software
00437 *
00438 * Module name:  getIntegrationTime
00439 * Input/Output: See function arguments to avoid duplication
00440 * Description:  Retrieves Integration time as well as the Number of Integrations.
00441 *
00442 * History:      
00443 * 09-May-06     (csabet) Created
00444 ******************************************************************************/
00445 void getIntegrationTime ( 
00446     int                fileNumber,    // In: File number
00447     char            *fileName,    // In: Name of file to process
00448     DetLinearity    *linearity,    // Ou: Pointer to the detector linearity data structure
00449     int                *error)        // Ou: Error status
00450 
00451 {
00452  
00453     //    Local Declarations
00454     //    ------------------
00455     const char  routine[] = "getIntegrationTime";
00456     char        *tempStr;
00457     float         numOfSubInteg, subIntegTime;
00458          
00459     //    Algorithm
00460     //    ---------
00461     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
00462     if (diagnostic > 4) fprintf (midiReportPtr, "Invoking      routine   '%s' \n", routine);
00463     
00464     //    Reset status
00465     *error = 0;
00466 
00467     //    Get integration time
00468     tempStr = qfits_query_hdr (fileName, "HIERARCH ESO DET DIT");
00469     if (tempStr != NULL)
00470         sscanf(tempStr, "%f", &subIntegTime);
00471     else
00472     {
00473         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot read Integration time");
00474         *error = 1;
00475         return;
00476     }
00477     tempStr = qfits_query_hdr (fileName, "HIERARCH ESO DET NDIT");
00478     if (tempStr != NULL)
00479         sscanf(tempStr, "%f", &numOfSubInteg);
00480     else
00481     {
00482         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot read Number of Integrations");
00483         *error = 1;
00484         return;
00485     }
00486     linearity->integTime[fileNumber] = numOfSubInteg * subIntegTime;
00487 
00488     return; 
00489 }
00490 /*****************************************************************************/
00491 
00492 
00493 
00494 /******************************************************************************
00495 *               European Southern Observatory
00496 *          VLTI MIDI Maintenance Templates Software
00497 *
00498 * Module name:  assessLinearity
00499 * Input/Output: See function arguments to avoid duplication
00500 * Description:  The dependence of the count rate on the integration time and therewith
00501 *                the number of detected photons is over wide range a linear function.
00502 *                It is known, that the function above a count rate of 50000 up to
00503 *                saturation (65536 counts) differs from linarity.
00504 *                Fit a second or third order polynomial to the count levels as a function 
00505 *                of the actual exposure time. That is y = A0 + A1 * t + A2 * t^2 + A3 * t^3
00506 *                The values of the coeficients are the required relevant QC parameters.
00507 *
00508 *                1. Now we have the following 10 images (im)
00509 *                    linearity->aveImage[im][pix]    im = 0 to 9, pix = 0 to subWinSize
00510 *
00511 *                2. We know which file has saturation from
00512 *                    linearity->saturated[im]        im = 0 to 9
00513 *
00514 *                3. We have Integration Time
00515 *                    linearity->integTime[im]        im = 0 to 9
00516 *
00517 *                4. Mean flux for each pixel (pix) of each image (im) is of course
00518 *                    given directly from (1) above. That is
00519 *                    linearity->aveImage[im][pix]    im = 0 to 9, pix = 0 to subWinSize
00520 *
00521 *                5. We can first create a 3D plot of raw linearity for each pixel. The
00522 *                    releveant axes are:
00523 *                    x = Integration Time (given from 3 above)
00524 *                    y = Pixel position                 pix = 0 to subWinSize
00525 *                    z = Mean Flux
00526 *
00527 *                6. For each pixel in 5 above we can compute the linearity coefficients:
00528 *                    A0[pix], A1[pix], A2[pix], A3[pix]
00529 *
00530 *                7. Finally we find the averages of the above coefficients over a desired
00531 *                    region of the image.
00532 *
00533 * History:      
00534 * 23-Jun-04     (csabet) Created
00535 * 09-May-06     (csabet) Modified to characterise each pixel
00536 ******************************************************************************/
00537 void assessLinearity (
00538     ImageFormat        *format,        // In: Pointer to the image format
00539     char            *firstFitsFile,    // In: Name of first FITS file
00540     DetLinearity    *linearity,        // Ou: Pointer to the detector linearity data structure
00541     int                *error)            // Ou: Error status
00542 {
00543     //  Local Declarations
00544     //    ------------------
00545     const char      routine[] = "assessLinearity";
00546     cpl_polynomial  *coefficients;
00547     cpl_vector        *xPosition, *values;
00548     int                j, f, x, y, p, xLength, yLength, xCoord, dxCoord, yCoord, dyCoord,
00549                     polyDeg = 3, power, numOfUnsatImages, imageSize, subImageSize;
00550     double            *integTime, *pixel, *cA0, *cA1, *cA2, *cA3, *linFit;
00551     char            *fileName, *title;
00552     float            *buffer;
00553     
00554     //    Statistics for pixel regression test
00555     float            sigData = 0.0, coeff1, coeff2, siga, sigb, chi2, q;
00556     int                sigDataAvailable = 0;            
00557     
00558     //  Algorithm
00559     //    ---------
00560     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
00561     if (diagnostic > 4) fprintf (midiReportPtr, "Invoking      routine   '%s' \n", routine);
00562 
00563     //    Reset status
00564     *error = 0;
00565 
00566     //    Count number of unsaturated images
00567     numOfUnsatImages = 0;
00568     for (j = 0; j < linearity->size; j++)
00569     {
00570         if (!(linearity->saturated[j])) numOfUnsatImages++;
00571     }
00572 
00573     //    Compute linearity coefficients for each pixel in a well illuminated central area
00574     //    --------------------------------------------------------------------------------
00575     xLength = DET_LIN_WIN_PU * format->iXWidth;
00576     if (xLength < DET_LIN_WIN_MIN) xLength = format->iXWidth;
00577     xCoord = (format->iXWidth - xLength) / 2;
00578     dxCoord = format->iXWidth - xCoord;
00579     xLength = dxCoord - xCoord;    // Avoing round-off error
00580 
00581     yLength = DET_LIN_WIN_PU * format->iYWidth;
00582     if (yLength < DET_LIN_WIN_MIN) yLength = format->iYWidth;
00583     yCoord = (format->iYWidth - yLength) / 2;
00584     dyCoord = format->iYWidth - yCoord;
00585     yLength = dyCoord - yCoord;    // Avoing round-off error
00586 
00587     imageSize = format->iXWidth * format->iYWidth;
00588 
00589     //    Load values of the window for QC log
00590     linearity->winx = xCoord;
00591     linearity->windx = dxCoord;
00592     linearity->winy = yCoord;
00593     linearity->windy = dyCoord;
00594     if (diagnostic)
00595     {
00596        cpl_msg_info(cpl_func,"\nSelected window size \n");
00597        cpl_msg_info(cpl_func,"-------------------- \n");
00598        cpl_msg_info(cpl_func,"xCoord  = %3d \n", linearity->winx);
00599        cpl_msg_info(cpl_func,"dxCoord = %3d \n", linearity->windx);
00600        cpl_msg_info(cpl_func,"yCoord  = %3d \n", linearity->winy);
00601        cpl_msg_info(cpl_func,"dyCoord = %3d \n", linearity->windy);
00602     }
00603     fprintf (midiReportPtr, "\nSelected window size QCLOG \n");
00604     fprintf (midiReportPtr, "-------------------- QCLOG \n");
00605     fprintf (midiReportPtr, "xCoord  = %3d QCLOG \n", linearity->winx);
00606     fprintf (midiReportPtr, "dxCoord = %3d QCLOG \n", linearity->windx);
00607     fprintf (midiReportPtr, "yCoord  = %3d QCLOG \n", linearity->winy);
00608     fprintf (midiReportPtr, "dyCoord = %3d QCLOG \n", linearity->windy);
00609     
00610     //    Allocate memory
00611     fileName = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00612     title = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00613     buffer = (float *) calloc (imageSize, sizeof (float));
00614     cA0 = (double *) calloc (imageSize, sizeof (double));
00615     cA1 = (double *) calloc (imageSize, sizeof (double));
00616     cA2 = (double *) calloc (imageSize, sizeof (double));
00617     cA3 = (double *) calloc (imageSize, sizeof (double));
00618     linFit = (double *) calloc (numOfUnsatImages, sizeof (double));
00619     
00620     //    Create a sub-image from each unsaturated image
00621     for (j = 0; j < numOfUnsatImages; j++)
00622     {
00623         for (y = 0; y < format->iYWidth; y++)
00624         {
00625             f = y * format->iXWidth;
00626             for (x = 0; x < format->iXWidth; x++)
00627             {
00628                 if (!((x >= xCoord) && (x < dxCoord) &&    (y >= yCoord) && (y < dyCoord)))
00629                 {
00630                     p = f + x;
00631                     linearity->aveImage[j][p] = 0.0;
00632                 }
00633             }
00634         }
00635         if (plotFile && diagnostic)
00636         {
00637             sprintf (fileName, "3dCentralImage%d", j+1);
00638             sprintf (title, "Averaged central image, file %d", j+1);
00639             midiCreatePlotFile3D (fileName, title, "X", "Y", "Flux", 0, linearity->aveImage[j], 
00640                 format->iXWidth, format->iYWidth, "lines", "3");
00641         }
00642     }
00643 
00644     //    Allocate memory
00645     pixel = (double *) calloc (numOfUnsatImages, sizeof (double));
00646     integTime = (double *) calloc (numOfUnsatImages, sizeof (double));
00647     
00648     //    For all unsaturated images Load integration time into a buffer
00649     for (j = 0; j < numOfUnsatImages; j++)
00650             integTime[j] = (double) (linearity->integTime[j]);
00651 
00652     for (y = 0; y < format->iYWidth; y++)
00653     {
00654         f = y * format->iXWidth;
00655         for (x = 0; x < format->iXWidth; x++)
00656         {
00657             //    For all unsaturated images Load pixel flux into a buffer
00658             if ((x >= xCoord) && (x < dxCoord) &&
00659                 (y >= yCoord) && (y < dyCoord))
00660             {
00661                 p = f + x;
00662                 for (j = 0; j < numOfUnsatImages; j++)
00663                     pixel[j] = (double) (linearity->aveImage[j][p]);
00664                 
00665                 //    Plot raw linearity and delete plot file
00666                 if (plotFile && diagnostic > 2)
00667                 {
00668                     sprintf (title, "Flux versus integration time. Pixel %d, %d", x, y);
00669                     midiCreatePlotFileDouble2D2P ("temp1", title, "Integration time", "Pixel flux",
00670                         1, integTime, pixel, 0,    numOfUnsatImages, 1, "lines 3");
00671                 }
00672             
00673                 //    Compute coefficients of a 3rd order polynomial
00674                 xPosition = cpl_vector_wrap (numOfUnsatImages, integTime);
00675                 values = cpl_vector_wrap (numOfUnsatImages, pixel);
00676                 coefficients = midi_polynomial_fit_1d_create (xPosition, values, polyDeg, NULL);
00677                 power = 0;
00678                 cA0[p] = cpl_polynomial_get_coeff (coefficients, &power);
00679                 power = 1;
00680                 cA1[p] = cpl_polynomial_get_coeff (coefficients, &power);
00681                 power = 2;
00682                 cA2[p] = cpl_polynomial_get_coeff (coefficients, &power);
00683                 power = 3;
00684                 cA3[p] = cpl_polynomial_get_coeff (coefficients, &power);
00685                 cpl_vector_unwrap (xPosition);
00686                 cpl_vector_unwrap (values);
00687                 cpl_polynomial_delete (coefficients);
00688 
00689                 //    Plot fit linearity and delete plot file
00690                 if (plotFile && diagnostic > 2)
00691                 {
00692                     //    Fill in the result
00693                     for (j = 0; j < numOfUnsatImages; j++)
00694                         linFit[j] = cA0[p] + cA1[p] * j + cA2[p] * (j * j) + cA3[p] * (j * j * j);
00695 
00696                     sprintf (title, "Flux versus integration time (polynomial fit). Pixel %d, %d", x, y);
00697                     midiCreatePlotFileDouble2D2P ("temp1", title, "Integration time", "Pixel flux",
00698                         1, integTime, linFit, 0, numOfUnsatImages, 1, "lines 1");
00699                 }
00700             
00701                 //    Now do a regression test (degree of deviation from linearity)
00702                 midiGetLinearFit (integTime, pixel, numOfUnsatImages, sigData, sigDataAvailable, 
00703                     &coeff1, &coeff2, &siga, &sigb, &chi2, &q, error);
00704                 
00705                 //    Load a measure of linear deviation. Here we use the
00706                 //    combined standard deviation of the linear coefficients
00707                 linearity->deviation[p] = sqrt ((siga+sigb)/2.0);
00708                 
00709                 if (diagnostic > 2)
00710                 {
00711                    cpl_msg_info(cpl_func,"\nPixel (%d, %d) statistics \n", x, y);
00712                    cpl_msg_info(cpl_func,"------------------------- \n");
00713                    cpl_msg_info(cpl_func,"coeff1 =   %f \n", coeff1);
00714                    cpl_msg_info(cpl_func,"coeff2 =   %f \n", coeff2);
00715                    cpl_msg_info(cpl_func,"siga   =   %f \n", siga);
00716                    cpl_msg_info(cpl_func,"sigb   =   %f \n", sigb);
00717                    cpl_msg_info(cpl_func,"chi2   =   %f \n", chi2);
00718                    cpl_msg_info(cpl_func,"q      =   %f \n", q);
00719                     fprintf (midiReportPtr, "\nPixel (%d, %d) statistics \n", x, y);
00720                     fprintf (midiReportPtr, "------------------------- \n");
00721                     fprintf (midiReportPtr, "coeff1 =   %f \n", coeff1);
00722                     fprintf (midiReportPtr, "coeff2 =   %f \n", coeff2);
00723                     fprintf (midiReportPtr, "siga   =   %f \n", siga);
00724                     fprintf (midiReportPtr, "sigb   =   %f \n", sigb);
00725                     fprintf (midiReportPtr, "chi2   =   %f \n", chi2);
00726                     fprintf (midiReportPtr, "q      =   %f \n", q);
00727                 }
00728             }
00729         }
00730     }
00731 
00732     //    Create plots and FITS images of coefficients
00733     if (plotFile && diagnostic)
00734     {
00735         midiCreatePlotFileDouble3D ("3dCoefficientMapA0", "Map of A0 coefficients", "X", "Y", "Coefficient value", 
00736             0, cA0, format->iXWidth, format->iYWidth, "points", "1");
00737         midiCreatePlotFileDouble3D ("3dCoefficientMapA1", "Map of A1 coefficients", "X", "Y", "Coefficient value", 
00738             0, cA1, format->iXWidth, format->iYWidth, "points", "1");
00739         midiCreatePlotFileDouble3D ("3dCoefficientMapA2", "Map of A2 coefficients", "X", "Y", "Coefficient value", 
00740             0, cA2, format->iXWidth, format->iYWidth, "points", "1");
00741         midiCreatePlotFileDouble3D ("3dCoefficientMapA3", "Map of A3 coefficients", "X", "Y", "Coefficient value", 
00742             0, cA3, format->iXWidth, format->iYWidth, "points", "1");
00743     }
00744     for (p = 0; p < imageSize; p++)    buffer[p] = (float) (cA0[p]);
00745     removeDc (imageSize, buffer, buffer);
00746     createFitsImage ("Coefficients A0", "CoefficientMapA0", firstFitsFile, format->iXWidth, format->iYWidth, buffer);
00747     for (p = 0; p < imageSize; p++)    buffer[p] = (float) (cA1[p]);
00748     removeDc (imageSize, buffer, buffer);
00749     createFitsImage ("Coefficients A1", "CoefficientMapA1", firstFitsFile, format->iXWidth, format->iYWidth, buffer);
00750     for (p = 0; p < imageSize; p++)    buffer[p] = (float) (cA2[p]);
00751     removeDc (imageSize, buffer, buffer);
00752     createFitsImage ("Coefficients A2", "CoefficientMapA2", firstFitsFile, format->iXWidth, format->iYWidth, buffer);
00753     for (p = 0; p < imageSize; p++)    buffer[p] = (float) (cA3[p]);
00754     removeDc (imageSize, buffer, buffer);
00755     createFitsImage ("Coefficients A3", "CoefficientMapA3", firstFitsFile, format->iXWidth, format->iYWidth, buffer);
00756 
00757     //    Create plot and FITS image of the linear deviation
00758     if (plotFile) midiCreatePlotFile3D ("3dLinearitySigmaMap", "Map of Linearity Standard Deviation", "X", "Y", "Sigma", 
00759         0, linearity->deviation, format->iXWidth, format->iYWidth, "lines", "1");
00760 
00761     //    Suitably prepare image for FITS
00762     removeDc (imageSize, linearity->deviation, buffer);
00763     createFitsImage ("Map of Linearity Standard Deviation", "LinearitySigmaMap", firstFitsFile, format->iXWidth, 
00764         format->iYWidth, buffer);
00765 
00766     //    Compute mean value of the coefficients and the overall linearity deviation
00767     linearity->meanCoeffA0 = 0.0;
00768     linearity->meanCoeffA1 = 0.0;
00769     linearity->meanCoeffA2 = 0.0;
00770     linearity->meanCoeffA3 = 0.0;
00771     subImageSize = 0;
00772     for (y = 0; y < format->iYWidth; y++)
00773     {
00774         f = y * format->iXWidth;
00775         for (x = 0; x < format->iXWidth; x++)
00776         {
00777             if ((x >= xCoord) && (x < dxCoord) && (y >= yCoord) && (y < dyCoord))
00778             {
00779                 p = f + x;
00780                 linearity->meanCoeffA0 += cA0[p];
00781                 linearity->meanCoeffA1 += cA1[p];
00782                 linearity->meanCoeffA2 += cA2[p];
00783                 linearity->meanCoeffA3 += cA3[p];
00784                 linearity->meanSigma += linearity->deviation[p];
00785                 subImageSize++;
00786             }
00787         }
00788     }
00789     if (subImageSize)
00790     {
00791         linearity->meanCoeffA0 /= subImageSize;
00792         linearity->meanCoeffA1 /= subImageSize;
00793         linearity->meanCoeffA2 /= subImageSize;
00794         linearity->meanCoeffA3 /= subImageSize;
00795         linearity->meanSigma /= subImageSize;
00796     }
00797     
00798    cpl_msg_info(cpl_func,"\nMean coefficients for polynomial fit: y = a0 + a1 * t + a2 * t^2 + a3 * t^3 \n");
00799    cpl_msg_info(cpl_func,"--------------------------------------------------------------------------- \n");
00800    cpl_msg_info(cpl_func,"a0, a1, a2, a3 = %f, %f, %f, %f \n", 
00801         linearity->meanCoeffA0, linearity->meanCoeffA1, linearity->meanCoeffA2, linearity->meanCoeffA3);
00802     fprintf (midiReportPtr, "\nMean coefficients for polynomial fit: y = a0 + a1 * t + a2 * t^2 + a3 * t^3 (QCLOG) \n");
00803     fprintf (midiReportPtr, "--------------------------------------------------------------------------- (QCLOG) \n");
00804     fprintf (midiReportPtr, "a0, a1, a2, a3 = %f, %f, %f, %f (QCLOG) \n", 
00805         linearity->meanCoeffA0, linearity->meanCoeffA1, linearity->meanCoeffA2, linearity->meanCoeffA3);
00806 
00807    cpl_msg_info(cpl_func,"\nMean linearity standard deviation = %f \n\n", linearity->meanSigma);
00808     fprintf (midiReportPtr, "\nMean linearity standard deviation = %f (QCLOG) \n\n", linearity->meanSigma);
00809 
00810     //    Plot linear fit of the mean
00811     for (j = 0; j < numOfUnsatImages; j++)
00812     {
00813         linFit[j] = linearity->meanCoeffA0 + linearity->meanCoeffA1 * j + linearity->meanCoeffA2 * (j * j) + 
00814             linearity->meanCoeffA3 * (j * j * j);
00815         linearity->mean[j] = (float) linFit[j];
00816         
00817     }
00818     midiCreatePlotFileDouble2D2P ("MeanFluxVersusTimePolyFit", "Meam flux versus time (polynomial fit)", 
00819         "Integration time", "Mean flux", 0, integTime, linFit, 0, numOfUnsatImages, 1, "lines 1");
00820     
00821     //    Release memory
00822     free (linFit);
00823     free (cA0);
00824     free (cA1);
00825     free (cA2);
00826     free (cA3);
00827     free (fileName);
00828     free (title);
00829     free (pixel);
00830     free (integTime);
00831     free (buffer);
00832      
00833     return;
00834 
00835 }
00836 /*****************************************************************************/
00837 
00838 
00839 
00840 /******************************************************************************
00841 *               European Southern Observatory
00842 *          VLTI MIDI Maintenance Templates Software
00843 *
00844 * Module name:  checkSaturationDetLin
00845 * Input/Output: See function arguments to avoid duplication
00846 * Description:  Checks if any pixel is saturated. If so this exposure
00847 *                will not be included in the later processing
00848 *
00849 * History:      
00850 * 05-May-06     (csabet) Created
00851 ******************************************************************************/
00852 void checkSaturationDetLin (
00853     short int    *inData,        // In: Pointer to the input data
00854     float        scalingOffset,    // In: Scaling Offset
00855     ImageFormat    *format,        // In: Pointer to the image format
00856     float        *image,            // Ou: Output image
00857     int            *saturated)        // Ou: Saturation indicator
00858 
00859 {
00860     //  Local Declarations
00861     //    ------------------
00862     const char  routine[] = "checkSaturationDetLin";
00863     int            i, count, pixel, frame, imageSize;
00864     
00865     //  Algorithm
00866     //    ---------
00867     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
00868     if (diagnostic > 4) fprintf (midiReportPtr, "Invoking      routine   '%s' \n", routine);
00869     
00870     //    Reset status
00871     imageSize = format->iXWidth * format->iYWidth;
00872     *saturated = 0;
00873     
00874     for (pixel = 0; pixel < imageSize; pixel++)
00875     {
00876         //    Along the time axis (frame)
00877         image[pixel] = 0;
00878         count = 0;
00879         for (frame = 0; frame < format->numOfFrames; frame++)
00880         {
00881             //    Load each pixel data along the time axis
00882             i = frame * imageSize + pixel;
00883             if (isnan (inData[i]))
00884             {
00885                 sprintf (midiMessage, "Found bad pixel %d on frame %d", frame, pixel);
00886                 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
00887             }
00888             else if (((float) (inData[i] + scalingOffset)) >= PIXEL_SATURATION)
00889             {
00890                 if (diagnostic > 2)
00891                 {
00892                     sprintf (midiMessage, "Found saturated pixel %d on frame %d", frame, pixel);
00893                     midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
00894                 }
00895                 *saturated = 1;
00896             }
00897             else
00898             {
00899                 count++;
00900                 image[pixel] += (float) (inData[i] + scalingOffset);
00901             }
00902         }
00903 
00904         //    Compute average image
00905         if (count) image[pixel] /= count;
00906     }
00907 
00908     if (*saturated)
00909     {
00910         sprintf (midiMessage, "Found saturated pixels in this image");
00911         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
00912     }
00913 
00914     return; 
00915 }
00916 /*****************************************************************************/

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