From fe289507c531edfb855ced77d0a7f4e223b2de48 Mon Sep 17 00:00:00 2001 From: Guilhem Lavaux Date: Wed, 19 Sep 2012 09:11:06 -0400 Subject: [PATCH] Support both for NetCDF-3 and NetCDF-4 --- src/{yorick.cpp => yorick_nc3.cpp} | 0 src/yorick_nc4.cpp | 274 +++++++++++++++++++++++++++++ 2 files changed, 274 insertions(+) rename src/{yorick.cpp => yorick_nc3.cpp} (100%) create mode 100644 src/yorick_nc4.cpp diff --git a/src/yorick.cpp b/src/yorick_nc3.cpp similarity index 100% rename from src/yorick.cpp rename to src/yorick_nc3.cpp diff --git a/src/yorick_nc4.cpp b/src/yorick_nc4.cpp new file mode 100644 index 0000000..d760009 --- /dev/null +++ b/src/yorick_nc4.cpp @@ -0,0 +1,274 @@ +#include "ctool_netcdf_ver.hpp" +#include "config.hpp" +#ifdef NETCDFCPP4 +#include +using namespace netCDF +#else +#include +#endif +#include +#include "yorick.hpp" +#include + +using namespace CosmoTool; +using namespace std; + +class NetCDF_handle +{ +public: + NcFile *outFile; + NcVar *curVar; + long *curPos; + long *counts; + long *dimList; + uint32_t rank; + + NetCDF_handle(NcFile *f, NcVar *v, long *dimList, uint32_t rank); + virtual ~NetCDF_handle(); +}; + +NetCDF_handle::NetCDF_handle(NcFile *f, NcVar *v, long *dimList, uint32_t rank) +{ + this->outFile = f; + this->curVar = v; + this->dimList = dimList; + this->rank = rank; + this->counts = new long[rank]; + this->curPos = new long[rank]; + + for (long i = 0; i < rank; i++) + this->curPos[i] = 0; + + for (long i = 0; i < rank; i++) + this->counts[i] = 1; +} + +NetCDF_handle::~NetCDF_handle() +{ + delete[] dimList; + delete outFile; +} + +template +class InputGenCDF: public NetCDF_handle, public ProgressiveInputImpl +{ +public: + InputGenCDF(NcFile *f, NcVar *v, long *dimList, uint32_t rank) + : NetCDF_handle(f,v,dimList,rank) + {} + virtual ~InputGenCDF() {} + + virtual T read() + { + T a; + + curVar->set_cur(curPos); + curVar->get(&a, counts); + + curPos[rank-1]++; + for (long i = rank-1; i >= 1; i--) + { + if (curPos[i] == dimList[i]) + { + curPos[i-1]++; + curPos[i] = 0; + } + } + return a; + } + + virtual void seek(uint32_t *pos) + { + for (long i = rank-1; i >= 0; i--) + curPos[i] = pos[rank-1-i]; + } +}; + +template +class OutputGenCDF: public NetCDF_handle, public ProgressiveOutputImpl +{ +public: + OutputGenCDF(NcFile *f, NcVar *v, long *dimList, uint32_t rank) + : NetCDF_handle(f,v,dimList,rank) + {} + virtual ~OutputGenCDF() {} + + virtual void put(T a) + { + curVar->set_cur(curPos); + curVar->put(&a, counts); + + curPos[rank-1]++; + for (long i = rank-1; i >= 1; i--) + { + if (curPos[i] == dimList[i]) + { + curPos[i-1]++; + curPos[i] = 0; + } + } + } +}; + +template +class NetCDF_type +{ +public: + static const NcType t = (NcType)-1; +}; + +template<> +class NetCDF_type +{ +public: + static const NcType t = ncInt; +}; + +template<> +class NetCDF_type +{ +public: + static const NcType t = ncInt; +}; + +template<> +class NetCDF_type +{ +public: + static const NcType t = ncFloat; +}; + +template<> +class NetCDF_type +{ +public: + static const NcType t = ncDouble; +}; + +namespace CosmoTool { + template + ProgressiveOutput + ProgressiveOutput::saveArrayProgressive(const std::string& fname, uint32_t *dimList, + uint32_t rank) + { + NcFile *f = new NcFile(fname.c_str(), NcFile::Replace); + + assert(f->is_valid()); + + const NcDim **dimArray = new const NcDim *[rank]; + for (uint32_t i = 0; i < rank; i++) + { + char dimName[255]; + + sprintf(dimName, "dim%d", i); + dimArray[i] = f->add_dim(dimName, dimList[rank-1-i]); + } + + NcVar *v = f->add_var("array", NetCDF_type::t, rank, dimArray); + + long *ldimList = new long[rank]; + + for (uint32_t i = 0; i < rank; i++) + ldimList[rank-1-i] = dimList[i]; + + OutputGenCDF *impl = new OutputGenCDF(f, v, ldimList, rank); + return ProgressiveOutput(impl); + } + + template + ProgressiveInput + ProgressiveInput::loadArrayProgressive(const std::string& fname, uint32_t *&dimList, + uint32_t& rank) + { + NcFile *f = new NcFile(fname.c_str(), NcFile::ReadOnly); + + assert(f->is_valid()); + + NcVar *v = f->get_var("array"); + + rank = v->num_dims(); + long *ldimList = v->edges(); + dimList = new uint32_t[rank]; + for (uint32_t i = 0; i < rank; i++) + { + dimList[rank-i-1] = ldimList[i]; + } + InputGenCDF *impl = new InputGenCDF(f, v, ldimList, rank); + + return ProgressiveInput(impl); + } + + template + void saveArray(const std::string& fname, + T *array, uint32_t *dimList, uint32_t rank) + { + NcFile f(fname.c_str(), NcFile::Replace); + + assert(f.is_valid()); + + const NcDim **dimArray = new const NcDim *[rank]; + for (uint32_t i = 0; i < rank; i++) + { + char dimName[255]; + + sprintf(dimName, "dim%d", i); + dimArray[i] = f.add_dim(dimName, dimList[i]); + } + + NcVar *v = f.add_var("array", NetCDF_type::t, rank, dimArray); + + long *edge = v->edges(); + v->put(array, edge); + delete[] edge; + } + + template + void loadArray(const std::string& fname, + T*&array, uint32_t *&dimList, uint32_t& rank) + throw (NoSuchFileException) + { + NcFile f(fname.c_str(), NcFile::ReadOnly); + + if (!f.is_valid()) + throw NoSuchFileException(fname); + + NcVar *v = f.get_var("array"); + rank = v->num_dims(); + long *edge = v->edges(); + uint32_t fullSize = 1; + dimList = new uint32_t[rank]; + for (int i = 0; i < rank; i++) + { + dimList[i] = edge[i]; + fullSize *= edge[i]; + } + if (fullSize != 0) { + array = new T[fullSize]; + v->get(array, edge); + } + delete[] edge; + } + + template class ProgressiveInput; + template class ProgressiveInput; + template class ProgressiveInput; + + template class ProgressiveOutput; + template class ProgressiveOutput; + template class ProgressiveOutput; + + template void loadArray(const std::string& fname, + int*& array, uint32_t *&dimList, uint32_t& rank); + template void loadArray(const std::string& fname, + float*& array, uint32_t *&dimList, uint32_t& rank); + template void loadArray(const std::string& fname, + double*& array, uint32_t *&dimList, uint32_t& rank); + + template void saveArray(const std::string& fname, + int *array, uint32_t *dimList, uint32_t rank); + template void saveArray(const std::string& fname, + float *array, uint32_t *dimList, uint32_t rank); + template void saveArray(const std::string& fname, + double *array, uint32_t *dimList, uint32_t rank); + +}