From 2443d96733c671906450617e82529fcd6d72b510 Mon Sep 17 00:00:00 2001 From: robin Date: Thu, 18 Apr 2024 13:21:53 +0200 Subject: [PATCH] feat: implemented reading hdf5 --- .gitignore | 2 + opening-hdf5/.gitignore | 4 ++ opening-hdf5/src/CMakeLists.txt | 28 ++++++++++ opening-hdf5/src/main.cpp | 99 +++++++++++++++++++++++++++++++++ 4 files changed, 133 insertions(+) create mode 100644 .gitignore create mode 100644 opening-hdf5/.gitignore create mode 100644 opening-hdf5/src/CMakeLists.txt create mode 100644 opening-hdf5/src/main.cpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5ca0973 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.DS_Store + diff --git a/opening-hdf5/.gitignore b/opening-hdf5/.gitignore new file mode 100644 index 0000000..13c6291 --- /dev/null +++ b/opening-hdf5/.gitignore @@ -0,0 +1,4 @@ +.DS_Store +src/.DS_Store +src/.cache +src/build diff --git a/opening-hdf5/src/CMakeLists.txt b/opening-hdf5/src/CMakeLists.txt new file mode 100644 index 0000000..07d1489 --- /dev/null +++ b/opening-hdf5/src/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required (VERSION 3.28) +project (ReadHDF5) + +set(CMAKE_CXX_STANDARD 23) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +find_package(netCDF REQUIRED) + +add_executable(ReadHDF5 main.cpp) + +execute_process( + COMMAND nc-config --includedir + OUTPUT_VARIABLE NETCDF_INCLUDE_DIR + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +execute_process( + COMMAND ncxx4-config --libdir + OUTPUT_VARIABLE NETCDFCXX_LIB_DIR + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +target_include_directories(ReadHDF5 PUBLIC ${netCDF_INCLUDE_DIR}) + +find_library(NETCDF_LIB NAMES netcdf-cxx4 netcdf_c++4 PATHS ${NETCDFCXX_LIB_DIR} NO_DEFAULT_PATH) +target_link_libraries(ReadHDF5 ${NETCDF_LIB}) diff --git a/opening-hdf5/src/main.cpp b/opening-hdf5/src/main.cpp new file mode 100644 index 0000000..1acc55d --- /dev/null +++ b/opening-hdf5/src/main.cpp @@ -0,0 +1,99 @@ +#include +#include +#include +#include + +#include + +using namespace std; +using namespace netCDF; + +template +void printContentsOfVec(const std::vector& vec) { + for (const auto& element : vec) { + cout << element << " "; + } + cout << std::endl; +} + +template +vector getVarVector(NcVar var) { + int length = 1; + for (NcDim dim : var.getDims()) { + length *= dim.getSize(); + } + + vector vec(length); + + var.getVar(vec.data()); + + return vec; +} + +template +using arr3d = std::mdspan< + T, + std::dextents< + std::size_t, + 3 + > + >; + + +template +void print3DMatrixSlice(arr3d arr, int t) { + for (int x = 0; x < arr.extent(1); x++) { + for (int y = 0; y < arr.extent(2); y++) { + print("{} ", arr[t,x,y]); + } + println(""); + } +} + +void print3DMatrixSlice(arr3d arr, int t) { + for (int x = 0; x < arr.extent(1); x++) { + for (int y = 0; y < arr.extent(2); y++) { + print("{:>10.4f} ", arr[t,x,y]); + } + println(""); + } +} + +/** + * Read a 3D matrix from a NetCDF variable. + * Reads data into a contiguous 1D data vector. + * Returns a pair of the size of the matrix (in the form of an extent) with the data vector. + * + * Inteded usage of this function involves using the two returned values + * to create an mdspan: + * + * auto arr = mdspan(vec.data(), size); + */ +template +pair, std::dextents> get3DMat(NcVar var) { + if(var.getDimCount() != 3) { + throw invalid_argument("Variable is not 3D"); + } + int timeLength = var.getDim(0).getSize(); + int latLength = var.getDim(1).getSize(); + int longLength = var.getDim(2).getSize(); + vector vec(timeLength*latLength*longLength); + var.getVar(vec.data()); + auto arr = std::mdspan(vec.data(), timeLength, latLength, longLength); + + return {vec, arr.extents()}; +} + +int main () { + netCDF::NcFile data("../../../hdf5/hydrodynamic_U.h5", netCDF::NcFile::read); + + multimap< string, NcVar > vars = data.getVars(); + + auto [vec, size] = get3DMat(vars.find("uo")->second); + + auto arr = std::mdspan(vec.data(), size); + + print3DMatrixSlice(arr, 100); + + return 0; +}