32namespace mio {
template <
class T>
class Array3D;
template <
class T>
class Array3DProxy2; }
43template <
class T>
class Array3DProxy {
45 friend class Array3D<T>;
46 Array3DProxy2<T> operator[](
const size_t& i_any) {
47 return Array3DProxy2<T>(array3D, anx, i_any);
51 Array3DProxy(Array3D<T>& i_array3D,
const size_t& i_anx) : array3D(i_array3D), anx(i_anx){}
63template <
class T>
class Array3DProxy2 {
65 friend class Array3DProxy<T>;
66 T& operator[](
const size_t& i_anz) {
67 return array3D(anx, any, i_anz);
71 Array3DProxy2(Array3D<T>& i_array3D,
const size_t& i_anx,
72 const size_t& i_any) : array3D(i_array3D), anx(i_anx), any(i_any){}
104 const size_t& i_nx,
const size_t& i_ny,
const size_t& i_nz,
105 const size_t& i_ncols,
const size_t& i_nrows,
const size_t& i_ndepth);
113 Array3D(
const size_t& anx,
const size_t& any,
const size_t& anz);
122 Array3D(
const size_t& anx,
const size_t& any,
const size_t& anz,
const T& init);
137 const size_t& i_nx,
const size_t& i_ny,
const size_t& i_nz,
138 const size_t& i_ncols,
const size_t& i_nrows,
const size_t& i_ndepth);
153 const size_t& i_nx,
const size_t& i_ny,
const size_t& i_nz,
154 const size_t& i_ncols,
const size_t& i_nrows,
const size_t& i_ndepth);
156 void fill(
const Array3D<T>& i_array3D,
const size_t& i_nx,
const size_t& i_ny,
const size_t& i_nz);
180 void resize(
const size_t& anx,
const size_t& any,
const size_t& anz);
181 void resize(
const size_t& anx,
const size_t& any,
const size_t& anz,
const T& init);
182 void size(
size_t& anx,
size_t& any,
size_t& anz)
const;
228 T&
operator ()(
const size_t& x,
const size_t& y,
const size_t& z);
229 const T
operator ()(
const size_t& x,
const size_t& y,
const size_t& z)
const;
268 return vecData.at(i);
276 return vecData.at(i);
284 if ((x >= nx) || (y >= ny) || (z >= nz)) {
285 std::ostringstream ss;
286 ss <<
"Trying to access array(" << x <<
"," << y <<
"," << z <<
")";
287 ss <<
" while array is (" << nx <<
"," << ny <<
"," << nz <<
")";
293 return vecData[x + y*nx + z*nxny];
298 if ((x >= nx) || (y >= ny) || (z >= nz)) {
299 std::ostringstream ss;
300 ss <<
"Trying to access array(" << x <<
"," << y <<
"," << z <<
")";
301 ss <<
" while array is (" << nx <<
"," << ny <<
"," << nz <<
")";
305 return vecData[x + y*nx + z*nxny];
309 return Array3DProxy<T>(*
this, i);
317 const size_t& i_nx,
const size_t& i_ny,
const size_t& i_nz,
318 const size_t& i_ncols,
const size_t& i_nrows,
const size_t& i_ndepth)
319 : vecData(i_ncols*i_nrows*i_ndepth), nx(i_ncols), ny(i_nrows), nz(i_ndepth), nxny(i_ncols*i_nrows), keep_nodata(true)
321 subset(i_array3D, i_nx, i_ny, i_nz, i_ncols, i_nrows, i_ndepth);
325 const size_t& i_nx,
const size_t& i_ny,
const size_t& i_nz,
326 const size_t& i_ncols,
const size_t& i_nrows,
const size_t& i_ndepth)
329 if (((i_nx+i_ncols) > i_array3D.
nx) || ((i_ny+i_nrows) > i_array3D.
ny) || ((i_nz+i_ndepth) > i_array3D.
nz)) {
330 std::ostringstream ss;
331 ss <<
"Trying to cut an array of size (" << i_array3D.
nx <<
"," << i_array3D.
ny <<
"," << i_array3D.
nz <<
") ";
332 ss <<
"to size (" << i_ncols <<
"," << i_nrows <<
"," << i_ndepth <<
") ";
333 ss <<
"starting at (" << i_nx <<
"," << i_ny <<
"," << i_nz <<
")";
337 if ((i_ncols == 0) || (i_nrows == 0) || (i_ndepth == 0))
340 resize(i_ncols, i_nrows, i_ndepth);
342 for (
size_t ii=0; ii<nz; ii++) {
343 for (
size_t jj=0; jj<ny; jj++) {
344 for (
size_t kk=0; kk<nx; kk++) {
346 operator()(kk,jj,ii) = i_array3D(i_nx+kk, i_ny+jj, i_nz+ii);
354 size_t i_ncols, i_nrows, i_ndepth;
355 i_array3D.
size(i_ncols, i_nrows, i_ndepth);
356 fill(i_array3D, i_nx, i_ny, i_nz, i_ncols, i_nrows, i_ndepth);
360 const size_t& i_nx,
const size_t& i_ny,
const size_t& i_nz,
361 const size_t& i_ncols,
const size_t& i_nrows,
const size_t& i_ndepth)
364 if (((i_nx+i_ncols) > i_array3D.
nx) || ((i_ny+i_nrows) > i_array3D.
ny) || ((i_nz+i_ndepth) > i_array3D.
nz)) {
365 std::ostringstream ss;
366 ss <<
"Filling an array of size (" << nx <<
"," << ny <<
"," << nz <<
") ";
367 ss <<
"with an array of size (" << i_ncols <<
"," << i_nrows <<
"," << i_ndepth <<
") ";
368 ss <<
"starting at (" << i_nx <<
"," << i_ny <<
"," << i_nz <<
")";
372 if ((i_ncols == 0) || (i_nrows == 0) || (i_ndepth == 0))
376 for (
size_t ii=i_nz; ii<(i_nz+i_ndepth); ii++) {
377 const size_t iz = ii-i_nz;
378 for (
size_t jj=i_ny; jj<(i_ny+i_nrows); jj++) {
379 const size_t iy = jj-i_ny;
380 for (
size_t kk=i_nx; kk<(i_nx+i_ncols); kk++) {
381 const size_t ix = kk-i_nx;
382 operator()(kk,jj,ii) = i_array3D(ix, iy, iz);
391 std::ostringstream ss;
392 ss <<
"Trying to insert layer at depth " << depth <<
" ";
393 ss <<
"in an array of size (" << nx <<
"," << ny <<
"," << nz <<
") ";
397 std::ostringstream ss;
398 ss <<
"Trying to insert layer of size (" << layer.
getNx() <<
"," << layer.
getNy() <<
") ";
399 ss <<
"in an array of size (" << nx <<
"," << ny <<
"," << nz <<
") ";
403 for (
size_t jj=0; jj<ny; jj++) {
404 for (
size_t ii=0; ii<nx; ii++) {
405 operator()(ii,jj,depth) = layer(ii, jj);
411 : vecData(anx*any*anz), nx(anx), ny(any), nz(anz), nxny(anx*any), keep_nodata(true)
416template<
class T>
Array3D<T>::Array3D(
const size_t& anx,
const size_t& any,
const size_t& anz,
const T& init)
417 : vecData(anx*any*anz, init), nx(anx), ny(any), nz(anz), nxny(anx*any), keep_nodata(true)
423 keep_nodata = i_keep_nodata;
432 vecData.resize(anx*any*anz);
439template<
class T>
void Array3D<T>::resize(
const size_t& anx,
const size_t& any,
const size_t& anz,
const T& init) {
441 vecData.resize(anx*any*anz, init);
472 nx = ny = nz = nxny = 0;
476 return (nx==0 && ny==0 && nz==0);
480 std::ostringstream os;
482 for (
size_t kk=0; kk<nz; kk++) {
483 os <<
"depth[" << kk <<
"]\n";
484 for (
size_t jj=0; jj<ny; jj++) {
485 for (
size_t ii=0; ii<nx; ii++) {
486 os << operator()(ii,jj,kk) <<
" ";
491 os <<
"</array3d>\n";
497 os.write(
reinterpret_cast<const char*
>(&array.
nx),
sizeof(array.
nx));
498 os.write(
reinterpret_cast<const char*
>(&array.
ny),
sizeof(array.
ny));
499 os.write(
reinterpret_cast<const char*
>(&array.
nz),
sizeof(array.
nz));
500 os.write(
reinterpret_cast<const char*
>(&array.
vecData[0]),
static_cast<std::streamsize
>(array.
nx*array.
ny*array.
nz*
sizeof(P)));
506 is.read(
reinterpret_cast<char*
>(&array.
nx),
sizeof(array.
nx));
507 is.read(
reinterpret_cast<char*
>(&array.
ny),
sizeof(array.
ny));
508 is.read(
reinterpret_cast<char*
>(&array.
nz),
sizeof(array.
nz));
511 is.read(
reinterpret_cast<char*
>(&array.
vecData[0]),
static_cast<std::streamsize
>(array.
nx*array.
ny*array.
nz*
sizeof(P)));
517 T min = std::numeric_limits<T>::max();
518 const size_t nxyz = ny*nx*nz;
520 if (keep_nodata==
false) {
521 min = *min_element(vecData.begin(), vecData.end());
522 if (min!=std::numeric_limits<T>::max())
return min;
525 for (
size_t jj=0; jj<nxyz; jj++) {
526 const T val = vecData[jj];
529 if (min!=std::numeric_limits<T>::max())
return min;
536 T max = -std::numeric_limits<T>::max();
537 const size_t nxyz = ny*nx*nz;
539 if (keep_nodata==
false) {
540 max = *max_element(vecData.begin(), vecData.end());
541 if (max!=-std::numeric_limits<T>::max())
return max;
544 for (
size_t jj=0; jj<nxyz; jj++) {
545 const T val = vecData[jj];
548 if (max!=-std::numeric_limits<T>::max())
return max;
556 const size_t nxyz = nx*ny*nz;
558 if (keep_nodata==
false) {
559 if (nxyz>0)
return std::accumulate(vecData.begin(), vecData.end(), 0.) / (T)(nxyz);
563 for (
size_t jj=0; jj<nxyz; jj++) {
564 const T val = vecData[jj];
577 const size_t nxyz = nx*ny*nz;
579 if (keep_nodata==
false) {
583 for (
size_t ii=0; ii<nxyz; ii++) {
591 if (std::numeric_limits<T>::is_signed) {
592 const size_t nxyz = nx*ny*nz;
593 if (keep_nodata==
false) {
594 for (
size_t jj=0; jj<nxyz; jj++) {
595 T& val = vecData[jj];
599 for (
size_t jj=0; jj<nxyz; jj++) {
600 T& val = vecData[jj];
616 if (nx!=rhs.
nx || ny!=rhs.
ny || nz!=rhs.
nz)
return false;
618 const size_t nxyz = nx*ny*nz;
619 for (
size_t jj=0; jj<nxyz; jj++)
630 std::fill(vecData.begin(), vecData.end(), value);
637 if ((rhs.
nx != nx) || (rhs.
ny != ny) || (rhs.
nz != nz)) {
638 std::ostringstream ss;
639 ss <<
"Trying to add two Array3D objects with different dimensions: ";
640 ss <<
"(" << nx <<
"," << ny <<
"," << nz <<
") + (" << rhs.
nx <<
"," << rhs.
ny <<
"," << rhs.
nz <<
")";
644 const size_t nxyz = nx*ny*nz;
645 if (keep_nodata==
false) {
646 for (
size_t jj=0; jj<nxyz; jj++) {
647 vecData[jj] += rhs(jj);
650 for (
size_t jj=0; jj<nxyz; jj++) {
654 vecData[jj] += rhs(jj);
671 if (rhs==0.)
return *
this;
674 const size_t nxyz = nx*ny*nz;
675 if (keep_nodata==
false) {
676 for (
size_t jj=0; jj<nxyz; jj++) {
680 for (
size_t jj=0; jj<nxyz; jj++) {
700 if ((rhs.
nx != nx) || (rhs.
ny != ny) || (rhs.
nz != nz)) {
701 std::ostringstream ss;
702 ss <<
"Trying to substract two Array3D objects with different dimensions: ";
703 ss <<
"(" << nx <<
"," << ny <<
"," << nz <<
") - (" << rhs.
nx <<
"," << rhs.
ny <<
"," << rhs.
nz <<
")";
707 const size_t nxyz = nx*ny*nz;
708 if (keep_nodata==
false) {
709 for (
size_t jj=0; jj<nxyz; jj++) {
710 vecData[jj] -= rhs(jj);
713 for (
size_t jj=0; jj<nxyz; jj++) {
717 vecData[jj] -= rhs(jj);
749 if ((rhs.
nx != nx) || (rhs.
ny != ny) || (rhs.
nz != nz)) {
750 std::ostringstream ss;
751 ss <<
"Trying to multiply two Array3D objects with different dimensions: ";
752 ss <<
"(" << nx <<
"," << ny <<
"," << nz <<
") * (" << rhs.
nx <<
"," << rhs.
ny <<
"," << rhs.
nz <<
")";
756 const size_t nxyz = nx*ny*nz;
757 if (keep_nodata==
false) {
758 for (
size_t jj=0; jj<nxyz; jj++) {
759 vecData[jj] *= rhs(jj);
762 for (
size_t jj=0; jj<nxyz; jj++) {
766 vecData[jj] *= rhs(jj);
783 if (rhs==1.)
return *
this;
786 const size_t nxyz = nx*ny*nz;
787 if (keep_nodata==
false) {
788 for (
size_t jj=0; jj<nxyz; jj++) {
792 for (
size_t jj=0; jj<nxyz; jj++) {
812 if ((rhs.
nx != nx) || (rhs.
ny != ny) || (rhs.
nz != nz)) {
813 std::ostringstream ss;
814 ss <<
"Trying to divide two Array3D objects with different dimensions: ";
815 ss <<
"(" << nx <<
"," << ny <<
"," << nz <<
") / (" << rhs.
nx <<
"," << rhs.
ny <<
"," << rhs.
nz <<
")";
819 const size_t nxyz = nx*ny*nz;
820 if (keep_nodata==
false) {
821 for (
size_t jj=0; jj<nxyz; jj++) {
822 vecData[jj] /= rhs(jj);
825 for (
size_t jj=0; jj<nxyz; jj++) {
829 vecData[jj] /= rhs(jj);
861 if (nx!=in_nx || ny!=in_ny || nz!=in_nz)
864 const size_t nxyz = nx*ny*nz;
865 for (
size_t jj=0; jj<nxyz; jj++)
#define AT
Definition: IOExceptions.h:28
The template class Array2D is a 2D Array (Matrix) able to hold any type of object as datatype....
Definition: Array2D.h:65
size_t getNx() const
Definition: Array2D.h:384
size_t getNy() const
Definition: Array2D.h:388
The template class Array3D is a 3D Array (Tensor) able to hold any type of object as datatype....
Definition: Array3D.h:87
bool operator!=(const Array3D< T > &) const
Operator that tests for inequality.
Definition: Array3D.h:871
static bool checkEpsilonEquality(const Array3D< double > &rhs1, const Array3D< double > &rhs2, const double &epsilon)
Definition: Array3D.h:625
const Array3D< T > operator+(const T &rhs) const
Definition: Array3D.h:689
bool checkEpsilonEquality(const Array3D< double > &rhs, const double &epsilon) const
Definition: Array3D.h:615
void clear()
Definition: Array3D.h:470
size_t nz
Definition: Array3D.h:261
const Array3D< T > operator/(const Array3D< T > &rhs) const
Definition: Array3D.h:836
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:359
T getMean() const
returns the mean value contained in the grid
Definition: Array3D.h:553
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:388
Array3D< T > & operator-=(const Array3D< T > &rhs)
Definition: Array3D.h:697
size_t getNy() const
Definition: Array3D.h:462
Array3D< T > & operator=(const T &value)
Definition: Array3D.h:629
T getMax() const
returns the maximum value contained in the grid
Definition: Array3D.h:534
const Array3D< T > getAbs() const
returns the grid of the absolute value of values contained in the grid
Definition: Array3D.h:607
bool keep_nodata
Definition: Array3D.h:263
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:324
const Array3D< T > operator-(const T &rhs) const
Definition: Array3D.h:738
Array3D(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:316
void size(size_t &anx, size_t &any, size_t &anz) const
Definition: Array3D.h:448
friend std::istream & operator>>(std::istream &is, Array3D< P > &array)
Definition: Array3D.h:504
size_t nxny
Definition: Array3D.h:262
size_t getCount() const
returns the number of points contained in the grid. If setNodataHandling(IOUtils::RAW_NODATA),...
Definition: Array3D.h:575
void abs()
Definition: Array3D.h:590
size_t getNx() const
Definition: Array3D.h:458
Array3D< T > & operator+=(const Array3D< T > &rhs)
Definition: Array3D.h:634
bool empty() const
Definition: Array3D.h:475
Array3DProxy< T > operator[](const size_t &i)
Definition: Array3D.h:308
size_t size() const
Definition: Array3D.h:454
std::vector< T > vecData
The actual objects are stored in a one-dimensional vector.
Definition: Array3D.h:258
size_t getNz() const
Definition: Array3D.h:466
Array3D< T > & operator/=(const T &rhs)
Definition: Array3D.h:844
void resize(const size_t &anx, const size_t &any, const size_t &anz)
Definition: Array3D.h:430
void resize(const size_t &anx, const size_t &any, const size_t &anz, const T &init)
Definition: Array3D.h:439
Array3D< T > & operator-=(const T &rhs)
Definition: Array3D.h:732
size_t nx
Definition: Array3D.h:259
bool getKeepNodata() const
get how to process nodata values (ie: as nodata or as normal numbers)
Definition: Array3D.h:426
const Array3D< T > operator*(const T &rhs) const
Definition: Array3D.h:801
T & operator()(const size_t &i)
Definition: Array3D.h:266
Array3D(const size_t &anx, const size_t &any, const size_t &anz, const T &init)
Definition: Array3D.h:416
const Array3D< T > operator-(const Array3D< T > &rhs) const
Definition: Array3D.h:724
Array3D< T > & operator*=(const Array3D< T > &rhs)
Definition: Array3D.h:746
const Array3D< T > operator*(const Array3D< T > &rhs) const
Definition: Array3D.h:773
void setKeepNodata(const bool i_keep_nodata)
set how to process nodata values (ie: as nodata or as normal numbers)
Definition: Array3D.h:422
const Array3D< T > operator/(const T &rhs) const
Definition: Array3D.h:850
T getMin() const
returns the minimum value contained in the grid
Definition: Array3D.h:515
const std::string toString() const
Definition: Array3D.h:479
Array3D()
Definition: Array3D.h:312
friend std::ostream & operator<<(std::ostream &os, const Array3D< P > &array)
Definition: Array3D.h:495
Array3D(const size_t &anx, const size_t &any, const size_t &anz)
Definition: Array3D.h:410
Array3D< T > & operator*=(const T &rhs)
Definition: Array3D.h:781
void fill(const Array3D< T > &i_array3D, const size_t &i_nx, const size_t &i_ny, const size_t &i_nz)
Definition: Array3D.h:352
bool operator==(const Array3D< T > &) const
Operator that tests for equality.
Definition: Array3D.h:858
const Array3D< T > operator+(const Array3D< T > &rhs) const
Definition: Array3D.h:661
size_t ny
Definition: Array3D.h:260
Array3D< T > & operator+=(const T &rhs)
Definition: Array3D.h:669
Array3D< T > & operator/=(const Array3D< T > &rhs)
Definition: Array3D.h:809
The basic exception class adjusted for the needs of SLF software.
Definition: IOExceptions.h:40
thrown when an index is out of bounds
Definition: IOExceptions.h:106
static const double e
Definition: Meteoconst.h:68
const double nodata
This is the internal nodata value.
Definition: IOUtils.h:75
size_t count(const std::string &input, const std::string &search)
count how many times a substring appears in a string
Definition: IOUtils.cc:257
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:121
std::istream & operator>>(std::istream &is, Config &cfg)
Definition: Config.cc:480
std::ostream & operator<<(std::ostream &os, const Config &cfg)
Definition: Config.cc:445