/***************************************************************************** * Routines to write a GHRSTT-PP Net CDF file level 2p file for the GOES * data. Currently written to conform to the GDS-1.6 * * Author: Jonathan Mittaz UMD CICS/ESSIC */ /* Version history : * * 20 March 2006 - Original version : Jonathan Mittaz * 19 March 2006 - Tidied up code : Jonathan Mittaz * 26 Jan 2012 - Added in code to do GDS2.0 * */ /* Routine names * * checkNCError : check for an error with the nedtDF * makeVarB : output to a netCDF file a byte variable * makeVarS : output to a netCDF file a short variable * writeNetCDF : routine that is called to write the output file */ /* Include files */ #include #include #include #include #include #include #include #ifndef GDS16 #include #endif /* Include routines from other parts of the code */ #include #include #include #define MAX_STRING_LENGTH 500 /* Define some macros */ #define myMIN(a,b) ((a < b) ? a : b) #define myMAX(a,b) ((a > b) ? a : b) /* Define prototypes */ void checkNCError( int errorCode, int lineNo ); void makeVarB( int ncFileId, char *pName, int ndims, int *pDims, size_t *pSize, signed char *pArray, int *pVarId, char *pLongName, char *pUnits, signed char fillVal, float offset, float factor, signed char minval, signed char maxval, char *pCoords, char *pSource, char *pReference,char *pReferences, char *pComment, char *pGridMapping, char *pDTime, char *pFlagMeanings, char *pFlagValues, int nFlagValues, char *pStandard_Name, char *pAxis, char *pHeight ); void makeVarS( int ncFileId, char *pName, int ndims, int *pDims, size_t *pSize, short *pArray, int *pVarId, char *pLongName, char *pUnits, short fillVal, float offset, float factor, short minval, short maxval, char *pCoords, char *pSource, char *pReference, char *pReferences, char *pComment, char *pGridMapping, char *pFlagMask, char *pFlagMeanings, int nFlagValues, char *pFlagValues, char *pStandard_Name, char *pAxis ); void makeVarSd( int ncFileId, char *pName, int ndims, int *pDims, size_t *pSize, short *pArray, int *pVarId, char *pLongName, char *pUnits, short fillVal, float offset, float factor, short minval, short maxval, char *pCoords, char *pSource, char *pReference, char *pReferences, char *pComment, char *pGridMapping, char *pDepth, char *pStandard_Name, char *pAxis ); /* Main writing routine */ #ifdef GDS16 void writeNetCDF( int Year, int Month, int Day, int Hour, int Min, int Seconds, char *pSatelliteName, char *pNorthSouth, int spatial_res, char *inFile, char *pStartTime, char *pStopTime, char *pStartDate, char *pStopDate, float minLat, float maxLat, float minLong, float maxLong, int nele, int nlin, int inTime, float *pLongitude, float *pLatitude, short *pSST, short *pSST_DTimeArr, signed char *pSSES_Bias, signed char *pSSES_StdDev, signed char *pSSI, signed char *pSSI_DTimeArr, signed char *pSSISrc, signed char *pDT, signed char *pWindSpeedArr, signed char *pWindSpeed_DTimeArr, signed char *pWindSpeedSrc, signed char *pAerosolArr, signed char *pAerosol_DTimeArr, signed char *pAerosolSrc, signed char *pIceArr, signed char *pIceSrc, signed char *pZenithArr, signed char *pRejection, signed char *pConfidence, signed char *pProximity, signed char *pClearSkyProb, int startYear, int startMonth, int startDay, int startHours, int startMins, int startSecs, int stopYear, int stopMonth, int stopDay, int stopHours, int stopMin, int stopSecs, char *pSpatial_Resolution, float spatial_res_lat, float spatial_res_lon, char *pSensor, float *pIce_DTime, signed char *pADIArr, signed char *pADI_DTimeArr, signed char *pSolarZenith, signed char *pDiurnalEstimate ) #else void writeNetCDF( int Year, int Month, int Day, int Hour, int Min, int Seconds, char *pSatelliteName, char *pNorthSouth, int spatial_res, char *inFile, char *pStartTime, char *pStopTime, char *pStartDate, char *pStopDate, float minLat, float maxLat, float minLong, float maxLong, int nele, int nlin, int inTime, float *pLongitude, float *pLatitude, short *pSST, short *pSST_DTimeArr, signed char *pSSES_Bias, signed char *pSSES_StdDev, signed char *pSSI, signed char *pSSI_DTimeArr, signed char *pSSISrc, signed char *pDT, signed char *pWindSpeedArr, signed char *pWindSpeed_DTimeArr, signed char *pWindSpeedSrc, signed char *pAerosolArr, signed char *pAerosol_DTimeArr, signed char *pAerosolSrc, signed char *pIceArr, signed char *pIceSrc, signed char *pZenithArr, short *pRejection, signed char *pConfidence, signed char *pProximity, signed char *pClearSkyProb, int startYear, int startMonth, int startDay, int startHours, int startMins, int startSecs, int stopYear, int stopMonth, int stopDay, int stopHours, int stopMin, int stopSecs, char *pSpatial_Resolution, float spatial_res_lat, float spatial_res_lon, char *pSensor, float *pIce_DTime, signed char *pADIArr, signed char *pADI_DTimeArr, signed char *pSolarZenith, signed char *pDiurnalEstimate ) #endif { int ni_dim = 0; int nj_dim = 0; int time_dim = 0; int dims[3] = {0,0,0}; size_t start[3] = {0,0,0}; size_t count[3] = {0,0,0}; size_t sizes[3] = {0,0,0}; char filename[MAX_STRING_LENGTH]; char string[MAX_STRING_LENGTH]; char source[MAX_STRING_LENGTH]; short intVal = 0; float fltVal = 0.; int ncFileId = 0; int errorCode = 0; int latId = 0; int lonId = 0; int timeId = 0; int sstId = 0; int sstDtId = 0; int ssesBiasId = 0; int ssesStdevId = 0; int dtId = 0; int ssiId = 0; int ssiDtId = 0; int windId = 0; int windDtId = 0; int iceId = 0; int aerosolId = 0; int aerosolDtId = 0; int windSrcId = 0; int SSISrcId = 0; int IceSrcId = 0; int AerosolSrcId = 0; int zenId = 0; int solarzenId = 0; int rejectionId = 0; int confidenceId = 0; int proximityId = 0; int clearSkyId = 0; int diurnalEstId = 0; int ADIId = 0; int ADIDtId = 0; int i = 0; time_t currTime = 0; struct tm *pBroken_time; #ifndef GDS16 uuid_t uuid; char uuid_string[MAX_STRING_LENGTH]; #endif char ice_dtime_string[MAX_STRING_LENGTH]; FILE *fp = NULL; #ifndef GDS16 struct tm *pCurrTime_str = NULL; #endif if( 0 != strncmp(pNorthSouth," ",1) ){ #ifdef GDS16 sprintf(string, "netcdf_output/%4.4d%2.2d%2.2d-%s-OSPO-L2P-%s_%s_%2.2d%2.2dZ-v01.nc", Year,Month,Day,pSatelliteName,pSatelliteName,pNorthSouth,Hour,Min); #else sprintf(string, "netcdf_output/%4.4d%2.2d%2.2d%2.2d%2.2d%2.2d-OSPO-L2P_GHRSST-SSTskin-%s-%s-v02.0-fv01.0.nc", Year,Month,Day,Hour,Min,Seconds,pSatelliteName,pNorthSouth); #endif } else { #ifdef GDS16 sprintf(string, "netcdf_output/%4.4d%2.2d%2.2d-%s-OSPO-L2P-%s_%2.2d%2.2dZ-v01.nc", Year,Month,Day,pSatelliteName,pSatelliteName,Hour,Min); #else sprintf(string, "netcdf_output/%4.4d%2.2d%2.2d%2.2d%2.2d%2.2d-OSPO-L2P_GHRSST-SSTskin-%s-v02.0-fv01.0.nc", Year,Month,Day,Hour,Min,Seconds,pSatelliteName); #endif } strcpy(filename,DATA_DIR); strcat(filename,string); printf("L2P: Writing to file %s\n",filename); /* Open netCDF file */ #ifdef GDS16 errorCode = nc_create( filename, NC_CLOBBER, &ncFileId ); checkNCError( errorCode, 26 ); #else errorCode = nc_create( filename, NC_CLASSIC_MODEL | NC_NETCDF4 | NC_CLOBBER, &ncFileId ); checkNCError( errorCode, 26 ); #endif /* Global attributes */ #ifdef GDS16 strcpy(string,"CF-1.0"); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "Conventions", strlen(string), string ); checkNCError( errorCode, 200 ); sprintf(string,"OSPO-L2P-%s",pSatelliteName); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "DSD_entry_id", strlen(string), string ); checkNCError( errorCode, 200 ); #else strcpy(string,"CF-1.4, Unidata Observation Dataset v1.0"); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "Conventions", strlen(string), string ); checkNCError( errorCode, 200 ); if( 0 != strncmp(pNorthSouth," ",1) ){ sprintf(string,"SST from %s %s",pSatelliteName,pNorthSouth); } else { sprintf(string,"SST from %s",pSatelliteName); } #endif sprintf(string, "Sea Surface Temperature from %s generated by OSPO", pSatelliteName); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "title", strlen(string), string ); checkNCError( errorCode, 201 ); #ifndef GDS16 if( 0 != strncmp(pNorthSouth," ",1) ){ sprintf(string,"The L2P product for %s (%s sector). The SST product was generated using the NOAA version of the Generalized Bayesian Cloud Screening code from the University of Edinburgh. A description of the algorithms can be found in Maturi et al. 2009, BAMS, 26, 570-581",pSatelliteName,pNorthSouth); } else { sprintf(string,"The L2P product for %s. The SST product was generated using the NOAA version of the Generalized Bayesian Cloud Screening code from the University of Edinburgh. A description of the algorithms can be found in Maturi et al. 2009, BAMS, 26, 570-581",pSatelliteName); } errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "summary", strlen(string), string ); checkNCError( errorCode, 200 ); #endif #ifdef GDS16 strcpy(string,"File specification: GHRSST Data Processing Specification v1.6. SST Algorithm: ATBD Bayesian Cloud Screening for GOES-12 (NOAA/NESDIS)"); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "references", strlen(string), string ); checkNCError( errorCode, 202 ); #else strcpy(string,"File specification: GHRSST Data Processing Specification v2.0. SST Algorithm: ATBD Baysian Cloud Screening for GOES-12 (NOAA/NESDIS)"); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "references", strlen(string), string ); checkNCError( errorCode, 202 ); #endif strcpy(string,"OSPO"); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "institution", strlen(string), string ); checkNCError( errorCode, 203 ); strcpy(string,"1.0"); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "product_version", strlen(string), string ); checkNCError( errorCode, 200 ); strcpy(string,"L2P created at NOAA/OSPO"); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "history", strlen(string), string ); checkNCError( errorCode, 209 ); #ifndef GDS16 strcpy(string,"Data derived using the Modularized Bayesian (GBCS) code with a Bayesian based cloud clearing methodology and a Physically based algorithm for SST generation"); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "comment", strlen(string), string ); checkNCError( errorCode, 203 ); strcpy(string,"GHRSST protocol describes data use as free and open"); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "license", strlen(string), string ); checkNCError( errorCode, 203 ); sprintf(string,"OSPO-%s-L2P-v1.0",pSatelliteName); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "id", strlen(string), string ); checkNCError( errorCode, 200 ); strcpy(string,"org.ghrsst"); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "naming_authority", strlen(string), string ); checkNCError( errorCode, 200 ); uuid_generate(uuid); sprintf(uuid_string,"%x%x%x%x-%x%x-%x%x-%x%x-%x%x%x%x%x%x", uuid[0],uuid[1],uuid[2],uuid[3],uuid[4],uuid[5],uuid[6], uuid[7],uuid[8],uuid[9],uuid[10],uuid[11],uuid[12], uuid[13],uuid[14],uuid[15]); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "uuid", strlen(uuid_string), uuid_string ); checkNCError( errorCode, 200 ); strcpy(string,"2.0"); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "gds_version_id", strlen(string), string ); checkNCError( errorCode, 205 ); #else strcpy(string,"v1.0-rev1.6"); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "GDS_version_id", strlen(string), string ); checkNCError( errorCode, 205 ); #endif strcpy(string,nc_inq_libvers()); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "netcdf_version_id", strlen(string), string ); checkNCError( errorCode, 206 ); currTime = time(NULL); #ifdef GDS16 strcpy(string,ctime(&currTime)); for(i=0;itm_year+1900, pCurrTime_str->tm_mon+1,pCurrTime_str->tm_mday,pCurrTime_str->tm_hour, pCurrTime_str->tm_min,pCurrTime_str->tm_sec); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "date_created", strlen(string), string ); checkNCError( errorCode, 207 ); #endif #ifndef GDS16 intVal = 3; errorCode = nc_put_att_short( ncFileId, NC_GLOBAL, "file_quality_level", NC_INT, 1, &intVal ); checkNCError( errorCode, 208 ); #endif errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "spatial_resolution", strlen(pSpatial_Resolution), pSpatial_Resolution ); checkNCError( errorCode, 212 ); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "start_time", strlen(pStartTime), pStartTime ); checkNCError( errorCode, 213 ); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "start_time", strlen(pStartTime), pStartTime ); checkNCError( errorCode, 213 ); #ifdef GDS16 errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "start_date", strlen(pStartDate), pStartDate ); checkNCError( errorCode, 213 ); #else errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "time_coverage_start", strlen(pStartTime), pStartTime ); checkNCError( errorCode, 213 ); #endif errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "stop_time", strlen(pStopTime), pStopTime ); checkNCError( errorCode, 214 ); #ifdef GDS16 errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "stop_date", strlen(pStopDate), pStopDate ); checkNCError( errorCode, 213 ); #else errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "time_coverage_end", strlen(pStopTime), pStopTime ); checkNCError( errorCode, 214 ); #endif errorCode = nc_put_att_float( ncFileId, NC_GLOBAL, "northernmost_latitude", NC_FLOAT, 1, &maxLat ); checkNCError( errorCode, 217 ); errorCode = nc_put_att_float( ncFileId, NC_GLOBAL, "southernmost_latitude", NC_FLOAT, 1, &minLat ); checkNCError( errorCode, 218 ); errorCode = nc_put_att_float( ncFileId, NC_GLOBAL, "easternmost_longitude", NC_FLOAT, 1, &maxLong ); checkNCError( errorCode, 200 ); errorCode = nc_put_att_float( ncFileId, NC_GLOBAL, "westernmost_longitude", NC_FLOAT, 1, &minLong ); checkNCError( errorCode, 200 ); #ifndef GDS16 sprintf(string,"OSPO-L2P-%s,NOAA-NCEP-GFS,NOAA-NCEP-RTG_SST_HR,NOAA-OSPO-AOT_DAILY",pSatelliteName); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "source", strlen(string), string ); checkNCError( errorCode, 210 ); #endif strcpy(string,pSatelliteName); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "platform", strlen(string), string ); checkNCError( errorCode, 210 ); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "sensor", strlen(pSensor), pSensor ); checkNCError( errorCode, 211 ); #ifndef GDS16 strcpy(string,"Unidata Dataset Discovery v1.0"); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "Metadata_Conventions", strlen(string), string ); checkNCError( errorCode, 211 ); sprintf(string,"http://podaac.jpl.nasa.gov/ws/metadata/dataset/?format=iso&shortName=%s-OSPO-L2P-v1.0",pSatelliteName); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "metadata_link", strlen(string), string ); checkNCError( errorCode, 211 ); strcpy(string,"Oceans > Ocean Temperature > Sea Surface Temperature"); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "keywords", strlen(string), string ); checkNCError( errorCode, 211 ); strcpy(string,"NASA Global Change Master Directory (GCMD) Science Keywords"); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "keywords_vocabulary", strlen(string), string ); checkNCError( errorCode, 211 ); strcpy(string,"NetCDF Climate and Forecast (CF) Metadata Convention"); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "standard_name_vocabulary", strlen(string), string ); checkNCError( errorCode, 211 ); strcpy(string,"degrees_north"); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "geospatial_lat_units", strlen(string), string ); checkNCError( errorCode, 211 ); sprintf(string,"%5.3f",spatial_res_lat); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "geospatial_lat_resolution", strlen(string), string ); checkNCError( errorCode, 211 ); strcpy(string,"degrees_east"); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "geospatial_lon_units", strlen(string), string ); checkNCError( errorCode, 211 ); sprintf(string,"%5.3f",spatial_res_lat); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "geospatial_lon_resolution", strlen(string), string ); checkNCError( errorCode, 211 ); #endif #ifdef GDS16 strcpy(string,"Eileen Maturi (Eileen.Maturi@noaa.gov)"); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "contact", strlen(string), string ); checkNCError( errorCode, 204 ); #else /* Lat/Lon resolution */ strcpy(string,"Please acknowledge the use of these data with the following statement: These data were provided by GHRSST and the U.S. National Oceanic and Atmospheric Administration"); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "acknowledgment", strlen(string), string ); checkNCError( errorCode, 204 ); strcpy(string,"Eileen Maturi"); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "creator_name", strlen(string), string ); checkNCError( errorCode, 204 ); strcpy(string,"Eileen.Maturi@noaa.gov"); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "creator_email", strlen(string), string ); checkNCError( errorCode, 204 ); strcpy(string,"http://www.star.nesdis.noaa.gov/sod/mecb/goes_validation/test/top_background.php"); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "creator_url", strlen(string), string ); checkNCError( errorCode, 204 ); strcpy(string,"Group for High Resolution Sea Surface Temperature"); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "project", strlen(string), string ); checkNCError( errorCode, 204 ); strcpy(string,"The GHRSST Project Office"); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "publisher_name", strlen(string), string ); checkNCError( errorCode, 204 ); strcpy(string,"http://www.ghrsst.org"); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "publisher_url", strlen(string), string ); checkNCError( errorCode, 204 ); strcpy(string,"ghrsst-po@nceo.ac.uk"); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "publisher_email", strlen(string), string ); checkNCError( errorCode, 204 ); strcpy(string,"L2P"); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "processing_level", strlen(string), string ); checkNCError( errorCode, 204 ); strcpy(string,"swath"); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "cdm_data_type", strlen(string), string ); checkNCError( errorCode, 204 ); #endif #ifdef GDS16 intVal = 1; errorCode = nc_put_att_short( ncFileId, NC_GLOBAL, "file_quality_index", NC_SHORT, 1, &intVal ); checkNCError( errorCode, 200 ); strcpy(string,"WARNING Some applications are unable to properly handle signed byte values. If values are encountered > 127, please subtract 256 from this reported value "); errorCode = nc_put_att_text( ncFileId, NC_GLOBAL, "comment", strlen(string), string ); checkNCError( errorCode, 200 ); #endif /* Create time/ni/nj dimensions */ /* Note this is backwards to the C convention */ errorCode = nc_def_dim( ncFileId, "time", 1, &time_dim ); checkNCError( errorCode, 29 ); errorCode = nc_def_dim( ncFileId, "ni", nele, &ni_dim ); checkNCError( errorCode, 27 ); errorCode = nc_def_dim( ncFileId, "nj", nlin, &nj_dim ); checkNCError( errorCode, 28 ); dims[0] = nj_dim; dims[1] = ni_dim; /* Add coordinates Lat/Long and time */ errorCode = nc_def_var( ncFileId, "lat", NC_FLOAT, 2, &dims[0], &latId ); checkNCError( errorCode, 30 ); #ifndef GDS16 /* Set compression */ errorCode = nc_def_var_deflate(ncFileId, latId, 0, 1, 9); checkNCError( errorCode, 900 ); #endif errorCode = nc_def_var( ncFileId, "lon", NC_FLOAT, 2, &dims[0], &lonId ); checkNCError( errorCode, 31 ); #ifndef GDS16 /* Set compression */ errorCode = nc_def_var_deflate(ncFileId, lonId, 0, 1, 9); checkNCError( errorCode, 901 ); #endif /* write attributes */ strcpy(string,"latitude"); errorCode = nc_put_att_text( ncFileId, latId, "long_name", strlen(string), string ); checkNCError( errorCode, 33 ); strcpy(string,"degrees_north"); errorCode = nc_put_att_text( ncFileId, latId, "units", strlen(string), string ); checkNCError( errorCode, 34 ); fltVal = -FLT_MAX; errorCode = nc_put_att_float( ncFileId, latId, "_FillValue", NC_FLOAT, 1, &fltVal ); checkNCError( errorCode, 35 ); #ifndef GDS16 fltVal = -90.; errorCode = nc_put_att_float( ncFileId, latId, "valid_min", NC_FLOAT, 1, &fltVal ); checkNCError( errorCode, 35 ); fltVal = 90.; errorCode = nc_put_att_float( ncFileId, latId, "valid_max", NC_FLOAT, 1, &fltVal ); checkNCError( errorCode, 35 ); strcpy(string,"latitude from McIDAS derived data"); errorCode = nc_put_att_text( ncFileId, latId, "comment", strlen(string), string ); checkNCError( errorCode, 34 ); sprintf(string,"%s-OSPO-L2P-v1.0",pSatelliteName); errorCode = nc_put_att_text( ncFileId, latId, "source", strlen(string), string ); checkNCError( errorCode, 34 ); #ifdef OLDGDS2 sprintf(string,"geographical coordinates, WGS84 projection"); errorCode = nc_put_att_text( ncFileId, latId, "reference_datum", strlen(string), string ); checkNCError( errorCode, 34 ); #endif sprintf(string,"Y"); errorCode = nc_put_att_text( ncFileId, latId, "axis", strlen(string), string ); checkNCError( errorCode, 34 ); sprintf(string,"latitude"); errorCode = nc_put_att_text( ncFileId, latId, "standard_name", strlen(string), string ); checkNCError( errorCode, 34 ); #endif /* write attributes */ strcpy(string,"longitude"); errorCode = nc_put_att_text( ncFileId, lonId, "long_name", strlen(string), string ); checkNCError( errorCode, 37 ); strcpy(string,"degrees_east"); errorCode = nc_put_att_text( ncFileId, lonId, "units", strlen(string), string ); checkNCError( errorCode, 38 ); fltVal = -FLT_MAX; errorCode = nc_put_att_float( ncFileId, lonId, "_FillValue", NC_FLOAT, 1, &fltVal ); checkNCError( errorCode, 39 ); #ifndef GDS16 fltVal = -180.; errorCode = nc_put_att_float( ncFileId, lonId, "valid_min", NC_FLOAT, 1, &fltVal ); checkNCError( errorCode, 35 ); fltVal = 180.; errorCode = nc_put_att_float( ncFileId, lonId, "valid_max", NC_FLOAT, 1, &fltVal ); checkNCError( errorCode, 35 ); strcpy(string,"longitude from McIDAS derived data"); errorCode = nc_put_att_text( ncFileId, lonId, "comment", strlen(string), string ); checkNCError( errorCode, 34 ); sprintf(string,"%s-OSPO-L2P-v1.0",pSatelliteName); errorCode = nc_put_att_text( ncFileId, lonId, "source", strlen(string), string ); checkNCError( errorCode, 34 ); #ifdef OLDGDS2 sprintf(string,"geographical coordinates, WGS84 projection"); errorCode = nc_put_att_text( ncFileId, lonId, "reference_datum", strlen(string), string ); checkNCError( errorCode, 34 ); #endif sprintf(string,"X"); errorCode = nc_put_att_text( ncFileId, lonId, "axis", strlen(string), string ); checkNCError( errorCode, 34 ); sprintf(string,"longitude"); errorCode = nc_put_att_text( ncFileId, lonId, "standard_name", strlen(string), string ); checkNCError( errorCode, 34 ); #endif /* Leave define mode */ errorCode = nc_enddef( ncFileId ); checkNCError( errorCode, 31 ); /* Setup start/edge number to be written */ start[0] = 0; start[1] = 0; count[0] = nlin; count[1] = nele; errorCode = nc_put_vara_float( ncFileId, latId, &start[0], &count[0], pLatitude ); checkNCError( errorCode, 32 ); /* Now do longitude */ /* Convert to -180,180 for GDS 2.0 specs */ /* Note if Longitude < 180 then it doesn't change */ for(i=0;i= *(pLongitude+i) ){ *(pLongitude+i) = *(pLongitude+i)-360.; } else if( *(pLongitude+i) < 0. || *(pLongitude+i) > 360. ){ *(pLongitude+i) = -FLT_MAX; } } errorCode = nc_put_vara_float( ncFileId, lonId, &start[0], &count[0], pLongitude ); checkNCError( errorCode, 36 ); /* Add time */ /* Enter define mode */ errorCode = nc_redef( ncFileId ); checkNCError( errorCode, 31 ); errorCode = nc_def_var( ncFileId, "time", NC_INT, 1, &time_dim, &timeId ); checkNCError( errorCode, 40 ); /* write attributes */ strcpy(string,"reference time of sst file"); errorCode = nc_put_att_text( ncFileId, timeId, "long_name", strlen(string), string ); checkNCError( errorCode, 41 ); strcpy(string,"seconds since 1981-01-01 00:00:00"); errorCode = nc_put_att_text( ncFileId, timeId, "units", strlen(string), string ); checkNCError( errorCode, 42 ); strcpy(string,"time in seconds since 1981-01-01 00:00:00"); errorCode = nc_put_att_text( ncFileId, timeId, "comment", strlen(string), string ); checkNCError( errorCode, 42 ); sprintf(string,"T"); errorCode = nc_put_att_text( ncFileId, timeId, "axis", strlen(string), string ); checkNCError( errorCode, 34 ); sprintf(string,"time"); errorCode = nc_put_att_text( ncFileId, timeId, "standard_name", strlen(string), string ); checkNCError( errorCode, 34 ); /* Exit define mode */ errorCode = nc_enddef( ncFileId ); checkNCError( errorCode, 31 ); /* Write variable */ errorCode = nc_put_var_int( ncFileId, timeId, &inTime ); checkNCError( errorCode, 43 ); /* Write SST */ dims[0] = time_dim; dims[1] = nj_dim; dims[2] = ni_dim; sizes[0] = 1; sizes[1] = nlin; sizes[2] = nele; sprintf(source,"%s-OSPO-L2P-v1.0",pSatelliteName); makeVarSd( ncFileId, SST_NAME, 3, &dims[0], &sizes[0], pSST, &sstId, SST_LONG_NAME,SST_UNITS,SST_NODATA,SST_OFFSET,SST_FACTOR, SST_MIN_VAL,SST_MAX_VAL,"lon lat", source, SST_REFERENCE, SST_REFERENCES, SST_COMMENT,"polar_stereographic","10 micrometers", "sea_surface_skin_temperature","IGNORE"); makeVarS( ncFileId, SST_DTIME_NAME, 3, &dims[0], &sizes[0], pSST_DTimeArr, &sstDtId, SST_DTIME_LONG_NAME,SST_DTIME_UNITS,SST_DTIME_NODATA, SST_DTIME_OFFSET,SST_DTIME_FACTOR,SST_DTIME_MIN_VAL, SST_DTIME_MAX_VAL,"lon lat",SST_DTIME_SOURCE,SST_DTIME_REFERENCE,SST_DTIME_REFERENCES, SST_DTIME_COMMENT,"polar_stereographic","IGNORE","IGNORE",0, "IGNORE","IGNORE","IGNORE"); /* SSES bias error */ makeVarB( ncFileId, SSES_BIAS_NAME, 3, &dims[0], &sizes[0], pSSES_Bias, &ssesBiasId, SSES_BIAS_LONG_NAME,SSES_BIAS_UNITS,SSES_BIAS_NODATA, SSES_BIAS_OFFSET,SSES_BIAS_FACTOR,SSES_BIAS_MIN_VAL, SSES_BIAS_MAX_VAL,"lon lat",SSES_BIAS_SOURCE,SSES_BIAS_REFERENCE,SSES_BIAS_REFERENCES, SSES_BIAS_COMMENT,"polar_stereographic",SSES_BIAS_DTIME, SSES_BIAS_SOURCE_FLAG_MEANINGS,SSES_BIAS_SOURCE_FLAG_VALUES, N_SSES_BIAS_SOURCE_FLAG_VALUES,"IGNORE","IGNORE","IGNORE"); /* SSES Std Dev */ makeVarB( ncFileId, SSES_STDEV_NAME, 3, &dims[0], &sizes[0], pSSES_StdDev, &ssesStdevId, SSES_STDEV_LONG_NAME,SSES_STDEV_UNITS, SSES_STDEV_NODATA,SSES_STDEV_OFFSET,SSES_STDEV_FACTOR, SSES_STDEV_MIN_VAL,SSES_STDEV_MAX_VAL,"lon lat", SSES_STDEV_SOURCE,SSES_STDEV_REFERENCE,SSES_STDEV_REFERENCES,SSES_STDEV_COMMENT, "polar_stereographic",SSES_STDEV_DTIME, SSES_STDEV_SOURCE_FLAG_MEANINGS,SSES_STDEV_SOURCE_FLAG_VALUES, N_SSES_STDEV_SOURCE_FLAG_VALUES,"IGNORE","IGNORE","IGNORE"); /* DT Analysis */ makeVarB( ncFileId, DT_ANAL_NAME, 3, &dims[0], &sizes[0], pDT, &dtId, DT_ANAL_LONG_NAME,DT_ANAL_UNITS, DT_ANAL_NODATA,DT_ANAL_OFFSET,DT_ANAL_FACTOR, DT_ANAL_MIN_VAL,DT_ANAL_MAX_VAL,"lon lat", DT_ANAL_SOURCE,DT_ANAL_REFERENCE,DT_ANAL_REFERENCES,DT_ANAL_COMMENT, "polar_stereographic",DT_ANAL_DTIME, DT_ANAL_SOURCE_FLAG_MEANINGS,DT_ANAL_SOURCE_FLAG_VALUES, N_DT_ANAL_SOURCE_FLAG_VALUES,"IGNORE","IGNORE","IGNORE"); #ifdef GDS16 /* Write SSI */ makeVarB( ncFileId, SSI_NAME, 3, &dims[0], &sizes[0], pSSI, &ssiId, SSI_LONG_NAME,SSI_UNITS,SSI_NODATA,SSI_OFFSET,SSI_FACTOR, SSI_MIN_VAL,SSI_MAX_VAL,"lon lat",SSI_SOURCE,SSI_REFERENCE,SSI_REFERENCES, SSI_COMMENT,"polar_stereographic",SSI_DTIME, SSI_SOURCE_FLAG_MEANINGS,SSI_SOURCE_FLAG_VALUES, N_SSI_SOURCE_FLAG_VALUES,"IGNORE","IGNORE","IGNORE"); makeVarB( ncFileId, SSI_DTIME_NAME, 3, &dims[0], &sizes[0], pSSI_DTimeArr, &ssiDtId, SSI_DTIME_LONG_NAME,SSI_DTIME_UNITS,SSI_DTIME_NODATA, SSI_DTIME_OFFSET,SSI_DTIME_FACTOR,SSI_DTIME_MIN_VAL, SSI_DTIME_MAX_VAL,"lon lat",SSI_DTIME_SOURCE,SSI_DTIME_REFERENCE,SSI_DTIME_REFERENCES, SSI_DTIME_COMMENT,"polar_stereographic",SSI_DTIME_DTIME, SSI_DTIME_SOURCE_FLAG_MEANINGS,SSI_DTIME_SOURCE_FLAG_VALUES, N_SSI_DTIME_SOURCE_FLAG_VALUES,"IGNORE","IGNORE","IGNORE"); #endif /* Write wind speed */ makeVarB( ncFileId, WIND_NAME, 3, &dims[0], &sizes[0], pWindSpeedArr, &windId, WIND_LONG_NAME,WIND_UNITS,WIND_NODATA,WIND_OFFSET, WIND_FACTOR, WIND_MIN_VAL,WIND_MAX_VAL,"lon lat",WIND_SOURCE, WIND_REFERENCE,WIND_REFERENCES,WIND_COMMENT,"polar_stereographic", WIND_SPEED_DTIME, WIND_SOURCE_FLAG_MEANINGS,WIND_SOURCE_FLAG_VALUES, N_WIND_SOURCE_FLAG_VALUES,"wind_speed","IGNORE","10 m"); #ifdef GDS16 makeVarB( ncFileId, WIND_DTIME_NAME, 3, &dims[0], &sizes[0], pWindSpeed_DTimeArr, &windDtId,WIND_DTIME_LONG_NAME, WIND_DTIME_UNITS,WIND_DTIME_NODATA, WIND_DTIME_OFFSET,WIND_FACTOR,WIND_DTIME_MIN_VAL, WIND_DTIME_MAX_VAL,"lon lat",WIND_DTIME_SOURCE, WIND_DTIME_REFERENCE,WIND_DTIME_REFERENCES,WIND_DTIME_COMMENT,"polar_stereographic", WIND_SPEED_DTIME_DTIME, WIND_SPEED_DTIME_SOURCE_FLAG_MEANINGS, WIND_SPEED_DTIME_SOURCE_FLAG_VALUES, N_WIND_SPEED_DTIME_SOURCE_FLAG_VALUES,"IGNORE","IGNORE","IGNORE"); #endif /* Ice value */ #ifdef GDS16 makeVarB( ncFileId, ICE_NAME, 3, &dims[0], &sizes[0], pIceArr,&iceId, ICE_LONG_NAME,ICE_UNITS,ICE_NODATA,ICE_OFFSET,ICE_FACTOR, ICE_MIN_VAL,ICE_MAX_VAL,"lon lat",ICE_SOURCE,ICE_REFERENCE,ICE_REFERENCES, ICE_COMMENT,"polar_stereographic",ICE_DTIME, ICE_SOURCE_FLAG_MEANINGS, ICE_SOURCE_FLAG_VALUES, N_ICE_SOURCE_FLAG_VALUES,"IGNORE","IGNORE","IGNORE"); #else sprintf(ice_dtime_string,"%f",pIce_DTime); makeVarB( ncFileId, ICE_NAME, 3, &dims[0], &sizes[0], pIceArr,&iceId, ICE_LONG_NAME,ICE_UNITS,ICE_NODATA,ICE_OFFSET,ICE_FACTOR, ICE_MIN_VAL,ICE_MAX_VAL,"lon lat",ICE_SOURCE,ICE_REFERENCE,ICE_REFERENCES, ICE_COMMENT,"polar_stereographic",ice_dtime_string, ICE_SOURCE_FLAG_MEANINGS, ICE_SOURCE_FLAG_VALUES, N_ICE_SOURCE_FLAG_VALUES,"sea_ice_area_fraction","IGNORE","IGNORE"); #endif #ifdef GDS16 /* Aerosol optical depth */ makeVarB( ncFileId, AEROSOL_NAME, 3, &dims[0], &sizes[0], pAerosolArr, &aerosolId, AEROSOL_LONG_NAME,AEROSOL_UNITS,AEROSOL_NODATA, AEROSOL_OFFSET,AEROSOL_FACTOR,AEROSOL_MIN_VAL,AEROSOL_MAX_VAL, "lon lat",AEROSOL_SOURCE,AEROSOL_REFERENCE,AEROSOL_REFERENCES,AEROSOL_COMMENT, "polar_stereographic",AEROSOL_DTIME, AEROSOL_SOURCE_FLAG_MEANINGS, AEROSOL_SOURCE_FLAG_VALUES, N_AEROSOL_SOURCE_FLAG_VALUES,"IGNORE","IGNORE","IGNORE"); /* Aerosol opt depth dtime */ makeVarB( ncFileId, AEROSOL_DTIME_NAME, 3, &dims[0], &sizes[0], pAerosol_DTimeArr,&aerosolDtId, AEROSOL_DTIME_LONG_NAME, AEROSOL_DTIME_UNITS,AEROSOL_DTIME_NODATA,AEROSOL_DTIME_OFFSET, AEROSOL_DTIME_FACTOR,AEROSOL_DTIME_MIN_VAL,AEROSOL_DTIME_MAX_VAL, "lon lat",AEROSOL_DTIME_SOURCE,AEROSOL_DTIME_REFERENCE,AEROSOL_DTIME_REFERENCES, AEROSOL_DTIME_COMMENT,"polar_stereographic",AEROSOL_DTIME_DTIME, AEROSOL_SOURCE_FLAG_MEANINGS, AEROSOL_SOURCE_FLAG_VALUES, N_AEROSOL_SOURCE_FLAG_VALUES,"IGNORE","IGNORE","IGNORE"); #else /* Aerosol dynamic indicator - replaces Aerosol variable*/ makeVarB( ncFileId, ADI_NAME, 3, &dims[0], &sizes[0], pADIArr, &ADIId, ADI_LONG_NAME, ADI_UNITS,ADI_NODATA,ADI_OFFSET, ADI_FACTOR,ADI_MIN_VAL,ADI_MAX_VAL, "lon lat",ADI_SOURCE, ADI_REFERENCE, ADI_REFERENCES, ADI_COMMENT,"polar_stereographic",ADI_DTIME, ADI_SOURCE_FLAG_MEANINGS, ADI_SOURCE_FLAG_VALUES, N_ADI_SOURCE_FLAG_VALUES,"IGNORE","IGNORE","IGNORE"); /* dtime */ makeVarB( ncFileId, ADI_DTIME_NAME, 3, &dims[0], &sizes[0], pADI_DTimeArr,&ADIDtId, ADI_DTIME_LONG_NAME, ADI_DTIME_UNITS,ADI_DTIME_NODATA,ADI_DTIME_OFFSET, ADI_DTIME_FACTOR,ADI_DTIME_MIN_VAL,ADI_DTIME_MAX_VAL, "lon lat",ADI_DTIME_SOURCE,ADI_DTIME_REFERENCE,ADI_DTIME_REFERENCES, ADI_DTIME_COMMENT,"polar_stereographic",ADI_DTIME_DTIME, ADI_DTIME_SOURCE_FLAG_MEANINGS, ADI_DTIME_SOURCE_FLAG_VALUES, N_ADI_DTIME_SOURCE_FLAG_VALUES,"IGNORE","IGNORE","IGNORE"); #endif #ifdef GDS16 /* Source of wind speed */ makeVarB( ncFileId, SRC_WIND_NAME, 3, &dims[0],&sizes[0], pWindSpeedSrc,&windSrcId,SRC_WIND_LONG_NAME,SRC_WIND_UNITS, SRC_WIND_NODATA,SRC_WIND_OFFSET,SRC_WIND_FACTOR,SRC_WIND_MIN_VAL, SRC_WIND_MAX_VAL,"lon lat",SRC_WIND_SOURCE,SRC_WIND_REFERENCE,SRC_WIND_REFERENCES, SRC_WIND_COMMENT,"polar_stereographic",SRC_WIND_DTIME, SRC_WIND_SOURCE_FLAG_MEANINGS, SRC_WIND_SOURCE_FLAG_VALUES, N_SRC_WIND_SOURCE_FLAG_VALUES,"IGNORE","IGNORE","IGNORE"); /* Source of ssi */ makeVarB( ncFileId, SRC_SSI_NAME, 3, &dims[0], &sizes[0], pSSISrc,&SSISrcId, SRC_SSI_LONG_NAME,SRC_SSI_UNITS,SRC_SSI_NODATA, SRC_SSI_OFFSET,SRC_SSI_FACTOR,SRC_SSI_MIN_VAL,SRC_SSI_MAX_VAL, "lon lat",SRC_SSI_SOURCE,SRC_SSI_REFERENCE,SRC_SSI_REFERENCES,SRC_SSI_COMMENT, "polar_stereographic",SRC_SSI_DTIME, SRC_SSI_SOURCE_FLAG_MEANINGS, SRC_SSI_SOURCE_FLAG_VALUES, N_SRC_SSI_SOURCE_FLAG_VALUES,"IGNORE","IGNORE","IGNORE"); /* Source of sea ice */ makeVarB( ncFileId, SRC_ICE_NAME, 3, &dims[0], &sizes[0], pIceSrc,&IceSrcId, SRC_ICE_LONG_NAME,SRC_ICE_UNITS,SRC_ICE_NODATA, SRC_ICE_OFFSET,SRC_ICE_FACTOR,SRC_ICE_MIN_VAL,SRC_ICE_MAX_VAL, "lon lat",SRC_ICE_SOURCE,SRC_ICE_REFERENCE,SRC_ICE_REFERENCES,SRC_ICE_COMMENT, "polar_stereographic",SRC_ICE_DTIME, SRC_ICE_SOURCE_FLAG_MEANINGS, SRC_ICE_SOURCE_FLAG_VALUES, N_SRC_ICE_SOURCE_FLAG_VALUES,"IGNORE","IGNORE","IGNORE"); /* Source of aerosol */ makeVarB( ncFileId, SRC_AEROSOL_NAME, 3, &dims[0], &sizes[0], pAerosolSrc, &AerosolSrcId,SRC_AEROSOL_LONG_NAME,SRC_AEROSOL_UNITS, SRC_AEROSOL_NODATA,SRC_AEROSOL_OFFSET,SRC_AEROSOL_FACTOR, SRC_AEROSOL_MIN_VAL,SRC_AEROSOL_MAX_VAL,"lon lat", SRC_AEROSOL_SOURCE,SRC_AEROSOL_REFERENCE,SRC_AEROSOL_REFERENCES,SRC_AEROSOL_COMMENT, "polar_stereographic",SRC_AEROSOL_DTIME, SRC_AEROSOL_SOURCE_FLAG_MEANINGS, SRC_AEROSOL_SOURCE_FLAG_VALUES, N_SRC_AEROSOL_SOURCE_FLAG_VALUES,"IGNORE","IGNORE","IGNORE"); #endif /* Zenith value */ makeVarB( ncFileId, ZENITH_NAME, 3, &dims[0], &sizes[0], pZenithArr,&zenId, ZENITH_LONG_NAME,ZENITH_UNITS,ZENITH_NODATA,ZENITH_OFFSET, ZENITH_FACTOR,ZENITH_MIN_VAL,ZENITH_MAX_VAL,"lon lat", ZENITH_SOURCE,ZENITH_REFERENCE,ZENITH_REFERENCES,ZENITH_COMMENT, "polar_stereographic",ZENITH_DTIME, ZENITH_SOURCE_FLAG_MEANINGS, ZENITH_SOURCE_FLAG_VALUES, N_ZENITH_SOURCE_FLAG_VALUES,"IGNORE","IGNORE","IGNORE"); #ifndef GDS16 /* Solar Zenith value */ makeVarB( ncFileId, SOLAR_ZENITH_NAME, 3, &dims[0], &sizes[0], pSolarZenith,&solarzenId,SOLAR_ZENITH_LONG_NAME, SOLAR_ZENITH_UNITS,SOLAR_ZENITH_NODATA,SOLAR_ZENITH_OFFSET, SOLAR_ZENITH_FACTOR,SOLAR_ZENITH_MIN_VAL,SOLAR_ZENITH_MAX_VAL, "lon lat",SOLAR_ZENITH_SOURCE,SOLAR_ZENITH_REFERENCE,SOLAR_ZENITH_REFERENCES, SOLAR_ZENITH_COMMENT,"polar_stereographic",SOLAR_ZENITH_DTIME, SOLAR_ZENITH_SOURCE_FLAG_MEANINGS, SOLAR_ZENITH_SOURCE_FLAG_VALUES, N_SOLAR_ZENITH_SOURCE_FLAG_VALUES,"IGNORE","IGNORE","IGNORE"); #endif /* Rejection Flags */ #ifdef GDS16 makeVarB( ncFileId, REJECTION_NAME, 3, &dims[0], &sizes[0], pRejection, &rejectionId,REJECTION_LONG_NAME,REJECTION_UNITS,REJECTION_NODATA, REJECTION_OFFSET,REJECTION_FACTOR,REJECTION_MIN_VAL, REJECTION_MAX_VAL,"lon lat",REJECTION_SOURCE, REJECTION_REFERENCE,REJECTION_REFERENCES,REJECTION_COMMENT,"polar_stereographic", REJECTION_DTIME, REJECTION_SOURCE_FLAG_MEANINGS, REJECTION_SOURCE_FLAG_VALUES, N_REJECTION_SOURCE_FLAG_VALUES,"IGNORE","IGNORE","IGNORE"); #else makeVarS( ncFileId, REJECTION_NAME, 3, &dims[0], &sizes[0], pRejection, &rejectionId,REJECTION_LONG_NAME,REJECTION_UNITS,REJECTION_NODATA, REJECTION_OFFSET,REJECTION_FACTOR,REJECTION_MIN_VAL, REJECTION_MAX_VAL,"lon lat",REJECTION_SOURCE, REJECTION_REFERENCE,REJECTION_REFERENCES,REJECTION_COMMENT,"polar_stereographic", REJECTION_SOURCE_FLAG_MASK, REJECTION_SOURCE_FLAG_MEANINGS, N_REJECTION_SOURCE_FLAG_VALUES, REJECTION_SOURCE_FLAG_VALUES,"IGNORE","IGNORE"); #endif #ifdef GDS16 /* Confidence Flags */ makeVarB( ncFileId, CONFIDENCE_NAME, 3, &dims[0], &sizes[0], pConfidence, &confidenceId,CONFIDENCE_LONG_NAME,CONFIDENCE_UNITS, CONFIDENCE_NODATA,CONFIDENCE_OFFSET,CONFIDENCE_FACTOR, CONFIDENCE_MIN_VAL,CONFIDENCE_MAX_VAL,"lon lat",CONFIDENCE_SOURCE, CONFIDENCE_REFERENCE,CONFIDENCE_REFERENCES,CONFIDENCE_COMMENT,"polar_stereographic", CONFIDENCE_DTIME, CONFIDENCE_SOURCE_FLAG_MEANINGS, CONFIDENCE_SOURCE_FLAG_VALUES, N_CONFIDENCE_SOURCE_FLAG_VALUES,"IGNORE","IGNORE","IGNORE"); #endif /* Proximity Flags */ /* Because limits on each flag are dependent on probabilities - make comment * on the fly */ sprintf(string,"Proximity code defined as : 0 = unprocessed 1 = Cloudy (Clear sky probability < %5.3f) 2 = Bad (%5.3f <= Clear sky probability < %5.3f) 3 = Suspect (%5.3f <= Clear sky probability < %5.3f) 4 = Acceptable (%5.3f <= Clear sky probability < %5.3f) 5 = Excellent (%5.3f <= Clear sky probability)", MAX_PROXIMITY_CODE_1,MIN_PROXIMITY_CODE_2, MAX_PROXIMITY_CODE_2,MIN_PROXIMITY_CODE_3, MAX_PROXIMITY_CODE_3,MIN_PROXIMITY_CODE_4, MAX_PROXIMITY_CODE_4,MIN_PROXIMITY_CODE_5); /* Write data */ makeVarB( ncFileId, PROXIMITY_NAME, 3, &dims[0], &sizes[0], pProximity, &proximityId,PROXIMITY_LONG_NAME,PROXIMITY_UNITS, PROXIMITY_UNPROCESSED, PROXIMITY_OFFSET,PROXIMITY_FACTOR,PROXIMITY_MIN_VAL, PROXIMITY_MAX_VAL,"lon lat",PROXIMITY_SOURCE, PROXIMITY_REFERENCE,PROXIMITY_REFERENCES,string,"polar_stereographic",PROXIMITY_DTIME, PROXIMITY_SOURCE_FLAG_MEANINGS, PROXIMITY_SOURCE_FLAG_VALUES, N_PROXIMITY_SOURCE_FLAG_VALUES,"IGNORE","IGNORE","IGNORE"); /* Experimental field - clear sky probability */ #ifndef NO_EXPERIMENTAL_FIELDS makeVarB( ncFileId, CLEAR_SKY_PROB_NAME, 3, &dims[0], &sizes[0], pClearSkyProb, &clearSkyId,CLEAR_SKY_PROB_LONG_NAME, CLEAR_SKY_PROB_UNITS,CLEAR_SKY_PROB_NODATA, CLEAR_SKY_PROB_OFFSET,CLEAR_SKY_PROB_FACTOR, CLEAR_SKY_PROB_MIN_VAL,CLEAR_SKY_PROB_MAX_VAL,"lon lat", CLEAR_SKY_PROB_SOURCE,CLEAR_SKY_PROB_REFERENCE,CLEAR_SKY_PROB_REFERENCES, CLEAR_SKY_PROB_COMMENT,"polar_stereographic", CLEAR_SKY_PROB_DTIME, CLEAR_SKY_PROB_SOURCE_FLAG_MEANINGS, CLEAR_SKY_PROB_SOURCE_FLAG_VALUES, N_CLEAR_SKY_PROB_SOURCE_FLAG_VALUES,"IGNORE","IGNORE","IGNORE"); makeVarB( ncFileId, DIURNAL_EST_NAME, 3, &dims[0], &sizes[0], pDiurnalEstimate, &diurnalEstId, DIURNAL_EST_LONG_NAME, DIURNAL_EST_UNITS,DIURNAL_EST_NODATA, DIURNAL_EST_OFFSET,DIURNAL_EST_FACTOR, DIURNAL_EST_MIN_VAL,DIURNAL_EST_MAX_VAL,"lon lat", DIURNAL_EST_SOURCE,DIURNAL_EST_REFERENCE,DIURNAL_EST_REFERENCES, DIURNAL_EST_COMMENT,"polar_stereographic", DIURNAL_EST_DTIME, DIURNAL_EST_FLAG_MEANINGS, DIURNAL_EST_FLAG_VALUES, DIURNAL_EST_SOURCE_FLAG_VALUES,"IGNORE","IGNORE","IGNORE"); #endif /* Close netCDF file */ errorCode = nc_close( ncFileId ); checkNCError( errorCode, 44 ); printf("Closing NetCDF file\n"); fflush(NULL); #ifdef GDS16 /* Now write xml meta data file */ if( 0 != strncmp(pNorthSouth," ",1) ){ sprintf(string, "netcdf_output/FR-%4.4d%2.2d%2.2d-%s-OSPO-L2P-%s_%s_%2.2d%2.2dZ-v01.xml", Year,Month,Day,pSatelliteName,pSatelliteName,pNorthSouth,Hour,Min); } else { sprintf(string, "netcdf_output/FR-%4.4d%2.2d%2.2d-%s-OSPO-L2P-%s_%2.2d%2.2dZ-v01.xml", Year,Month,Day,pSatelliteName,pSatelliteName,Hour,Min); } strcpy(filename,DATA_DIR); strcat(filename,string); if( NULL == (fp = fopen(filename,"w")) ) printError("writeNetCDF","Cannot open file %s",NULL,filename); fprintf(fp,"\n"); fprintf(fp,"\n"); fprintf(fp,"\n"); if( 0 == strcmp(pSatelliteName,"GOES15") ){ if( 0 == strcmp(pNorthSouth,"North") ) fprintf(fp," OSPO-L2P-GOES15\n"); else fprintf(fp," OSPO-L2P-GOES15\n"); } else if( 0 == strcmp(pSatelliteName,"GOES13") ){ if( 0 == strcmp(pNorthSouth,"North") ) fprintf(fp," OSPO-L2P-GOES13\n"); else fprintf(fp," OSPO-L2P-GOES13\n"); } else if( 0 == strcmp(pSatelliteName,"GOES12") ){ if( 0 == strcmp(pNorthSouth,"North") ) fprintf(fp," OSPO-L2P-GOES12\n"); else fprintf(fp," OSPO-L2P-GOES12\n"); } else if( 0 == strcmp(pSatelliteName,"GOES11") ){ if( 0 == strcmp(pNorthSouth,"North") ) fprintf(fp," OSPO-L2P-GOES11\n"); else fprintf(fp," OSPO-L2P-GOES11\n"); } else if( 0 == strcmp(pSatelliteName,"GOES10") ){ if( 0 == strcmp(pNorthSouth,"North") ) fprintf(fp," OSPO-L2P-GOES10\n"); else fprintf(fp," OSPO-L2P-GOES10\n"); } else if( 0 == strcmp(pSatelliteName,"MTSAT1R") ){ fprintf(fp," OSPO-L2P-MTSAT1R\n"); } else if( 0 == strcmp(pSatelliteName,"MTSAT2") ){ fprintf(fp," OSPO-L2P-MTSAT2\n"); } else if( 0 == strcmp(pSatelliteName,"MSG02") ){ fprintf(fp," OSPO-L2P-MSG02\n"); } else printError("writeNetCDF","Cannot match satelite name",NULL,NULL); if( 0 != strncmp(pNorthSouth," ",1) ){ fprintf(fp," %4.4d%2.2d%2.2d-%s-OSPO-L2P-%s_%s_%2.2d%2.2dZ-v01.nc\n", Year,Month,Day,pSatelliteName,pSatelliteName,pNorthSouth,Hour,Min); } else { fprintf(fp," %4.4d%2.2d%2.2d-%s-OSPO-L2P-%s_%2.2d%2.2dZ-v01.nc\n", Year,Month,Day,pSatelliteName,pSatelliteName,Hour,Min); } pBroken_time = gmtime(&currTime); fprintf(fp, " %4.4d%.2d%2.2dT%2.2d%2.2d%2.2dZ\n", pBroken_time->tm_year+1900,pBroken_time->tm_mon+1, pBroken_time->tm_mday,pBroken_time->tm_hour,pBroken_time->tm_min, pBroken_time->tm_sec); fprintf(fp," 1.0\n"); fprintf(fp," \n"); if( 0 == strncmp(pSatelliteName,"GOES",4) ){ fprintf(fp, " ftp://140.90.213.156/pub/geo_sst/L2P/goes/%4.4d%2.2d%2.2d-%s-OSPO-L2P-%s_%s_%2.2d%2.2dZ-v01.nc.gz\n", Year,Month,Day,pSatelliteName,pSatelliteName,pNorthSouth,Hour,Min); } else if( 0 == strncmp(pSatelliteName,"MSG",3) ) { fprintf(fp, " ftp://140.90.213.156/pub/geo_sst/L2P/msg/%4.4d%2.2d%2.2d-%s-OSPO-L2P-%s_%s_%2.2d%2.2dZ-v01.nc.gz\n", Year,Month,Day,pSatelliteName,pSatelliteName,pNorthSouth,Hour,Min); } else if( 0 == strncmp(pSatelliteName,"MTSAT",5) ) { fprintf(fp, " ftp://140.90.213.156/pub/geo_sst/L2P/mtsat/%4.4d%2.2d%2.2d-%s-OSPO-L2P-%s_%s_%2.2d%2.2dZ-v01.nc.gz\n", Year,Month,Day,pSatelliteName,pSatelliteName,pNorthSouth,Hour,Min); } fprintf(fp," FTP directory containing Level2p data\n"); fprintf(fp," \n"); /* Temporal coverage */ fprintf(fp," \n"); /* Start time */ fprintf(fp," %4.4d%2.2d%2.2dT%2.2d%2.2d%2.2dZ\n", startYear,startMonth,startDay,startHours,startMins,startSecs); /* Stop time */ fprintf(fp," %4.4d%2.2d%2.2dT%2.2d%2.2d%2.2dZ\n", stopYear,stopMonth,stopDay,stopHours,stopMin,stopSecs); fprintf(fp," \n"); /* Spatial coverage */ fprintf(fp," \n"); fprintf(fp," %7.3f\n", minLat); fprintf(fp," %6.3f\n", maxLat); fprintf(fp," %7.3f\n", minLong); fprintf(fp," %7.3f\n", maxLong); fprintf(fp," \n"); /* Contact */ fprintf(fp," \n"); fprintf(fp," Technical Contact\n"); fprintf(fp," Eileen\n"); fprintf(fp," Maturi\n"); fprintf(fp," Eileen.Maturi@noaa.gov\n"); fprintf(fp," 301-763-8102 x172\n"); fprintf(fp," 301-763-8572\n"); fprintf(fp,"
NOAA/NESDIS/STAR/SOCD, 5200 Auth Road, WWB, RM 601 Camp Springs, MD 20746, USA
\n"); fprintf(fp,"
\n"); /* Metadata history */ fprintf(fp," \n"); fprintf(fp," 1.0\n"); fprintf(fp, " %4.4d%.2d%2.2dT%2.2d%2.2d%2.2dZ\n", pBroken_time->tm_year+1900,pBroken_time->tm_mon+1, pBroken_time->tm_mday,pBroken_time->tm_hour,pBroken_time->tm_min, pBroken_time->tm_sec); fprintf(fp, " %4.4d%.2d%2.2dT%2.2d%2.2d%2.2dZ\n", pBroken_time->tm_year+1900,pBroken_time->tm_mon+1, pBroken_time->tm_mday,pBroken_time->tm_hour,pBroken_time->tm_min, pBroken_time->tm_sec); fprintf(fp, " File created on %4.4d%.2d%2.2dT%2.2d%2.2d%2.2dZ\n", pBroken_time->tm_year+1900,pBroken_time->tm_mon+1, pBroken_time->tm_mday,pBroken_time->tm_hour,pBroken_time->tm_min, pBroken_time->tm_sec); fprintf(fp," \n"); fprintf(fp," gzip\n"); /* End of metadata */ fprintf(fp,"
\n"); /* Close metadata file */ fclose(fp); #endif } /* Generic code to write out a byte variable to the netCDF output */ /* Note that whether or not a value is used is dependent on the * its value - this is so flags/values etc. can be called by the same * routine */ /* Note - all bytes are written as signed char */ void makeVarB( int ncFileId, char *pName, int ndims, int *pDims, size_t *pSize, signed char *pArray, int *pVarId, char *pLongName, char *pUnits, signed char fillVal, float offset, float factor, signed char minval, signed char maxval, char *pCoords, char *pSource, char *pReference, char *pReferences, char *pComment, char *pGridMapping, char *pDTime, char *pFlagMeanings, char *pFlagValues, int nFlagValues, char *pStandard_Name, char *pAxis, char *pHeight ) { int errorCode = 0; size_t start[3] = {0,0,0}; size_t count[3] = {0,0,0}; int i = 0; float fvalue = 0.; int uchar_value; signed char *pFlagValuesArr = 0; char strtok_str[MAX_STRING_LENGTH]; char ind_str[MAX_STRING_LENGTH]; /* Enter define mode */ errorCode = nc_redef( ncFileId ); checkNCError( errorCode, 31 ); /* Define sizes */ errorCode = nc_def_var( ncFileId, pName, NC_BYTE, ndims, pDims, pVarId ); checkNCError( errorCode, 1 ); #ifndef GDS16 /* Set compression */ errorCode = nc_def_var_deflate(ncFileId, *pVarId, 0, 1, 9); checkNCError( errorCode, 902 ); #endif /* write attributes */ errorCode = nc_put_att_text( ncFileId, *pVarId, "long_name", strlen(pLongName), pLongName ); checkNCError( errorCode, 3 ); #ifndef GDS16 errorCode = nc_put_att_text( ncFileId, *pVarId, "grid_mapping", strlen(pGridMapping), pGridMapping ); checkNCError( errorCode, 15 ); /* Add reference to this data if there */ if( 0 != strncmp(pReference,"IGNORE",6) ){ errorCode = nc_put_att_text( ncFileId, *pVarId, "reference", strlen(pReference), pReference ); checkNCError( errorCode, 24 ); } /* Add references to this data if there */ if( 0 != strncmp(pReferences,"IGNORE",6) ){ errorCode = nc_put_att_text( ncFileId, *pVarId, "references", strlen(pReferences), pReferences ); checkNCError( errorCode, 24 ); } #endif /* If units to be written write them (IGNORE means no units) */ if( 0 != strncmp(pUnits,"IGNORE",6) ){ errorCode = nc_put_att_text( ncFileId, *pVarId, "units", strlen(pUnits), pUnits ); checkNCError( errorCode, 4 ); } /* In the GDS the fill value is set to -128 - so 127 means don't include * a fill value */ if( 127 != fillVal ){ errorCode = nc_put_att_schar( ncFileId, *pVarId, "_FillValue", NC_BYTE, 1, &fillVal ); checkNCError( errorCode, 5 ); } /* Offset is never -128 - so used to denote no offset to be written */ if( -128 != offset ){ errorCode = nc_put_att_float( ncFileId, *pVarId, "add_offset", NC_FLOAT, 1, &offset ); checkNCError( errorCode, 6 ); } /* Factor is never -128 - so used to denote no factor to be written */ if( -128 != factor ){ errorCode = nc_put_att_float( ncFileId, *pVarId, "scale_factor", NC_FLOAT, 1, &factor ); checkNCError( errorCode, 7 ); } /* minval is never 128 - so used to denote no minval to be written */ if( 127 != minval ){ errorCode = nc_put_att_schar( ncFileId, *pVarId, "valid_min", NC_BYTE, 1, &minval ); checkNCError( errorCode, 8 ); } /* maxval is never -128 - so used to denote no maxval to be written */ if( -128 != maxval ){ errorCode = nc_put_att_schar( ncFileId, *pVarId, "valid_max", NC_BYTE, 1, &maxval ); checkNCError( errorCode, 9 ); } /* if coordinates is not IGNORE write */ if( 0 != strncmp(pCoords,"IGNORE",6) ){ errorCode = nc_put_att_text( ncFileId, *pVarId, "coordinates", strlen(pCoords), pCoords ); checkNCError( errorCode, 10 ); } /* if source is not IGNORE write */ if( 0 != strncmp(pSource,"IGNORE",6) ){ errorCode = nc_put_att_text( ncFileId, *pVarId, "source", strlen(pSource), pSource ); checkNCError( errorCode , 11); } /* if comment is not IGNORE write */ if( 0 != strncmp(pComment,"IGNORE",6) ){ errorCode = nc_put_att_text( ncFileId, *pVarId, "comment", strlen(pComment), pComment ); checkNCError( errorCode, 12 ); } #ifndef GDS16 /* if dtime is not IGNORE write out time difference in hours */ if( 0 != strncmp(pDTime,"IGNORE",6) ){ /* Get floating point value of pDTime */ sscanf(pDTime,"%f",&fvalue); errorCode = nc_put_att_float( ncFileId, *pVarId, "time_offset", NC_FLOAT, 1, &fvalue ); checkNCError( errorCode, 13 ); } /* Flag meanings if present */ if( 0 != strncmp(pFlagMeanings,"IGNORE",6) ){ errorCode = nc_put_att_text( ncFileId, *pVarId, "flag_meanings", strlen(pFlagMeanings), pFlagMeanings ); checkNCError( errorCode, 14 ); /* Get array of numbers of FlagValue */ if( NULL == (pFlagValuesArr = (signed char *) calloc(nFlagValues,sizeof(pFlagValuesArr))) ){ fprintf(stderr,"ERROR: Cannot allocate pFlagValuesArr (makeVarB)\n"); exit(-1); } if( 0 < nFlagValues ){ strncpy(strtok_str,pFlagValues,MAX_STRING_LENGTH); strtok_str[MAX_STRING_LENGTH-1] = '\0'; sscanf(strtok(strtok_str,","),"%d",&uchar_value); *(pFlagValuesArr) = (signed char) uchar_value; for(i=1;i