|
|
@ -280,9 +280,7 @@ class NCFileWBase |
|
|
|
|
|
|
|
|
|
|
|
template<class T> |
|
|
|
template<class T> |
|
|
|
requires requires(int nc, int vid, const T* d) { |
|
|
|
requires requires(int nc, int vid, const T* d) { |
|
|
|
{ |
|
|
|
{ NCTypeD<T, void>::put_var(nc, vid, d) } -> std::same_as<int>; |
|
|
|
NCTypeD<T, void>::put_var(nc, vid, d) |
|
|
|
|
|
|
|
} -> std::same_as<int>; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
void WriteVar(const MString& vname, const T* data) |
|
|
|
void WriteVar(const MString& vname, const T* data) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -297,9 +295,7 @@ class NCFileWBase |
|
|
|
|
|
|
|
|
|
|
|
template<class T> |
|
|
|
template<class T> |
|
|
|
requires requires(int nc, int vid, const size_t* start, const size_t* count, const T* d) { |
|
|
|
requires requires(int nc, int vid, const size_t* start, const size_t* count, const T* d) { |
|
|
|
{ |
|
|
|
{ NCTypeD<T, void>::put_vara(nc, vid, start, count, d) } -> std::same_as<int>; |
|
|
|
NCTypeD<T, void>::put_vara(nc, vid, start, count, d) |
|
|
|
|
|
|
|
} -> std::same_as<int>; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
void WriteVar(const MString& vname, size_t ind, const T* data) |
|
|
|
void WriteVar(const MString& vname, size_t ind, const T* data) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -422,23 +418,23 @@ class NCFileW: public NCFileWBase |
|
|
|
if constexpr(Is1DType(dtype)) |
|
|
|
if constexpr(Is1DType(dtype)) |
|
|
|
{ |
|
|
|
{ |
|
|
|
const size_t c = data.N(); |
|
|
|
const size_t c = data.N(); |
|
|
|
float buf[c]; |
|
|
|
auto buf = std::make_unique<float[]>(c); |
|
|
|
for(size_t ix = 0; ix < c; ix++) buf[ix] = data.IsFill(ix) ? fill : op(ix); |
|
|
|
for(size_t ix = 0; ix < c; ix++) buf[ix] = data.IsFill(ix) ? fill : op(ix); |
|
|
|
if(tdep) |
|
|
|
if(tdep) |
|
|
|
WriteVar(name, tind, buf); |
|
|
|
WriteVar(name, tind, buf.get()); |
|
|
|
else |
|
|
|
else |
|
|
|
WriteVar(name, buf); |
|
|
|
WriteVar(name, buf.get()); |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
{ |
|
|
|
{ |
|
|
|
const size_t c[2] = {data.Ny(), data.Nx()}; |
|
|
|
const size_t c[2] = {data.Ny(), data.Nx()}; |
|
|
|
float buf[c[0] * c[1]]; |
|
|
|
auto buf = std::make_unique<float[]>(c[0] * c[1]); |
|
|
|
for(size_t iy = 0; iy < c[0]; iy++) |
|
|
|
for(size_t iy = 0; iy < c[0]; iy++) |
|
|
|
for(size_t ix = 0; ix < c[1]; ix++) buf[iy * c[1] + ix] = data.IsFill(ix, iy) ? fill : op(ix, iy); |
|
|
|
for(size_t ix = 0; ix < c[1]; ix++) buf[iy * c[1] + ix] = data.IsFill(ix, iy) ? fill : op(ix, iy); |
|
|
|
if(tdep) |
|
|
|
if(tdep) |
|
|
|
WriteVar(name, tind, buf); |
|
|
|
WriteVar(name, tind, buf.get()); |
|
|
|
else |
|
|
|
else |
|
|
|
WriteVar(name, buf); |
|
|
|
WriteVar(name, buf.get()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if(!*this) return "Can't write variable " + name + ": " + ErrMessage(); |
|
|
|
if(!*this) return "Can't write variable " + name + ": " + ErrMessage(); |
|
|
@ -449,11 +445,9 @@ class NCFileW: public NCFileWBase |
|
|
|
template<class D> MString WriteVariable(const D& data, const MString& name, size_t tind) |
|
|
|
template<class D> MString WriteVariable(const D& data, const MString& name, size_t tind) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if constexpr(Is1DType(DetType<D>())) |
|
|
|
if constexpr(Is1DType(DetType<D>())) |
|
|
|
return WriteVariable( |
|
|
|
return WriteVariable(data, name, [&data = std::as_const(data)](size_t i) { return data(i); }, tind); |
|
|
|
data, name, [&data = std::as_const(data)](size_t i) { return data(i); }, tind); |
|
|
|
|
|
|
|
else |
|
|
|
else |
|
|
|
return WriteVariable( |
|
|
|
return WriteVariable(data, name, [&data = std::as_const(data)](size_t i, size_t j) { return data(i, j); }, tind); |
|
|
|
data, name, [&data = std::as_const(data)](size_t i, size_t j) { return data(i, j); }, tind); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
template<class D, class Op> |
|
|
|
template<class D, class Op> |
|
|
@ -490,63 +484,63 @@ class NCFileW: public NCFileWBase |
|
|
|
else if constexpr(dtype == GPSET) |
|
|
|
else if constexpr(dtype == GPSET) |
|
|
|
{ |
|
|
|
{ |
|
|
|
const size_t c = data.N(); |
|
|
|
const size_t c = data.N(); |
|
|
|
float bufx[c]; |
|
|
|
auto bufx = std::make_unique<float[]>(c); |
|
|
|
float bufy[c]; |
|
|
|
auto bufy = std::make_unique<float[]>(c); |
|
|
|
for(size_t ix = 0; ix < c; ix++) |
|
|
|
for(size_t ix = 0; ix < c; ix++) |
|
|
|
{ |
|
|
|
{ |
|
|
|
bufx[ix] = data.Lon(ix); |
|
|
|
bufx[ix] = data.Lon(ix); |
|
|
|
bufy[ix] = data.Lat(ix); |
|
|
|
bufy[ix] = data.Lat(ix); |
|
|
|
} |
|
|
|
} |
|
|
|
WriteVar("longitude", bufx); |
|
|
|
WriteVar("longitude", bufx.get()); |
|
|
|
WriteVar("latitude", bufy); |
|
|
|
WriteVar("latitude", bufy.get()); |
|
|
|
} |
|
|
|
} |
|
|
|
else if constexpr(dtype == RGRID) |
|
|
|
else if constexpr(dtype == RGRID) |
|
|
|
{ |
|
|
|
{ |
|
|
|
const size_t cx = data.Nx(), cy = data.Ny(); |
|
|
|
const size_t cx = data.Nx(), cy = data.Ny(); |
|
|
|
float bufx[cx]; |
|
|
|
auto bufx = std::make_unique<float[]>(cx); |
|
|
|
float bufy[cy]; |
|
|
|
auto bufy = std::make_unique<float[]>(cy); |
|
|
|
for(size_t ix = 0; ix < cx; ix++) bufx[ix] = data.Ix2X(ix); |
|
|
|
for(size_t ix = 0; ix < cx; ix++) bufx[ix] = data.Ix2X(ix); |
|
|
|
for(size_t iy = 0; iy < cy; iy++) bufy[iy] = data.Iy2Y(iy); |
|
|
|
for(size_t iy = 0; iy < cy; iy++) bufy[iy] = data.Iy2Y(iy); |
|
|
|
WriteVar("x", bufx); |
|
|
|
WriteVar("x", bufx.get()); |
|
|
|
WriteVar("y", bufy); |
|
|
|
WriteVar("y", bufy.get()); |
|
|
|
} |
|
|
|
} |
|
|
|
else if constexpr(dtype == GRGRID) |
|
|
|
else if constexpr(dtype == GRGRID) |
|
|
|
{ |
|
|
|
{ |
|
|
|
const size_t cx = data.Nx(), cy = data.Ny(); |
|
|
|
const size_t cx = data.Nx(), cy = data.Ny(); |
|
|
|
float bufx[cx]; |
|
|
|
auto bufx = std::make_unique<float[]>(cx); |
|
|
|
float bufy[cy]; |
|
|
|
auto bufy = std::make_unique<float[]>(cy); |
|
|
|
for(size_t ix = 0; ix < cx; ix++) bufx[ix] = data.Ix2Lon(ix); |
|
|
|
for(size_t ix = 0; ix < cx; ix++) bufx[ix] = data.Ix2Lon(ix); |
|
|
|
for(size_t iy = 0; iy < cy; iy++) bufy[iy] = data.Iy2Lat(iy); |
|
|
|
for(size_t iy = 0; iy < cy; iy++) bufy[iy] = data.Iy2Lat(iy); |
|
|
|
WriteVar("longitude", bufx); |
|
|
|
WriteVar("longitude", bufx.get()); |
|
|
|
WriteVar("latitude", bufy); |
|
|
|
WriteVar("latitude", bufy.get()); |
|
|
|
} |
|
|
|
} |
|
|
|
else if constexpr(dtype == GRID) |
|
|
|
else if constexpr(dtype == GRID) |
|
|
|
{ |
|
|
|
{ |
|
|
|
const size_t c[2] = {data.Ny(), data.Nx()}; |
|
|
|
const size_t c[2] = {data.Ny(), data.Nx()}; |
|
|
|
float bufx[c[0] * c[1]]; |
|
|
|
auto bufx = std::make_unique<float[]>(c[0] * c[1]); |
|
|
|
float bufy[c[0] * c[1]]; |
|
|
|
auto bufy = std::make_unique<float[]>(c[0] * c[1]); |
|
|
|
for(size_t iy = 0; iy < c[0]; iy++) |
|
|
|
for(size_t iy = 0; iy < c[0]; iy++) |
|
|
|
for(size_t ix = 0; ix < c[1]; ix++) |
|
|
|
for(size_t ix = 0; ix < c[1]; ix++) |
|
|
|
{ |
|
|
|
{ |
|
|
|
bufx[iy * c[1] + ix] = data.X(ix, iy); |
|
|
|
bufx[iy * c[1] + ix] = data.X(ix, iy); |
|
|
|
bufy[iy * c[1] + ix] = data.Y(ix, iy); |
|
|
|
bufy[iy * c[1] + ix] = data.Y(ix, iy); |
|
|
|
} |
|
|
|
} |
|
|
|
WriteVar("x", bufx); |
|
|
|
WriteVar("x", bufx.get()); |
|
|
|
WriteVar("y", bufy); |
|
|
|
WriteVar("y", bufy.get()); |
|
|
|
} |
|
|
|
} |
|
|
|
else if constexpr(dtype == GGRID) |
|
|
|
else if constexpr(dtype == GGRID) |
|
|
|
{ |
|
|
|
{ |
|
|
|
const size_t c[2] = {data.Ny(), data.Nx()}; |
|
|
|
const size_t c[2] = {data.Ny(), data.Nx()}; |
|
|
|
float bufx[c[0] * c[1]]; |
|
|
|
auto bufx = std::make_unique<float[]>(c[0] * c[1]); |
|
|
|
float bufy[c[0] * c[1]]; |
|
|
|
auto bufy = std::make_unique<float[]>(c[0] * c[1]); |
|
|
|
for(size_t iy = 0; iy < c[0]; iy++) |
|
|
|
for(size_t iy = 0; iy < c[0]; iy++) |
|
|
|
for(size_t ix = 0; ix < c[1]; ix++) |
|
|
|
for(size_t ix = 0; ix < c[1]; ix++) |
|
|
|
{ |
|
|
|
{ |
|
|
|
bufx[iy * c[1] + ix] = data.Lon(ix, iy); |
|
|
|
bufx[iy * c[1] + ix] = data.Lon(ix, iy); |
|
|
|
bufy[iy * c[1] + ix] = data.Lat(ix, iy); |
|
|
|
bufy[iy * c[1] + ix] = data.Lat(ix, iy); |
|
|
|
} |
|
|
|
} |
|
|
|
WriteVar("longitude", bufx); |
|
|
|
WriteVar("longitude", bufx.get()); |
|
|
|
WriteVar("latitude", bufy); |
|
|
|
WriteVar("latitude", bufy.get()); |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
return "Unknown data type"; |
|
|
|
return "Unknown data type"; |
|
|
|