diff --git a/include/SW_netCDF_General.h b/include/SW_netCDF_General.h index cca205bd6..f4e48d69f 100644 --- a/include/SW_netCDF_General.h +++ b/include/SW_netCDF_General.h @@ -134,6 +134,7 @@ void SW_NC_create_full_var( int deflateLevel, const char *latName, const char *lonName, + const int coordAttIndex, LOG_INFO *LogInfo ); diff --git a/src/SW_netCDF_General.c b/src/SW_netCDF_General.c index 8111f0ed4..52df71949 100644 --- a/src/SW_netCDF_General.c +++ b/src/SW_netCDF_General.c @@ -770,6 +770,7 @@ void SW_NC_get_str_att_val( int attCallRes; int attLenCallRes; size_t attLen = 0; + SW_NC_get_var_identifier(ncFileID, varName, &varID, LogInfo); if (LogInfo->stopRun) { return; // Exit function prematurely due to error @@ -914,6 +915,9 @@ and writing attributes variable @param[in] latName User-provided latitude name @param[in] lonName User-provided longitude name +@param[in] coordAttIndex Specifies the coordinate attribute location +within the provided `attNames`/`attVals` (if there isn't an attribute +of this name, it's value should be -1) @param[in,out] LogInfo Holds information dealing with logfile output */ void SW_NC_create_full_var( @@ -936,6 +940,7 @@ void SW_NC_create_full_var( int deflateLevel, const char *latName, const char *lonName, + const int coordAttIndex, LOG_INFO *LogInfo ) { @@ -953,7 +958,11 @@ void SW_NC_create_full_var( unsigned int numTimeVertVegVals = 3; unsigned int varVal = 0; size_t chunkSizes[MAX_NUM_DIMS] = {1, 1, 1, 1, 1}; - + char coordValBuf[MAX_FILENAMESIZE] = ""; + char *writePtr = coordValBuf; + char *tempCoordPtr; + int writeSize = MAX_FILENAMESIZE; + char finalCoordVal[MAX_FILENAMESIZE]; for (index = 0; index < numConstDims; index++) { SW_NC_get_dim_identifier( @@ -994,10 +1003,36 @@ void SW_NC_create_full_var( return; // Exit function prematurely due to error } + tempCoordPtr = sw_memccpy(writePtr, " ", '\0', writeSize); + writeSize--; + writePtr = tempCoordPtr - 1; + + tempCoordPtr = sw_memccpy( + writePtr, (char *) timeVertVegNames[index], '\0', writeSize + ); + writeSize -= (int) (tempCoordPtr - coordValBuf - 1); + writePtr = tempCoordPtr - 1; + dimArrSize++; } } + if (coordAttIndex > -1 && !isnull(attVals[coordAttIndex])) { + snprintf( + finalCoordVal, + MAX_FILENAMESIZE, + "%s%s", + attVals[coordAttIndex], + coordValBuf + ); + + free((void *) ((char *) attVals[coordAttIndex])); + attVals[coordAttIndex] = Str_Dup(finalCoordVal, LogInfo); + if (LogInfo->stopRun) { + return; + } + } + for (index = numConstDims; index < MAX_NUM_DIMS; index++) { if (index - numConstDims < 3) { varVal = timeVertVegVals[index - numConstDims]; diff --git a/src/SW_netCDF_Input.c b/src/SW_netCDF_Input.c index 6e28ec953..99377470c 100644 --- a/src/SW_netCDF_Input.c +++ b/src/SW_netCDF_Input.c @@ -2183,6 +2183,7 @@ void SW_NCIN_create_progress(SW_DOMAIN *SW_Domain, LOG_INFO *LogInfo) { SW_Domain->OutDom.netCDFOutput.deflateLevel, readinGeoYName, readinGeoXName, + -1, LogInfo ); diff --git a/src/SW_netCDF_Output.c b/src/SW_netCDF_Output.c index 8818dc0bf..81585da4e 100644 --- a/src/SW_netCDF_Output.c +++ b/src/SW_netCDF_Output.c @@ -588,6 +588,9 @@ into one location to write out variable information @param[out] resAtts Resulting attributes to write out @param[in] sumType Sum type of the output key +@param[in] siteDom Specifies if the domain is site-oriented +@param[in] readinYName User-provided geographical y-axis name +@param[in] readinXName User-provided geographical x-axis name @param[out] LogInfo Holds information on warnings and errors */ static int gather_var_attributes( @@ -597,6 +600,9 @@ static int gather_var_attributes( int varNum, char *resAtts[], OutSum sumType, + Bool siteDom, + const char *readinYName, + const char *readinXName, LOG_INFO *LogInfo ) { int fillSize = 0; @@ -604,6 +610,7 @@ static int gather_var_attributes( int resSNP; char cellRedef[MAX_FILENAMESIZE]; char establOrginName[MAX_FILENAMESIZE]; + char coordsAtt[MAX_FILENAMESIZE]; // Determine attribute 'original_name' if (key == eSW_Estab) { @@ -665,6 +672,29 @@ static int gather_var_attributes( } } + /* Fill coordinates attribute */ + snprintf( + coordsAtt, + MAX_FILENAMESIZE, + (siteDom) ? "%s %s site" : "%s %s", + readinYName, + readinXName + ); + if (resSNP < 0 || (unsigned) resSNP >= (sizeof coordsAtt)) { + LogError( + LogInfo, + LOGWARN, + "attribute 'coordinates' of variable '%s' was truncated.", + varInfo[VARNAME_INDEX] + ); + } + + resAtts[fillSize] = Str_Dup(coordsAtt, LogInfo); + if (LogInfo->stopRun) { + return 0; // Exit function prematurely due to error + } + fillSize++; + if (key == eSW_Temp || key == eSW_SoilTemp) { resAtts[fillSize] = (char *) "temperature: on_scale"; fillSize++; @@ -923,13 +953,16 @@ static void create_output_file( "comment", "units", "cell_method", + "coordinates", "units_metadata" }; char *attVals[MAX_NATTS] = {NULL}; OutSum sumType = OutDom->sumtype[key]; + Bool siteDom = (Bool) (strcmp(domType, "s") == 0); int numAtts = 0; const int nameAtt = 0; + const int coordAttInd = 5; int newFileID = -1; // Default to not created int cellMethAttInd = 0; @@ -1001,6 +1034,7 @@ static void create_output_file( deflateLevel, latName, lonName, + coordAttInd, LogInfo ); @@ -1008,8 +1042,8 @@ static void create_output_file( if (newFileID > -1) { // new file was created cellMethAttInd = (key == eSW_Temp || key == eSW_SoilTemp) ? - numAtts - 2 : - numAtts - 1; + numAtts - 3 : + numAtts - 2; } if (!isnull(attVals[cellMethAttInd])) { free(attVals[cellMethAttInd]); @@ -1018,19 +1052,25 @@ static void create_output_file( } if (key == eSW_Estab && !isnull(attVals[nameAtt])) { free(attVals[nameAtt]); + attVals[nameAtt] = NULL; + } + if (!isnull(attVals[coordAttInd])) { + free(attVals[coordAttInd]); + attVals[coordAttInd] = NULL; } if (LogInfo->stopRun && FileExists(newFileName)) { - nc_close(newFileID); - return; // Exit function prematurely due to error + goto closeFile; } } } +closeFile: { // Only close the file if it was created if (newFileID > -1) { nc_close(newFileID); } } +} /* =================================================== */ /* Global Function Definitions */