calibration.c

00001 /******************************************************************************
00002 *******************************************************************************
00003 *               European Southern Observatory
00004 *             VLTI MIDI Data Reduction Software
00005 *
00006 * Module name:  calibration.c
00007 * Description:  Contains routines for all calibration preparation routines
00008 *
00009 * History:
00010 * 21-Jul-03     (csabet) Created
00011 *******************************************************************************
00012 ******************************************************************************/
00013 
00014 /******************************************************************************
00015 *   Compiler directives
00016 ******************************************************************************/
00017 
00018 /******************************************************************************
00019 *   Include files
00020 ******************************************************************************/
00021 #include <stdlib.h>
00022 #include <math.h>
00023 #include <sys/types.h>
00024 #include <sys/stat.h>
00025 #include <unistd.h>
00026 #include <stdio.h>
00027 #include <cpl.h>
00028 #include <string.h>
00029 #include "midiGlobal.h"
00030 #include "midiLib.h"
00031 #include "memoryHandling.h"
00032 #include "calibration.h"
00033 #include "diagnostics.h"
00034 #include "errorHandling.h"
00035 #include "statistics.h"
00036 #include "midiFitsUtility.h"
00037 #include "qfits_table.h"
00038 
00039 /**********************************************************
00040 *   Global Variables
00041 **********************************************************/
00042 
00043 /*============================ C O D E    A R E A ===========================*/
00044 
00045 
00046 
00047 /******************************************************************************
00048 *               European Southern Observatory
00049 *            VLTI MIDI Data Reduction Software
00050 *
00051 * Module name:  getCalibratedChWave
00052 * Input/Output: See function arguments to avoid duplication
00053 * Description:    Retrieves the table of channel frequencies, either from the database
00054 *                or from the current directory. Format for the database is simply
00055 *                a table of pairs of floats. The one in the current directory has
00056 *                the following format:
00057 *
00058 *                Record 1    Grism ID
00059 *                Record 2    Beam Combiner
00060 *                Record 3    Number of records
00061 *                Record 4    Value1 value2
00062 *                .
00063 *                .
00064 *                Record n    value1 value2
00065 *
00066 * History:
00067 * 09-Sep-05 (csabet) Created
00068 ******************************************************************************/
00069 void getCalibratedChWave (
00070     MidiFiles    *fileNames,    // In: Pointer to MIDI file structure
00071     ImageFormat    *format,    // In: Image format
00072     float       **waveCal,    // Ou: Wavelength calibration
00073     int            *error)        // Ou: Error status
00074 
00075 {
00076 
00077     //    Local Declarations
00078     //    ------------------
00079     const char    routine[] = "getCalibratedChWave";
00080     char        *fileString, *givenGrismId, *givenBeamCombiner;
00081     FILE        *filePtr=NULL;
00082     int            i, numOfRecords;
00083 
00084     //    Algorithm
00085     //    ---------
00086     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
00087     if (diagnostic > 4) fprintf(midiReportPtr, "Invoking      routine   '%s' \n", routine);
00088 
00089     //    Reset status
00090     *error = 1;
00091     
00092     //    Check if correct wavelength calibration file exists in the calibration database
00093     //    If calibration is not in the database then get it from the current directory
00094     fileString = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00095     sprintf (fileString , "%s_%s_%s.dat", fileNames->waveCalibName, format->grismId, format->beamCombiner);
00096     if ((filePtr = fopen (fileString, "r")) != NULL)    // It is in the database
00097     {
00098         //    Read from file and load into array
00099         if (diagnostic)cpl_msg_info(cpl_func,"Trying to extract Wavelength Calibration from %s \n", fileString);
00100         fprintf (midiReportPtr, "Trying to extract Wavelength Calibration from %s \n", fileString);
00101         numOfRecords = 0;
00102         
00103         if (strcmp (format->beamCombiner, "SCI_PHOT") == 0)
00104             while (fscanf (filePtr, "%f %f %f %f\n", 
00105                 &(waveCal[0][numOfRecords]), &(waveCal[1][numOfRecords]),
00106                 &(waveCal[2][numOfRecords]), &(waveCal[3][numOfRecords])) != EOF) numOfRecords++;
00107         else
00108             while (fscanf (filePtr, "%f %f\n", 
00109                 &(waveCal[0][numOfRecords]), &(waveCal[1][numOfRecords])) != EOF) numOfRecords++;
00110                 
00111         fclose (filePtr);
00112         if (numOfRecords == format->iXWidth)
00113         {
00114             *error = 0;
00115             if (diagnostic)cpl_msg_info(cpl_func,"Found a wavelength calibration file %s with %d rows of floats \n", 
00116                 fileString, numOfRecords);
00117             fprintf (midiReportPtr, "Found a wavelength calibration file %s with %d rows of floats \n", 
00118                 fileString, numOfRecords);
00119         }
00120         else
00121         {
00122             *error = 1;
00123             sprintf (midiMessage, "Inconsistent calibration data in %s. Data ignored", fileString);
00124             midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
00125         }
00126     }
00127     else 
00128     {
00129         *error = 1;
00130         sprintf (midiMessage, "Cannot find calibration data file ... %s", fileString);
00131         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
00132     }
00133     free (fileString);
00134 
00135     if (*error)
00136     {
00137         //    Allocate memory
00138         *error = 0;
00139         givenGrismId = (char *) calloc (MIN_STRING_LENGTH, sizeof (char));
00140         givenBeamCombiner = (char *) calloc (MIN_STRING_LENGTH, sizeof (char));
00141 
00142         //    Check if wavelength calibration is available. Try to open the file for reading
00143         if (diagnostic)cpl_msg_info(cpl_func,"Trying to extract Wavelength Calibration from %s \n", fileNames->wclNameRead);
00144         fprintf (midiReportPtr, "Trying to extract Wavelength Calibration from %s \n", fileNames->wclNameRead);
00145         if ((filePtr = fopen (fileNames->wclNameRead, "r")) == NULL)
00146         {
00147             *error = 1;
00148             midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, 
00149                 "Cannot find the Wavelength Calibration file\n             Data will be computed from the interferometry file");
00150         }
00151         else *error = 0;    // File exists
00152     
00153         //    Read Grism ID
00154         if (!(*error))
00155         {
00156             if (fscanf (filePtr, "%s \n", givenGrismId) == EOF)
00157             {
00158                 *error = 1;
00159                 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, 
00160                     "Cannot read Grism ID from\n             Data will be computed from the interferometry file");
00161                 fclose (filePtr);
00162                 if (strcmp (format->obsCatg, "SCIENCE") == 0) remove (fileNames->wclNameRead);
00163             }
00164             else
00165             {
00166                 //    Check if the given Grism ID is the same as that of the current batch
00167                 if (strcmp (format->grismId, givenGrismId) != 0)
00168                 {
00169                     *error = 1;
00170                     midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, 
00171                         "Inconsistent Grism ID\n             Data will be computed from the interferometry file");
00172                     fclose (filePtr);
00173                     if (strcmp (format->obsCatg, "SCIENCE") == 0) remove (fileNames->wclNameRead);
00174                 }
00175             }
00176            cpl_msg_info(cpl_func,"Given grism ID          = %s. Expected %s \n", givenGrismId, format->grismId);
00177             fprintf (midiReportPtr, "Given grism ID          = %s. Expected %s \n", givenGrismId, format->grismId);
00178         }
00179 
00180         //    Read Beam Combiner
00181         if (!(*error))
00182         {
00183             if (fscanf (filePtr, "%s \n", givenBeamCombiner) == EOF)
00184             {
00185                 *error = 1;
00186                 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, 
00187                     "Cannot read Beam Combiner from\n             Data will be computed from the interferometry file");
00188                 fclose (filePtr);
00189                 if (strcmp (format->obsCatg, "SCIENCE") == 0) remove (fileNames->wclNameRead);
00190             }
00191             else
00192             {
00193                 //    Check if the given Beam Combiner is the same as that of the current batch
00194                 if (strcmp (format->beamCombiner, givenBeamCombiner) != 0)
00195                 {
00196                     *error = 1;
00197                     midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, 
00198                         "Inconsistent Beam Combiner\n             Data will be computed from the interferometry file");
00199                     fclose (filePtr);
00200                     if (strcmp (format->obsCatg, "SCIENCE") == 0) remove (fileNames->wclNameRead);
00201                 }
00202             }
00203            cpl_msg_info(cpl_func,"Given Beam Combiner     = %s. Expected %s \n", givenBeamCombiner, format->beamCombiner);
00204             fprintf (midiReportPtr, "Given Beam Combiner     = %s. Expected %s \n", givenBeamCombiner, format->beamCombiner);
00205         }
00206     
00207         //    If so far so good then get the number of records 
00208         if (!(*error))
00209         {
00210             if (fscanf (filePtr, "%d\n", &numOfRecords) == EOF)
00211             {
00212                 *error = 1;
00213                 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, 
00214                     "Cannot read Number of Records\n             Data will be computed from the interferometry file");
00215                 if (filePtr) fclose (filePtr);
00216                 if (strcmp (format->obsCatg, "SCIENCE") == 0) remove (fileNames->wclNameRead);
00217             }
00218             else 
00219             {
00220                 //    Check if number of records is consistent
00221                 if (numOfRecords != format->iXWidth)
00222                 {
00223                     *error = 1;
00224                     sprintf (midiMessage, "Inconsistent Number of Records from %s. Expected %d \n", 
00225                         fileNames->wclNameRead, format->iXWidth); 
00226                     midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
00227                     if (filePtr) fclose (filePtr);
00228                     if (strcmp (format->obsCatg, "SCIENCE") == 0) remove (fileNames->wclNameRead);
00229                 }
00230             }
00231            cpl_msg_info(cpl_func,"Given Number of Records = %d. Expected %d \n", numOfRecords, format->iXWidth);
00232             fprintf (midiReportPtr, "Given Number of Records = %d. Expected %d \n", numOfRecords, format->iXWidth);
00233         }
00234         
00235         //    If all is well then try to load the data into the array
00236         if (!(*error))
00237         {
00238             for (i = 0; i < format->iXWidth; i++)
00239             {
00240                 if (strcmp (format->beamCombiner, "SCI_PHOT") == 0)
00241                 {
00242                     if (fscanf (filePtr, "%f %f %f %f \n", &(waveCal[0][i]), &(waveCal[1][i]), 
00243                         &(waveCal[2][i]), &(waveCal[3][i])) == EOF)
00244                     {
00245                         *error = 1;
00246                         sprintf (midiMessage, "Read %d rows of wavelength values from %s. Expected %d \n", 
00247                             i, fileNames->wclNameRead, format->iXWidth);
00248                         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
00249                         break;
00250                     }
00251                     if (diagnostic)cpl_msg_info(cpl_func,"Channel %3d    %7.4f   %7.4f    %7.4f    %7.4f \n", 
00252                         i, waveCal[0][i], waveCal[1][i], waveCal[2][i], waveCal[3][i]);
00253                     fprintf (midiReportPtr, "Channel %3d    %7.4f   %7.4f    %7.4f    %7.4f \n", 
00254                         i, waveCal[0][i], waveCal[1][i], waveCal[2][i], waveCal[3][i]);
00255                 }
00256                 else
00257                 {
00258                     if (fscanf (filePtr, "%f %f \n", &(waveCal[0][i]), &(waveCal[1][i])) == EOF)
00259                     {
00260                         *error = 1;
00261                         sprintf (midiMessage, "Read %d rows of wavelength values from %s. Expected %d \n", 
00262                             i, fileNames->wclNameRead, format->iXWidth);
00263                         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
00264                         break;
00265                     }
00266                     if (diagnostic)cpl_msg_info(cpl_func,"Channel %3d    %7.4f   %7.4f \n", i,  waveCal[0][i], waveCal[1][i]);
00267                     fprintf (midiReportPtr, "Channel %3d    %7.4f   %7.4f \n", i,  waveCal[0][i], waveCal[1][i]);
00268                 }
00269             }
00270            cpl_msg_info(cpl_func,"\nRead %d rows of wavelength values from %s \n", format->iXWidth, fileNames->wclNameRead);
00271             fprintf (midiReportPtr, "\nRead %d rows of wavelength values from %s \n", format->iXWidth, fileNames->wclNameRead);
00272             fclose (filePtr);
00273             if (strcmp (format->obsCatg, "SCIENCE") == 0) remove (fileNames->wclNameRead);
00274         }
00275         free (givenGrismId);
00276         free (givenBeamCombiner);        
00277     }
00278     
00279     return;
00280 }
00281 /*****************************************************************************/
00282 
00283 
00284 /******************************************************************************
00285 *               European Southern Observatory
00286 *            VLTI MIDI Data Reduction Software
00287 *
00288 * Module name:  calibrateWaveUsingPolynom
00289 * Input/Output: See function arguments to avoid duplication
00290 * Description:    Wavelength calibration. Checks if calibration file exists. If not
00291 *                It creates a file using hardcoded polynomial method
00292 *
00293 * History:
00294 * 03-Feb-05 (csabet) Created
00295 ******************************************************************************/
00296 void calibrateWaveUsingPolynom (
00297     MidiFiles        *fileNames,            // In: Pointer to MIDI file structure
00298     ImageFormat        *format)            // In: Image format
00299 
00300 {
00301 
00302     //    Local Declarations
00303     //    ------------------
00304     const char    routine[] = "calibrateWaveUsingPolynom";
00305     int            error, numOfRecords;
00306     FILE        *waveCalPtr=NULL;
00307     char        *fileString;
00308     float        record1, record2, record3, record4;
00309 
00310     //    Algorithm
00311     //    ---------
00312     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
00313     if (diagnostic > 4) fprintf(midiReportPtr, "Invoking      routine   '%s' \n", routine);
00314 
00315     //    Reset status
00316     error = 0;
00317 
00318    cpl_msg_info(cpl_func,"\nWavelength calibration for batch %d \n", batchNumber);
00319    cpl_msg_info(cpl_func,"-------------------------------- \n");
00320     fprintf (midiReportPtr, "\nWavelength calibration for batch %d \n", batchNumber);
00321     fprintf (midiReportPtr, "-------------------------------- \n");
00322 
00323     //    Check if correct wavelength calibration file exists in the calibration database
00324     fileString = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00325     sprintf (fileString , "%s_%s_%s.dat", fileNames->waveCalibName, format->grismId, format->beamCombiner);
00326     if ((waveCalPtr = fopen (fileString, "r")) != NULL)
00327     {
00328         if (diagnostic)cpl_msg_info(cpl_func,"\nTrying to extract Wavelength Calibration from %s \n", fileString);
00329         fprintf (midiReportPtr, "\nTrying to extract Wavelength Calibration from %s \n", fileString);
00330         numOfRecords = 0;
00331         if (strcmp (format->beamCombiner, "SCI_PHOT") == 0)
00332             while (fscanf (waveCalPtr, "%f %f %f %f\n", &record1, &record2, &record3, &record4) != EOF) numOfRecords++;
00333         else
00334             while (fscanf (waveCalPtr, "%f %f\n", &record1, &record2) != EOF) numOfRecords++;
00335         fclose (waveCalPtr);
00336         if (numOfRecords == format->iXWidth)
00337         {
00338             if (diagnostic)cpl_msg_info(cpl_func,"\nFound a wavelength calibration file %s with %d pairs of floats \n", 
00339                 fileString, numOfRecords);
00340             fprintf (midiReportPtr, "\nFound a wavelength calibration file %s with %d pairs of floats \n", 
00341                 fileString, numOfRecords);
00342         }
00343         else 
00344         {
00345             error = 1;
00346             sprintf (midiMessage, "Inconsistent calibration data in %s. Data ignored", fileString);
00347             midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
00348         }
00349     }
00350     else 
00351     {
00352         error = 1;
00353         sprintf (midiMessage, "Cannot find calibration data file ... %s", fileString);
00354         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
00355     }
00356     free (fileString);
00357 
00358     if (error)
00359     {
00360         getWaveCalPoly (fileNames, format, &error);
00361         if (error) midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot create wavelength calibration");
00362     }
00363 
00364     return;
00365 }
00366 /*****************************************************************************/
00367 
00368 
00369  
00370 /******************************************************************************
00371 *               European Southern Observatory
00372 *            VLTI MIDI Data Reduction Software
00373 *
00374 * Module name:  getWaveCalPoly
00375 * Input/Output: See function arguments to avoid duplication
00376 * Description:    Supplies the a priori waveCal[][] from a CALIB sources. 
00377 *                The contents are filled in by a calibration polynomial.
00378 *                The format of the output file is as shown below:
00379 *                Record 1    Grism ID
00380 *                Record 2    Beam Combiner
00381 *                Record 3    Number of records
00382 *                Record 4    Value1 value2
00383 *                .
00384 *                .
00385 *                Record n    value1 value2
00386 *
00387 * History:
00388 * 17-Jan-05     (jmeisner) Created
00389 * 26-Jan-05     (csabet) Cleaned up, created database and integrated
00390 ******************************************************************************/
00391 void getWaveCalPoly (
00392     MidiFiles    *fileNames,    // IO: Pointer to midi files structure
00393     ImageFormat    *imageFormat,
00394     int            *error)        // Ou: Error status
00395 {
00396  
00397     /*  Local Declarations
00398     --------------------*/
00399     const char    routine[] = "getWaveCalPoly";
00400     float         A[2], B[2],    C[2], D[2], x, **waveCal=NULL;
00401     int         i, j, regions, useGrism;
00402     FILE        *waveCalPtr;
00403     struct stat    buf;
00404  
00405     /*  Algorithm
00406     -----------*/
00407     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
00408     if (diagnostic > 4) fprintf(midiReportPtr, "Invoking      routine   '%s' \n", routine);
00409  
00410    cpl_msg_info(cpl_func,"\nComputing wavelength calibration using Calibration Polynomial \n");
00411     fprintf (midiReportPtr, "\nComputing wavelength calibration using Calibration Polynomial \n");
00412  
00413     //    Reset status. Check if wavelength calibration file exist. If so delete it
00414     if (stat (fileNames->wclNameWrite, &buf) == 0) remove (fileNames->wclNameWrite);
00415     *error = 0;
00416     regions = 2;
00417     useGrism = 0;
00418     
00419     //    Allocate memory
00420     waveCal = callocWaveCalibration (regions, imageFormat);
00421  
00422     //    Open the wavelength calibration file for writing
00423     if ((waveCalPtr = fopen (fileNames->wclNameWrite, "w")) == NULL)
00424     {
00425         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot open file to store wavelength calibrations");
00426         freeWaveCalibration (regions, waveCal);
00427         *error = 1;
00428         return;
00429     }
00430     
00431     //    Check Grism ID
00432     if (strcmp (imageFormat->grismId, "GRISM") == 0) useGrism = 1;
00433    
00434     //    Now here are some numbers obtained from Jeff, to use for the time being......
00435     if (useGrism)    // for the grism
00436     {
00437         A[0] = 1.9837227e-08;
00438         A[1] = 3.0043738e-08;
00439         B[0] = -7.7775886e-06;
00440         B[1] = -1.2241891e-05;
00441         C[0] = 0.023746001;
00442         C[1] = 0.024323120;
00443         D[0] = 7.6040181;
00444         D[1] = 7.5892995;
00445         for (i = 0; i < imageFormat->iXWidth; i++)
00446         {
00447             for (j = 0; j < regions; j++)
00448             {
00449                 x = (float) i;
00450                 waveCal[j][i] = 299.8F/(A[j]*x*x*x + B[j]*x*x + C[j]*x + D[j]); 
00451             }
00452         }
00453     }
00454  
00455     if (!useGrism)    // for the Prism:
00456     {
00457         A[0] = -6.1780766e-07;
00458         A[1] = -6.8179155e-07;
00459         B[0] = -1.6145018e-06;
00460         B[1] = 2.1291316e-05;
00461         C[0] = -0.037844515;
00462         C[1] = -0.040598183;
00463         D[0] = 14.576070;
00464         D[1] = 14.652558;
00465         for (i = 0; i < imageFormat->iXWidth; i++)
00466         {
00467             for (j = 0; j < regions; j++)
00468             {
00469                 x = (float) i;
00470                 waveCal[j][i] = 299.8F/(A[j]*x*x*x + B[j]*x*x + C[j]*x + D[j]); 
00471             }
00472         }
00473     }
00474  
00475     //    Convert to wavelength
00476     for (j = 0; j < regions; j++)
00477     {
00478         for (i = 0; i < imageFormat->iXWidth; i++) waveCal[j][i] = SPEED_OF_LIGHT / waveCal[j][i];
00479     }    
00480  
00481     //    Report
00482     if (diagnostic)cpl_msg_info(cpl_func,"\nWavelength Calibration \n");
00483     fprintf (midiReportPtr, "\nWavelength Calibration \n");
00484     for (i = 0; i < imageFormat->iXWidth; i++)
00485     {
00486         if (strcmp (imageFormat->beamCombiner, "SCI_PHOT") == 0)
00487         {
00488             if (diagnostic)cpl_msg_info(cpl_func,"%3d   %7.4f   %7.4f   %7.4f   %7.4f \n", i, 
00489                 waveCal[0][i], waveCal[0][i], waveCal[1][i], waveCal[0][i]);
00490             fprintf (midiReportPtr, "%3d   %7.4f   %7.4f   %7.4f   %7.4f \n", i, 
00491                 waveCal[0][i], waveCal[0][i], waveCal[1][i], waveCal[0][i]);
00492         }
00493         else
00494         {
00495             if (diagnostic)cpl_msg_info(cpl_func,"%3d   %7.4f   %7.4f \n", i, waveCal[0][i], waveCal[1][i]);
00496             fprintf (midiReportPtr, "%3d   %7.4f   %7.4f \n", i, waveCal[0][i], waveCal[1][i]);
00497         }
00498     }
00499     if (diagnostic)cpl_msg_info(cpl_func,"\n");
00500     fprintf (midiReportPtr, "\n");
00501  
00502     //    Write into the Wavelength Calibration file
00503     fprintf (waveCalPtr, "%s \n", imageFormat->grismId);        //    Record 1
00504     fprintf (waveCalPtr, "%s \n", imageFormat->beamCombiner);    //    Record 2
00505     fprintf (waveCalPtr, "%d \n", imageFormat->iXWidth);        //    Record 3
00506     if (strcmp (imageFormat->beamCombiner, "SCI_PHOT") == 0)
00507     {
00508         for (i = 0; i < imageFormat->iXWidth; i++)
00509             fprintf (waveCalPtr, "%f   %f   %f   %f \n", waveCal[0][i], waveCal[0][i], 
00510                 waveCal[1][i], waveCal[0][i]);
00511     }
00512     else
00513     {
00514         for (i = 0; i < imageFormat->iXWidth; i++)
00515             fprintf (waveCalPtr, "%f   %f \n", waveCal[0][i], waveCal[1][i]);
00516     }
00517  
00518     fclose (waveCalPtr);
00519     
00520    cpl_msg_info(cpl_func,"Created the wavelength calibration file ... %s \n", fileNames->wclNameWrite);
00521     fprintf (midiReportPtr, "Created the wavelength calibration file ... %s \n", fileNames->wclNameWrite);
00522     
00523     //    Release memory
00524     freeWaveCalibration (regions, waveCal);
00525     
00526     return;
00527 }
00528 /******************************************************************************/
00529  
00530  
00531 /******************************************************************************
00532 *               European Southern Observatory
00533 *            VLTI MIDI Data Reduction Software
00534 *
00535 * Module name:    checkDelayLineJumps
00536 * Input/Output:    See function arguments to avoid duplication
00537 * Description:    Check the Big delay line and the Piezo for illegal DL jumps (within one scan):
00538 *
00539 * History:
00540 * 03-Feb-06        (csabet) Aapted from Jeff Meisner for SCI_PHOT
00541 ******************************************************************************/
00542 void checkDelayLineJumps (
00543     const char            *dataKey,        // In: Whether Interferometry or Photometry etc.
00544     ImageFormat        *format,
00545     CompressedData    *compressed)  
00546 {
00547 
00548     //    Local Declarations
00549     //    ------------------
00550     const char    routine[] = "checkDelayLineJumps";
00551     int            i, x, numSummed = 0;
00552     float        lastDL, diff, avg, rms, threshold, lastPiezo,
00553                 sum=0.0, sumsqr=0.0;
00554 
00555     //    Algorithm
00556     //    ---------
00557     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
00558     if (diagnostic > 4) fprintf (midiReportPtr, "Invoking      routine   '%s' \n", routine);
00559 
00560    cpl_msg_info(cpl_func,"\nChecking Delay Line Jumps within scans for %s \n", dataKey);
00561    cpl_msg_info(cpl_func,"-------------------------------------------- \n");
00562     fprintf (midiReportPtr, "\nChecking Delay Line Jumps within scans for %s \n", dataKey);
00563     fprintf (midiReportPtr, "-------------------------------------------- \n");
00564 
00565     for (i = 0; i < format->numOfFrames; i++)
00566     {
00567         if ((i % format->framesPerScan) == 0)    // If the first sample of a scan
00568             lastDL = compressed->bigDL[i];
00569         else if (lastDL != compressed->bigDL[i])
00570         {
00571            cpl_msg_info(cpl_func,"<<Warning>>: Delay Line jump at scan %d, from %f to %f \n", 
00572                 i/format->framesPerScan, lastDL, compressed->bigDL[i]);
00573             fprintf (midiReportPtr, "<<Warning>>: Delay Line jump at scan %d, from %f to %f \n", 
00574                 i, lastDL, compressed->bigDL[i]);
00575             compressed->badScanList[i/format->framesPerScan] |= BSL_DLJ_ERROR;                // Indicates DL jump within scan
00576             lastDL = (compressed->bigDL)[i];
00577         }
00578     }
00579     
00580     //    Now look at the Piezo, and try to set the optical freq cal:
00581     for (i = 0; i < format->numOfFrames; i++) 
00582     {
00583         if ((i % format->framesPerScan) == 0)    // If the first sample of a scan
00584             lastPiezo  = (compressed->localOPD)[i];
00585         else
00586         {    
00587             //    If this was NOT just after a flyback, good values and good scan
00588             if (!(isnan (compressed->localOPD[i])) && 
00589                 !(isnan (lastPiezo)) && 
00590                 !(compressed->badScanList[i/format->framesPerScan])) // All regions and channels are affected
00591             {
00592                 diff = compressed->localOPD[i] - lastPiezo;    //  compressed->localOPD[i-1]
00593                 sum += diff;
00594                 sumsqr += diff * diff;
00595                 numSummed++;
00596                 lastPiezo = compressed->localOPD[i];        // for next pass through loop
00597             }
00598         }
00599     }
00600         
00601     avg = sum/((float) numSummed);
00602     rms =  sqrtp(sumsqr/((float) numSummed) - avg * avg);
00603     if ( rms < (0.02 * fabs(avg))) rms = 0.02F * fabs(avg);
00604 
00605     //    Now for a second pass, not using the outliers (but marking them!!):
00606     threshold = 5.F * rms;    // Set at 5 sigma
00607     for (i = 0; i < format->numOfFrames; i++) 
00608     {
00609         if ((i % format->framesPerScan) == 0)    // If the first sample of a scan
00610             lastPiezo  = compressed->localOPD[i];
00611         else
00612         {   // If this was NOT just after a flyback, good values and good scan
00613             if (!(isnan (compressed->localOPD[i])) && 
00614                 !(isnan (lastPiezo)) && 
00615                 !(compressed->badScanList[i/format->framesPerScan])) // All regions and channels are affected
00616             {
00617                 diff = compressed->localOPD[i] - lastPiezo;    //  compressed->localOPD[i-1]
00618                 if (fabs(diff-avg) > threshold) 
00619                 {
00620                    cpl_msg_info(cpl_func,"<<Warning>>: PIEZO jump at scan %d, of %f microns. Expected %f \n",
00621                         i/format->framesPerScan, 1000000.F*diff, 1000000.F * avg);
00622                     fprintf (midiReportPtr, "<<Warning>>: PIEZO jump at scan %d, of %f microns. Expected %f \n",
00623                         i/format->framesPerScan, 1000000.F*diff, 1000000.F * avg);
00624                     compressed->badScanList[i/format->framesPerScan] |= BSL_DLJ_ERROR;                // Indicates piezo jump within scan.
00625                     lastPiezo += avg;    // <<<< Fake it!
00626                 }
00627                 else  // Normally:
00628                 {
00629                     sum += diff;
00630                     numSummed++;
00631                     lastPiezo = compressed->localOPD[i]; // for next pass thru loop
00632                 }
00633             }
00634         }
00635     }
00636     avg = sum/((float) numSummed);
00637     if (diagnostic)cpl_msg_info(cpl_func,"Average piezo step = %5.3f microns \n", 1000000.F*avg);
00638     fprintf(midiReportPtr, "Average piezo step = %5.3f microns \n", 1000000.F*avg);
00639 
00640     format->optFreqCal  = 1.F/(3335.F*fabs(avg));    // NOW SET HERE!!!;
00641 
00642     if (diagnostic)cpl_msg_info(cpl_func,"Setting optical wavelength calibration for this observation: %5.3f micron\n", 
00643         format->optFreqCal);
00644     fprintf(midiReportPtr, "Setting optical wavelength calibration for this observation: %5.3f micron\n", 
00645         format->optFreqCal);
00646     
00647     //    Transfer badScanList to rejectList for DISPERSED processing
00648     for (x = 0; x < format->iXWidth; x++)
00649     {
00650         for (i = 0; i < format->numOfFrames; i++)
00651             compressed->rejectList[x][i] |= compressed->badScanList[i/format->framesPerScan];
00652     }
00653     
00654     return;     
00655 }
00656 /******************************************************************************/
00657 
00658 
00659 
00660 /******************************************************************************
00661 *               European Southern Observatory
00662 *            VLTI MIDI Data Reduction Software
00663 *
00664 * Module name:  checkDelayLineConsistencies
00665 * Input/Output: See function arguments to avoid duplication
00666 * Description:    Checks delay line to see if it is reasonable
00667 *
00668 * History:
00669 * 03-Feb-06 (csabet) Adapted from Jeff Meisner for SCI_PHOT
00670 ******************************************************************************/
00671 void checkDelayLineConsistencies (
00672     const char            *dataKey1,            // In: Whether Interferometry or Photometry etc.
00673     const char            *dataKey2,            // In: Whether Interferometry or Photometry etc.
00674     CompressedData    *compressedInterf,    // In: Compressed Interferometry data
00675     CompressedData    *compressedPhotom,    // In: Compressed photometry data
00676     ImageFormat        *formatInterf,        // In: Interferompetry data size
00677     ImageFormat        *formatPhotom,        // In: Photometry data size
00678     int                *error)                // Ou: Error status
00679 
00680 {
00681 
00682     //    Local Declarations
00683     //    ------------------
00684     const char            routine[] = "checkDelayLineConsistencies";
00685     int                 j, type, numOfFrames, startFrame, toBeCounted;
00686     CompressedData         *thisData=NULL;
00687     float                frameTime100[ARB_NUM_OF_FRAMETIME];    // Number of frametime between 100 frames
00688     float                mean[3], rms;
00689 
00690 
00691     //    Algorithm
00692     //    ---------
00693     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
00694     if (diagnostic > 4) fprintf(midiReportPtr, "Invoking      routine   '%s' \n", routine);
00695 
00696    cpl_msg_info(cpl_func,"\nChecking Delay Line Consistencies between %s and %s \n", dataKey1, dataKey2);
00697    cpl_msg_info(cpl_func,"------------------------------------------- \n");
00698     fprintf (midiReportPtr, "\nChecking Delay Line Consistencies between %s and %s \n", dataKey1, dataKey2);
00699     fprintf (midiReportPtr, "------------------------------------------- \n");
00700 
00701     //    Reset status
00702     *error = 0;
00703     
00704     //    Look at the DL data and the TIME data. Perhaps check to see if reasonable
00705     for (type = 0; type < 2; type++)
00706     {
00707         if (type == 0) thisData = compressedInterf;    // Interferometry
00708         if (type == 1) thisData = compressedPhotom;    // Photometry
00709         if (type == 0) numOfFrames = formatInterf->numOfFrames;    // Interferometry
00710         if (type == 1) numOfFrames = formatPhotom->numOfFrames;    // Photometry
00711         if (numOfFrames < (ARB_NUM_OF_FRAMETIME + 101)) continue;
00712         toBeCounted = 0;    // In case of bad value (csabet, 02-Mar-05)
00713         for (j = 0; j < ARB_NUM_OF_FRAMETIME; j++)
00714         {
00715             startFrame = j * ((numOfFrames-101)/ARB_NUM_OF_FRAMETIME);
00716             if (!isnan (thisData->time[startFrame+100]) && !isnan (thisData->time[startFrame]))
00717             {
00718                 //    Now in milliseconds
00719                 frameTime100[j] = (thisData->time[startFrame+100] - thisData->time[startFrame]) * 864000.0;
00720                 toBeCounted++;
00721             }
00722         }
00723         makeStats (frameTime100, toBeCounted, mean+type, &rms);
00724         if (diagnostic)cpl_msg_info(cpl_func,"Found FRAME TIME for dataset %d = %7.2f ms (apparent rms = %f) \n", 
00725             type, mean[type], rms*10.0);
00726         fprintf (midiReportPtr, "Found FRAME TIME for dataset %d = %7.2f ms (apparent rms = %f) \n", 
00727             type, mean[type], rms*10.0);
00728         if (rms > (0.01 * mean[type])) midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, 
00729             "Apparently an inconsistent FRAME TIME");
00730     }
00731     
00732     if (fabs(mean[1] - mean[0]) > (0.01 * mean[0]))
00733     {
00734         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, 
00735             "Found inconsistent FRAME TIME between Interferometry & Photometry files");
00736         *error = 1;
00737     }
00738 
00739     return;
00740 }
00741 /*****************************************************************************/
00742 
00743 
00744 
00745 /******************************************************************************
00746 *               European Southern Observatory
00747 *            VLTI MIDI Data Reduction Software
00748 *
00749 * Module name:  createMaskFile
00750 * Input/Output: See function arguments to avoid duplication
00751 * Description:
00752 *
00753 * History:
00754 * 21-Jul-03 (csabet) Created
00755 ******************************************************************************/
00756 void createMaskFile (
00757     MidiFiles    *fileNames,    // IO: Pointer to midi files structure
00758     int            *error)        // Ou: Error status
00759 {
00760 
00761     //    Local Declarations
00762     //    ------------------
00763     const char                routine[] = "createMaskFile";
00764     FILE                    *inFitsBatchPtr = NULL;
00765     ImageFormat                *param;
00766     int                        imagingDataExtension;
00767     char                    *stringTemp, *classification, *maskPath;
00768     struct stat                buf;
00769 
00770     //    Algorithm
00771     //    ---------
00772     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
00773     if (diagnostic > 4) fprintf(midiReportPtr, "Invoking      routine   '%s' \n", routine);
00774 
00775    cpl_msg_info(cpl_func,"\nCreating a mask file for batch  %d \n", batchNumber);
00776    cpl_msg_info(cpl_func,"------------------------------ \n");
00777     fprintf (midiReportPtr, "\nCreating a mask file for batch  %d \n", batchNumber);
00778     fprintf (midiReportPtr, "------------------------------ \n");
00779 
00780     //    Reset status
00781     *error = 0;
00782 
00783     //    Allocate memory
00784     param = callocImageFormat ();
00785     maskPath = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00786     stringTemp = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00787     classification = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00788 
00789     //    Open the list of files
00790     if ((inFitsBatchPtr = fopen (fileNames->inFitsBatch, "r")) == NULL)
00791     {
00792         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, 
00793             "Cannot open input FITS file list\n                 This batch has been ignored");
00794         freeImageFormat (param);
00795         free (classification);
00796         free (stringTemp);
00797         *error = 1;
00798         return;
00799     }
00800 
00801     //    Loop through the file list
00802     while (fgets (stringTemp, MAX_STRING_LENGTH, inFitsBatchPtr) != NULL)
00803     {
00804         sprintf (classification, "%s", "");
00805         sscanf (stringTemp, "%s%s", fileNames->inFitsName, classification);
00806         if (diagnostic)cpl_msg_info(cpl_func,"Processing file   %s \n", fileNames->inFitsName);
00807         fprintf(midiReportPtr, "Processing file   %s \n", fileNames->inFitsName);
00808 
00809         //    Get extension number of IMAGING_DATA in input file
00810         imagingDataExtension  = findImagingDataExtension (fileNames->inFitsName, TAB_IMAGING_DATA, error);
00811         if (*error) break;
00812 
00813         //    Get Image Format
00814         if (imagingDataExtension > 0)
00815         {
00816             getImageFormat (fileNames->inFitsName, imagingDataExtension, param, error);
00817             if (*error) break;
00818         }
00819         else param->hasData = 0;
00820 
00821         //    Check if the file has data
00822         if (param->hasData)
00823         {
00824             //    If mask file is not available then create it
00825             sprintf (fileNames->maskFileName, "Mask_ONLINE_%s_%s.fits", param->grismId, param->beamCombiner);
00826             sprintf (maskPath, "%s%s", outFileDir, fileNames->maskFileName);
00827             if ((stat (maskPath, &buf)) != 0)
00828             {
00829                 //    Check if Categ, Tech, Type is suitable for this task
00830                 if (((strcmp (param->obsCatg, "CALIB") == 0) || 
00831                     (strcmp (param->obsCatg, "SCIENCE") == 0)) &&
00832                     (strcmp (param->obsTech, "IMAGE,WINDOW,CHOPNOD") == 0) && 
00833                     (strcmp (param->obsType, "PHOTOMETRY,OBJECT") == 0))
00834                 {
00835                     preparePhotomAperMask (fileNames->inFitsName, maskPath, error);
00836                     if (*error) midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot create mask file from");
00837                 }
00838                 else if ((strcmp (param->beamCombiner, "SCI_PHOT") == 0))
00839                 {
00840                     //    Use only one file
00841                     createMaskSP (fileNames->inFitsName, maskPath, error);
00842                     if (*error) midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot create mask file from");
00843                     break;
00844                 }
00845                 else if (((strcmp (param->obsCatg, "CALIB") == 0) || (strcmp (param->obsCatg, "SCIENCE") == 0)) &&
00846                     (strcmp (param->obsTech, "UNKNOWN_TECH") == 0) && (strcmp (param->obsType, "UNKNOWN_TYPE") == 0))
00847                     prepareSpectroPhotomAperMask ();
00848                 else if (((strcmp (param->obsCatg, "CALIB") == 0) || (strcmp (param->obsCatg, "SCIENCE") == 0)) &&
00849                     (strcmp (param->obsTech, "UNKNOWN_TECH") == 0) && (strcmp (param->obsType, "UNKNOWN_TYPE") == 0))
00850                     prepareMasterFlat ();
00851                 else if (((strcmp (param->obsCatg, "CALIB") == 0) || (strcmp (param->obsCatg, "SCIENCE") == 0)) &&
00852                     (strcmp (param->obsTech, "UNKNOWN_TECH") == 0) && (strcmp (param->obsType, "UNKNOWN_TYPE") == 0))
00853                     prepareMasterDark ();
00854                 else if (((strcmp (param->obsCatg, "CALIB") == 0) || (strcmp (param->obsCatg, "SCIENCE") == 0)) &&
00855                     (strcmp (param->obsTech, "UNKNOWN_TECH") == 0) && (strcmp (param->obsType, "UNKNOWN_TYPE") == 0))
00856                     prepareDispersionRelation ();
00857                 else if (((strcmp (param->obsCatg, "CALIB") == 0) || (strcmp (param->obsCatg, "SCIENCE") == 0)) &&
00858                     (strcmp (param->obsTech, "UNKNOWN_TECH") == 0) && (strcmp (param->obsType, "UNKNOWN_TYPE") == 0))
00859                     prepareZeroPoint ();
00860                 else if (((strcmp (param->obsCatg, "CALIB") == 0) || (strcmp (param->obsCatg, "SCIENCE") == 0)) &&
00861                     (strcmp (param->obsTech, "UNKNOWN_TECH") == 0) && (strcmp (param->obsType, "UNKNOWN_TYPE") == 0))
00862                     prepareSpectralSensitivity ();
00863                 else
00864                     midiReportInfo (midiReportPtr, routine, __FILE__, __LINE__, "The above file is not suitable for this task");
00865             }
00866             else
00867             {
00868                 if (diagnostic)cpl_msg_info(cpl_func,"Found mask FITS file   %s \n", maskPath);
00869                 fprintf (midiReportPtr, "Found mask FITS file   %s \n", maskPath);
00870                 break;
00871             }
00872         }
00873         else
00874         {
00875             if (diagnostic)
00876             {
00877                 sprintf (midiMessage, "No data tables in %s. Not processed", fileNames->inFitsName);
00878                 midiReportInfo (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
00879             }
00880         }
00881     }
00882 
00883     //    Release memory and close files
00884     fclose (inFitsBatchPtr);
00885     freeImageFormat (param);
00886     free (classification);
00887     free (stringTemp);
00888     free (maskPath);
00889 
00890     return;
00891 }
00892 /*****************************************************************************/
00893 
00894 /******************************************************************************
00895 *               European Southern Observatory
00896 *            VLTI MIDI Data Reduction Software
00897 *
00898 * Module name:  prepareMasterFlat
00899 * Input/Output: See function arguments to avoid duplication
00900 * Description:
00901 *
00902 * History:
00903 * 21-Jul-03     (csabet) Created
00904 ******************************************************************************/
00905 void prepareMasterFlat (void)
00906 {
00907 
00908     /*  Local Declarations
00909     --------------------*/
00910     const char  routine[] = "prepareMasterFlat";
00911 
00912     /*  Algorithm
00913     -----------*/
00914     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
00915     if (diagnostic > 4) fprintf(midiReportPtr, "Invoking      routine   '%s' \n", routine);
00916 
00917     midiReportTbd (midiReportPtr, routine, __FILE__, __LINE__, "Entire routine to be written");
00918 
00919     return;
00920 }
00921 /*****************************************************************************/
00922 
00923 
00924 /******************************************************************************
00925 *               European Southern Observatory
00926 *            VLTI MIDI Data Reduction Software
00927 *
00928 * Module name:  prepareMasterDark
00929 * Input/Output: See function arguments to avoid duplication
00930 * Description:
00931 *
00932 *
00933 * History:
00934 * 21-Jul-03     (csabet) Created
00935 ******************************************************************************/
00936 void prepareMasterDark (void)
00937 {
00938 
00939     /*  Local Declarations
00940     --------------------*/
00941     const char  routine[] = "prepareMasterDark";
00942     
00943     /*  Algorithm
00944     -----------*/
00945     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
00946     if (diagnostic > 4) fprintf(midiReportPtr, "Invoking      routine   '%s' \n", routine);
00947 
00948     midiReportTbd (midiReportPtr, routine, __FILE__, __LINE__, "Entire routine to be written");
00949 
00950     return;
00951 }
00952 /*****************************************************************************/
00953 
00954 
00955 /******************************************************************************
00956 *               European Southern Observatory
00957 *            VLTI MIDI Data Reduction Software
00958 *
00959 * Module name:  prepareDispersiveRelation
00960 * Input/Output: See function arguments to avoid duplication
00961 * Description:
00962 *
00963 *
00964 * History:
00965 * 21-Jul-03     (csabet) Created
00966 ******************************************************************************/
00967 void prepareDispersionRelation (void)
00968 {
00969 
00970     /*  Local Declarations
00971     --------------------*/
00972     const char  routine[] = "prepareDispersiveRelation";
00973 
00974     /*  Algorithm
00975     -----------*/
00976     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
00977     if (diagnostic > 4) fprintf(midiReportPtr, "Invoking      routine   '%s' \n", routine);
00978 
00979     midiReportTbd (midiReportPtr, routine, __FILE__, __LINE__, "Entire routine to be written");
00980 
00981     return;
00982 }
00983 /*****************************************************************************/
00984 
00985 
00986 /******************************************************************************
00987 *               European Southern Observatory
00988 *            VLTI MIDI Data Reduction Software
00989 *
00990 * Module name:  prepareSpectroPhotomAperMask
00991 * Input/Output: See function arguments to avoid duplication
00992 * Description:
00993 *
00994 *
00995 * History:
00996 * 21-Jul-03     (csabet) Created
00997 ******************************************************************************/
00998 void prepareSpectroPhotomAperMask (void)
00999 {
01000 
01001     /*  Local Declarations
01002     --------------------*/
01003     const char  routine[] = "prepareSpectroPhotomAperMask";
01004 
01005     /*  Algorithm
01006     -----------*/
01007     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
01008     if (diagnostic > 4) fprintf(midiReportPtr, "Invoking      routine   '%s' \n", routine);
01009     
01010     midiReportTbd (midiReportPtr, routine, __FILE__, __LINE__, "Entire routine to be written");
01011 
01012     return;
01013 }
01014 /*****************************************************************************/
01015 
01016 
01017 /******************************************************************************
01018 *               European Southern Observatory
01019 *            VLTI MIDI Data Reduction Software
01020 *
01021 * Module name:  createMaskSP
01022 * Input/Output: See function arguments to avoid duplication
01023 * Description:
01024 *
01025 *
01026 * History:
01027 * 07-Mar-06     (csabet) Created
01028 ******************************************************************************/
01029 void createMaskSP (
01030     char    *inFitsName,    // In: Name of the input data file
01031     char    *maskFitsName,    // In: Name of the mask file
01032     int        *error)            // Ou: Error status
01033 {
01034  
01035     //    Local Declarations
01036     //    ------------------
01037     const char        routine[] = "createMaskSP";
01038     ImageFormat        *format;
01039     int                i, x, y, extNumOfImagingData, subWindowSize, tableWidth, numOfColumns, 
01040                     edgeLX, edgeRX, edgeFY, edgeBY, numOfRows;
01041     qfits_header    *primHeadMask, *imagDataHeader;
01042     char            *dateTime, *tdim1, *tdim2, *tdim3, *tdim4;
01043     FILE            *maskFitsPtr;
01044     qfits_table        *maskTable;
01045     float            **array, *data1, *data2, *data3, *data4;
01046     qfits_col        *col;
01047  
01048     //    Algorithm
01049     //    ---------
01050     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
01051     if (diagnostic > 4) fprintf(midiReportPtr, "Invoking      routine   '%s' \n", routine);
01052  
01053     //    Reset status
01054     *error = 0;
01055     numOfRows = 1;
01056     numOfColumns = 4;
01057     tableWidth = - 1;
01058     
01059    cpl_msg_info(cpl_func,"Creating mask FITS file   %s \n", maskFitsName);
01060     fprintf (midiReportPtr, "Creating mask FITS file   %s \n", maskFitsName);
01061  
01062     //    Get 'extNumOfImagingDataFile' extension number of IMAGING_DATA in input file
01063     extNumOfImagingData  = findImagingDataExtension (inFitsName, TAB_IMAGING_DATA, error);
01064  
01065     //    Get Image Format parameters and allocate memory for the data1 and data2 */
01066     format = callocImageFormat ();
01067     getImageFormat (inFitsName, extNumOfImagingData, format, error);
01068     subWindowSize = format->iXWidth * format->iYWidth;
01069  
01070     //    Extract Primary Header from the input file
01071     if (diagnostic)cpl_msg_info(cpl_func,"Extracting primary header from input FITS file   %s \n", inFitsName);
01072     if (diagnostic) fprintf(midiReportPtr, "Extracting primary header from input FITS file   %s \n", inFitsName);
01073     primHeadMask = qfits_header_read (inFitsName);
01074     if (primHeadMask == NULL)
01075     {
01076         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot extract primary header from input FITS file");
01077        cpl_msg_info(cpl_func,"\nCannot Create mask FITS file for batch  %d \n", batchNumber);
01078         fprintf (midiReportPtr, "\nCannot Create mask FITS file for batch  %d \n", batchNumber);
01079         freeImageFormat (format);
01080         *error = 1;
01081         return;
01082     }
01083  
01084     //    Update primary header for the Mask file
01085     dateTime = qfits_get_datetime_iso8601 ();
01086     qfits_header_mod (primHeadMask, "DATE", dateTime, "Date and time this file was written");
01087     qfits_header_mod (primHeadMask, "INSTRUME", "MIDI", "MIDI Mask created by DRS pipeline" );
01088     qfits_header_add (primHeadMask, "EXTNAME", "Primary", "MIDI Mask primary header", "" );
01089  
01090     //    Create the mask file and dump the primary header and close the file
01091     maskFitsPtr = fopen (maskFitsName, "w");
01092     qfits_header_dump (primHeadMask, maskFitsPtr);
01093     qfits_header_destroy (primHeadMask);
01094     fclose (maskFitsPtr);
01095  
01096     //    Allocate memory for data
01097     data1 = (float *) calloc (subWindowSize, sizeof (float));
01098     data2 = (float *) calloc (subWindowSize, sizeof (float));
01099     data3 = (float *) calloc (subWindowSize, sizeof (float));
01100     data4 = (float *) calloc (subWindowSize, sizeof (float));
01101     tdim1 = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
01102     tdim2 = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
01103     tdim3 = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
01104     tdim4 = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
01105  
01106     //    Load data
01107     midiReportTbd (midiReportPtr, routine, __FILE__, __LINE__, "This is a temporary rectangular mask");
01108     edgeFY = 0.30 * format->iYWidth;
01109     edgeBY = 0.50 * format->iYWidth;
01110     edgeLX = 0.20 * format->iXWidth;
01111     edgeRX = 0.20 * format->iXWidth;
01112     for (y = edgeFY; y < format->iYWidth-edgeBY; y++)
01113     {
01114         for (x = edgeLX; x < format->iXWidth-edgeRX; x++)
01115         {
01116             i = x + y * format->iXWidth;
01117             data1[i] = 1.0;
01118             data2[i] = 1.0;
01119             data3[i] = 1.0;
01120             data4[i] = 1.0;
01121         }
01122     }
01123  
01124     //    Open the mask file for writing
01125     maskFitsPtr = fopen (maskFitsName, "a");
01126     if (maskFitsPtr == NULL)
01127     {
01128         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot open mask file");
01129         *error = 1;
01130         free (tdim1);
01131         free (tdim2);
01132         free (tdim3);
01133         free (tdim4);
01134         free (data1);
01135         free (data2);
01136         free (data3);
01137         free (data4);
01138         freeImageFormat (format);
01139         return;
01140     }
01141  
01142     //    Create a new table
01143     maskTable = qfits_table_new (maskFitsName, QFITS_BINTABLE, tableWidth, numOfColumns, numOfRows);
01144     if (!maskTable)
01145     {
01146         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot create table");
01147         *error = 1;
01148         free (tdim1);
01149         free (tdim2);
01150         free (tdim3);
01151         free (tdim4);
01152         free (data1);
01153         free (data2);
01154         free (data3);
01155         free (data4);
01156         freeImageFormat (format);
01157         fclose (maskFitsPtr);
01158         return;
01159     }
01160  
01161     //    Fill in the column information
01162     col = maskTable->col;
01163     qfits_col_fill (col, subWindowSize, 2, sizeof(float), TFITS_BIN_TYPE_E, "DATA1", " ", " ", " ",
01164         0, 0.0, 0, 1.0, 0);
01165     col++;
01166     qfits_col_fill (col, subWindowSize, 2, sizeof(float), TFITS_BIN_TYPE_E, "DATA2", " ", " ", " ",
01167         0, 0.0, 0, 1.0, 0);
01168     col++;
01169     qfits_col_fill (col, subWindowSize, 2, sizeof(float), TFITS_BIN_TYPE_E, "DATA3", " ", " ", " ",
01170         0, 0.0, 0, 1.0, 0);
01171     col++;
01172     qfits_col_fill (col, subWindowSize, 2, sizeof(float), TFITS_BIN_TYPE_E, "DATA4", " ", " ", " ",
01173         0, 0.0, 0, 1.0, subWindowSize* sizeof(float));
01174  
01175     //    Create the imaging data header
01176     imagDataHeader = qfits_table_ext_header_default(maskTable);
01177     qfits_header_add (imagDataHeader, "EXTNAME", "IMAGING_DATA", "MIDI Mask Extension name", "" );
01178  
01179  
01180     //    Add dimensionality to the extension header
01181     sprintf (tdim1, "'(%d,%d)'", format->iXWidth, format->iYWidth);
01182     sprintf (tdim2, "'(%d,%d)'", format->iXWidth, format->iYWidth);
01183     sprintf (tdim3, "'(%d,%d)'", format->iXWidth, format->iYWidth);
01184     sprintf (tdim4, "'(%d,%d)'", format->iXWidth, format->iYWidth);
01185     qfits_header_add (imagDataHeader, "TDIM1", tdim1, "Column dimensionality", "" );
01186     qfits_header_add (imagDataHeader, "TDIM2", tdim2, "Column dimensionality", "" );
01187     qfits_header_add (imagDataHeader, "TDIM3", tdim2, "Column dimensionality", "" );
01188     qfits_header_add (imagDataHeader, "TDIM4", tdim2, "Column dimensionality", "" );
01189  
01190     //    Allocate space for the array of data
01191     array = (float **) calloc (numOfColumns, sizeof(float *));
01192     array[0] = data1;
01193     array[1] = data2;
01194     array[2] = data3;
01195     array[3] = data4;
01196  
01197     if (qfits_table_append_xtension_hdr (maskFitsPtr, maskTable, (const void **)array, imagDataHeader) == -1)
01198         *error = 1;
01199  
01200     qfits_header_destroy (imagDataHeader);
01201     qfits_table_close (maskTable);
01202  
01203     if (!(*error))
01204     {
01205        cpl_msg_info(cpl_func,"Created Mask FITS file: %s \n", maskFitsName);
01206         fprintf (midiReportPtr, "Created Mask FITS file: %s \n", maskFitsName);
01207     }
01208  
01209     //    Release memory
01210     free (array);
01211     fclose (maskFitsPtr);
01212     free (tdim1);
01213     free (tdim2);
01214     free (tdim3);
01215     free (tdim4);
01216     free (data1);
01217     free (data2);
01218     free (data3);
01219     free (data4);
01220     freeImageFormat (format);
01221  
01222     return;
01223 }
01224 /*****************************************************************************/
01225  
01226  
01227 /******************************************************************************
01228 *               European Southern Observatory
01229 *            VLTI MIDI Data Reduction Software
01230 *
01231 * Module name:  preparePhotomAperMask
01232 * Input/Output: See function arguments to avoid duplication
01233 * Description:
01234 *
01235 *
01236 * History:
01237 * 21-Jul-03     (csabet) Created
01238 ******************************************************************************/
01239 void preparePhotomAperMask (
01240     char    *inFileName,    // In: Name of the input data file
01241     char    *maskFileName,    // In: Name of the mask file
01242     int        *error)            // Ou: Error status
01243 {
01244 
01245     /*  Local Declarations
01246     --------------------*/
01247     const char          routine[] = "preparePhotomAperMask";
01248     static short int    *aveData_1, *aveData_2;
01249     short int           *inData_1, *inData_2;
01250     ImageFormat         *format;
01251     int                 i, j, extNumOfImagingData, numOfElemets,
01252                         scalingOffset, indexData1, indexData2, subWindowSize, pixel;
01253     static int          aprioriNumOfElemets = 0, numOfFiles = 0;
01254     qfits_table         *imagDataTable;
01255     char                *tempStr, *dataName;
01256     int                 foundData1 = 0, foundData2 = 0;
01257 
01258     /*  Algorithm
01259     -----------*/
01260     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
01261     if (diagnostic > 4) fprintf(midiReportPtr, "Invoking      routine   '%s' \n", routine);
01262 
01263     /*  Reset status */
01264     *error = 0;
01265     numOfFiles++;
01266 
01267     /*  Get 'extNumOfImagingDataFile' extension number of IMAGING_DATA in input file */
01268     extNumOfImagingData  = findImagingDataExtension (inFileName, TAB_IMAGING_DATA, error);
01269 
01270     /*  Get Image Format parameters and allocate memory for the data1 and data2 */
01271     format = callocImageFormat ();
01272     getImageFormat (inFileName, extNumOfImagingData, format, error);
01273     subWindowSize = format->iXWidth * format->iYWidth;
01274     numOfElemets = subWindowSize * format->numOfFrames;
01275 
01276     /*  Allocate memory in the first call */
01277     if (numOfFiles == 1)
01278     {
01279         aprioriNumOfElemets = numOfElemets;
01280         aveData_1 = (short int *) calloc (numOfElemets, sizeof (short int));
01281         aveData_2 = (short int *) calloc (numOfElemets, sizeof (short int));
01282     }
01283 
01284     if (aprioriNumOfElemets != numOfElemets)
01285     {
01286         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Inconsistent photometry files");
01287         *error = 1;
01288         freeImageFormat (format);
01289         free (aveData_1);
01290         free (aveData_2);
01291         return;
01292     }
01293 
01294     /*  Open IMAGING_DATA */
01295     imagDataTable = qfits_table_open (inFileName, extNumOfImagingData);
01296     if (!imagDataTable)
01297     {
01298         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot load IMAGING_DATA");
01299         *error = 1;
01300         freeImageFormat (format);
01301         free (aveData_1);
01302         free (aveData_2);
01303         return;
01304     }
01305 
01306     dataName = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
01307     //    Get the scaling offset
01308     for (i = 14; i < 25; i++)
01309     {
01310         sprintf (dataName, "TZERO%d", i);
01311         tempStr = qfits_query_ext (inFileName, dataName, extNumOfImagingData);
01312         if (tempStr != NULL)
01313         {
01314             if (diagnostic)cpl_msg_info(cpl_func,"Scaling Offset = %s\n", tempStr);
01315             fprintf( midiReportPtr, "Scaling Offset = %s\n", tempStr);
01316             sscanf (tempStr, "%d", &scalingOffset);
01317             break;
01318         }
01319     }
01320     if (tempStr == NULL)
01321     {
01322         scalingOffset = 0;
01323         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot read Scaling Offset. It is set to 0");
01324     }
01325     free (dataName);
01326     
01327     /*  Get data table information */
01328     indexData1 = 0;
01329     indexData2 = 0;
01330     for (i = 0; i < imagDataTable->nc; i++)
01331     {
01332         if (strcmp (imagDataTable->col[i].tlabel, "DATA1") == 0)
01333         {
01334             foundData1 = 1;
01335             indexData1 = i;
01336         }
01337         if (strcmp (imagDataTable->col[i].tlabel, "DATA2") == 0)
01338         {
01339             foundData2 = 1;
01340             indexData2 = i;
01341         }
01342     }
01343     if (foundData1 == 0 || foundData2 == 0)
01344         {
01345         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot find requested columns in date FITS file");
01346         *error = 1;
01347         qfits_table_close (imagDataTable);
01348         free (aveData_1);
01349         freeImageFormat (format);
01350         free (aveData_2);
01351         return;
01352     }
01353 
01354     /*  Load data */
01355     inData_1 = (short int *) (qfits_query_column (imagDataTable, indexData1, NULL));
01356     inData_2 = (short int *) (qfits_query_column (imagDataTable, indexData2, NULL));
01357 
01358     /*  Cumulate data */
01359     for (j = 0; j < format->numOfFrames; j++)
01360     {
01361         for (pixel = 0; pixel < subWindowSize; pixel++)
01362         {
01363             i = j * subWindowSize + pixel;
01364             if (isnan (inData_1[i]) || isnan (inData_2[i]))
01365             {
01366                 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Corrupted DATA1 or DATA2");
01367                 qfits_table_close (imagDataTable);
01368                 free (inData_1);
01369                 free (inData_2);
01370                 freeImageFormat (format);
01371                 *error = 1;
01372                 return;
01373             }
01374             aveData_1[i] += (inData_1[i] + scalingOffset);
01375             aveData_2[i] += (inData_2[i] + scalingOffset);
01376         }
01377     }
01378     free (inData_1);
01379     free (inData_2);
01380 
01381     /*  Create the mask file */
01382     if (numOfFiles == 2)
01383     {
01384         for (i = 0; i < numOfElemets; i++)
01385         {
01386             aveData_1[i] *= 0.5;
01387             aveData_2[i] *= 0.5;
01388         }
01389         createMidiMaskFile(format->iXWidth, format->iYWidth, inFileName, (short int *)(aveData_1), (short int *)(aveData_2),
01390             format->numOfFrames, subWindowSize, maskFileName, error);
01391         if (*error)
01392             midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot create mask file");
01393 
01394         /*  Reset counter for other batches */
01395         numOfFiles = 0;
01396 
01397         /*  Release memory */
01398         free (aveData_1);
01399         free (aveData_2);
01400     }
01401 
01402     /*  Release memory */
01403     freeImageFormat (format);
01404 
01405     qfits_table_close (imagDataTable);
01406 
01407     return;
01408 }
01409 /*****************************************************************************/
01410 
01411 
01412 
01413 /******************************************************************************
01414 *               European Southern Observatory
01415 *            VLTI MIDI Data Reduction Software
01416 *
01417 * Module name:  prepareZeroPoint
01418 * Input/Output: See function arguments to avoid duplication
01419 * Description:
01420 *
01421 *
01422 * History:
01423 * 21-Jul-03     (csabet) Created
01424 ******************************************************************************/
01425 void prepareZeroPoint (void)
01426 {
01427 
01428     /*  Local Declarations
01429     --------------------*/
01430     const char  routine[] = "prepareZeroPoint";
01431 
01432     /*  Algorithm
01433     -----------*/
01434     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
01435     if (diagnostic > 4) fprintf(midiReportPtr, "Invoking      routine   '%s' \n", routine);
01436 
01437     midiReportTbd (midiReportPtr, routine, __FILE__, __LINE__, "Entire routine to be written");
01438 
01439     return;
01440 }
01441 /*****************************************************************************/
01442 
01443 
01444 /******************************************************************************
01445 *               European Southern Observatory
01446 *            VLTI MIDI Data Reduction Software
01447 *
01448 * Module name:  prepareSpectralSensitivity
01449 * Input/Output: See function arguments to avoid duplication
01450 * Description:
01451 *
01452 *
01453 * History:
01454 * 21-Jul-03     (csabet) Created
01455 ******************************************************************************/
01456 void prepareSpectralSensitivity (void)
01457 {
01458 
01459     /*  Local Declarations
01460     --------------------*/
01461     const char  routine[] = "prepareSpectralSensitivity";
01462 
01463     /*  Algorithm
01464     -----------*/
01465     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
01466     if (diagnostic > 4) fprintf(midiReportPtr, "Invoking      routine   '%s' \n", routine);
01467 
01468     midiReportTbd (midiReportPtr, routine, __FILE__, __LINE__, "Entire routine to be written");
01469 
01470     return;
01471 }
01472 /*****************************************************************************/

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