//////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////// // // Class: NetCDFFileIO // // Filename: ReadL1ANetCDF.cpp // // Header Files: NetCDFFileIO.h // // Description: This class is designed to provide a series // of utilities to read the Level 1A // routine NetCDF files that the GUVI DP POC // is producing. These are as follows: // GUVI Imaging Level 1A data product // GUVI Static Imaging Level 1A data product // GUVI Spectrograph Level 1A data product // // Author: M. Weiss // // Date: April, 1999 // // Change History: // --------------- // Oct. 99 MW modified to match new data file definitions. // Added usage of GUVIBaseTypes. // Nov. 99 MW Added check so that negative errors aren't // scaled // Jan. 02 MW Added calls to nc_close in ReadL1AImaging, // ReadL1AStaticImaging and ReadL1ASpectrograph // methods. Changed SecOfDay to MSecOfDay. // Utilization of Vector from standard template // library to store a full orbits worth of data. // Changed processing and output parameter to // return a full orbits worth of data. // //////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////// // include files #include #include "NetCDFFileIO.h" #include "LogUtil.h" //////////////////////////////////////////////////////////// // // Method: ReadLevel1AImaging // // Description: This method reads the GUVI level 1A data // netcdf file. This method returns a single // orbits worth of imaging data for every call // // Inputs: // Name Description // ---- ----------- // inFileName file name of data to be read // orbitIData a pointer to the data to be read // // Return: // Name Description // ---- ----------- // n/a true = successful read // false = unsuccessful read // bool NetCDFFileIO::ReadLevel1AImaging( string inFileName, OrbitOfImaging& orbitIData ) { // to store a single scans worth of imaging data into ImagingFormat imagingData; // indicates which scan number we're currently on Integer scanNum; size_t numScans; Integer status; Integer ncid; // netcdf file id // the following are used for the netcdf variable // ids Integer scanDim; Integer xtrkDim; Integer alongTrkDim; Integer colorDim; Integer dcDim; Integer bcDim; // netcdf variables defined in file Integer timeID; Integer detectorID; Integer slitID; Integer dcID; Integer bcID; Integer pixelID; Integer errorID; Integer irID; Integer orID; Integer dqID; Short tempError; // holding value for scaled error // open the file specified by inFileName status = nc_open(inFileName.c_str(), NC_NOWRITE, &ncid); // check if the file open was successful if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AImaging: Can't open netcdf file, name\n", inFileName.c_str()); return false; } // get the netcdf dimension ids status = nc_inq_dimid(ncid, "perScan", &scanDim); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AImaging: Can't find scan dim\n"); nc_close(ncid); return false; } status = nc_inq_dimid(ncid, "perCrossTrackPixels", &xtrkDim); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AImaging: Can't find xtrk dim\n"); nc_close(ncid); return false; } status = nc_inq_dimid(ncid, "perAlongTrackPixels", &alongTrkDim); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AImaging: Can't find along track dim\n"); nc_close(ncid); return false; } status = nc_inq_dimid(ncid, "perColors", &colorDim); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AImaging: Can't find color dim\n"); nc_close(ncid); return false; } status = nc_inq_dimid(ncid, "perDarkCountPixels", &dcDim); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AImaging: Can't find dark count pixels dim\n"); nc_close(ncid); return false; } status = nc_inq_dimid(ncid, "perBackgroundCountPixels", &bcDim); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AImaging: Can't find background count pixels dim\n"); nc_close(ncid); return false; } // get all of the variable ids. doing it here since it's not dependent // upon which indices you're looking at in a dimensional field status = nc_inq_varid(ncid, "Time", &timeID); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AImaging: Can't find time\n"); nc_close(ncid); return false; } status = nc_inq_varid(ncid, "Detector", &detectorID); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AImaging: Can't find Detector\n"); nc_close(ncid); return false; } status = nc_inq_varid(ncid, "Slit", &slitID); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AImaging: Can't find slit\n"); nc_close(ncid); return false; } size_t countdc[] = {1, NUM_DARK_COUNT_PIXELS}; status = nc_inq_varid(ncid, "DarkCountPixels", &dcID); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AImaging: Can't find variable dark counts\n"); nc_close(ncid); return false; } size_t countbc[] = {1, NUM_X_BACKGROUND_PIXELS * NUM_Y_BACKGROUND_PIXELS}; status = nc_inq_varid(ncid, "BackgroundPixels", &bcID); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AImaging: Can't find variable backgrund counts\n"); nc_close(ncid); return false; } status = nc_inq_varid(ncid, "DataQualityIndicator", &dqID); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AImaging: Can't find data quality\n"); nc_close(ncid); return false; } status = nc_inq_varid(ncid, "PixelData", &pixelID); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AImaging: Can't find variable pixel data\n"); nc_close(ncid); return false; } status = nc_inq_varid(ncid, "Error", &errorID); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AImaging: Can't find variable error\n"); nc_close(ncid); return false; } status = nc_inq_varid(ncid, "InputRate", &irID); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AImaging: Can't find variable input rate data\n"); nc_close(ncid); return false; } status = nc_inq_varid(ncid, "OutputRate", &orID); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AImaging: Can't find variable output rate data\n"); nc_close(ncid); return false; } // find out how many scans are in the file so that they can all be // processed status = nc_inq_dimlen(ncid, scanDim, &numScans); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AImaging: Can't get num of dimensions for perScan\n"); nc_close(ncid); return false; } // now get data from the data product file for all scans for (scanNum = 0; scanNum numScans; scanNum++) { // first get the data that appears on a scan basis but // to do that have to first find out what variable // corresponds with the approrpriate variable id and // then issue a netcdf to get the associated data size_t startscan[1] = {scanNum}; status = nc_get_var1_long(ncid, timeID, startscan, &imagingData.ScanData.MsecsOfDay); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AImaging: Can't read time\n"); nc_close(ncid); return false; } status = nc_get_var1_uchar(ncid, detectorID, startscan, &imagingData.ScanData.DetectorNum); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AImaging: Can't read detector num\n"); nc_close(ncid); return false; } status = nc_get_var1_uchar(ncid, slitID, startscan, &imagingData.ScanData.SlitPosition); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AImaging: Can't read slit position\n"); nc_close(ncid); return false; } size_t startdc[2] = {scanNum, 0}; status = nc_get_vara_short(ncid, dcID, startdc, countdc, imagingData->ScanData.DarkCountPixel); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AImaging: Can't read dark count pixels\n"); nc_close(ncid); return false; } size_t startbc[2] = {scanNum, 0}; status = nc_get_vara_short(ncid, bcID, startbc, countbc, imagingData->ScanData.BackgroundCountPixel); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AImaging: Can't read background count pixels\n"); nc_close(ncid); return false; } status = nc_get_var1_uchar(ncid, dqID, startscan, &imagingData.ScanData.DataQuality); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AImaging: Can't read data quality\n"); nc_close(ncid); return false; } // now add the imaging pixel data that has already // been uncompressed and the other imaging data that // appears on a cross track basis size_t dim2[2] = {scanNum, 0}; size_t dim4[4] = {scanNum, 0, 0, 0}; // need to go through the imaging data record for all // crosstracks because netcdf has a problem with mixing // record fields with arrays for (Integer i = 0; i TOTAL_CROSS_TRACK_PIXELS; i++) { dim2[1] = i; dim4[1] = i; // need to go through the imaging data record also // for all imaging colors also due to a netcdf bug // or quirk for (Integer j = 0; j NUM_IMAGING_COLORS; j++) { dim4[2] = j; // and all colors for (Integer k = 0; k NUM_ALONG_TRACK_PIXELS; k++) { // set the array position for the appropriate cross track // pixel index dim2[3] = k; status = nc_get_var1_float(ncid, pixelID, dim4, &imagingData.PixelData[i].Pixel[j][k]); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AImaging: Can't read pixel data\n"); nc_close(ncid); return false; } status = nc_get_var1_short(ncid, errorID, dim4, &tempError); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AImaging: Can't read error\n"); nc_close(ncid); return false; } // a negative value for error indicates that the data // is totally invalid so don't scale that imagingData.PixelData[i].Error[j][k] = (Float)tempError; if (tempError > 0) imagingData->PixelData[i].Error[j][k] /= (Float)UNCERTAINTY_SCALE_FACTOR; } // of for all along track pixels } // of for all colors status = nc_get_var1_int(ncid, irID, dim2, (int*) &imagingData.PixelData[i].InputRate); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AImaging: Can't read input rate\n"); nc_close(ncid); return false; } status = nc_get_var1_int(ncid, orID, dim2, (int*) &imagingData.PixelData[i].OutputRate); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AImaging: Can't read OUTPUT RATE\n"); nc_close(ncid); return false; } } // of for all cross track pixels orbitIData.push_back(orbitIData); } // for all scans // finished reading so close the netcdf file nc_close(ncid); return true; } //////////////////////////////////////////////////////////// // // Method: ReadLevel1AStaticImaging // // Description: This method reads the GUVI level 1A data // netcdf file. This method returns a single // orbits worth of static imaging data for every // call // // Inputs: // Name Description // ---- ----------- // inFileName file name of data to be read // orbitSiData a pointer to the data to be read // // Return: // Name Description // ---- ----------- // n/a true = successful read // false = unsuccessful read // bool NetCDFFileIO::ReadLevel1AStaticImaging( string inFileName, OrbitOfStaticImaging& orbitSiData ) { // to store a single scans worth of data StatImagFormat siData; // indicates which scan number we're currently on Integer scanNum; size_t numScans; Integer status; Integer ncid; // netcdf file id // the following are used for the netcdf variable // ids Integer scanDim; Integer xtrkDim; Integer alongTrkDim; Integer colorDim; Integer dcDim; Integer bcDim; // netcdf variables defined in file Integer timeID; Integer detectorID; Integer slitID; Integer mirrorID; Integer fineTimeID; Integer dcID; Integer bcID; Integer pixelID; Integer errorID; Integer irID; Integer orID; Integer dqID; Short tempError; // holding value for scaled error // open the file specified by inFileName status = nc_open(inFileName.c_str(), NC_NOWRITE, &ncid); // check if the file open was successful if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AStaticImaging: Can't open netcdf file, name\n", inFileName.c_str()); return false; } // get the netcdf dimension ids status = nc_inq_dimid(ncid, "perScan", &scanDim); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AStaticImaging: Can't find scan dim\n"); nc_close(ncid); return false; } status = nc_inq_dimid(ncid, "perCrossTrackPixels", &xtrkDim); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AStaticImaging: Can't find xtrk dim\n"); nc_close(ncid); return false; } status = nc_inq_dimid(ncid, "perAlongTrackPixels", &alongTrkDim); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AStaticImaging: Can't find along track dim\n"); nc_close(ncid); return false; } status = nc_inq_dimid(ncid, "perColors", &colorDim); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AStaticImaging: Can't find color dim\n"); nc_close(ncid); return false; } status = nc_inq_dimid(ncid, "perDarkCountPixels", &dcDim); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AStaticImaging: Can't find dark count pixels dim\n"); nc_close(ncid); return false; } status = nc_inq_dimid(ncid, "perBackgroundCountPixels", &bcDim); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AStaticImaging: Can't find background count pixels dim\n"); nc_close(ncid); return false; } // get all of the variable ids. doing it here since it's not dependent // upon which indices you're looking at in a dimensional field status = nc_inq_varid(ncid, "Time", &timeID); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AStaticImaging: Can't find time\n"); nc_close(ncid); return false; } status = nc_inq_varid(ncid, "FineTime", &fineTimeID); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AStaticImaging: Can't find fine time\n"); nc_close(ncid); return false; } status = nc_inq_varid(ncid, "Detector", &detectorID); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AStaticImaging: Can't find Detector\n"); nc_close(ncid); return false; } status = nc_inq_varid(ncid, "Slit", &slitID); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AStaticImaging: Can't find slit\n"); nc_close(ncid); return false; } status = nc_inq_varid(ncid, "Mirror", &mirrorID); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AStaticImaging: Can't find mirror\n"); nc_close(ncid); return false; } size_t countdc[] = {1, NUM_DARK_COUNT_PIXELS}; status = nc_inq_varid(ncid, "DarkCountPixels", &dcID); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AStaticImaging: Can't find variable dark counts\n"); nc_close(ncid); return false; } size_t countbc[] = {1, NUM_X_BACKGROUND_PIXELS * NUM_Y_BACKGROUND_PIXELS}; status = nc_inq_varid(ncid, "BackgroundPixels", &bcID); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AStaticImaging: Can't find variable backgrund counts\n"); nc_close(ncid); return false; } status = nc_inq_varid(ncid, "DataQualityIndicator", &dqID); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AStaticImaging: Can't find data quality\n"); nc_close(ncid); return false; } status = nc_inq_varid(ncid, "PixelData", &pixelID); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AStaticImaging: Can't find variable pixel data\n"); nc_close(ncid); return false; } status = nc_inq_varid(ncid, "Error", &errorID); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AStaticImaging: Can't find variable error\n"); nc_close(ncid); return false; } status = nc_inq_varid(ncid, "InputRate", &irID); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AStaticImaging: Can't find variable input rate data\n"); nc_close(ncid); return false; } status = nc_inq_varid(ncid, "OutputRate", &orID); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AStaticImaging: Can't find variable output rate data\n"); nc_close(ncid); return false; } // find out how many scans are in the file so that they can all be // processed status = nc_inq_dimlen(ncid, scanDim, &numScans); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AStaticImaging: Can't get num of dimensions for perScan\n"); nc_close(ncid); return false; } // now get data from the data product file for all scans for (scanNum = 0; scanNum numScans; scanNum++) { // first get the data that appears on a scan basis but // to do that have to first find out what variable // corresponds with the approrpriate variable id and // then issue a netcdf to get the associated data size_t startscan[1] = {scanNum}; status = nc_get_var1_long(ncid, timeID, startscan, &siData.ScanData.MsecsOfDay); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AStaticImaging: Can't read time\n"); nc_close(ncid); return false; } status = nc_get_var1_uchar(ncid, detectorID, startscan, &siData.ScanData.DetectorNum); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AStaticImaging: Can't read detector num\n"); nc_close(ncid); return false; } status = nc_get_var1_uchar(ncid, slitID, startscan, &siData.ScanData.SlitPosition); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AStaticImaging: Can't read slit position\n"); nc_close(ncid); return false; } status = nc_get_var1_short(ncid, mirrorID, startscan, &siData.ScanData.MirrorPosition); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AStaticImaging: Can't read mirror position\n"); nc_close(ncid); return false; } size_t startdc[2] = {scanNum, 0}; status = nc_get_var1_short(ncid, dcID, startdc, countdc, siData.ScanData.DarkCountPixel); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AStaticImaging: Can't read dark count pixels\n"); nc_close(ncid); return false; } size_t startbc[2] = {scanNum, 0}; status = nc_get_vara_short(ncid, bcID, startbc, countbc, siData->ScanData.BackgroundCountPixel); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AStaticImaging: Can't read background count pixels\n"); nc_close(ncid); return false; } status = nc_get_var1_uchar(ncid, dqID, startscan, &siData.ScanData.DataQuality); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AStaticImaging: Can't read data quality\n"); nc_close(ncid); return false; } // now add the static imaging pixel data that has already // been uncompressed and the other imaging data that // appears on a cross track basis size_t dim2[2] = {scanNum, 0}; size_t dim4[4] = {scanNum, 0, 0, 0}; // need to go through the static imaging data record for // all crosstracks because netcdf has a problem with mixing // record fields with arrays for (Integer i = 0; i TOTAL_CROSS_TRACK_PIXELS; i++) { dim2[1] = i; dim4[1] = i; status = nc_get_var1_float(ncid, fineTimeID, dim2, &siData.PixelData[i].FineTime); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AStaticImaging: Can't read fine time\n"); nc_close(ncid); return false; } // need to go through the static imaging data record // also for all imaging colors also due to a netcdf // bug or quirk for (Integer j = 0; j NUM_IMAGING_COLORS; j++) { dim4[2] = j; // and all colors for (Integer k = 0; k NUM_ALONG_TRACK_PIXELS; k++) { // set the array position for the appropriate cross track // pixel index dim4[3] = k; status = nc_get_var1_float(ncid, pixelID, dim4, &siData.PixelData[i].Pixel[j][k]); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AStaticImaging: Can't read pixel data\n"); nc_close(ncid); return false; } status = nc_get_var1_short(ncid, errorID, dim4, &tempError); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AStaticImaging: Can't read error\n"); nc_close(ncid); return false; } // a negative value for error indicates that the data // is totally invalid so don't scale that siData->PixelData[i].Error[j][k] = (Float)tempError; if (tempError > 0) siData->PixelData[i].Error[j][k] /= (Float)UNCERTAINTY_SCALE_FACTOR; } // of for all along track pixels } // of for all colors status = nc_get_var1_int(ncid, irID, dim2, (int*) &siData.PixelData[i].InputRate); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AStaticImaging: Can't read input rate\n"); nc_close(ncid); return false; } status = nc_get_var1_int(ncid, orID, dim2, (int*) &siData.PixelData[i].OutputRate); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1AStaticImaging: Can't read OUTPUT RATE\n"); nc_close(ncid); return false; } } // of for all cross track pixels orbitIData.push_back(orbitSiData); } // for all scans // finished reading so close the netcdf file nc_close(ncid); return true; } //////////////////////////////////////////////////////////// // // Method: ReadLevel1ASpectrograph // // Description: This method reads the GUVI level 1A data // netcdf file. This method returns a single // orbits worth of spectrograph data for every // call // // Inputs: // Name Description // ---- ----------- // inFileName file name of data to be read // orbitSpData a pointer to the data to be read // // Return: // Name Description // ---- ----------- // n/a true = successful read // false = unsuccessful read // bool NetCDFFileIO::ReadLevel1ASpectrograph( string inFileName, OrbitOfSpectrograph& orbitSpData ) { // to store a single scans worth of data SpectrographFormat* spData; // indicates which scan number we're currently on Integer scanNum; size_t numScans; Integer status; Integer ncid; // netcdf file id // the following are used for the netcdf variable // ids Integer scanDim; Integer alongTrkDim; Integer colorDim; Integer dcDim; Integer bcDim; // netcdf variables defined in file Integer timeID; Integer detectorID; Integer slitID; Integer mirrorID; Integer dcID; Integer bcID; Integer pixelID; Integer errorID; Integer irID; Integer orID; Integer dqID; Short tempError; // holding value for scaled error // open the file specified by inFileName status = nc_open(inFileName.c_str(), NC_NOWRITE, &ncid); // check if the file open was successful if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1ASpectrograph: Can't open netcdf file, name\n", inFileName.c_str() ); return false; } // get the netcdf dimension ids status = nc_inq_dimid(ncid, "perScan", &scanDim); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1ASpectrograph: Can't find scan dim\n"); nc_close(ncid); return false; } status = nc_inq_dimid(ncid, "perAlongTrackPixels", &alongTrkDim); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1ASpectrograph: Can't find along track dim\n"); nc_close(ncid); return false; } status = nc_inq_dimid(ncid, "perColors", &colorDim); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1ASpectrograph: Can't find color dim\n"); nc_close(ncid); return false; } status = nc_inq_dimid(ncid, "perDarkCountPixels", &dcDim); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1ASpectrograph: Can't find dark count pixels dim\n"); nc_close(ncid); return false; } status = nc_inq_dimid(ncid, "perBackgroundCountPixels", &bcDim); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1ASpectrograph: Can't find background count pixels dim\n"); nc_close(ncid); return false; } // get all of the variable ids. doing it here since it's not dependent // upon which indices you're looking at in a dimensional field status = nc_inq_varid(ncid, "Time", &timeID); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1ASpectrograph: Can't find time\n"); nc_close(ncid); return false; } status = nc_inq_varid(ncid, "Detector", &detectorID); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1ASpectrograph: Can't find Detector\n"); nc_close(ncid); return false; } status = nc_inq_varid(ncid, "Slit", &slitID); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1ASpectrograph: Can't find slit\n"); nc_close(ncid); return false; } status = nc_inq_varid(ncid, "Mirror", &mirrorID); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1ASpectrograph: Can't find mirror\n"); nc_close(ncid); return false; } size_t countdc[] = {1, NUM_DARK_COUNT_PIXELS}; status = nc_inq_varid(ncid, "DarkCountPixels", &dcID); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1ASpectrograph: Can't find variable dark counts\n"); nc_close(ncid); return false; } size_t countbc[] = {1, NUM_X_BACKGROUND_PIXELS * NUM_Y_BACKGROUND_PIXELS}; status = nc_inq_varid(ncid, "BackgroundPixels", &bcID); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1ASpectrograph: Can't find variable backgrund counts\n"); nc_close(ncid); return false; } status = nc_inq_varid(ncid, "DataQualityIndicator", &dqID); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1ASpectrograph: Can't find data quality\n"); nc_close(ncid); return false; } status = nc_inq_varid(ncid, "PixelData", &pixelID); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1ASpectrograph: Can't find variable pixel data\n"); nc_close(ncid); return false; } status = nc_inq_varid(ncid, "Error", &errorID); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1ASpectrograph: Can't find variable error\n"); nc_close(ncid); return false; } status = nc_inq_varid(ncid, "InputRate", &irID); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1ASpectrograph: Can't find variable input rate data\n"); nc_close(ncid); return false; } status = nc_inq_varid(ncid, "OutputRate", &orID); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1ASpectrograph: Can't find variable output rate data\n"); nc_close(ncid); return false; } // find out how many scans are in the file so that they can all be // processed status = nc_inq_dimlen(ncid, scanDim, &numScans); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1ASpectrograph: Can't get num of dimensions for perScan\n"); nc_close(ncid); return false; } // now get data from the data product file for all scans for (scanNum = 0; scanNum numScans; scanNum++) { // first get the data that appears on a scan basis but // to do that have to first find out what variable // corresponds with the approrpriate variable id and // then issue a netcdf to get the associated data size_t startscan[1] = {scanNum}; status = nc_get_var1_long(ncid, timeID, startscan, &spData.ScanData.MsecsOfDay); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1ASpectrograph: Can't read time\n"); nc_close(ncid); return false; } status = nc_get_var1_uchar(ncid, detectorID, startscan, &spData.ScanData.DetectorNum); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1ASpectrograph: Can't read detector num\n"); nc_close(ncid); return false; } status = nc_get_var1_uchar(ncid, slitID, startscan, &spData.ScanData.SlitPosition); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1ASpectrograph: Can't read slit position\n"); nc_close(ncid); return false; } status = nc_get_var1_short(ncid, mirrorID, startscan, &spData.ScanData.MirrorPosition); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1ASpectrograph: Can't read mirror position\n"); nc_close(ncid); return false; } status = nc_get_var1_int(ncid, irID, startscan, (int*) &spData.ScanData.InputRate); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1ASpectrograph: Can't read input rate\n"); nc_close(ncid); return false; } status = nc_get_var1_int(ncid, orID, startscan, (int*) &spData.ScanData.OutputRate); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1ASpectrograph: Can't read OUTPUT RATE\n"); nc_close(ncid); return false; } size_t startdc[2] = {scanNum, 0}; status = nc_get_vara_short(ncid, dcID, startdc, countdc, spData.ScanData.DarkCountPixel); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1ASpectrograph: Can't read dark count pixels\n"); nc_close(ncid); return false; } size_t startbc[2] = {scanNum, 0}; status = nc_get_vara_short(ncid, bcID, startbc, countbc, spData.ScanData.BackgroundCountPixel); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1ASpectrograph: Can't read background count pixels\n"); nc_close(ncid); return false; } status = nc_get_var1_uchar(ncid, dqID, startscan, &spData.ScanData.DataQuality); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1ASpectrograph: Can't read data quality\n"); nc_close(ncid); return false; } // now add the spectrograph pixel data that has already // been uncompressed and the other imaging data that // appears on a cross track basis size_t dim3[3] = {scanNum, 0, 0}; // need to go through the spectrograph data record for // all crosstracks because netcdf has a problem with mixing // record fields with arrays for (Integer i = 0; i NUM_ALONG_TRACK_PIXELS; i++) { dim3[1] = i; // need to go through the spectrograph data record // also for all spectrograph colors also due to a // netcdf bug or quirk for (Integer j = 0; j NUM_SPECTROGRAPH_COLORS; j++) { dim3[2] = j; status = nc_get_var1_float(ncid, pixelID, dim3, &spData.PixelData[i].Pixel[j]); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1ASpectrograph: Can't read pixel data\n"); nc_close(ncid); return false; } status = nc_get_var1_short(ncid, errorID, dim3, &tempError); if (status != NC_NOERR) { LogMessage(LOG_ERROR, "NetCDFFileIO.ReadLevel1ASpectrograph: Can't read error\n"); nc_close(ncid); return false; } // a negative value for error indicates that the data // is totally invalid so don't scale that spData->PixelData[i].Error[j] = (Float)tempError; if (tempError > 0) spData.PixelData[i].Error[j] /= (Float)UNCERTAINTY_SCALE_FACTOR; } // of for all colors } // of for all along track pixels orbitSiData.push_back(orbitSpData); } // for all scans // finished reading so close the netcdf file nc_close(ncid); return true; } // End of file