29 namespace mio {
template <
class T>
class Array3D;
template <
class T>
class Array3DProxy2; }
40 template <
class T>
class Array3DProxy {
43 Array3DProxy2<T> operator[](
const size_t& i_any) {
44 return Array3DProxy2<T>(array3D, anx, i_any);
48 Array3DProxy(Array3D<T>& i_array3D,
const size_t& i_anx) : array3D(i_array3D), anx(i_anx){}
60 template <
class T>
class Array3DProxy2 {
62 friend class Array3DProxy<T>;
63 T& operator[](
const size_t& i_anz) {
64 return array3D(anx, any, i_anz);
68 Array3DProxy2(Array3D<T>& i_array3D,
const size_t& i_anx,
69 const size_t& i_any) : array3D(i_array3D), anx(i_anx), any(i_any){}
84 template<
class T>
class Array3D {
100 Array3D(
const Array3D<T>& i_array3D,
101 const size_t& i_nx,
const size_t& i_ny,
const size_t& i_nz,
102 const size_t& i_ncols,
const size_t& i_nrows,
const size_t& i_ndepth);
110 Array3D(
const size_t& anx,
const size_t& any,
const size_t& anz);
119 Array3D(
const size_t& anx,
const size_t& any,
const size_t& anz,
const T& init);
133 void subset(
const Array3D<T>& i_array3D,
134 const size_t& i_nx,
const size_t& i_ny,
const size_t& i_nz,
135 const size_t& i_ncols,
const size_t& i_nrows,
const size_t& i_ndepth);
149 void fill(
const Array3D<T>& i_array3D,
150 const size_t& i_nx,
const size_t& i_ny,
const size_t& i_nz,
151 const size_t& i_ncols,
const size_t& i_nrows,
const size_t& i_ndepth);
153 void fill(
const Array3D<T>& i_array3D,
const size_t& i_nx,
const size_t& i_ny,
const size_t& i_nz);
162 void insert(
const Array2D<T>& layer,
const size_t& depth);
177 void resize(
const size_t& anx,
const size_t& any,
const size_t& anz);
178 void resize(
const size_t& anx,
const size_t& any,
const size_t& anz,
const T& init);
179 void size(
size_t& anx,
size_t& any,
size_t& anz)
const;
181 size_t getNx()
const;
182 size_t getNy()
const;
183 size_t getNz()
const;
213 const Array3D<T>
getAbs()
const;
217 template<
class P>
friend std::iostream& operator<<(std::iostream& os, const Array3D<P>&
array);
218 template<
class P>
friend std::iostream&
operator>>(std::iostream& is, Array3D<P>&
array);
221 static bool checkEpsilonEquality(
const Array3D<double>& rhs1,
const Array3D<double>& rhs2,
const double& epsilon);
225 T&
operator ()(
const size_t& x,
const size_t& y,
const size_t& z);
226 const T
operator ()(
const size_t& x,
const size_t& y,
const size_t& z)
const;
233 const Array3D<T>
operator+(
const T& rhs)
const;
234 Array3D<T>&
operator+=(
const Array3D<T>& rhs);
235 const Array3D<T>
operator+(
const Array3D<T>& rhs)
const;
238 const Array3D<T>
operator-(
const T& rhs)
const;
239 Array3D<T>&
operator-=(
const Array3D<T>& rhs);
240 const Array3D<T>
operator-(
const Array3D<T>& rhs)
const;
243 const Array3D<T>
operator*(
const T& rhs)
const;
244 Array3D<T>&
operator*=(
const Array3D<T>& rhs);
245 const Array3D<T>
operator*(
const Array3D<T>& rhs)
const;
248 const Array3D<T>
operator/(
const T& rhs)
const;
249 Array3D<T>&
operator/=(
const Array3D<T>& rhs);
250 const Array3D<T>
operator/(
const Array3D<T>& rhs)
const;
266 return vecData.at(i);
274 return vecData.at(i);
282 if ((x >= nx) || (y >= ny) || (z >= nz)) {
283 std::ostringstream ss;
284 ss <<
"Trying to access array(" << x <<
"," << y <<
"," << z <<
")";
285 ss <<
" while array is (" << nx <<
"," << ny <<
"," << nz <<
")";
291 return vecData[x + y*nx + z*nxny];
296 if ((x >= nx) || (y >= ny) || (z >= nz)) {
297 std::ostringstream ss;
298 ss <<
"Trying to access array(" << x <<
"," << y <<
"," << z <<
")";
299 ss <<
" while array is (" << nx <<
"," << ny <<
"," << nz <<
")";
303 return vecData[x + y*nx + z*nxny];
307 return Array3DProxy<T>(*
this, i);
315 const size_t& i_nx,
const size_t& i_ny,
const size_t& i_nz,
316 const size_t& i_ncols,
const size_t& i_nrows,
const size_t& i_ndepth)
317 : vecData(i_ncols*i_nrows*i_ndepth), nx(i_ncols), ny(i_nrows), nz(i_ndepth), nxny(i_ncols*i_nrows), keep_nodata(true)
319 subset(i_array3D, i_nx, i_ny, i_nz, i_ncols, i_nrows, i_ndepth);
323 const size_t& i_nx,
const size_t& i_ny,
const size_t& i_nz,
324 const size_t& i_ncols,
const size_t& i_nrows,
const size_t& i_ndepth)
327 if (((i_nx+i_ncols) > i_array3D.nx) || ((i_ny+i_nrows) > i_array3D.ny) || ((i_nz+i_ndepth) > i_array3D.nz)) {
328 std::ostringstream ss;
329 ss <<
"Trying to cut an array of size (" << i_array3D.nx <<
"," << i_array3D.ny <<
"," << i_array3D.nz <<
") ";
330 ss <<
"to size (" << i_ncols <<
"," << i_nrows <<
"," << i_ndepth <<
") ";
331 ss <<
"starting at (" << i_nx <<
"," << i_ny <<
"," << i_nz <<
")";
335 if ((i_ncols == 0) || (i_nrows == 0) || (i_ndepth == 0))
338 resize(i_ncols, i_nrows, i_ndepth);
340 for (
size_t ii=0; ii<nz; ii++) {
341 for (
size_t jj=0; jj<ny; jj++) {
342 for (
size_t kk=0; kk<nx; kk++) {
344 operator()(kk,jj,ii) = i_array3D(i_nx+kk, i_ny+jj, i_nz+ii);
352 size_t i_ncols, i_nrows, i_ndepth;
353 i_array3D.size(i_ncols, i_nrows, i_ndepth);
354 fill(i_array3D, i_nx, i_ny, i_nz, i_ncols, i_nrows, i_ndepth);
358 const size_t& i_nx,
const size_t& i_ny,
const size_t& i_nz,
359 const size_t& i_ncols,
const size_t& i_nrows,
const size_t& i_ndepth)
362 if (((i_nx+i_ncols) > i_array3D.nx) || ((i_ny+i_nrows) > i_array3D.ny) || ((i_nz+i_ndepth) > i_array3D.nz)) {
363 std::ostringstream ss;
364 ss <<
"Filling an array of size (" << nx <<
"," << ny <<
"," << nz <<
") ";
365 ss <<
"with an array of size (" << i_ncols <<
"," << i_nrows <<
"," << i_ndepth <<
") ";
366 ss <<
"starting at (" << i_nx <<
"," << i_ny <<
"," << i_nz <<
")";
370 if ((i_ncols == 0) || (i_nrows == 0) || (i_ndepth == 0))
374 for (
size_t ii=i_nz; ii<(i_nz+i_ndepth); ii++) {
375 for (
size_t jj=i_ny; jj<(i_ny+i_nrows); jj++) {
376 for (
size_t kk=i_nx; kk<(i_nx+i_ncols); kk++) {
377 const size_t ix = kk-i_nx;
378 const size_t iy = jj-i_ny;
379 const size_t iz = ii-i_nz;
380 operator()(kk,jj,ii) = i_array3D(ix, iy, iz);
389 std::ostringstream ss;
390 ss <<
"Trying to insert layer at depth " << depth <<
" ";
391 ss <<
"in an array of size (" << nx <<
"," << ny <<
"," << nz <<
") ";
395 std::ostringstream ss;
396 ss <<
"Trying to insert layer of size (" << layer.
getNx() <<
"," << layer.
getNy() <<
") ";
397 ss <<
"in an array of size (" << nx <<
"," << ny <<
"," << nz <<
") ";
401 for (
size_t jj=0; jj<ny; jj++) {
402 for (
size_t ii=0; ii<nx; ii++) {
403 operator()(ii,jj,depth) = layer(ii, jj);
409 : vecData(anx*any*anz), nx(anx), ny(any), nz(anz), nxny(anx*any), keep_nodata(true)
414 template<
class T>
Array3D<T>::Array3D(
const size_t& anx,
const size_t& any,
const size_t& anz,
const T& init)
415 : vecData(anx*any*anz, init), nx(anx), ny(any), nz(anz), nxny(anx*any), keep_nodata(true)
421 keep_nodata = i_keep_nodata;
430 vecData.resize(anx*any*anz);
437 template<
class T>
void Array3D<T>::resize(
const size_t& anx,
const size_t& any,
const size_t& anz,
const T& init) {
439 vecData.resize(anx*any*anz, init);
470 nx = ny = nz = nxny = 0;
474 return (nx==0 && ny==0 && nz==0);
478 std::ostringstream os;
480 for (
size_t kk=0; kk<nz; kk++) {
481 os <<
"depth[" << kk <<
"]\n";
482 for (
size_t jj=0; jj<ny; jj++) {
483 for (
size_t ii=0; ii<nx; ii++) {
484 os << operator()(ii,jj,kk) <<
" ";
489 os <<
"</array3d>\n";
493 template<
class P> std::iostream& operator<<(std::iostream& os, const Array3D<P>&
array) {
494 os.write(reinterpret_cast<const char*>(&
array.keep_nodata),
sizeof(
array.keep_nodata));
495 os.write(reinterpret_cast<const char*>(&
array.nx),
sizeof(
array.nx));
496 os.write(reinterpret_cast<const char*>(&
array.ny),
sizeof(
array.ny));
497 os.write(reinterpret_cast<const char*>(&
array.nz),
sizeof(
array.nz));
498 os.write(reinterpret_cast<const char*>(&
array.vecData[0]), static_cast<std::streamsize>(
array.nx*
array.ny*
array.nz*
sizeof(P)));
503 is.read(reinterpret_cast<char*>(&array.keep_nodata),
sizeof(array.keep_nodata));
504 is.read(reinterpret_cast<char*>(&array.nx),
sizeof(array.nx));
505 is.read(reinterpret_cast<char*>(&array.ny),
sizeof(array.ny));
506 is.read(reinterpret_cast<char*>(&array.nz),
sizeof(array.nz));
507 array.vecData.resize(array.nx*array.ny*array.nz);
508 is.read(reinterpret_cast<char*>(&array.vecData[0]), static_cast<std::streamsize>(array.nx*array.ny*array.nz*
sizeof(P)));
514 T min = std::numeric_limits<T>::max();
515 const size_t nxyz = ny*nx*nz;
517 if (keep_nodata==
false) {
518 for (
size_t jj=0; jj<nxyz; jj++) {
519 const T val = vecData[jj];
520 if (val<min) min=val;
524 for (
size_t jj=0; jj<nxyz; jj++) {
525 const T val = vecData[jj];
528 if (min!=std::numeric_limits<T>::max())
return min;
535 T max = -std::numeric_limits<T>::max();
536 const size_t nxyz = ny*nx*nz;
538 if (keep_nodata==
false) {
539 for (
size_t jj=0; jj<nxyz; jj++) {
540 const T val = vecData[jj];
541 if (val>max) max=val;
545 for (
size_t jj=0; jj<nxyz; jj++) {
546 const T val = vecData[jj];
549 if (max!=-std::numeric_limits<T>::max())
return max;
557 const size_t nxyz = nx*ny*nz;
559 if (keep_nodata==
false) {
560 for (
size_t jj=0; jj<nxyz; jj++) {
561 const T val = vecData[jj];
564 if (nxyz>0)
return mean/(T)(nxyz);
568 for (
size_t jj=0; jj<nxyz; jj++) {
569 const T val = vecData[jj];
575 if (count>0)
return mean/(T)(count);
582 const size_t nxyz = nx*ny*nz;
584 if (keep_nodata==
false) {
588 for (
size_t ii=0; ii<nxyz; ii++) {
596 if (std::numeric_limits<T>::is_signed) {
597 const size_t nxyz = nx*ny*nz;
598 if (keep_nodata==
false) {
599 for (
size_t jj=0; jj<nxyz; jj++) {
600 T& val = vecData[jj];
604 for (
size_t jj=0; jj<nxyz; jj++) {
605 T& val = vecData[jj];
621 if (nx!=rhs.
nx || ny!=rhs.
ny || nz!=rhs.
nz)
return false;
623 const size_t nxyz = nx*ny*nz;
624 for (
size_t jj=0; jj<nxyz; jj++)
635 if (
this != &source) {
636 keep_nodata = source.keep_nodata;
641 vecData = source.vecData;
647 std::fill(vecData.begin(), vecData.end(), value);
654 if ((rhs.nx != nx) || (rhs.ny != ny) || (rhs.nz != nz)) {
655 std::ostringstream ss;
656 ss <<
"Trying to add two Array3D objects with different dimensions: ";
657 ss <<
"(" << nx <<
"," << ny <<
"," << nz <<
") + (" << rhs.nx <<
"," << rhs.ny <<
"," << rhs.nz <<
")";
661 const size_t nxyz = nx*ny*nz;
662 if (keep_nodata==
false) {
663 for (
size_t jj=0; jj<nxyz; jj++) {
664 vecData[jj] += rhs(jj);
667 for (
size_t jj=0; jj<nxyz; jj++) {
671 vecData[jj] += rhs(jj);
688 if (rhs==0.)
return *
this;
691 const size_t nxyz = nx*ny*nz;
692 if (keep_nodata==
false) {
693 for (
size_t jj=0; jj<nxyz; jj++) {
697 for (
size_t jj=0; jj<nxyz; jj++) {
717 if ((rhs.nx != nx) || (rhs.ny != ny) || (rhs.nz != nz)) {
718 std::ostringstream ss;
719 ss <<
"Trying to substract two Array3D objects with different dimensions: ";
720 ss <<
"(" << nx <<
"," << ny <<
"," << nz <<
") - (" << rhs.nx <<
"," << rhs.ny <<
"," << rhs.nz <<
")";
724 const size_t nxyz = nx*ny*nz;
725 if (keep_nodata==
false) {
726 for (
size_t jj=0; jj<nxyz; jj++) {
727 vecData[jj] -= rhs(jj);
730 for (
size_t jj=0; jj<nxyz; jj++) {
734 vecData[jj] -= rhs(jj);
766 if ((rhs.nx != nx) || (rhs.ny != ny) || (rhs.nz != nz)) {
767 std::ostringstream ss;
768 ss <<
"Trying to multiply two Array3D objects with different dimensions: ";
769 ss <<
"(" << nx <<
"," << ny <<
"," << nz <<
") * (" << rhs.nx <<
"," << rhs.ny <<
"," << rhs.nz <<
")";
773 const size_t nxyz = nx*ny*nz;
774 if (keep_nodata==
false) {
775 for (
size_t jj=0; jj<nxyz; jj++) {
776 vecData[jj] *= rhs(jj);
779 for (
size_t jj=0; jj<nxyz; jj++) {
783 vecData[jj] *= rhs(jj);
800 if (rhs==1.)
return *
this;
803 const size_t nxyz = nx*ny*nz;
804 if (keep_nodata==
false) {
805 for (
size_t jj=0; jj<nxyz; jj++) {
809 for (
size_t jj=0; jj<nxyz; jj++) {
829 if ((rhs.nx != nx) || (rhs.ny != ny) || (rhs.nz != nz)) {
830 std::ostringstream ss;
831 ss <<
"Trying to divide two Array3D objects with different dimensions: ";
832 ss <<
"(" << nx <<
"," << ny <<
"," << nz <<
") / (" << rhs.nx <<
"," << rhs.ny <<
"," << rhs.nz <<
")";
836 const size_t nxyz = nx*ny*nz;
837 if (keep_nodata==
false) {
838 for (
size_t jj=0; jj<nxyz; jj++) {
839 vecData[jj] /= rhs(jj);
842 for (
size_t jj=0; jj<nxyz; jj++) {
846 vecData[jj] /= rhs(jj);
876 const size_t in_nx=in.getNx(), in_ny=in.getNy(), in_nz=in.getNz();
878 if (nx!=in_nx || ny!=in_ny || nz!=in_nz)
881 const size_t nxyz = nx*ny*nz;
882 for (
size_t jj=0; jj<nxyz; jj++)
T getMin() const
returns the minimum value contained in the grid
Definition: Array3D.h:512
size_t getNy() const
Definition: Array3D.h:460
T getMax() const
returns the maximum value contained in the grid
Definition: Array3D.h:533
size_t getNx() const
Definition: Array2D.h:386
const Array3D< T > operator+(const T &rhs) const
Definition: Array3D.h:706
Array3D< T > & operator*=(const T &rhs)
Definition: Array3D.h:798
size_t size() const
Definition: Array3D.h:452
const Array3D< T > operator*(const T &rhs) const
Definition: Array3D.h:818
Array3D< T > & operator=(const Array3D< T > &)
Definition: Array3D.h:634
void clear()
Definition: Array3D.h:468
friend std::iostream & operator>>(std::iostream &is, Array3D< P > &array)
Definition: Array3D.h:502
The template class Array2D is a 2D Array (Matrix) able to hold any type of object as datatype...
Definition: Array2D.h:29
void fill(const Array3D< T > &i_array3D, const size_t &i_nx, const size_t &i_ny, const size_t &i_nz, const size_t &i_ncols, const size_t &i_nrows, const size_t &i_ndepth)
A method that can be used to insert a subplane into an existing Array3D object that is passed as i_ar...
Definition: Array3D.h:357
bool checkEpsilonEquality(const Array3D< double > &rhs, const double &epsilon) const
Definition: Array3D.h:620
bool checkEpsilonEquality(const double &val1, const double &val2, const double &epsilon)
Check whether two values are equal regarding a certain epsilon environment (within certain radius of ...
Definition: IOUtils.h:81
bool empty() const
Definition: Array3D.h:473
size_t nx
Definition: Array3D.h:257
const Array3D< T > getAbs() const
returns the grid of the absolute value of values contained in the grid
Definition: Array3D.h:612
bool keep_nodata
Definition: Array3D.h:261
T & operator()(const size_t &i)
Definition: Array3D.h:264
Array3D< T > & operator+=(const T &rhs)
Definition: Array3D.h:686
size_t getNx() const
Definition: Array3D.h:456
Array3D< T > & operator-=(const T &rhs)
Definition: Array3D.h:749
std::vector< T > vecData
The actual objects are stored in a one-dimensional vector.
Definition: Array3D.h:256
size_t getCount() const
returns the number of points contained in the grid. If setNodataHandling(IOUtils::RAW_NODATA), then the number of points is the size of the grid. If setNodataHandling(IOUtils::PARSE_NODATA), then it is the number of non-nodata values in the grid
Definition: Array3D.h:580
Array3DProxy< T > operator[](const size_t &i)
Definition: Array3D.h:306
#define AT
Definition: IOExceptions.h:29
const Array3D< T > operator/(const T &rhs) const
Definition: Array3D.h:867
const double nodata
This is the internal nodata value.
Definition: IOUtils.h:60
const Array3D< T > operator-(const T &rhs) const
Definition: Array3D.h:755
size_t nz
Definition: Array3D.h:259
void abs()
Definition: Array3D.h:595
Array3D()
Definition: Array3D.h:310
size_t nxny
Definition: Array3D.h:260
void subset(const Array3D< T > &i_array3D, const size_t &i_nx, const size_t &i_ny, const size_t &i_nz, const size_t &i_ncols, const size_t &i_nrows, const size_t &i_ndepth)
Definition: Array3D.h:322
Array3D< T > & operator/=(const T &rhs)
Definition: Array3D.h:861
size_t getNz() const
Definition: Array3D.h:464
void resize(const size_t &anx, const size_t &any, const size_t &anz)
Definition: Array3D.h:428
bool operator==(const Array3D< T > &) const
Operator that tests for equality.
Definition: Array3D.h:875
T getMean() const
returns the mean value contained in the grid
Definition: Array3D.h:554
thrown when an index is out of bounds
Definition: IOExceptions.h:108
const std::string toString() const
Definition: Array3D.h:477
size_t ny
Definition: Array3D.h:258
bool getKeepNodata() const
get how to process nodata values (ie: as nodata or as normal numbers)
Definition: Array3D.h:424
const double e
Definition: Meteoconst.h:66
void insert(const Array2D< T > &layer, const size_t &depth)
insert a 2D layer in an Array3D object The (nx ,ny) dimensions of the 2D and the 3D arrays must match...
Definition: Array3D.h:386
The template class Array3D is a 3D Array (Tensor) able to hold any type of object as datatype...
Definition: Array3D.h:29
The basic exception class adjusted for the needs of SLF software.
Definition: IOExceptions.h:41
size_t getNy() const
Definition: Array2D.h:390
std::iostream & operator>>(std::iostream &is, Config &cfg)
Definition: Config.cc:141
void setKeepNodata(const bool i_keep_nodata)
set how to process nodata values (ie: as nodata or as normal numbers)
Definition: Array3D.h:420
value::array array
Definition: picojson.h:194
bool operator!=(const Array3D< T > &) const
Operator that tests for inequality.
Definition: Array3D.h:888