Skip to content

Commit

Permalink
Support for Creating and Setting NetCDF Variables (#39)
Browse files Browse the repository at this point in the history
  • Loading branch information
amstokely committed Feb 12, 2025
1 parent 434c723 commit e3e36c4
Show file tree
Hide file tree
Showing 7 changed files with 1,013 additions and 4 deletions.
2 changes: 2 additions & 0 deletions obs2ioda-v2/src/cxx/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ set(obs2ioda_cxx_SOURCES
netcdf_file.cc
netcdf_group.cc
netcdf_dimension.cc
netcdf_variable.cc
netcdf_attribute.cc
)
set(obs2ioda_cxx_LIBRARIES
NetCDF::NetCDF_CXX
Expand Down
115 changes: 115 additions & 0 deletions obs2ioda-v2/src/cxx/netcdf_attribute.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
#include "netcdf_attribute.h"
#include "netcdf_file.h"
#include "netcdf_error.h"
#include <variant>

namespace Obs2Ioda {
template<typename T>
int netcdfPutAtt(
const int netcdfID,
const char *groupName,
const char *varName,
const char *attName,
const netCDF::NcType &netcdfDataType,
T values
) {
try {
auto file = FileMap::getInstance().getFile(
netcdfID
);
const auto group = !groupName
? file
: std::make_shared<
netCDF::NcGroup>(
file->getGroup(
groupName
)
);
if (varName) {
auto var = group->getVar(
varName
);
var.putAtt(
attName,
netcdfDataType,
values
);
} else {
group->putAtt(
attName,
netcdfDataType,
values
);
}
return 0;
} catch (netCDF::exceptions::NcException &e) {
return netcdfErrorMessage(
e,
__LINE__,
__FILE__
);
}
}

int netcdfPutAttInt(
int netcdfID,
const char *groupName,
const char *varName,
const char *attName,
const int *attValue
) {
return netcdfPutAtt<int>(
netcdfID,
groupName,
varName,
attName,
netCDF::NcType(
netCDF::ncInt
),
*attValue
);
}

int netcdfPutAttString(
const int netcdfID,
const char *groupName,
const char *varName,
const char *attName,
const char *attValue
) {
try {
auto file = FileMap::getInstance().getFile(
netcdfID
);
const auto group = !groupName
? file
: std::make_shared<
netCDF::NcGroup>(
file->getGroup(
groupName
)
);

if (!varName) {
group->putAtt(
attName,
attValue
);
} else {
group->getVar(
varName
).putAtt(
attName,
attValue
);
}
return 0;
} catch (netCDF::exceptions::NcException &e) {
return netcdfErrorMessage(
e,
__LINE__,
__FILE__
);
}
}
}
40 changes: 40 additions & 0 deletions obs2ioda-v2/src/cxx/netcdf_attribute.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#ifndef NETCDF_ATTRIBUTE_H
#define NETCDF_ATTRIBUTE_H

namespace Obs2Ioda {
extern "C" {
/**
* @brief Writes an integer attribute to a variable, group, or as a global attribute in a NetCDF file.
*
* If `varName` is provided, the attribute is assigned to the specified variable.
* If `varName` is `NULL`, the attribute is assigned to the group.
* If both `groupName` and `varName` are `NULL`, the attribute is written as a global attribute.
*
* @param netcdfID The identifier of the NetCDF file where the attribute will be written.
* @param groupName The name of the group containing the variable. If `NULL`, the root group is assumed.
* @param varName The name of the variable to which the attribute will be attached. If `NULL`, the attribute is assigned to the group.
* @param attName The name of the attribute to be written.
* @param attValue A pointer to the integer value to be assigned to the attribute.
* @return int A status code indicating the outcome of the operation:
* - 0: Success.
* - Non-zero: Failure, with an error message logged.
*/
int netcdfPutAttInt(
int netcdfID,
const char *groupName,
const char *varName,
const char *attName,
const int *attValue
);

int netcdfPutAttString(
int netcdfID,
const char *groupName,
const char *varName,
const char *attName,
const char *attValue
);
}
}

#endif //NETCDF_ATTRIBUTE_H
220 changes: 220 additions & 0 deletions obs2ioda-v2/src/cxx/netcdf_variable.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
#include "netcdf_variable.h"
#include "netcdf_file.h"
#include "netcdf_error.h"

namespace Obs2Ioda {
int netcdfAddVar(
int netcdfID,
const char *groupName,
const char *varName,
nc_type netcdfDataType,
int numDims,
const char **dimNames
) {
try {
auto file = FileMap::getInstance().getFile(netcdfID);
const auto group = !groupName
? file
: std::make_shared<
netCDF::NcGroup>(
file->getGroup(
groupName));
std::vector<netCDF::NcDim> dims;
dims.reserve(numDims);
for (int i = 0; i < numDims; i++) {
dims.push_back(file->getDim(dimNames[i]));;
}
auto var = group->addVar(
varName,
netCDF::NcType(netcdfDataType),
dims
);
return 0;
} catch (netCDF::exceptions::NcException &e) {
return netcdfErrorMessage(
e,
__LINE__,
__FILE__
);
}
}

template<typename T>
int netcdfPutVar(
int netcdfID,
const char *groupName,
const char *varName,
const T *values
) {
try {
auto file = FileMap::getInstance().getFile(netcdfID);
const auto group = !groupName
? file
: std::make_shared<
netCDF::NcGroup>(
file->getGroup(
groupName));
auto var = group->getVar(varName);
var.putVar(values);
return 0;
} catch (netCDF::exceptions::NcException &e) {
return netcdfErrorMessage(
e,
__LINE__,
__FILE__
);
}
}

int netcdfPutVarInt(
int netcdfID,
const char *groupName,
const char *varName,
const int *values
) {
return netcdfPutVar(
netcdfID,
groupName,
varName,
values
);
}

int netcdfPutVarInt64(
int netcdfID,
const char *groupName,
const char *varName,
const long long *values
) {
return netcdfPutVar(
netcdfID,
groupName,
varName,
values
);
}

int netcdfPutVarReal(
int netcdfID,
const char *groupName,
const char *varName,
const float *values
) {
return netcdfPutVar(
netcdfID,
groupName,
varName,
values
);
}

int netcdfPutVarString(
int netcdfID,
const char *groupName,
const char *varName,
const char **values
) {
return netcdfPutVar(
netcdfID,
groupName,
varName,
values
);
}

template<typename T>
int netcdfSetFill(
int netcdfID,
const char *groupName,
const char *varName,
int fillMode,
T fillValue
) {
try {
auto file = FileMap::getInstance().getFile(netcdfID);
const auto group = !groupName
? file
: std::make_shared<
netCDF::NcGroup>(
file->getGroup(
groupName));
auto var = group->getVar(varName);
var.setFill(
fillMode,
fillValue
);
return 0;
} catch (netCDF::exceptions::NcException &e) {
return netcdfErrorMessage(
e,
__LINE__,
__FILE__
);
}
}

int netcdfSetFillInt(
int netcdfID,
const char *groupName,
const char *varName,
int fillMode,
int fillValue
) {
return netcdfSetFill(
netcdfID,
groupName,
varName,
fillMode,
fillValue
);
}

int netcdfSetFillReal(
int netcdfID,
const char *groupName,
const char *varName,
int fillMode,
float fillValue
) {
return netcdfSetFill(
netcdfID,
groupName,
varName,
fillMode,
fillValue
);
}

int netcdfSetFillInt64(
int netcdfID,
const char *groupName,
const char *varName,
int fillMode,
long long fillValue
) {
return netcdfSetFill(
netcdfID,
groupName,
varName,
fillMode,
fillValue
);
}

int netcdfSetFillString(
int netcdfID,
const char *groupName,
const char *varName,
int fillMode,
const char *fillValue
) {
return netcdfSetFill(
netcdfID,
groupName,
varName,
fillMode,
fillValue

);
}
}
Loading

0 comments on commit e3e36c4

Please sign in to comment.