procWavCal.c

00001 
00002 /******************************************************************************
00003 *******************************************************************************
00004 *               European Southern Observatory
00005 *          VLTI MIDI Maintenance Templates Software
00006 *
00007 * Module name:  procWaveCal.c
00008 * Description:  Contains routines for processing the templates
00009 *
00010 * History:      
00011 * 02-Jun-05     (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 <errno.h>
00026 #include <string.h>
00027 #include "midiGlobal.h"
00028 #include "midiLib.h"
00029 #include "imageProcessing.h"
00030 #include "memoryHandling.h"
00031 #include "createProdWavCal.h"
00032 #include "procWavCal.h"
00033 #include "errorHandling.h"
00034 #include "midiFitsUtility.h"
00035 #include "fitsAnalysisTec.h"
00036 #include "diagnostics.h"
00037 #include "statistics.h"
00038 #include "cpl_polynomial.h"
00039 #include "qfits.h"
00040 #include "midi_cplutils.h"
00041 
00042 /**********************************************************
00043 *   Constant definitions
00044 **********************************************************/
00045 
00046 /**********************************************************
00047 *   Global Variables 
00048 **********************************************************/
00049 
00050 /*============================ C O D E    A R E A ===========================*/
00051 
00052 
00053 /******************************************************************************
00054 *               European Southern Observatory
00055 *          VLTI MIDI Maintenance Templates Software
00056 *
00057 * Module name:  procWaveCal
00058 * Input/Output: See function arguments to avoid duplication
00059 * Description:  The main objective is to calibrate the channel against wavelength.
00060 *                That is to assign the correct wavelength to the detector channels.
00061 *
00062 * History:      
00063 * 02-Jun-05     (csabet) Created
00064 ******************************************************************************/
00065 void procWaveCal (
00066     int            processing,    // In: Correlate = 1, Create = 2
00067     MidiFiles    *fileNames,    // In: Pointer to file names
00068     int            *error)        // Ou: Error status
00069 {
00070 
00071     //    Local Declarations
00072     //    ------------------
00073     const char        routine[] = "procWaveCal";
00074     FILE            *signaturePtr=NULL, *filePtr=NULL;
00075     int                numOfFiles, numOfRecords;
00076     ImageFormat        *format=NULL;
00077     WaveCalibration    *waveCal=NULL;
00078     char            *fileString;
00079     float            record1, record2, record3, record4;
00080     
00081     //    Algorithm
00082     //    ---------
00083     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
00084     if (diagnostic > 4) fprintf (midiReportPtr, "Invoking      routine   '%s' \n", routine);
00085 
00086     //    Write a signature
00087     signaturePtr = fopen ("MIDI_sig_wav.log", "w");
00088     fclose (signaturePtr);
00089 
00090     //    Reset status
00091     *error = 0;
00092     numOfFiles = 0;
00093     
00094     //    Allocate memory
00095     format = callocImageFormat ();
00096     
00097     analyseFitsWaveCal (fileNames, format, &numOfFiles, error);
00098     if (*error)
00099     {
00100         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot analyse WAVECAL");
00101         freeImageFormat (format);
00102         return;
00103     }
00104 
00105     //    If correlation is requested, check if database file exists
00106     if (processing == 1)
00107     {
00108         //    Check if correct frequency calibration file exists in the calibration database
00109         fileString = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00110         sprintf (fileString , "%s_%s_%s.dat", fileNames->waveCalibName, format->grismId, format->beamCombiner);
00111         if ((filePtr = fopen (fileString, "r")) != NULL)    // It is in the database
00112         {
00113             //    Read from file and load into array
00114            cpl_msg_info(cpl_func,"\nChecking consistency of Wavelength Calibration file ... %s \n", fileString);
00115             fprintf (midiReportPtr, "\nChecking consistency of Wavelength Calibration file ... %s \n", fileString);
00116             numOfRecords = 0;
00117             if (strcmp (format->beamCombiner, "SCI_PHOT") == 0)
00118                 while (fscanf (filePtr, "%f %f %f %f\n", &record1, &record2, &record3, &record4) != EOF) numOfRecords++;
00119             else
00120                 while (fscanf (filePtr, "%f %f\n", &record1, &record2) != EOF) numOfRecords++;
00121 
00122             fclose (filePtr);
00123             if (numOfRecords == format->iXWidth)
00124             {
00125                 *error = 0;
00126                cpl_msg_info(cpl_func,"Found a wavelength calibration file %s with %d pairs of floats \n", 
00127                     fileString, numOfRecords);
00128                 fprintf (midiReportPtr, "Found a wavelength calibration file %s with %d pairs of floats \n", 
00129                     fileString, numOfRecords);
00130             }
00131             else
00132             {
00133                 *error = 1;
00134                 sprintf (midiMessage, "Inconsistent calibration data in %s. Nothing to correlate", fileString);
00135                 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
00136             }
00137         }
00138         else 
00139         {
00140             *error = 1;
00141             sprintf (midiMessage, "Cannot find calibration data file ... %s. Nothing to correlate", fileString);
00142             midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
00143         }
00144         free (fileString);
00145         
00146         if (*error)
00147         {
00148             freeImageFormat (format);
00149             return;
00150         }
00151     }
00152         
00153     //    Get the size of the Wavelength Calibration data
00154     numOfRecords = getWlCalib2Spectra (fileNames, error);
00155     if (*error)
00156     {
00157         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot get Wavelength Calibration data");
00158         freeImageFormat (format);
00159         return;
00160     }
00161     
00162     //    Get largest size
00163     if (numOfRecords < format->iXWidth) numOfRecords = format->iXWidth;
00164     
00165     //    Main task for wavelength calibration
00166     waveCal = callocWaveCal (numOfFiles, numOfRecords, format);
00167     computeWaveCal (processing, numOfFiles, fileNames, waveCal, error);
00168     if (*error)
00169     {
00170         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot process WAVECAL");
00171         freeWaveCal (format, waveCal);
00172         freeImageFormat (format);
00173         return;
00174     }
00175     
00176     //    Create product files
00177     createWaveCalProd (processing, fileNames, format, waveCal, error);
00178     if (*error)    midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot create WAVECAL products");
00179 
00180     //    Release memory
00181     freeWaveCal (format, waveCal);
00182     freeImageFormat (format);
00183 
00184 
00185     return; 
00186 }
00187 /*****************************************************************************/
00188 
00189 
00190 
00191 /******************************************************************************
00192 *               European Southern Observatory
00193 *          VLTI MIDI Maintenance Templates Software
00194 *
00195 * Module name:  computeWaveCal
00196 * Input/Output: See function arguments to avoid duplication
00197 * Description:  Performs Wavelength Calibration
00198 *
00199 * History:      
00200 * 10-Jun-05     (csabet) Created
00201 ******************************************************************************/
00202 void computeWaveCal (
00203     int                processing,    // In: Correlate = 1, Create = 2
00204     int                numOfFiles,    // In:    Number of data files
00205     MidiFiles        *fileNames,    // In: Pointer to the MIDI file structure
00206     WaveCalibration *waveCal,    // Ou: Pointer to the Wavelength Calibration data structure
00207     int                *error)        // Ou:    Error status
00208 {
00209 
00210     //    Local Declarations
00211     //    ------------------
00212     const char  routine[] = "computeWaveCal";
00213     char                        *fileTemp, *classification;
00214     FILE                    *inFitsBatchPtr;
00215     ImageFormat             *format;
00216     int                     localError, fileNumber, extNumOfImagingDataFile;
00217     
00218     //    Algorithm
00219     //    ---------
00220     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
00221     if (diagnostic > 4) fprintf (midiReportPtr, "Invoking      routine   '%s' \n", routine);
00222 
00223     //    Allocate memory
00224     classification = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00225     fileTemp = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00226     format = callocImageFormat ();
00227 
00228     //    Reset status
00229     *error = 0;
00230     localError = 0;
00231     fileNumber = 0;
00232     waveCal->exists = 0;
00233     format->hasData = 0;
00234             
00235     //    Open the list of files
00236     if ((inFitsBatchPtr = fopen (fileNames->inFitsBatch, "r")) == NULL)
00237     {
00238         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, 
00239             "Cannot open input FITS file list. No compression has been carried out for this batch");
00240         freeImageFormat (format);
00241         free (fileTemp);
00242         free (classification);
00243         *error = 1;
00244         return;
00245     }
00246 
00247     //    Loop through the files and analyse
00248     while (fgets (fileTemp, MAX_STRING_LENGTH, inFitsBatchPtr) != NULL)
00249     {
00250         sprintf (classification, "%s", "");
00251         sscanf (fileTemp, "%s%s", fileNames->inFitsName, classification);
00252         if (diagnostic)cpl_msg_info(cpl_func,"\n   Processing file   %s \n", fileNames->inFitsName);
00253         fprintf(midiReportPtr, "\n   Processing file   %s \n", fileNames->inFitsName);
00254 
00255         //    Get 'extNumOfImagingDataFile' extension number of IMAGING_DATA in input file
00256         extNumOfImagingDataFile  = findImagingDataExtension (fileNames->inFitsName, TAB_IMAGING_DATA, &localError);
00257         if (localError) 
00258         {
00259             *error = 1;
00260             break;
00261         }
00262 
00263         //    Get Image Format parameters
00264         if (extNumOfImagingDataFile > 0)
00265         {
00266             getImageFormat (fileNames->inFitsName, extNumOfImagingDataFile, format, &localError);
00267             if (localError) 
00268             {
00269                 *error = 1;
00270                 break;
00271             }
00272         }
00273         else format->hasData = 0;
00274 
00275         //    Check if the file has data
00276         if (format->hasData)
00277         {
00278             //    Check Categ, Tech and Type and then compute the image size
00279             if ((strcmp (format->obsCatg, "CALIB") == 0) &&
00280                 (strcmp (format->obsTech, "SPECTRUM") == 0) &&
00281                 (strcmp (format->obsType, "WAVE,SPECTEMPL") == 0))
00282             {
00283                 //    Increment file number but make sure it is not greater than the allocated
00284                 fileNumber++;
00285                 if (fileNumber > numOfFiles)
00286                 {
00287                     *error = 1;
00288                     sprintf (midiMessage, "Inconsistent number of files. Expected %d. Found %d", numOfFiles, fileNumber);
00289                     midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
00290                     break;
00291                 }
00292                 
00293                 //    Save file IDs
00294                 sprintf (waveCal->shutterId[fileNumber-1], "%s", format->shutterId);
00295                 sprintf (waveCal->filterName[fileNumber-1], "%s", format->filterName);
00296                 
00297                 //    Preprocess data
00298                 compressWaveCal (fileNumber-1, fileNames->inFitsName, extNumOfImagingDataFile, format, waveCal, &localError);
00299                 if (localError)
00300                 {
00301                     *error = 1;
00302                     midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot preprocess");
00303                     continue;
00304                 }
00305             
00306                 //    Validate data
00307                 validateWaveCalData (fileNumber-1, fileNames->inFitsName, waveCal, format, &localError);
00308                 if (localError)
00309                 {
00310                     *error = 1;
00311                     midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot validate data");
00312                     continue;
00313                 }
00314             }
00315             else
00316                 midiReportInfo (midiReportPtr, routine, __FILE__, __LINE__, "The above file is not suitable for this task");
00317         }
00318         else
00319         {
00320             if (diagnostic)
00321             {
00322                 sprintf (midiMessage, "No data tables in %s. Not processed", fileNames->inFitsName);
00323                 midiReportInfo (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
00324             }
00325         }
00326     }
00327 
00328     //    Issue an interim error message
00329     if ((*error) || (fileNumber != numOfFiles))
00330     {
00331         sprintf (midiMessage, "Cannot do Wavelength Calibration. error=%d, numOfFiles=%d. Expected %d",
00332             *error, fileNumber, numOfFiles); 
00333         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
00334         fclose (inFitsBatchPtr);
00335         freeImageFormat (format);
00336         free (fileTemp);
00337         free (classification);
00338         return;
00339     }
00340     
00341     //    If so far all is well then carry out with the Calibration
00342     waveCal->exists = 1;
00343    cpl_msg_info(cpl_func,"\nWavelength Calibration Inventry: \n");
00344    cpl_msg_info(cpl_func,"=============================== \n");
00345    cpl_msg_info(cpl_func,"   Expected number of data files  = %d\n", numOfFiles);
00346    cpl_msg_info(cpl_func,"   Number of data files processed = %d\n", fileNumber);
00347    cpl_msg_info(cpl_func,"\n");
00348     fprintf (midiReportPtr, "\nWavelength Calibration Inventry: \n");
00349     fprintf (midiReportPtr, "=============================== \n");
00350     fprintf (midiReportPtr, "   Expected number of data files  = %d\n", numOfFiles);
00351     fprintf (midiReportPtr, "   Number of data files processed = %d\n", fileNumber);
00352     fprintf (midiReportPtr, "\n");
00353 
00354     //    Remove dark
00355     removeDark (format, waveCal, error);
00356         
00357     //    Perform Wavelength Calibration
00358     calibrateWaveChannels (processing, fileNames, waveCal, format, error);
00359     
00360     //    Close the file list
00361     fclose (inFitsBatchPtr);
00362     
00363     //    Release memory
00364     freeImageFormat (format);
00365     free (fileTemp);
00366     free (classification);    
00367 
00368     return; 
00369 }
00370 /*****************************************************************************/
00371 
00372 
00373 /******************************************************************************
00374 *               European Southern Observatory
00375 *          VLTI MIDI Maintenance Templates Software
00376 *
00377 * Module name:  compressWaveCal
00378 * Input/Output: See function arguments to avoid duplication
00379 * Description:  Compresses Wavelength Calibration raw data
00380 *
00381 * History:      
00382 * 10-Jun-05     (csabet) Created
00383 ******************************************************************************/
00384 void compressWaveCal (
00385     int                fileNumber,        // In: File number
00386     char            *inFitsName,    // In: Name of file to process
00387     int                extensionNumber,// In: Extension number of the IMAGE_DATA
00388     ImageFormat        *format,        // In: Pointer to the image format
00389     WaveCalibration    *waveCal,        // Ou: Pointer to the wavelength calibration
00390     int                *error)            // Ou: Error status
00391 
00392 {
00393   
00394     //    Local Declarations
00395     //    ------------------
00396     const char  routine[] = "compressWaveCal";
00397     qfits_table    *pTable=NULL;
00398     short int    **inData;
00399     char        *inTarType=NULL, *tempStr, *dataName, lastTT;
00400     int            i, pixel, *foundData, scalingOffset, *indexData, numOfSkyFrames, numOfFramesUsed,
00401                 frame, region, indexTarType, foundTarType, transitions, numOfUndefinedFrames,
00402                 numOfBadFrames,    tartypMult;
00403        
00404     //    Algorithm
00405     //    ---------
00406     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
00407     if (diagnostic > 4) fprintf (midiReportPtr, "Invoking      routine   '%s' \n", routine);
00408     
00409     //    Reset status
00410     *error = 0;
00411     foundTarType = 0;
00412     
00413     /*    Signifies that there are 2 (instead of 1!) characters per tartyp 
00414     value (only first is useful). In future, if the problem producing the MIDI 
00415     files is solved, can be changed to 1 (only for newer files) or made variable 
00416     (with some way to determine whether it is an "old" type file). Note: this problem 
00417     really has nothing to do with Qfits, but with the (unintended) way the files are written */
00418     tartypMult = 2;    
00419                     
00420     //    Allocate memory
00421     inData = (short int **) calloc (format->numOfDetectorRegions, sizeof (short int *));
00422     foundData = (int *) calloc (format->numOfDetectorRegions, sizeof (int));
00423     indexData = (int *) calloc (format->numOfDetectorRegions, sizeof (int));
00424     dataName = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00425     
00426     //    Open IMAGING_DATA = INDEX 2
00427     pTable = qfits_table_open (inFitsName, extensionNumber);
00428     if (!pTable)
00429     {
00430         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot load IMAGING_DATA");
00431         for (region = 0; region < format->numOfDetectorRegions; region++) free (inData[region]);
00432         free (foundData);
00433         free (indexData);
00434         free (dataName);
00435         *error = 1;
00436         return;
00437     }
00438         
00439     //    Get data table information
00440     for (region = 0; region < format->numOfDetectorRegions; region++)
00441     {
00442         foundData[region] = 0;
00443         indexData[region] = 0;
00444     }
00445     for (i = 0; i < pTable->nc; i++)
00446     {
00447         for (region = 0; region < format->numOfDetectorRegions; region++)
00448         {
00449             sprintf (dataName, "DATA%d", region+1);
00450             if (strcmp (pTable->col[i].tlabel, dataName) == 0)
00451             {
00452                 foundData[region] = 1;
00453                 indexData[region] = i;
00454                 if (diagnostic)cpl_msg_info(cpl_func,"Found 'DATA%d' at column %d in data file %s \n", region+1, i+1, inFitsName);
00455                 if (diagnostic) fprintf(midiReportPtr, "Found 'DATA%d' at column %d in data file %s \n", region+1, i+1, inFitsName);
00456             }
00457         }
00458         if (strcmp (pTable->col[i].tlabel, "TARTYP2") == 0)    // Now changed to TARTYP2, for all newer files
00459         {
00460             foundTarType = 1;
00461             indexTarType = i;
00462         }
00463     }
00464 
00465     //    Now issue warnings
00466     if (foundTarType == 0)
00467     {
00468         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot find TARTYP2 in data FITS file");
00469         *error = 1;
00470     }
00471     for (region = 0; region < format->numOfDetectorRegions; region++)
00472     {
00473         if (foundData[region] == 0)
00474         {
00475             midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot find requested DATA column in data FITS file");
00476             *error = 1;
00477         }
00478     }
00479     
00480     //    Release memory and exit this module if there has been a warning. No point going any further
00481     if (*error)
00482     {
00483         qfits_table_close (pTable);
00484         for (region = 0; region < format->numOfDetectorRegions; region++) free (inData[region]);
00485         free (foundData);
00486         free (indexData);
00487         free (dataName);
00488         return;
00489     }
00490 
00491     //    Get TARTYP2
00492     inTarType = (char *) qfits_query_column (pTable, indexTarType, NULL);
00493     for (frame = 0; frame < format->numOfFrames; frame++)
00494         waveCal->tarType[frame] = inTarType[frame*tartypMult];     // New way around tartype problem (JM)
00495 
00496     //    Check if the data is chopped
00497     transitions = 0;
00498     lastTT = waveCal->tarType[0];
00499     for (frame = 0; frame < format->numOfFrames; frame++)
00500     {
00501         if (waveCal->tarType[frame] == lastTT) continue;
00502         transitions++;    // INCLUDES transitions to U etc.
00503         lastTT = waveCal->tarType[frame];
00504     }
00505     if ((format->chopped = (transitions > 10)))    // Apparently is a chopped file
00506     {
00507         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Wavelength Calibration data is chopped");
00508         *error = 1;
00509         qfits_table_close (pTable);
00510         for (region = 0; region < format->numOfDetectorRegions; region++) free (inData[region]);
00511         free (foundData);
00512         free (indexData);
00513         free (dataName);
00514         return;
00515     }
00516 
00517     //    Read all regions from input files
00518     for (region = 0; region < format->numOfDetectorRegions; region++)
00519         inData[region] = (short int*) qfits_query_column (pTable, indexData[region], NULL);
00520 
00521     //    Get the scaling offset
00522     for (i = 14; i < 25; i++)
00523     {
00524         sprintf (dataName, "TZERO%d", i);
00525         tempStr = qfits_query_ext (inFitsName, dataName, extensionNumber);
00526         if (tempStr != NULL)
00527         {
00528             if (diagnostic)cpl_msg_info(cpl_func,"Scaling Offset = %s\n", tempStr);
00529             if (diagnostic) fprintf (midiReportPtr, "Scaling Offset = %s\n", tempStr);
00530             sscanf (tempStr, "%d", &scalingOffset);
00531             break;
00532         }
00533     }
00534     if (tempStr == NULL)
00535     {
00536         scalingOffset = 0;
00537         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot read Scaling Offset. It is set to 0");
00538     }
00539 
00540     //    Compression starts here
00541     for (region = 0; region < format->numOfDetectorRegions; region++)
00542     {
00543         for (pixel = 0; pixel < format->subWindowSize; pixel++)
00544         {
00545             //    Along the time axis (frame)
00546             numOfUndefinedFrames = 0;
00547             numOfBadFrames = 0;
00548             numOfFramesUsed = 0;
00549             numOfSkyFrames = 0;
00550             if (strcmp (waveCal->filterName[fileNumber], "[ArIII]") == 0)
00551                 (waveCal->ArIII->image)[region][pixel] = 0.0;
00552             else if (strcmp (waveCal->filterName[fileNumber], "[NeII]") == 0)
00553                 (waveCal->NeII->image)[region][pixel] = 0.0;
00554             else if (strcmp (waveCal->filterName[fileNumber], "[SIV]") == 0)
00555                 (waveCal->SIV->image)[region][pixel] = 0.0;
00556             else if (strcmp (waveCal->filterName[fileNumber], "WL-CALIB_2") == 0)
00557                 (waveCal->foil->image)[region][pixel] = 0.0;
00558             else if (strcmp (waveCal->filterName[fileNumber], "OPEN") == 0)
00559                 (waveCal->open->image)[region][pixel] = 0.0;
00560             else if (strcmp (waveCal->filterName[fileNumber], "CLOSED") == 0)
00561                 (waveCal->dark->image)[region][pixel] = 0.0;
00562             else
00563             {
00564                 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Unknown Filter ID");
00565                 *error = 1;
00566                 qfits_table_close (pTable);
00567                 for (region = 0; region < format->numOfDetectorRegions; region++) free (inData[region]);
00568                 free (foundData);
00569                 free (indexData);
00570                 free (dataName);
00571                 return;
00572             }
00573             
00574             for (frame = 0; frame < format->numOfFrames; frame++)
00575             {
00576                 //    Only consider Target, "T" and Sky, "S"
00577                 if (waveCal->tarType[frame] == 'U')
00578                 {
00579                     if (diagnostic && !pixel) 
00580                     {
00581                         sprintf (midiMessage, "Found undefined, 'U'  'TARTYP2' at frame %d of DATA%d in %s", 
00582                             frame+1, region+1, inFitsName);
00583                         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
00584                     }
00585                     numOfUndefinedFrames++;
00586                     continue;
00587                 }
00588                 
00589                 //    Load each pixel data along the time axis
00590                 i = frame * format->subWindowSize + pixel;
00591                 if (isnan (inData[region][i]))
00592                 {
00593                     numOfBadFrames++;
00594                     sprintf (midiMessage, "Found bad pixel %d of DATA%d in %s", i, region, inFitsName);
00595                     midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
00596                 }
00597                 else
00598                 {
00599                     if (waveCal->tarType[frame] == 'S') numOfSkyFrames++;
00600                     numOfFramesUsed++;
00601 
00602                     if (strcmp (waveCal->filterName[fileNumber], "[ArIII]") == 0)
00603                         (waveCal->ArIII->image)[region][pixel] += (float) (inData[region][i]);
00604                     else if (strcmp (waveCal->filterName[fileNumber], "[NeII]") == 0)
00605                         (waveCal->NeII->image)[region][pixel] += (float) (inData[region][i]);
00606                     else if (strcmp (waveCal->filterName[fileNumber], "[SIV]") == 0)
00607                         (waveCal->SIV->image)[region][pixel] += (float) (inData[region][i]);
00608                     else if (strcmp (waveCal->filterName[fileNumber], "WL-CALIB_2") == 0)
00609                         (waveCal->foil->image)[region][pixel] += (float) (inData[region][i]);
00610                     else if (strcmp (waveCal->filterName[fileNumber], "OPEN") == 0)
00611                         (waveCal->open->image)[region][pixel] += (float) (inData[region][i]);
00612                     else if (strcmp (waveCal->filterName[fileNumber], "CLOSED") == 0)
00613                         (waveCal->dark->image)[region][pixel] += (float) (inData[region][i]);
00614                     else
00615                     {
00616                         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Unknown Filter ID");
00617                         *error = 1;
00618                         qfits_table_close (pTable);
00619                         for (region = 0; region < format->numOfDetectorRegions; region++) free (inData[region]);
00620                         free (foundData);
00621                         free (indexData);
00622                         free (dataName);
00623                         return;
00624                     }
00625                 }
00626             }
00627 
00628             //    Compute average image
00629             if (diagnostic && !pixel)
00630             {
00631                cpl_msg_info(cpl_func,"\nData Statistics \n");
00632                cpl_msg_info(cpl_func,"--------------- \n");
00633                cpl_msg_info(cpl_func,"Number of frames used in DATA%d      = %d \n", region+1, numOfFramesUsed);
00634                cpl_msg_info(cpl_func,"Number of Sky frames in DATA%d       = %d \n", region+1, numOfSkyFrames);
00635                cpl_msg_info(cpl_func,"Number of Bad frames in DATA%d       = %d \n", region+1, numOfBadFrames);
00636                cpl_msg_info(cpl_func,"Number of Undefined frames in DATA%d = %d \n", region+1, numOfUndefinedFrames);
00637                 fprintf (midiReportPtr, "\nData Statistics \n");
00638                 fprintf (midiReportPtr, "--------------- \n");
00639                 fprintf (midiReportPtr, "Number of frames used in DATA%d      = %d \n", region+1, numOfFramesUsed);
00640                 fprintf (midiReportPtr, "Number of Sky frames in DATA%d       = %d \n", region+1, numOfSkyFrames);
00641                 fprintf (midiReportPtr, "Number of Bad frames in DATA%d       = %d \n", region+1, numOfBadFrames);
00642                 fprintf (midiReportPtr, "Number of Undefined frames in DATA%d = %d \n", region+1, numOfUndefinedFrames);
00643             }
00644             if (numOfFramesUsed)
00645             {
00646                 if (strcmp (waveCal->filterName[fileNumber], "[ArIII]") == 0)
00647                 {
00648                     (waveCal->ArIII->image)[region][pixel] /= numOfFramesUsed;
00649                     (waveCal->ArIII->image)[region][pixel] += scalingOffset;
00650                 }
00651                 else if (strcmp (waveCal->filterName[fileNumber], "[NeII]") == 0)
00652                 {
00653                     (waveCal->NeII->image)[region][pixel] /= numOfFramesUsed;
00654                     (waveCal->NeII->image)[region][pixel] += scalingOffset;
00655                 }
00656                 else if (strcmp (waveCal->filterName[fileNumber], "[SIV]") == 0)
00657                 {
00658                     (waveCal->SIV->image)[region][pixel] /= numOfFramesUsed;
00659                     (waveCal->SIV->image)[region][pixel] += scalingOffset;
00660                 }
00661                 else if (strcmp (waveCal->filterName[fileNumber], "WL-CALIB_2") == 0)
00662                 {
00663                     (waveCal->foil->image)[region][pixel] /= numOfFramesUsed;
00664                     (waveCal->foil->image)[region][pixel] += scalingOffset;
00665                 }
00666                 else if (strcmp (waveCal->filterName[fileNumber], "OPEN") == 0)
00667                 {
00668                     (waveCal->open->image)[region][pixel] /= numOfFramesUsed;
00669                     (waveCal->open->image)[region][pixel] += scalingOffset;
00670                 }
00671                 else if (strcmp (waveCal->filterName[fileNumber], "CLOSED") == 0)
00672                 {
00673                     (waveCal->dark->image)[region][pixel] /= numOfFramesUsed;
00674                     (waveCal->dark->image)[region][pixel] += scalingOffset;
00675                 }
00676                 else
00677                 {
00678                     midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Unknown Filter ID");
00679                     *error = 1;
00680                     qfits_table_close (pTable);
00681                     for (region = 0; region < format->numOfDetectorRegions; region++) free (inData[region]);
00682                     free (foundData);
00683                     free (indexData);
00684                     free (dataName);
00685                     return;
00686                 }
00687             }
00688         }
00689     }
00690 
00691     //    Clean up now:
00692     for (region = 0; region < format->numOfDetectorRegions; region++) free (inData[region]);
00693     if (pTable) qfits_table_close (pTable);
00694     if (inTarType) free(inTarType);
00695     free (inData);
00696     free (foundData);
00697     free (indexData);
00698     free (dataName);
00699 
00700     return; 
00701 }
00702 /*****************************************************************************/
00703 
00704 
00705 /******************************************************************************
00706 *               European Southern Observatory
00707 *          VLTI MIDI Maintenance Templates Software
00708 *
00709 * Module name:  validateWaveCalData
00710 * Input/Output: See function arguments to avoid duplication
00711 * Description:  Validates the input data
00712 *
00713 * History:      
00714 * 13-Jun-05     (csabet) Created
00715 ******************************************************************************/
00716 void validateWaveCalData (
00717     int                fileNumber,        // In: File number
00718     char            *fileName,        // In: Input FITS name
00719     WaveCalibration    *compressed,    // In: Compressed data
00720     ImageFormat        *format,        // In: File format 
00721     int                *error)            // Ou: Error status
00722 
00723 {
00724 
00725     //  Local Declarations
00726     //    ------------------
00727     const char  routine[] = "validateWaveCalData";
00728     int            region;
00729     char        *title=NULL, *fileString=NULL;
00730 
00731     //  Algorithm
00732     //    ---------
00733     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
00734     if (diagnostic > 4) fprintf (midiReportPtr, "Invoking      routine   '%s' \n", routine);
00735     
00736     //    Reset status
00737     *error = 0;
00738     
00739     //    Allocate memory
00740     title = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00741     fileString = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00742 
00743     //    Analyse Raw Images
00744     if (strcmp (compressed->filterName[fileNumber], "[ArIII]") == 0)
00745     {
00746         //    Save file name
00747         sprintf (compressed->ArIII->fileName, "%s", fileName);
00748 
00749         for (region = 0; region < format->numOfDetectorRegions; region++)
00750         {
00751             
00752             //    Create Raw Image FITS files
00753             if (diagnostic)
00754             {
00755                 sprintf (fileString , "region %d", region+1);
00756                 sprintf (title , "AveRawImgArIIIDATA%d", region+1);
00757                 createFitsImage (fileString, title, fileName, format->iXWidth, format->iYWidth, 
00758                     (compressed->ArIII->image)[region]);
00759     
00760                 if (plotFile)
00761                 {
00762                     sprintf (fileString, "3dAveRawImgArIIIDATA%d", region+1);
00763                     sprintf (title, "[ArIII] Raw, averaged along time, Region %d", region+1);
00764                     midiCreatePlotFile3D (fileString, title, "X", "Y", "Flux", 0, 
00765                         (compressed->ArIII->image)[region], format->iXWidth, format->iYWidth, "lines", "3");
00766                 }
00767             }
00768         }
00769     }
00770     else if (strcmp (compressed->filterName[fileNumber], "[NeII]") == 0)
00771     {
00772         //    Save file name
00773         sprintf (compressed->NeII->fileName, "%s", fileName);
00774 
00775         for (region = 0; region < format->numOfDetectorRegions; region++)
00776         {            
00777             //    Create Raw Image FITS files
00778             if (diagnostic)
00779             {
00780                 sprintf (fileString , "region %d", region+1);
00781                 sprintf (title , "AveRawImgNeIIDATA%d", region+1);
00782                 createFitsImage (fileString, title, fileName, format->iXWidth, format->iYWidth, 
00783                     (compressed->NeII->image)[region]);
00784     
00785                 if (plotFile)
00786                 {
00787                     sprintf (fileString, "3dAveRawImgNeIIDATA%d", region+1);
00788                     sprintf (title, "[NeII] Raw, averaged along time, Region %d", region+1);
00789                     midiCreatePlotFile3D (fileString, title, "X", "Y", "Flux", 0, 
00790                         (compressed->NeII->image)[region], format->iXWidth, format->iYWidth, "lines", "3");
00791                 }
00792             }
00793         }
00794     }
00795     else if (strcmp (compressed->filterName[fileNumber], "[SIV]") == 0)
00796     {
00797         //    Save file name
00798         sprintf (compressed->SIV->fileName, "%s", fileName);
00799             
00800         for (region = 0; region < format->numOfDetectorRegions; region++)
00801         {
00802             //    Create Raw Image FITS files
00803             if (diagnostic)
00804             {
00805                 sprintf (fileString , "region %d", region+1);
00806                 sprintf (title , "AveRawImgSIVDATA%d", region+1);
00807                 createFitsImage (fileString, title, fileName, format->iXWidth, format->iYWidth, 
00808                     (compressed->SIV->image)[region]);
00809     
00810                 if (plotFile)
00811                 {
00812                     sprintf (fileString, "3dAveRawImgSIVDATA%d", region+1);
00813                     sprintf (title, "[SIV] Raw, averaged along time, Region %d", region+1);
00814                     midiCreatePlotFile3D (fileString, title, "X", "Y", "Flux", 0, 
00815                         (compressed->SIV->image)[region], format->iXWidth, format->iYWidth, "lines", "3");
00816                 }
00817             }
00818         }
00819     }
00820     else if (strcmp (compressed->filterName[fileNumber], "WL-CALIB_2") == 0)
00821     {
00822         //    Save file name
00823         sprintf (compressed->foil->fileName, "%s", fileName);
00824             
00825         for (region = 0; region < format->numOfDetectorRegions; region++)
00826         {
00827             //    Create Raw Image FITS files
00828             if (diagnostic)
00829             {
00830                 sprintf (fileString , "region %d", region+1);
00831                 sprintf (title , "AveRawImgFoilDATA%d", region+1);
00832                 createFitsImage (fileString, title, fileName, format->iXWidth, format->iYWidth, 
00833                     (compressed->foil->image)[region]);
00834     
00835                 if (plotFile)
00836                 {
00837                     sprintf (fileString, "3dAveRawImgFoilDATA%d", region+1);
00838                     sprintf (title, "Foil Raw, averaged along time, Region %d", region+1);
00839                     midiCreatePlotFile3D (fileString, title, "X", "Y", "Flux", 0, 
00840                         (compressed->foil->image)[region], format->iXWidth, format->iYWidth, "lines", "3");
00841                 }
00842             }
00843         }
00844     }
00845     else if (strcmp (compressed->filterName[fileNumber], "OPEN") == 0)
00846     {
00847         //    Save file name
00848         sprintf (compressed->open->fileName, "%s", fileName);
00849             
00850         for (region = 0; region < format->numOfDetectorRegions; region++)
00851         {
00852             //    Create Raw Image FITS files
00853             if (diagnostic)
00854             {
00855                 sprintf (fileString , "region %d", region+1);
00856                 sprintf (title , "AveRawImgOpenDATA%d", region+1);
00857                 createFitsImage (fileString, title, fileName, format->iXWidth, format->iYWidth, 
00858                     (compressed->open->image)[region]);
00859     
00860                 if (plotFile)
00861                 {
00862                     sprintf (fileString, "3dAveRawImgOpenDATA%d", region+1);
00863                     sprintf (title, "Open Raw, averaged along, Region %d", region+1);
00864                     midiCreatePlotFile3D (fileString, title, "X", "Y", "Flux", 0, 
00865                         (compressed->open->image)[region], format->iXWidth, format->iYWidth, "lines", "3");
00866                 }
00867             }
00868         }
00869     }
00870     else if (strcmp (compressed->filterName[fileNumber], "CLOSED") == 0)
00871     {
00872         //    Save file name
00873         sprintf (compressed->dark->fileName, "%s", fileName);
00874             
00875         for (region = 0; region < format->numOfDetectorRegions; region++)
00876         {
00877             //    Create Raw Image FITS files
00878             if (diagnostic)
00879             {
00880                 sprintf (fileString , "region %d", region+1);
00881                 sprintf (title , "AveRawImgDarkDATA%d", region+1);
00882                 createFitsImage (fileString, title, fileName, format->iXWidth, format->iYWidth, 
00883                     (compressed->dark->image)[region]);
00884     
00885                 if (plotFile)
00886                 {
00887                     sprintf (fileString, "3dAveRawImgDarkDATA%d", region+1);
00888                     sprintf (title, "Dark Raw, averaged along time, Region %d", region+1);
00889                     midiCreatePlotFile3D (fileString, title, "X", "Y", "Flux", 0, 
00890                         (compressed->dark->image)[region], format->iXWidth, format->iYWidth, "lines", "3");
00891                 }
00892             }
00893         }
00894     }
00895     else
00896     {
00897         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Unknown Filter ID");
00898         *error = 1;
00899         free (title);
00900         free (fileString);
00901         return;
00902     }
00903 
00904 
00905     //    Release memory
00906     free (title);
00907     free (fileString);
00908     
00909     return; 
00910 }
00911 /*****************************************************************************/
00912 
00913 
00914 /******************************************************************************
00915 *               European Southern Observatory
00916 *          VLTI MIDI Maintenance Templates Software
00917 *
00918 * Module name:  getWlCalib2Spectra
00919 * Input/Output: See function arguments to avoid duplication
00920 * Description:  Get WL-CALIB_2 spectra. Returns -1 if error
00921 *
00922 * History:      
00923 * 20-Jun-05     (csabet) Created
00924 ******************************************************************************/
00925 int getWlCalib2Spectra (
00926     MidiFiles    *fileNames,    // In: Pointer to file names
00927     int            *error)        // Ou: Error status
00928 
00929 {
00930 
00931     //  Local Declarations
00932     //    ------------------
00933     const char  routine[] = "getWlCalib2Spectra";
00934     FILE        *wlFilePtr=NULL;
00935     int            numOfRecords;
00936     char        *filePath, *tempString;
00937     float        elem1, elem2;
00938 
00939     //  Algorithm
00940     //    ---------
00941     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
00942     if (diagnostic > 4) fprintf (midiReportPtr, "Invoking      routine   '%s' \n", routine);
00943     
00944     //    Reset status
00945     *error = 0;
00946     numOfRecords = 0;
00947 
00948     //    Allocate memory
00949     filePath = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00950     tempString = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00951 
00952     //    Check the tracing record for WL-CALIB_2 foil
00953     //    --------------------------------------------
00954     sprintf (filePath, "%swl-calib_2.dat", fileNames->calibDbDir);
00955     if ((wlFilePtr = fopen (filePath, "r")) == NULL)
00956     {
00957         sprintf (midiMessage, "Cannot Open %s", filePath);
00958         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
00959         free (filePath);
00960         free (tempString);
00961         *error = 1;
00962         return (-1);
00963     }
00964     //    Ignore first record which gives the title of the data file
00965     fgets (tempString, MAX_STRING_LENGTH, wlFilePtr);
00966     sprintf (midiMessage, "Counting elements in %s", tempString);
00967     midiReportInfo (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
00968     while (fscanf (wlFilePtr, "%f %f\n", &elem1, &elem2) != EOF) 
00969         numOfRecords++;
00970     sprintf (midiMessage, "WL-CALIB_2 has %d pairs of 'float'(s)", numOfRecords);
00971     midiReportInfo (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
00972     fclose (wlFilePtr);
00973 
00974     //    Release memory
00975     free (filePath);
00976     free (tempString);
00977     
00978     return (numOfRecords); 
00979 }
00980 /*****************************************************************************/
00981 
00982 
00983 
00984 /******************************************************************************
00985 *               European Southern Observatory
00986 *          VLTI MIDI Maintenance Templates Software
00987 *
00988 * Module name:  removeDark
00989 * Input/Output: See function arguments to avoid duplication
00990 * Description:  Extracts all the necessary resources for calibration
00991 *
00992 * History:      
00993 * 14-June-05    (csabet) Created
00994 ******************************************************************************/
00995 void removeDark (
00996     ImageFormat        *format,    // In: File format 
00997     WaveCalibration    *waveCal,    // In: Compressed data
00998     int                *error)        // Ou: Error status
00999 
01000 {
01001 
01002     //  Local Declarations
01003     //    ------------------
01004     const char    routine[] = "removeDark";
01005     int            region, pixel;
01006     char        *title=NULL, *fileString=NULL;
01007     
01008     //  Algorithm
01009     //    ---------
01010     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
01011     if (diagnostic > 4) fprintf (midiReportPtr, "Invoking      routine   '%s' \n", routine);
01012 
01013     //    Reset status
01014     *error = 0;
01015 
01016     //    Allocate memory
01017     title = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
01018     fileString = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
01019 
01020     //    Get images with dark subtracted
01021     for (region = 0; region < format->numOfDetectorRegions; region++)
01022     {
01023         for (pixel = 0; pixel < format->subWindowSize; pixel++)
01024         {
01025             (waveCal->ArIII->image)[region][pixel] -= (waveCal->dark->image)[region][pixel];
01026             (waveCal->NeII->image)[region][pixel] -= (waveCal->dark->image)[region][pixel];
01027             (waveCal->SIV->image)[region][pixel] -= (waveCal->dark->image)[region][pixel];
01028             (waveCal->foil->image)[region][pixel] -= (waveCal->dark->image)[region][pixel];
01029             (waveCal->open->image)[region][pixel] -= (waveCal->dark->image)[region][pixel];
01030         }
01031     }
01032         
01033     //    Create Image FITS files
01034     for (region = 0; region < format->numOfDetectorRegions; region++)
01035     {
01036         sprintf (fileString , "region %d", region+1);
01037         sprintf (title , "AveImgArIIIDATA%d", region+1);
01038         createFitsImage (fileString, title, waveCal->ArIII->fileName, format->iXWidth, format->iYWidth, 
01039             (waveCal->ArIII->image)[region]);
01040     }
01041 
01042     for (region = 0; region < format->numOfDetectorRegions; region++)
01043     {
01044         sprintf (fileString , "region %d", region+1);
01045         sprintf (title , "AveImgNeIIDATA%d", region+1);
01046         createFitsImage (fileString, title, waveCal->NeII->fileName, format->iXWidth, format->iYWidth, 
01047             (waveCal->NeII->image)[region]);
01048     }
01049 
01050     for (region = 0; region < format->numOfDetectorRegions; region++)
01051     {
01052         sprintf (fileString , "region %d", region+1);
01053         sprintf (title , "AveImgSIVDATA%d", region+1);
01054         createFitsImage (fileString, title, waveCal->SIV->fileName, format->iXWidth, format->iYWidth, 
01055             (waveCal->SIV->image)[region]);
01056     }
01057     
01058     for (region = 0; region < format->numOfDetectorRegions; region++)
01059     {
01060         sprintf (fileString , "region %d", region+1);
01061         sprintf (title , "AveImgFoilDATA%d", region+1);
01062         createFitsImage (fileString, title, waveCal->foil->fileName, format->iXWidth, format->iYWidth, 
01063             (waveCal->foil->image)[region]);
01064     }
01065     
01066     for (region = 0; region < format->numOfDetectorRegions; region++)
01067     {
01068         sprintf (fileString , "region %d", region+1);
01069         sprintf (title , "AveImgOpenDATA%d", region+1);
01070         createFitsImage (fileString, title, waveCal->open->fileName, format->iXWidth, format->iYWidth, 
01071             (waveCal->open->image)[region]);
01072     }
01073 
01074     //    Create 3D plots
01075     if (plotFile)
01076     {
01077         for (region = 0; region < format->numOfDetectorRegions; region++)
01078         {
01079             sprintf (fileString, "3dAveImgArIIIDATA%d", region+1);
01080             sprintf (title, "[ArIII] Dark removed, averaged along time, Region %d", region+1);
01081             midiCreatePlotFile3D (fileString, title, "X", "Y", "Flux", 0, 
01082                 (waveCal->ArIII->image)[region], format->iXWidth, format->iYWidth, "lines", "3");
01083         }
01084 
01085         for (region = 0; region < format->numOfDetectorRegions; region++)
01086         {
01087             sprintf (fileString, "3dAveImgNeIIDATA%d", region+1);
01088             sprintf (title, "[NeII] Dark removed, averaged along time, Region %d", region+1);
01089             midiCreatePlotFile3D (fileString, title, "X", "Y", "Flux", 0, 
01090                 (waveCal->NeII->image)[region], format->iXWidth, format->iYWidth, "lines", "3");
01091         }
01092 
01093         for (region = 0; region < format->numOfDetectorRegions; region++)
01094         {
01095             sprintf (fileString, "3dAveImgSIVDATA%d", region+1);
01096             sprintf (title, "[SIV] Dark removed, averaged along time, Region %d", region+1);
01097             midiCreatePlotFile3D (fileString, title, "X", "Y", "Flux", 0, 
01098                 (waveCal->SIV->image)[region], format->iXWidth, format->iYWidth, "lines", "3");
01099         }
01100 
01101         for (region = 0; region < format->numOfDetectorRegions; region++)
01102         {
01103             sprintf (fileString, "3dAveImgFoilDATA%d", region+1);
01104             sprintf (title, "Foil Dark removed, averaged along time, Region %d", region+1);
01105             midiCreatePlotFile3D (fileString, title, "X", "Y", "Flux", 0, 
01106                 (waveCal->foil->image)[region], format->iXWidth, format->iYWidth, "lines", "3");
01107         }
01108 
01109         for (region = 0; region < format->numOfDetectorRegions; region++)
01110         {
01111             sprintf (fileString, "3dAveImgOpenDATA%d", region+1);
01112             sprintf (title, "Open Dark removed, averaged along time, Region %d", region+1);
01113             midiCreatePlotFile3D (fileString, title, "X", "Y", "Flux", 0, 
01114                 (waveCal->open->image)[region], format->iXWidth, format->iYWidth, "lines", "3");
01115         }
01116     }
01117         
01118     //    Release memory
01119     free (title);
01120     free (fileString);
01121 
01122     return; 
01123 }
01124 /*****************************************************************************/
01125 
01126 
01127 
01128 /******************************************************************************
01129 *               European Southern Observatory
01130 *          VLTI MIDI Maintenance Templates Software
01131 *
01132 * Module name:  calibrateWaveChannels
01133 * Input/Output: See function arguments to avoid duplication
01134 * Description:  Perform the final wavelength calibration. 
01135 *                1.    From the three filter files get three wavelengths for three channels.
01136 *                    A linear fit gives the function (table) Wavelength [X], X = 0, N
01137 *                    where N is the number of channels
01138 *
01139 *               Filter  Pk Freq.        Pk Wavelength
01140 *                ======================================
01141 *                NeII    2.34297e+13 Hz  12.7955  micron
01142 *                SIV     2.85818e+13 Hz  10.489   micron
01143 *                ArIII   3.33005e+13 Hz   9.00272 micron
01144 *
01145 *                2.     From the polycarbonate foil template, get the function (table) 
01146 *                    Flux [x], x = 0, N,    where N is the number of channels.
01147 *
01148 *                3.    From the manufacturer's table get the function (table) 
01149 *                    Flux [l], l = 0, W,    where W is the number of wavelength positions
01150 *
01151 * History:      
01152 * 14-June-05    (csabet) 
01153 ******************************************************************************/
01154 void calibrateWaveChannels (
01155     int                processing,    // In: Correlate = 1, Create = 2
01156     MidiFiles        *fileNames,    // In: Pointer to file names
01157     WaveCalibration *waveCal,    // Ou: Pointer to the Wavelength Calibration data structure
01158     ImageFormat        *format,    // In: Pointer to the image format
01159     int                *error)        // Ou: Error status
01160 
01161 {
01162 
01163     //  Local Declarations
01164     //    ------------------
01165     const char    routine[] = "calibrateWaveChannels";
01166 
01167     //  Algorithm
01168     //    ---------
01169     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
01170     if (diagnostic > 4) fprintf (midiReportPtr, "Invoking      routine   '%s' \n", routine);
01171 
01172     //    Reset status
01173     *error = 0;
01174 
01175     //    Fitting of Filter Spectra
01176     fitFilterSpectra (waveCal, format, error);
01177 
01178     //    Get approximate channel assignment
01179     calibrateWaveFromNBF (waveCal, format, error);
01180     if (*error) return;
01181         
01182     //    Fitting of Foil Spectra frequency
01183     fitFoilSpectra (fileNames, waveCal, format, error);
01184     
01185     //    Fitting of Open Spectra
01186     fitOpenSpectra (error);
01187     
01188     //    Create frequency calibration database
01189     if (processing == 2) createWaveCalibDB (fileNames, waveCal, format, error);
01190     else correlateWaveCalibDB (fileNames, waveCal, format, error);
01191     
01192     return; 
01193 }
01194 /*****************************************************************************/
01195 
01196 
01197 /******************************************************************************
01198 *               European Southern Observatory
01199 *          VLTI MIDI Maintenance Templates Software
01200 *
01201 * Module name:  calibrateWaveFromNBF
01202 * Input/Output: See function arguments to avoid duplication
01203 * Description:  Creates an approximate wavelength calibration file based on the
01204 *                Narrow Band Filter (NBF) spectra only
01205 *
01206 * History:      
01207 * 08-Sep-05    (csabet)
01208 ******************************************************************************/
01209 void calibrateWaveFromNBF (
01210     WaveCalibration *waveCal,    // Ou: Pointer to the Wavelength Calibration data structure
01211     ImageFormat        *format,    // In: Pointer to the image format
01212     int                *error)        // Ou: Error status
01213 
01214 {
01215 
01216     //  Local Declarations
01217     //    ------------------
01218     const char    routine[] = "calibrateWaveFromNBF";
01219     int            region, *channel, chA, chN, chS, numOfNBF, order;
01220     float        *wave, *chFloat;
01221     char        *fileString, *title;
01222     
01223     //  Algorithm
01224     //    ---------
01225     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
01226     if (diagnostic > 4) fprintf (midiReportPtr, "Invoking      routine   '%s' \n", routine);
01227 
01228     //    Reset status
01229     *error = 0;
01230     numOfNBF = 3;
01231 
01232     //    Allocate memory
01233     channel = (int *) calloc (numOfNBF, sizeof (int));
01234     wave = (float *) calloc (numOfNBF, sizeof (float));
01235     
01236     for (region = 0; region < format->numOfDetectorRegions; region++)
01237     {
01238         //    Sort channels
01239         channel[0] = (waveCal->ArIII->xCoord)[region];
01240         channel[1] = (waveCal->NeII->xCoord)[region];
01241         channel[2] = (waveCal->SIV->xCoord)[region];
01242         chA = (waveCal->ArIII->xCoord)[region];
01243         chN = (waveCal->NeII->xCoord)[region];
01244         chS = (waveCal->SIV->xCoord)[region];
01245         signalSortInt (channel, 0, numOfNBF);
01246 
01247         //    Correct alignment
01248         if (channel[0] == chA) wave[0] = (waveCal->ArIII->wavelength)[region];
01249         else if (channel[0] == chN) wave[0] = (waveCal->NeII->wavelength)[region];
01250         else wave[0] = (waveCal->SIV->wavelength)[region];
01251         
01252         if (channel[1] == chA) wave[1] = (waveCal->ArIII->wavelength)[region];
01253         else if (channel[1] == chN) wave[1] = (waveCal->NeII->wavelength)[region];
01254         else wave[1] = (waveCal->SIV->wavelength)[region];
01255         
01256         if (channel[2] == chA) wave[2] = (waveCal->ArIII->wavelength)[region];
01257         else if (channel[2] == chN) wave[2] = (waveCal->NeII->wavelength)[region];
01258         else wave[2] = (waveCal->SIV->wavelength)[region];
01259         
01260         if (plotFile)
01261         {
01262             chFloat = (float *) calloc (3, sizeof (float));
01263             chFloat[0] = (float) channel[0];
01264             chFloat[1] = (float) channel[1];
01265             chFloat[2] = (float) channel[2];
01266             fileString = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
01267             title = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
01268             sprintf (fileString , "NarrowBandFilterSectionalProfileDATA%d", region+1);
01269             sprintf (title , "Narrow Band Filter Sectional Profile Region %d", region+1);
01270             midiCreatePlotFile2D2P (fileString, title, "Detector Channel", "Wavelength in micron", 0, chFloat, wave, 0, 3, 1);
01271             free (fileString);
01272             free (title);
01273             free (chFloat);
01274         }
01275 
01276         //    Calibrate using a polynomial fit of order 
01277        cpl_msg_info(cpl_func,"\nCalibrating wavelength for region %d \n", region+1);
01278        cpl_msg_info(cpl_func,"--------------------------------- \n");
01279         fprintf (midiReportPtr, "\nCalibrating wavelength for region %d \n", region+1);
01280         fprintf (midiReportPtr, "--------------------------------- \n");
01281         order = 22;
01282         midiPolyFit (order, channel, wave, numOfNBF, format->iXWidth, waveCal->calibratedWave[region], error);
01283         if (*error)
01284         {
01285             midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot Calibrate");
01286             free (channel);
01287             free (wave);
01288             return;
01289         }
01290         
01291         if (plotFile)
01292         {
01293             fileString = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
01294             title = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
01295             sprintf (fileString , "CalibrationUsingPoly%dFitDATA%d", order/10, region+1);
01296             sprintf (title , "Calibration using a Polynomial fit of order %d for Region %d", order/10, region+1);
01297             midiCreatePlotFile2D (fileString, title, "Detector Channel", "Wavelength in micron", 
01298                 0, waveCal->calibratedWave[region], 0, format->iXWidth, 1, 0);
01299             free (fileString);
01300             free (title);
01301         }
01302     }
01303     
01304     //    Release memory
01305     free (channel);
01306     free (wave);
01307     
01308     return; 
01309 }
01310 /*****************************************************************************/
01311 
01312 
01313 
01314 
01315 /******************************************************************************
01316 *               European Southern Observatory
01317 *          VLTI MIDI Maintenance Templates Software
01318 *
01319 * Module name:  midiPolyFit
01320 * Input/Output: See function arguments to avoid duplication
01321 * Description:  A polynomial fit of various orders. We use two simple (fast)
01322 *                but specific routines together with two general methods as follows:
01323 *                10        Simple and fast first order (for diagnostics only)
01324 *                20        Simple and fast 2nd order deterministic (for diagnostics only)
01325 *                11        First order based on minimising chi-squared. Returns full set of statistics
01326 *                22        Second order returning Mean Squared Error only
01327 *
01328 * History:      
01329 * 14-June-05    (csabet)
01330 ******************************************************************************/
01331 void midiPolyFit (
01332     int        order,        // In: Order (see above)
01333     int        *xCoord,    // In: Array of elements along X
01334     float    *yCoord,    // In: array of elements along Y
01335     int        numOfIn,    // In: Number of input points
01336     int        numOfOut,    // In: Number of output points
01337     float    *yOut,        // Ou: Pointer to the output result
01338     int        *error)        // Ou: Error status
01339 
01340 {
01341 
01342     //  Local Declarations
01343     //    ------------------
01344     const char        routine[] = "midiPolyFit";
01345     float            x1, x1s, x2, x2s, x3, x3s, y1, y2, y3, d, d1, d2, d3, 
01346                     coeff1, coeff2, coeff3, q, chi2, siga, sigb, sigc, sigData;
01347     cpl_polynomial  *coeffPoly;
01348     cpl_vector        *xPoly, *yPoly;
01349     int                i, degPoly, power, sigDataAvailable;
01350     double            *valuePloy,    *positionPoly, mse;
01351 
01352 
01353     //  Algorithm
01354     //    ---------
01355     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
01356     if (diagnostic > 4) fprintf (midiReportPtr, "Invoking      routine   '%s' \n", routine);
01357 
01358     //    Reset status
01359     *error = 0;
01360     coeff1=coeff2=coeff3=0.0;
01361     siga=sigb=sigc=chi2=q=mse=-1;
01362 
01363     //    Exception
01364     if (order == 10)
01365     {
01366        cpl_msg_info(cpl_func,"Fitting %d points to %d points using Fast-Simple 1st order polynomial \n", numOfIn, numOfOut);
01367         fprintf (midiReportPtr, "Fitting %d points to %d points using Fast-Simple 1st order polynomial \n", numOfIn, numOfOut);
01368 
01369         //    Assign short form
01370         x1 = xCoord[0];
01371         x2 = xCoord[1];
01372         x3 = xCoord[2];
01373         y1 = yCoord[0];
01374         y2 = yCoord[1];
01375         y3 = yCoord[2];
01376     
01377         //    Coefficients for a line going through extreme points are
01378         coeff1 = y1 - x1 * ((y3 - y1) / (x3 - x1));
01379         coeff2 = (y3 - y1) / (x3 - x1);
01380         if (diagnostic)cpl_msg_info(cpl_func,"Initial coefficients are: %f %f \n", coeff1, coeff2);
01381         if (diagnostic) fprintf (midiReportPtr, "Initial coefficients are: %f %f \n", coeff1, coeff2);
01382         
01383         //    Distance of middle point is
01384         d = fabs ((coeff2 * x2 - y2 + coeff1) / sqrt (coeff2 * coeff2 + 1));
01385         
01386         //    Update coeff1 for half the distance
01387         coeff1 = 0.5 * d * sqrt(coeff2 * coeff2 + 1) - coeff2 * x2 + y2;
01388     }
01389     else if (order == 20)
01390     {
01391        cpl_msg_info(cpl_func,"Fitting %d points to %d points using Fast-Simple 2nd order polynomial \n", numOfIn, numOfOut);
01392         fprintf (midiReportPtr, "Fitting %d points to %d points using Fast-Simple 2nd order polynomial \n", numOfIn, numOfOut);
01393 
01394         //    Assign short form
01395         x1 = xCoord[0];
01396         x2 = xCoord[1];
01397         x3 = xCoord[2];
01398         x1s = xCoord[0] * xCoord[0];
01399         x2s = xCoord[1] * xCoord[1];
01400         x3s = xCoord[2] * xCoord[2];
01401         y1 = yCoord[0];
01402         y2 = yCoord[1];
01403         y3 = yCoord[2];
01404     
01405         d = (x2 * x3s - x2s * x3) - x1 * (x3s - x2s) + x1s * (x3 - x2);
01406         d1 = y1 * (x2 * x3s - x2s * x3) - x1 * (y2 * x3s - x2s * y3) + x1s * (y2 * x3 - x2 * y3);
01407         d2 = (y2 * x3s - x2s * y3) - y1 * (x3s - x2s) + x1s * (y3 - y2);
01408         d3 = (x2 * y3 - y2 * x3) - x1 * (y3 - y2) + y1 * (x3 - x2);
01409     
01410         coeff1 = d1/d;
01411         coeff2 = d2/d;
01412         coeff3 = d3/d;
01413     }
01414     else if (order == 11)
01415     {
01416        cpl_msg_info(cpl_func,"Fitting %d points to %d points using 1st order polynomial \n", numOfIn, numOfOut);
01417         fprintf (midiReportPtr, "Fitting %d points to %d points using 1st order polynomial \n", numOfIn, numOfOut);
01418 
01419         //    Load input data
01420         valuePloy = (double *) calloc (numOfIn, sizeof (double));
01421         positionPoly = (double *) calloc (numOfIn, sizeof (double));
01422         for (i = 0; i < numOfIn; i++)
01423         {
01424             positionPoly[i] = (double) (xCoord[i]);
01425             valuePloy[i] = (double) (yCoord[i]);
01426         }
01427 
01428         //    We assume no knowledge of standard deviation on input data
01429         sigData = 0.0;
01430         sigDataAvailable = 0;
01431         midiGetLinearFit (positionPoly, valuePloy, numOfIn, sigData, sigDataAvailable, 
01432             &coeff1, &coeff2, &siga, &sigb, &chi2, &q, error);
01433         free (positionPoly);
01434         free (valuePloy);
01435         if (*error)
01436         {
01437             sprintf (midiMessage, "Cannot compute linear fit in routine '%s'", routine);
01438             midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
01439             return;
01440         }
01441     }
01442     else if (order == 22)
01443     {
01444        cpl_msg_info(cpl_func,"Fitting %d points to %d points using 2nd order polynomial \n", numOfIn, numOfOut);
01445         fprintf (midiReportPtr, "Fitting %d points to %d points using 2nd order polynomial \n", numOfIn, numOfOut);
01446     
01447         //    Load input data
01448         valuePloy = (double *) calloc (numOfIn, sizeof (double));
01449         positionPoly = (double *) calloc (numOfIn, sizeof (double));
01450         for (i = 0; i < numOfIn; i++)
01451         {
01452             positionPoly[i] = (double) (xCoord[i]);
01453             valuePloy[i] = (double) (yCoord[i]);
01454         }
01455 
01456         degPoly = 2;
01457         xPoly = cpl_vector_wrap (numOfIn, positionPoly);
01458         yPoly = cpl_vector_wrap (numOfIn, valuePloy);
01459         coeffPoly = midi_polynomial_fit_1d_create (xPoly, yPoly, degPoly, &mse);
01460         power = 0;
01461         coeff1 = cpl_polynomial_get_coeff (coeffPoly, &power);
01462         power = 1;
01463         coeff2 = cpl_polynomial_get_coeff (coeffPoly, &power);
01464         power = 2;
01465         coeff3 = cpl_polynomial_get_coeff (coeffPoly, &power);
01466 
01467         //    Release memory
01468         cpl_vector_unwrap (xPoly);
01469         cpl_vector_unwrap (yPoly);
01470         cpl_polynomial_delete (coeffPoly);
01471         free (positionPoly);
01472         free (valuePloy);
01473     }
01474     else
01475     {
01476         *error = 1;
01477         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Invalid polynomial order");
01478         return;
01479     }
01480 
01481    cpl_msg_info(cpl_func,"Coeffient 1, Uncertainty = (%f, %f) \n", coeff1, siga);
01482    cpl_msg_info(cpl_func,"Coeffient 2, Uncertainty = (%f, %f) \n", coeff2, sigb);
01483    cpl_msg_info(cpl_func,"Coeffient 3, Uncertainty = (%f, %f) \n", coeff3, sigc);
01484    cpl_msg_info(cpl_func,"Mean Squared Error       = %g \n", mse);
01485    cpl_msg_info(cpl_func,"Chi-squared              = %f \n", chi2);
01486    cpl_msg_info(cpl_func,"Goodness-of-fit          = %f \n", q);
01487     fprintf (midiReportPtr, "Coeffient 1, Uncertainty = (%f, %f) \n", coeff1, siga);
01488     fprintf (midiReportPtr, "Coeffient 2, Uncertainty = (%f, %f) \n", coeff2, sigb);
01489     fprintf (midiReportPtr, "Coeffient 3, Uncertainty = (%f, %f) \n", coeff3, sigc);
01490     fprintf (midiReportPtr, "Mean Squared Error       = %g \n", mse);
01491     fprintf (midiReportPtr, "Chi-squared              = %f \n", chi2);
01492     fprintf (midiReportPtr, "Goodness-of-fit          = %f \n", q);
01493     
01494    cpl_msg_info(cpl_func,"NB. negative values for the statistics indicate unavailability \n");
01495     fprintf (midiReportPtr, "NB. negative values for the statistics indicate unavailability \n");
01496     
01497     
01498     //    Fill in the output array using 
01499     for (i = 0; i < numOfOut; i++)
01500         yOut[i] = (coeff1) + (coeff2 * i) + (coeff3 * i * i);
01501 
01502     return; 
01503 }
01504 /*****************************************************************************/
01505 
01506 
01507 
01508 /******************************************************************************
01509 *               European Southern Observatory
01510 *          VLTI MIDI Maintenance Templates Software
01511 *
01512 * Module name:  correlateWaveCalibDB
01513 * Input/Output: See function arguments to avoid duplication
01514 * Description:  Correlates the real-time template with that in the database
01515 *
01516 * History:      
01517 * 08-Sep-05    (csabet)
01518 ******************************************************************************/
01519 void correlateWaveCalibDB (
01520     MidiFiles        *fileNames,    // In: Pointer to file names
01521     WaveCalibration *waveCal,    // Ou: Pointer to the Wavelength Calibration data structure
01522     ImageFormat        *format,    // In: Pointer to the image format
01523     int                *error)        // Ou: Error status
01524 
01525 {
01526 
01527     //  Local Declarations
01528     //    ------------------
01529     const char    routine[] = "correlateWaveCalibDB";
01530     int            i, region;
01531     float        *arrayError, **waveTable, standDev;
01532     char        *fileString, *title, *fileName;
01533     FILE        *filePtr=NULL;
01534     
01535     //  Algorithm
01536     //    ---------
01537     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
01538     if (diagnostic > 4) fprintf (midiReportPtr, "Invoking      routine   '%s' \n", routine);
01539 
01540     //    Reset status
01541     *error = 0;
01542 
01543    cpl_msg_info(cpl_func,"\nCorrelating template with the database \n");
01544    cpl_msg_info(cpl_func,"-------------------------------------- \n");
01545     fprintf (midiReportPtr, "\nCorrelating template with the database \n");
01546     fprintf (midiReportPtr, "-------------------------------------- \n");
01547 
01548     //    Allocate memory
01549     fileString = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
01550     arrayError = (float *) calloc (format->iXWidth, sizeof (float));
01551     waveTable = (float **) calloc (format->numOfDetectorRegions, sizeof (float *));
01552     for (region = 0; region < format->numOfDetectorRegions; region++)
01553         waveTable[region] = calloc (format->iXWidth, sizeof (float));
01554 
01555     //    We know that this file exists in the calibration database and it's consistent
01556     sprintf (fileString , "%s_%s_%s.dat", fileNames->waveCalibName, format->grismId, format->beamCombiner);
01557     if ((filePtr = fopen (fileString, "r")) != NULL)    // It is in the database
01558     {
01559         //    Read from file and load into array
01560        cpl_msg_info(cpl_func,"Reading Wavelength Calibration file ... %s \n", fileString);
01561         fprintf (midiReportPtr, "Reading Wavelength Calibration file ... %s \n", fileString);
01562         i = 0;
01563         //    Read calibrated frequency from the database in THz
01564         if (strcmp (format->beamCombiner, "SCI_PHOT") == 0)
01565         {
01566             while (fscanf (filePtr, "%f %f %f %f\n", &(waveTable[0][i]), &(waveTable[1][i]),
01567                 &(waveTable[2][i]), &(waveTable[3][i])) != EOF) i++;
01568         }
01569         else
01570         {
01571             while (fscanf (filePtr, "%f %f \n", &(waveTable[0][i]), &(waveTable[1][i])) != EOF) i++;
01572         }
01573 
01574         fclose (filePtr);
01575        cpl_msg_info(cpl_func,"Read %d wavelength values in micron \n", i*format->numOfDetectorRegions);
01576         fprintf (midiReportPtr, "Read %d pairs of wavelengths in micron \n", i);
01577 
01578         //    Do correlation
01579         for (region = 0; region < format->numOfDetectorRegions; region++)
01580         {
01581             //    Compute error series
01582             for (i = 0; i < format->iXWidth; i++)
01583                 arrayError[i] = waveCal->calibratedWave[region][i] - waveTable[region][i];
01584 
01585             if (plotFile)
01586             {
01587                 fileName = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
01588                 title = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
01589 
01590                 sprintf (fileName , "WavelengthCalibDataBaseDATA%d", region+1);
01591                 sprintf (title , "Wavelength Calibration from Database, Region %d", region+1);
01592                 midiCreatePlotFile2D (fileName, title, "Channel", "Wavelength in micro", 0, 
01593                     waveTable[region], 0, format->iXWidth, 1, 0);
01594 
01595                 sprintf (fileName , "WavelengthCalibCurrentTemplateDATA%d", region+1);
01596                 sprintf (title , "Wavelength Calibration for Current template, Region %d", region+1);
01597                 midiCreatePlotFile2D (fileName, title, "Channel", "Wavelength in micron", 0, 
01598                     waveCal->calibratedWave[region], 0, format->iXWidth, 1, 0);
01599 
01600                 sprintf (fileName , "CorrelationErrorDATA%d", region+1);
01601                 sprintf (title , "Correlation Error of Region %d", region+1);
01602                 midiCreatePlotFile2D (fileName, title, "Channel", "Wavelength in micron", 0, 
01603                     arrayError, 0, format->iXWidth, 1, 0);
01604                 free (fileName);
01605                 free (title);
01606             }
01607                 
01608             //    Compute variance
01609             waveCal->variance[region] = signalVariance (arrayError,    0, format->iXWidth,    &standDev);
01610            cpl_msg_info(cpl_func,"Error Variance for region %d = %f \n", region+1, waveCal->variance[region]);
01611             fprintf (midiReportPtr, "Error Variance for region %d = %f \n", region+1, waveCal->variance[region]);
01612         }
01613     }
01614     else 
01615     {
01616         *error = 1;
01617         sprintf (midiMessage, "Cannot find calibration data file ... %s. Nothing to correlate", fileString);
01618         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
01619     }
01620 
01621     //    Release memory
01622     free (fileString);
01623     free (arrayError);
01624     for (region = 0; region < format->numOfDetectorRegions; region++) free (waveTable[region]);
01625     free (waveTable);
01626         
01627     return; 
01628 }
01629 /*****************************************************************************/
01630 
01631 
01632 /******************************************************************************
01633 *               European Southern Observatory
01634 *          VLTI MIDI Maintenance Templates Software
01635 *
01636 * Module name:  createWaveCalibDB
01637 * Input/Output: See function arguments to avoid duplication
01638 * Description:  Creates an approximate wavelength calibration file based on the
01639 *                Narrow band filter spectra only
01640 *
01641 * History:      
01642 * 08-Sep-05    (csabet)
01643 ******************************************************************************/
01644 void createWaveCalibDB (
01645     MidiFiles        *fileNames,    // In: Pointer to file names
01646     WaveCalibration *waveCal,    // Ou: Pointer to the Wavelength Calibration data structure
01647     ImageFormat        *format,    // In: Pointer to the image format
01648     int                *error)        // Ou: Error status
01649 
01650 {
01651 
01652     //  Local Declarations
01653     //    ------------------
01654     const char    routine[] = "createWaveCalibDB";
01655     char        *fileString, *title;
01656     FILE        *filePtr=NULL;
01657     int            i, region;
01658     
01659     //  Algorithm
01660     //    ---------
01661     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
01662     if (diagnostic > 4) fprintf (midiReportPtr, "Invoking      routine   '%s' \n", routine);
01663 
01664     //    Reset status
01665     *error = 0;
01666 
01667     //    Plot for diagnostic
01668     if (plotFile && diagnostic)
01669     {
01670         fileString = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
01671         title = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
01672         for (region = 0; region < format->numOfDetectorRegions; region++)
01673         {
01674             sprintf (fileString , "WavelengthCalib_%s_%sDATA%d", format->grismId, format->beamCombiner, region+1);
01675             sprintf (title , "Wavelength Calibration for %s %s, Region %d", format->grismId, format->beamCombiner, region+1);
01676             midiCreatePlotFile2D (fileString, title, "Channel", "Wavelength in micron", 0, 
01677                 waveCal->calibratedWave[region], 0, format->iXWidth, 1, 0);
01678         }
01679         free (fileString);
01680         free (title);
01681     }
01682     
01683     //    Create database file
01684     fileString = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
01685     sprintf (fileString , "%s_%s_%s.dat", fileNames->waveCalibName, format->grismId, format->beamCombiner);
01686     if ((filePtr = fopen (fileString, "w")) == NULL)
01687     {
01688         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot create wavelength calibration file");
01689         *error = 1;
01690         free (fileString);
01691         return;
01692     }
01693     
01694     //    Write the wavelength data into file
01695     for (i = 0; i < format->iXWidth; i++)
01696     {
01697         for (region = 0; region < format->numOfDetectorRegions; region++)
01698             fprintf (filePtr, "%3.10f ", waveCal->calibratedWave[region][i]);
01699         fprintf (filePtr, "\n");    
01700     }
01701     
01702    cpl_msg_info(cpl_func,"\nCreated wavelength calibration file ... %s \n", fileString);
01703     fprintf (midiReportPtr, "\nCreated wavelength calibration file ... %s \n", fileString);
01704     
01705     //    Close files and release memory
01706     free (fileString);    
01707     fclose (filePtr);
01708 
01709     return; 
01710 }
01711 /*****************************************************************************/
01712 
01713 
01714 /******************************************************************************
01715 *               European Southern Observatory
01716 *          VLTI MIDI Maintenance Templates Software
01717 *
01718 * Module name:  fitFilterSpectra
01719 * Input/Output: See function arguments to avoid duplication
01720 * Description:  Fitting of filter spectra. The peaks of the filters are:
01721 *
01722 *               Filter  Pk Freq.        Pk Wavelength
01723 *                ======================================
01724 *                NeII    2.34297e+13 Hz  12.7955  micron
01725 *                SIV     2.85818e+13 Hz  10.489   micron
01726 *                ArIII   3.33005e+13 Hz   9.00272 micron
01727 *
01728 *                Use corresponding image for each filter and, using the Gaussian Fit
01729 *                method, find the positions of the centre-pinholes (there should be
01730 *                3 for each filter image). From these computed positions and the above
01731 *                given peak values, one can assign wavelength to the detector channels.
01732 *                This facilitates a partial detector calibration.
01733 *
01734 * History:      
01735 * 14-June-05    (csabet) Created
01736 ******************************************************************************/
01737 void fitFilterSpectra (
01738     WaveCalibration *waveCal,    // Ou: Pointer to the Wavelength Calibration data structure
01739     ImageFormat        *format,    // In: Pointer to the image format
01740     int                *error)        // Ou: Error status
01741 
01742 {
01743 
01744     //  Local Declarations
01745     //    ------------------
01746     const char    routine[] = "fitFilterSpectra";
01747     int            region;
01748 
01749     //  Algorithm
01750     //    ---------
01751     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
01752     if (diagnostic > 4) fprintf (midiReportPtr, "Invoking      routine   '%s' \n", routine);
01753 
01754     //    Reset status
01755     *error = 0;
01756     
01757     //    Get the spectra for the NeII filter
01758     for (region = 0; region < format->numOfDetectorRegions; region++)
01759         getFilterSpectra (region, "NeII", (waveCal->NeII->image)[region], format, 
01760             &(waveCal->NeII->xCoord[region]), &(waveCal->NeII->yCoord[region]), error);
01761     
01762     //    Get the spectra for the SIV filter
01763     for (region = 0; region < format->numOfDetectorRegions; region++)
01764         getFilterSpectra (region, "SIV", (waveCal->SIV->image)[region], format, 
01765             &(waveCal->SIV->xCoord[region]), &(waveCal->SIV->yCoord[region]), error);
01766     
01767     //    Get the spectra for the ArIII filter
01768     for (region = 0; region < format->numOfDetectorRegions; region++)
01769         getFilterSpectra (region, "ArIII", (waveCal->ArIII->image)[region], format, 
01770             &(waveCal->ArIII->xCoord[region]), &(waveCal->ArIII->yCoord[region]), error);
01771 
01772     //    Computed centre pinholes
01773     for (region = 0; region < format->numOfDetectorRegions; region++)
01774     {
01775        cpl_msg_info(cpl_func,"\nComputed Centre Pinholes for region %d: \n", region+1);
01776        cpl_msg_info(cpl_func,"----------------------------------- \n");
01777        cpl_msg_info(cpl_func,"NeII Centre Pinhole  = (%f, %f) \n", (waveCal->NeII->xCoord)[region], (waveCal->NeII->yCoord)[region]);
01778        cpl_msg_info(cpl_func,"SIV Centre Pinhole   = (%f, %f) \n", (waveCal->SIV->xCoord)[region], (waveCal->SIV->yCoord)[region]);
01779        cpl_msg_info(cpl_func,"ArIII Centre Pinhole = (%f, %f) \n", (waveCal->ArIII->xCoord)[region], (waveCal->ArIII->yCoord)[region]);
01780     
01781         fprintf (midiReportPtr, "\nComputed Centre Pinholes for region %d: \n", region+1);
01782         fprintf (midiReportPtr, "----------------------------------- \n");
01783         fprintf (midiReportPtr, "NeII Centre Pinhole  = (%f, %f) \n", 
01784             (waveCal->NeII->xCoord)[region], (waveCal->NeII->yCoord)[region]);
01785         fprintf (midiReportPtr, "SIV Centre Pinhole   = (%f, %f) \n", 
01786             (waveCal->SIV->xCoord)[region], (waveCal->SIV->yCoord)[region]);
01787         fprintf (midiReportPtr, "ArIII Centre Pinhole = (%f, %f) \n", 
01788             (waveCal->ArIII->xCoord)[region], (waveCal->ArIII->yCoord)[region]);
01789     }
01790         
01791     //    Assign computed peak values to the peak values given by the manufacturer
01792     for (region = 0; region < format->numOfDetectorRegions; region++)
01793     {
01794        cpl_msg_info(cpl_func,"\nDetector Channel Assignment for region %d: \n", region+1);
01795        cpl_msg_info(cpl_func,"-------------------------------------- \n");
01796        cpl_msg_info(cpl_func,"Channel %3d = %f THz  %f micron \n", (int) ((waveCal->NeII->xCoord)[region]),
01797             FREQ_PEAK_NeII, WAVELENGTH_PEAK_NeII);
01798        cpl_msg_info(cpl_func,"Channel %3d = %f THz  %f micron \n", (int) ((waveCal->SIV->xCoord)[region]),
01799             FREQ_PEAK_SIV, WAVELENGTH_PEAK_SIV);
01800        cpl_msg_info(cpl_func,"Channel %3d = %f THz  %f micron \n", (int) ((waveCal->ArIII->xCoord)[region]),
01801             FREQ_PEAK_ArIII, WAVELENGTH_PEAK_ArIII);
01802     
01803         fprintf (midiReportPtr, "\nDetector Channel Assignment for region %d: \n", region+1);
01804         fprintf (midiReportPtr, "-------------------------------------- \n");
01805         fprintf (midiReportPtr, "Channel %3d = %f THz  %f micron \n", (int) ((waveCal->NeII->xCoord)[region]),
01806             FREQ_PEAK_NeII, WAVELENGTH_PEAK_NeII);
01807         fprintf (midiReportPtr, "Channel %3d = %f THz  %f micron \n", (int) ((waveCal->SIV->xCoord)[region]),
01808             FREQ_PEAK_SIV, WAVELENGTH_PEAK_SIV);
01809         fprintf (midiReportPtr, "Channel %3d = %f THz  %f micron \n", (int) ((waveCal->ArIII->xCoord)[region]),
01810             FREQ_PEAK_ArIII, WAVELENGTH_PEAK_ArIII);
01811     
01812         (waveCal->NeII->wavelength)[region] = WAVELENGTH_PEAK_NeII;
01813         (waveCal->SIV->wavelength)[region] = WAVELENGTH_PEAK_SIV;
01814         (waveCal->ArIII->wavelength)[region] = WAVELENGTH_PEAK_ArIII;
01815     }
01816     
01817     return; 
01818 }
01819 /*****************************************************************************/
01820 
01821 
01822 /******************************************************************************
01823 *               European Southern Observatory
01824 *          VLTI MIDI Maintenance Templates Software
01825 *
01826 * Module name:  getFilterSpectra
01827 * Input/Output: See function arguments to avoid duplication
01828 * Description:  Determines the position of the centre-pinhole in the given image
01829 *
01830 * History:      
01831 * 30-Aug-05    (csabet)
01832 ******************************************************************************/
01833 void getFilterSpectra (
01834     int            region,        // In: Region of the image
01835     const char        *filter,    // In: Name of the filter
01836     float         *image,        // Ou: Pointer to the Wavelength Calibration data structure
01837     ImageFormat    *format,    // In: Pointer to the image format
01838     float        *xCPH,        // Ou: X coordinate of the centre pinhole
01839     float        *yCPH,        // Ou: Y coordinate of the centre pinhole
01840     int            *error)        // Ou: Error status
01841 
01842 {
01843 
01844     //  Local Declarations
01845     //    ------------------
01846     const char    routine[] = "getFilterSpectra";
01847     int            i, j, frame, span, quartSpan;
01848     float        *array, *arrayPeak, maxFlux, peak, fluxMax;
01849     char        *fileString, *title;
01850     
01851     //  Algorithm
01852     //    ---------
01853     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
01854     if (diagnostic > 4) fprintf (midiReportPtr, "Invoking      routine   '%s' \n", routine);
01855 
01856     //    Reset status
01857     *error = 0;
01858     *xCPH = 0.0;
01859     *yCPH = 0.0;
01860     span = EXPECTED_PINHOLE_WIDTH;
01861     quartSpan = span / 4;
01862 
01863 
01864    cpl_msg_info(cpl_func,"\nComputing Coordinates for %s filter region %d \n", filter, region+1);
01865    cpl_msg_info(cpl_func,"-------------------------------------------- \n");
01866     fprintf (midiReportPtr, "\nComputing Coordinates for %s filter region %d\n", filter, region+1);
01867     fprintf (midiReportPtr, "-------------------------------------------- \n");
01868     
01869     //================================================
01870     //    This section computes the approximate X coordinate of the centre pinhole
01871     
01872     //    Allocate memory
01873     array = (float *) calloc (format->iXWidth, sizeof (float));
01874     
01875     //    Compress spectrum in the Y direction
01876     for (i = 0; i < format->iYWidth; i++)
01877     {
01878         frame = i * format->iXWidth;
01879         for (j = 0; j < format->iXWidth; j++)
01880             array[j] += image[frame + j];
01881     }
01882     
01883     //    Normalize array for a better correlation
01884     fluxMax = array[0];
01885     for (i = 0; i < format->iXWidth; i++)
01886         if (array[i] > fluxMax) fluxMax = array[i];
01887     for (i = 0; i < format->iXWidth; i++)
01888         array[i] /= fluxMax;
01889 
01890     if (plotFile && diagnostic)
01891     {
01892         fileString = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
01893         title = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
01894                 
01895         sprintf (fileString , "%sSpectraAveAlongYDATA%d", filter, region+1);
01896         sprintf (title , "%s Spectra averaged along Y region %d", filter, region+1);
01897         midiCreatePlotFile2D (fileString, title, "Channel", "Flux", 0, array, 0, format->iXWidth, 1, 0);
01898         free (fileString);
01899         free (title);
01900     }
01901 
01902     //    The peak of the above spectra gives the approximate x-coordinate of the centre-pinhole
01903     maxFlux = 0.0;
01904     peak = 0;
01905     for (i = 0; i < format->iXWidth; i++)
01906     {
01907         if (array[i] > maxFlux)
01908         {
01909             maxFlux = array[i];
01910             peak = i;
01911         }
01912     }
01913 
01914     //    Now smooth the array around the peak
01915     *xCPH = midiGaussianSmooth (array, format->iXWidth, peak, span, error);
01916    cpl_msg_info(cpl_func,"Found apprximate X at %f \n", *xCPH);
01917     fprintf (midiReportPtr, "Found apprximate X at %f \n", *xCPH);
01918     
01919     //    Release memory
01920     free (array);
01921     //================================================
01922 
01923 
01924 
01925     //================================================
01926     //    This section computes the exact Y coordinate of the centre pinhole
01927     
01928     //    Allocate memory
01929     array = (float *) calloc (format->iYWidth, sizeof (float));
01930     arrayPeak = (float *) calloc (3, sizeof (float));
01931     
01932     //    Compress spectrum in the X direction
01933     for (i = 0; i < format->iYWidth; i++)
01934     {
01935         frame = i * format->iXWidth;
01936         for (j = 0; j < format->iXWidth; j++)
01937             array[i] += image[frame + j];
01938     }
01939 
01940     //    Normalize array for a better correlation
01941     fluxMax = array[0];
01942     for (i = 0; i < format->iYWidth; i++)
01943         if (array[i] > fluxMax) fluxMax = array[i];
01944     for (i = 0; i < format->iYWidth; i++)
01945         array[i] /= fluxMax;
01946 
01947     if (plotFile && diagnostic)
01948     {
01949         fileString = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
01950         title = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
01951                 
01952         sprintf (fileString , "%sSpectraAveAlongXDATA%d", filter, region+1);
01953         sprintf (title , "%s Spectra averaged along X region %d", filter, region+1);
01954         midiCreatePlotFile2D (fileString, title, "Sub-frame", "Flux", 0, array, 0, format->iYWidth, 1, 0);
01955         free (fileString);
01956         free (title);
01957     }
01958     
01959     //    Here we expect three peaks
01960     //    Find the strongest peak
01961     maxFlux = 0.0;
01962     arrayPeak[0] = 0;
01963     for (i = 0; i < format->iYWidth; i++)
01964     {
01965         if (array[i] > maxFlux)
01966         {
01967             maxFlux = array[i];
01968             arrayPeak[0] = i;
01969         }
01970     }
01971    cpl_msg_info(cpl_func,"Found first Y at      %f \n", arrayPeak[0]);
01972     fprintf (midiReportPtr, "Found first Y at      %f \n", arrayPeak[0]);
01973     
01974     //    Find the second strongest peak
01975     maxFlux = 0.0;
01976     arrayPeak[1] = 0;
01977     for (i = 0; i < format->iYWidth; i++)
01978     {
01979         if ( !((i > arrayPeak[0]-quartSpan) && (i < arrayPeak[0]+quartSpan)) )
01980         {
01981             if (array[i] > maxFlux)
01982             {
01983                 maxFlux = array[i];
01984                 arrayPeak[1] = i;
01985             }
01986         }
01987     }
01988    cpl_msg_info(cpl_func,"Found second Y at     %f \n", arrayPeak[1]);
01989     fprintf (midiReportPtr, "Found second Y at     %f \n", arrayPeak[1]);
01990 
01991     //    Find the third strongest peak
01992     maxFlux = 0.0;
01993     arrayPeak[2] = 0;
01994     for (i = 0; i < format->iYWidth; i++)
01995     {
01996         if ( !((i > arrayPeak[0]-quartSpan) && (i < arrayPeak[0]+quartSpan)) && 
01997             !((i > arrayPeak[1]-quartSpan) && (i < arrayPeak[1]+quartSpan)) ) 
01998         {
01999             if (array[i] > maxFlux)
02000             {
02001                 maxFlux = array[i];
02002                 arrayPeak[2] = i;
02003             }
02004         }
02005     }
02006    cpl_msg_info(cpl_func,"Found third Y at      %f \n", arrayPeak[2]);
02007     fprintf (midiReportPtr, "Found third Y at      %f \n", arrayPeak[2]);
02008 
02009     //    Find the median of the above three peaks
02010     peak = signalMedian (arrayPeak, 0, 3);
02011     free (arrayPeak);
02012    cpl_msg_info(cpl_func,"Found median Y at     %f \n", peak);
02013     fprintf (midiReportPtr, "Found median Y at     %f \n", peak);
02014     
02015     //    Normalise around median
02016     if (peak == 0)
02017     {
02018         *error = 1;
02019         midiReportInfo (midiReportPtr, routine, __FILE__, __LINE__, "Cannot find median");
02020         free (array);
02021         return;
02022     }
02023     fluxMax = array[0];
02024     if (quartSpan > peak)
02025         quartSpan = peak;
02026         
02027     for (i = peak-quartSpan; i <= peak+quartSpan; i++)
02028         if (array[i] > fluxMax) fluxMax = array[i];
02029     for (i = peak-quartSpan; i <= peak+quartSpan; i++)
02030         array[i] /= fluxMax;
02031 
02032     if (plotFile && diagnostic)
02033     {
02034         fileString = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
02035         title = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
02036                 
02037         sprintf (fileString , "%sCentrePinholeAlongYDATA%d", filter, region+1);
02038         sprintf (title , "%s Centre Pinhole along Y region %d", filter, region+1);
02039         midiCreatePlotFile2D (fileString, title, "Sub-frame", "Flux", 0, array, peak-quartSpan, peak+quartSpan+1, 1, 0);
02040         free (fileString);
02041         free (title);
02042     }
02043     
02044     //    Now smooth the array around the median and find the exact Y coordinate
02045     *yCPH = midiGaussianSmooth (array, format->iYWidth, peak, quartSpan, error);
02046    cpl_msg_info(cpl_func,"Found exact Y at      %f \n", *yCPH);
02047     fprintf (midiReportPtr, "Found exact Y at      %f \n", *yCPH);
02048     free (array);
02049     //================================================
02050 
02051 
02052     
02053     //================================================
02054     //    This section computes the exact X coordinate of the centre pinhole
02055     
02056     //    Allocate memory
02057     array = (float *) calloc (format->iXWidth, sizeof (float));
02058     
02059     //    Compress spectrum in the Y direction around the exact Y coordinate
02060     for (i = *yCPH-quartSpan; i < *yCPH+quartSpan; i++)
02061     {
02062         frame = i * format->iXWidth;
02063         for (j = 0; j < format->iXWidth; j++)
02064             array[j] += image[frame + j];
02065     }
02066     
02067     //    Normalize array for a better correlation
02068     fluxMax = array[0];
02069     for (i = 0; i < format->iXWidth; i++)
02070         if (array[i] > fluxMax) fluxMax = array[i];
02071     for (i = 0; i < format->iXWidth; i++)
02072         array[i] /= fluxMax;
02073 
02074     if (plotFile && diagnostic)
02075     {
02076         fileString = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
02077         title = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
02078                 
02079         sprintf (fileString , "%sCentrePinholeAveAlongYDATA%d", filter, region+1);
02080         sprintf (title , "%s Centre pinhole averaged along Y region %d", filter, region+1);
02081         midiCreatePlotFile2D (fileString, title, "Channel", "Flux", 0, array, 0, format->iXWidth, 1, 0);
02082         free (fileString);
02083         free (title);
02084     }
02085 
02086     //    The peak of the above spectra gives the approximate x-coordinate of the centre-pinhole
02087     maxFlux = 0.0;
02088     peak = 0;
02089     for (i = 0; i < format->iXWidth; i++)
02090     {
02091         if (array[i] > maxFlux)
02092         {
02093             maxFlux = array[i];
02094             peak = i;
02095         }
02096     }
02097 
02098     //    Now smooth the array around the peak
02099     *xCPH = midiGaussianSmooth (array, format->iXWidth, peak, span, error);
02100    cpl_msg_info(cpl_func,"Found exact X at      %f \n", *xCPH);
02101     fprintf (midiReportPtr, "Found exact X at      %f \n", *xCPH);
02102     //================================================
02103     
02104     //    Release memory
02105     free (array);
02106     //================================================
02107     
02108     return; 
02109 }
02110 /*****************************************************************************/
02111 
02112 
02113 /******************************************************************************
02114 *               European Southern Observatory
02115 *          VLTI MIDI Maintenance Templates Software
02116 *
02117 * Module name:  fitFoilSpectra
02118 * Input/Output: See function arguments to avoid duplication
02119 * Description:  Fitting of Foil spectra
02120 *
02121 * History:      
02122 * 14-June-05    (csabet)
02123 ******************************************************************************/
02124 void fitFoilSpectra (
02125     MidiFiles        *fileNames,    // In: Pointer to file names
02126     WaveCalibration *waveCal,    // Ou: Pointer to the Wavelength Calibration data structure
02127     ImageFormat        *format,    // In: Pointer to the image format
02128     int                *error)        // Ou: Error status
02129 
02130 {
02131 
02132     //  Local Declarations
02133     //    ------------------
02134     const char    routine[] = "fitFoilSpectra";
02135     float        **foilSpectra, **openSpectra, fluxMax;
02136     int            i, region, length;
02137     char        *fileString, *title;
02138     FILE        *wlFilePtr=NULL;
02139     
02140     //  Algorithm
02141     //    ---------
02142     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
02143     if (diagnostic > 4) fprintf (midiReportPtr, "Invoking      routine   '%s' \n", routine);
02144 
02145     //    Reset status
02146     *error = 0;
02147     
02148     midiReportTbd (midiReportPtr, routine, __FILE__, __LINE__, "Entire code to be designed");
02149     
02150     //    Allocate memory
02151     foilSpectra = (float **) calloc (format->numOfDetectorRegions, sizeof (float *));
02152     openSpectra = (float **) calloc (format->numOfDetectorRegions, sizeof (float *));
02153     for (region = 0; region < format->numOfDetectorRegions; region++)
02154     {
02155         foilSpectra[region] = (float *) calloc (format->iXWidth, sizeof (float));
02156         openSpectra[region] = (float *) calloc (format->iXWidth, sizeof (float));
02157     }
02158     
02159     //    For each region get foil spectra
02160     for (region = 0; region < format->numOfDetectorRegions; region++)
02161         getFoilSpectra (region, "Foil", waveCal->foil->image[region], format, foilSpectra[region], error);
02162 
02163     //    For each region get OPEN spectra
02164     for (region = 0; region < format->numOfDetectorRegions; region++)
02165         getFoilSpectra (region, "Open", waveCal->open->image[region], format, openSpectra[region], error);
02166 
02167     //    Divide foilSpectra by openSpectra
02168     for (region = 0; region < format->numOfDetectorRegions; region++)
02169     {
02170         for (i = 0; i < format->iXWidth; i++)
02171             foilSpectra[region][i] /= openSpectra[region][i];
02172 
02173         //    Normalize array for a better correlation
02174         fluxMax = foilSpectra[region][0];
02175         for (i = 0; i < format->iXWidth; i++)
02176             if (foilSpectra[region][i] > fluxMax) fluxMax = foilSpectra[region][i];
02177         for (i = 0; i < format->iXWidth; i++)
02178             foilSpectra[region][i] /= fluxMax;
02179 
02180         //    Plot it
02181         if (plotFile && diagnostic)
02182         {
02183             fileString = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
02184             title = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
02185             sprintf (fileString , "FoilDivideOpenAveAlongYDATA%d", region+1);
02186             sprintf (title , "Foil divided by Open Averaged along Y region %d", region+1);
02187             midiCreatePlotFile2D (fileString, title, "Channel", "Flux", 0, foilSpectra[region], 0, format->iXWidth, 1, 0);
02188             free (fileString);
02189             free (title);
02190         }
02191     }
02192 
02193     //    Compare with published spectra. Load the WL-CALIB_2 spectra
02194     fileString = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
02195     title = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
02196     sprintf (fileString, "%swl-calib_2.dat", fileNames->calibDbDir);
02197     if ((wlFilePtr = fopen (fileString, "r")) == NULL)
02198     {
02199         sprintf (midiMessage, "Cannot Open %s", fileString);
02200         midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
02201         free (fileString);
02202         free (title);
02203         *error = 1;
02204         return;
02205     }
02206     
02207     //    Ignore first record which gives the title of the data file
02208     fgets (title, MAX_STRING_LENGTH, wlFilePtr);
02209     length = 0;
02210     //    First column in the file is the    wavenumber and the second is transmission
02211     while (fscanf (wlFilePtr, "%f %f\n", &(waveCal->foil->actualWavelength[length]), 
02212         &(waveCal->foil->actualTransmission[length])) != EOF) length++;
02213 
02214     //    Convert to microns
02215     for (i = 0; i < length; i++)
02216         waveCal->foil->actualWavelength[i] = 10000.0 * (1.0 / waveCal->foil->actualWavelength[i]);
02217 
02218     sprintf (midiMessage, "Read %d pairs of 'float'(s) from %s", length, fileString);
02219     midiReportInfo (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
02220     fclose (wlFilePtr);
02221     free (fileString);
02222     free (title);
02223 
02224     //    Plot manufacturer's Foil transmission
02225     midiCreatePlotFile2D2P ("FoilTransmission", "Foil Transmission Versus Wavelength", 
02226         "Wavelength in micron", "Transmission", 0, waveCal->foil->actualWavelength, waveCal->foil->actualTransmission, 0, length, 1);
02227     
02228     //    Release memory
02229     for (region = 0; region < format->numOfDetectorRegions; region++)
02230     {
02231         free (foilSpectra[region]); 
02232         free (openSpectra[region]); 
02233     }
02234     free (foilSpectra);
02235     free (openSpectra);
02236 
02237     return; 
02238 }
02239 /*****************************************************************************/
02240 
02241 
02242 /******************************************************************************
02243 *               European Southern Observatory
02244 *          VLTI MIDI Maintenance Templates Software
02245 *
02246 * Module name:  getFoilSpectra
02247 * Input/Output: See function arguments to avoid duplication
02248 * Description:  Processing of the foil spectra
02249 *
02250 * History:      
02251 * 02-Sep-05    (csabet)
02252 ******************************************************************************/
02253 void getFoilSpectra (
02254     int            region,        // In: Region of the image
02255     const char        *filter,    // In: Name of the filter
02256     float        *image,        // In: pointer to the image
02257     ImageFormat    *format,    // In: Pointer to the image format
02258     float        *spectra,    // Ou: pointer to the resulting spectra
02259     int            *error)        // Ou: Error status
02260 
02261 {
02262 
02263     //  Local Declarations
02264     //    ------------------
02265     const char    routine[] = "getFoilSpectra";
02266     char        *fileString, *title;
02267     int            i, j, frame;
02268     float        fluxMax;
02269         
02270     //  Algorithm
02271     //    ---------
02272     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
02273     if (diagnostic > 4) fprintf (midiReportPtr, "Invoking      routine   '%s' \n", routine);
02274 
02275     //    Reset status
02276     *error = 0;
02277 
02278     midiReportTbd (midiReportPtr, routine, __FILE__, __LINE__, "Entire code to be designed");    
02279 
02280    cpl_msg_info(cpl_func,"\nObtaining %s Spectra for region %d \n", filter, region+1);
02281    cpl_msg_info(cpl_func,"------------------------------- \n");
02282     fprintf (midiReportPtr, "\nObtaining %s Spectra for region %d \n", filter, region+1);
02283     fprintf (midiReportPtr, "------------------------------- \n");
02284     
02285     //    Compress spectrum in the Y direction
02286     for (i = 0; i < format->iYWidth; i++)
02287     {
02288         frame = i * format->iXWidth;
02289         for (j = 0; j < format->iXWidth; j++)
02290             spectra[j] += image[frame + j];
02291     }
02292 
02293     //    Normalize array for a better correlation
02294     fluxMax = spectra[0];
02295     for (i = 0; i < format->iXWidth; i++)
02296         if (spectra[i] > fluxMax) fluxMax = spectra[i];
02297     for (i = 0; i < format->iXWidth; i++)
02298         spectra[i] /= fluxMax;
02299 
02300     //    Plot it
02301     if (plotFile && diagnostic)
02302     {
02303         fileString = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
02304         title = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
02305                 
02306         sprintf (fileString , "%sSpectraAveAlongYDATA%d", filter, region+1);
02307         sprintf (title , "%s Spectra Averaged along Y region %d", filter, region+1);
02308         midiCreatePlotFile2D (fileString, title, "Channel", "Flux", 0, spectra, 0, format->iXWidth, 1, 0);
02309         free (fileString);
02310         free (title);
02311     }
02312         
02313     return; 
02314 }
02315 /*****************************************************************************/
02316 
02317 
02318 /******************************************************************************
02319 *               European Southern Observatory
02320 *          VLTI MIDI Maintenance Templates Software
02321 *
02322 * Module name:  fitOpenSpectra
02323 * Input/Output: See function arguments to avoid duplication
02324 * Description:  Fitting of Open spectra
02325 *
02326 * History:      
02327 * 14-June-05    (csabet)
02328 ******************************************************************************/
02329 void fitOpenSpectra (
02330     int    *error)    // Ou: Error status
02331 
02332 {
02333 
02334     //  Local Declarations
02335     //    ------------------
02336     const char    routine[] = "fitOpenSpectra";
02337 
02338     //  Algorithm
02339     //    ---------
02340     if (diagnostic > 4)cpl_msg_info(cpl_func,"Invoking      routine   '%s' \n", routine);
02341     if (diagnostic > 4) fprintf (midiReportPtr, "Invoking      routine   '%s' \n", routine);
02342 
02343     //    Reset status
02344     *error = 0;
02345 
02346     midiReportTbd (midiReportPtr, routine, __FILE__, __LINE__, "Entire code to be designed");    
02347 
02348     return; 
02349 }
02350 /*****************************************************************************/

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