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

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