58 const size_t& i_nw,
const size_t& i_nx,
const size_t& i_ny,
const size_t& i_nz,
59 const size_t& i_sizeW,
const size_t& i_sizeX,
const size_t& i_sizeY,
const size_t& i_sizeZ);
61 Array4D(
const size_t& anw,
const size_t& anx,
const size_t& any,
const size_t& anz);
71 Array4D(
const size_t& i_sizeW,
const size_t& i_sizeX,
const size_t& i_sizeY,
const size_t& i_sizeZ,
const T& init);
88 const size_t& i_nw,
const size_t& i_nx,
const size_t& i_ny,
const size_t& i_nz,
89 const size_t& i_sizeW,
const size_t& i_sizeX,
const size_t& i_sizeY,
const size_t& i_sizeZ);
106 const size_t& i_nw,
const size_t& i_nx,
const size_t& i_ny,
const size_t& i_nz,
107 const size_t& i_sizeW,
const size_t& i_sizeX,
const size_t& i_sizeY,
const size_t& i_sizeZ);
109 void fill(
const Array4D<T>& i_array4D,
const size_t& i_nw,
const size_t& i_nx,
const size_t& i_ny,
const size_t& i_nz);
124 void resize(
const size_t& anw,
const size_t& anx,
const size_t& any,
const size_t& anz);
125 void resize(
const size_t& anw,
const size_t& anx,
const size_t& any,
const size_t& anz,
const T& init);
126 void size(
size_t& anw,
size_t& anx,
size_t& any,
size_t& anz)
const;
128 size_t getNw()
const;
129 size_t getNx()
const;
130 size_t getNy()
const;
131 size_t getNz()
const;
173 T&
operator ()(
const size_t& w,
const size_t& x,
const size_t& y,
const size_t& z);
174 const T
operator ()(
const size_t& w,
const size_t& x,
const size_t& y,
const size_t& z)
const;
214 return vecData.at(i);
222 return vecData.at(i);
230 if ((w >= nw) || (x >= nx) || (y >= ny) || (z >= nz)) {
231 std::stringstream ss;
232 ss <<
"Trying to access array(" << w <<
"," << x <<
"," << y <<
"," << z <<
")";
233 ss <<
" while array is ("<< nw <<
"," << nx <<
"," << ny <<
"," << nz <<
")";
239 return vecData[w + x*nw + y*nwnx + z*nwnxny];
242template<
class T>
inline const T
Array4D<T>::operator()(
const size_t& w,
const size_t& x,
const size_t& y,
const size_t& z)
const {
244 if ((w >= nw) || (x >= nx) || (y >= ny) || (z >= nz)) {
245 std::stringstream ss;
246 ss <<
"Trying to access array("<< w <<
"," << x <<
"," << y <<
"," << z <<
")";
247 ss <<
" while array is ("<< nw <<
"," << nx <<
"," << ny <<
"," << nz <<
")";
251 return vecData[w + nw*x + y*nwnx + z*nwnxny];
254template<
class T>
Array4D<T>::Array4D() : vecData(), nw(0), nx(0), ny(0), nz(0), nwnx(0), nwnxny(0), keep_nodata(true)
259 const size_t& i_nw,
const size_t& i_nx,
const size_t& i_ny,
const size_t& i_nz,
260 const size_t& i_sizeW,
const size_t& i_sizeX,
const size_t& i_sizeY,
const size_t& i_sizeZ)
261 : vecData(i_sizeW*i_sizeX*i_sizeY*i_sizeZ), nw(i_sizeW), nx(i_sizeX), ny(i_sizeY), nz(i_sizeZ), nwnx(i_sizeW*i_sizeX), nwnxny(i_sizeW*i_sizeX*i_sizeY), keep_nodata(true)
263 subset(i_array4D, i_nw, i_nx, i_ny, i_nz, i_sizeW, i_sizeX, i_sizeY, i_sizeZ);
267 const size_t& i_nw,
const size_t& i_nx,
const size_t& i_ny,
const size_t& i_nz,
268 const size_t& i_sizeW,
const size_t& i_sizeX,
const size_t& i_sizeY,
const size_t& i_sizeZ)
271 if (((i_nw+i_sizeW) > i_array4D.
nw) || ((i_nx+i_sizeX) > i_array4D.
nx) || ((i_ny+i_sizeY) > i_array4D.
ny) || ((i_nz+i_sizeZ) > i_array4D.
nz)) {
272 std::stringstream ss;
273 ss <<
"Trying to cut an array of size ("<< i_array4D.
nw <<
"," << i_array4D.
nx <<
"," << i_array4D.
ny <<
"," << i_array4D.
nz <<
") ";
274 ss <<
"to size (" << i_sizeW <<
"," << i_sizeX <<
"," << i_sizeY <<
"," << i_sizeZ <<
") ";
275 ss <<
"starting at ("<< i_nw <<
"," << i_nx <<
"," << i_ny <<
"," << i_nz <<
")";
279 if ((i_sizeW == 0) || (i_sizeX == 0) || (i_sizeY == 0) || (i_sizeZ == 0))
282 resize(i_sizeW, i_sizeX, i_sizeY, i_sizeZ);
284 for (
size_t ii=0; ii<nz; ii++) {
285 for (
size_t jj=0; jj<ny; jj++) {
286 for (
size_t kk=0; kk<nx; kk++) {
287 for (
size_t ll=0; ll<nw; ll++)
289 operator()(ll,kk,jj,ii) = i_array4D(i_nw+ll, i_nx+kk, i_ny+jj, i_nz+ii);
295template<
class T>
void Array4D<T>::fill(
const Array4D<T>& i_array4D,
const size_t& i_nw,
const size_t& i_nx,
const size_t& i_ny,
const size_t& i_nz)
297 size_t i_sizeW, i_sizeX, i_sizeY, i_sizeZ;
298 i_array4D.
size(i_sizeW, i_sizeX, i_sizeY, i_sizeZ);
299 fill(i_array4D, i_nw, i_nx, i_ny, i_nz, i_sizeW, i_sizeX, i_sizeY, i_sizeZ);
303 const size_t& i_nw,
const size_t& i_nx,
const size_t& i_ny,
const size_t& i_nz,
304 const size_t& i_sizeW,
const size_t& i_sizeX,
const size_t& i_sizeY,
const size_t& i_sizeZ)
307 if (((i_nw+i_sizeW) > i_array4D.
nw) || ((i_nx+i_sizeX) > i_array4D.
nx) || ((i_ny+i_sizeY) > i_array4D.
ny) || ((i_nz+i_sizeZ) > i_array4D.
nz)) {
308 std::stringstream ss;
309 ss <<
"Filling an array of size (" << nw <<
"," << nx <<
"," << ny <<
"," << nz <<
") ";
310 ss <<
"with an array of size (" << i_sizeW <<
"," << i_sizeX <<
"," << i_sizeY <<
"," << i_sizeZ <<
") ";
311 ss <<
"starting at (" << i_nw <<
"," << i_nx <<
"," << i_ny <<
"," << i_nz <<
")";
315 if ((i_sizeW == 0) || (i_sizeX == 0) || (i_sizeY == 0) || (i_sizeZ == 0))
319 for (
size_t ii=i_nz; ii<(i_nz+i_sizeZ); ii++) {
320 const size_t iz = ii-i_nz;
321 for (
size_t jj=i_ny; jj<(i_ny+i_sizeY); jj++) {
322 const size_t iy = jj-i_ny;
323 for (
size_t kk=i_nx; kk<(i_nx+i_sizeX); kk++) {
324 const size_t ix = kk-i_nx;
325 for (
size_t ll=i_nw; ll<(i_nw+i_sizeW); ll++) {
326 const size_t iw = ll-i_nw;
327 operator()(ll,kk,jj,ii) = i_array4D(iw,ix, iy, iz);
334template<
class T>
Array4D<T>::Array4D(
const size_t& anw,
const size_t& anx,
const size_t& any,
const size_t& anz)
335 : vecData(anw*anx*any*anz), nw(anw), nx(anx), ny(any), nz(anz), nwnx(anw*anx), nwnxny(anw*anx*any), keep_nodata(true)
340template<
class T>
Array4D<T>::Array4D(
const size_t& anw,
const size_t& anx,
const size_t& any,
const size_t& anz,
const T& init)
341 : vecData(anw*anx*any*anz, init), nw(anw), nx(anx), ny(any), nz(anz), nwnx(anw*anx), nwnxny(anw*anx*any), keep_nodata(true)
347 keep_nodata = i_keep_nodata;
354template<
class T>
void Array4D<T>::resize(
const size_t& anw,
const size_t& anx,
const size_t& any,
const size_t& anz) {
356 vecData.resize(anw*anx*any*anz);
365template<
class T>
void Array4D<T>::resize(
const size_t& anw,
const size_t& anx,
const size_t& any,
const size_t& anz,
const T& init) {
367 vecData.resize(anw*anx*any*anz, init);
376template<
class T>
void Array4D<T>::size(
size_t& anw,
size_t& anx,
size_t& any,
size_t& anz)
const {
405 nw = nx = ny = nz = nwnx = nwnxny = 0;
409 return (nw==0 && nx==0 && ny==0 && nz==0);
413 std::stringstream os;
415 for (
size_t ll=0; ll<nw; ll++) {
416 os <<
"dim4[" << ll <<
"]\n";
417 for (
size_t kk=0; kk<nz; kk++) {
418 os <<
"depth[" << kk <<
"]\n";
419 for (
size_t ii=0; ii<nx; ii++) {
420 for (
size_t jj=0; jj<ny; jj++) {
421 os << operator()(ii,jj,kk,ll) <<
" ";
427 os <<
"</array4d>\n";
433 os.write(
reinterpret_cast<const char*
>(&array.
nx),
sizeof(array.
nx));
434 os.write(
reinterpret_cast<const char*
>(&array.
ny),
sizeof(array.
ny));
435 os.write(
reinterpret_cast<const char*
>(&array.
nz),
sizeof(array.
nz));
436 os.write(
reinterpret_cast<const char*
>(&array.
nw),
sizeof(array.
nw));
437 os.write(
reinterpret_cast<const char*
>(&array.
vecData[0]),
static_cast<std::streamsize
>(array.
nx*array.
ny*array.
nz*array.
nw*
sizeof(P)));
443 is.read(
reinterpret_cast<char*
>(&array.
nx),
sizeof(array.
nx));
444 is.read(
reinterpret_cast<char*
>(&array.
ny),
sizeof(array.
ny));
445 is.read(
reinterpret_cast<char*
>(&array.
nz),
sizeof(array.
nz));
446 is.read(
reinterpret_cast<char*
>(&array.
nw),
sizeof(array.
nw));
450 is.read(
reinterpret_cast<char*
>(&array.
vecData[0]),
static_cast<std::streamsize
>(array.
nx*array.
ny*array.
nz*array.
nw*
sizeof(P)));
456 T min = std::numeric_limits<T>::max();
457 const size_t nwyz = nwnxny*nz;
459 if (keep_nodata==
false) {
460 min = *min_element(vecData.begin(), vecData.end());
461 if (min!=std::numeric_limits<T>::max())
return min;
464 for (
size_t jj=0; jj<nwyz; jj++) {
465 const T val = vecData[jj];
468 if (min!=std::numeric_limits<T>::max())
return min;
475 T max = -std::numeric_limits<T>::max();
476 const size_t nwyz = nwnxny*nz;
478 if (keep_nodata==
false) {
479 max = *max_element(vecData.begin(), vecData.end());
480 if (max!=-std::numeric_limits<T>::max())
return max;
483 for (
size_t jj=0; jj<nwyz; jj++) {
484 const T val = vecData[jj];
487 if (max!=-std::numeric_limits<T>::max())
return max;
495 const size_t nwyz = nwnxny*nz;
497 if (keep_nodata==
false) {
498 if (nwyz>0)
return std::accumulate(vecData.begin(), vecData.end(), 0.) / (T)(nwyz);
502 for (
size_t jj=0; jj<nwyz; jj++) {
503 const T val = vecData[jj];
516 const size_t nwyz = nwnxny*nz;
518 if (keep_nodata==
false) {
522 for (
size_t ii=0; ii<nwyz; ii++) {
530 if (std::numeric_limits<T>::is_signed) {
531 const size_t nwyz = nwnxny*nz;
532 if (keep_nodata==
false) {
533 for (
size_t jj=0; jj<nwyz; jj++) {
534 T& val = vecData[jj];
538 for (
size_t jj=0; jj<nwyz; jj++) {
539 T& val = vecData[jj];
556 if (nw!=rhs.
nw || nx!=rhs.
nx || ny!=rhs.
ny || nz!=rhs.
nz)
return false;
558 const size_t nwyz = nwnxny*nz;
559 for (
size_t jj=0; jj<nwyz; jj++)
570 std::fill(vecData.begin(), vecData.end(), value);
577 if ((rhs.
nw != nw) || (rhs.
nx != nx) || (rhs.
ny != ny) || (rhs.
nz != nz)) {
578 std::stringstream ss;
579 ss <<
"Trying to add two Array4D objects with different dimensions: ";
580 ss <<
"(" << nw <<
"," << nx <<
"," << ny <<
"," << nz <<
") + (" << rhs.
nw <<
"," << rhs.
nx <<
"," << rhs.
ny <<
"," << rhs.
nz <<
")";
584 const size_t nwyz = nwnxny*nz;
585 if (keep_nodata==
false) {
586 for (
size_t jj=0; jj<nwyz; jj++) {
587 vecData[jj] += rhs(jj);
590 for (
size_t jj=0; jj<nwyz; jj++) {
594 vecData[jj] += rhs(jj);
611 if (rhs==0.)
return *
this;
614 const size_t nwyz = nwnxny*nz;
615 if (keep_nodata==
false) {
616 for (
size_t jj=0; jj<nwyz; jj++) {
620 for (
size_t jj=0; jj<nwyz; jj++) {
640 if ((rhs.
nw != nw) || (rhs.
nx != nx) || (rhs.
ny != ny) || (rhs.
nz != nz)) {
641 std::stringstream ss;
642 ss <<
"Trying to substract two Array4D objects with different dimensions: ";
643 ss <<
"(" << nw <<
"," << nx <<
"," << ny <<
"," << nz <<
") - (" << rhs.
nw <<
"," << rhs.
nx <<
"," << rhs.
ny <<
"," << rhs.
nz <<
")";
647 const size_t nwyz = nwnxny*nz;
648 if (keep_nodata==
false) {
649 for (
size_t jj=0; jj<nwyz; jj++) {
650 vecData[jj] -= rhs(jj);
653 for (
size_t jj=0; jj<nwyz; jj++) {
657 vecData[jj] -= rhs(jj);
689 if ((rhs.
nw != nw) || (rhs.
nx != nx) || (rhs.
ny != ny) || (rhs.
nz != nz)) {
690 std::stringstream ss;
691 ss <<
"Trying to multiply two Array4D objects with different dimensions: ";
692 ss <<
"("<< nw <<
"," << nx <<
"," << ny <<
"," << nz <<
") * (" << rhs.
nw <<
"," << rhs.
nx <<
"," << rhs.
ny <<
"," << rhs.
nz <<
")";
696 const size_t nwxyz = nwnxny*nz;
697 if (keep_nodata==
false) {
698 for (
size_t jj=0; jj<nwxyz; jj++) {
699 vecData[jj] *= rhs(jj);
702 for (
size_t jj=0; jj<nwxyz; jj++) {
706 vecData[jj] *= rhs(jj);
723 if (rhs==1.)
return *
this;
726 const size_t nwxyz = nwnxny*nz;
727 if (keep_nodata==
false) {
728 for (
size_t jj=0; jj<nwxyz; jj++) {
732 for (
size_t jj=0; jj<nwxyz; jj++) {
752 if ((rhs.
nw != nw) || (rhs.
nx != nx) || (rhs.
ny != ny) || (rhs.
nz != nz)) {
753 std::stringstream ss;
754 ss <<
"Trying to divide two Array4D objects with different dimensions: ";
755 ss <<
"(" << nw <<
"," << nx <<
"," << ny <<
"," << nz <<
") / (" << rhs.
nw <<
"," << rhs.
nx <<
"," << rhs.
ny <<
"," << rhs.
nz <<
")";
759 const size_t nwxyz = nwnxny*nz;
760 if (keep_nodata==
false) {
761 for (
size_t jj=0; jj<nwxyz; jj++) {
762 vecData[jj] /= rhs(jj);
765 for (
size_t jj=0; jj<nwxyz; jj++) {
769 vecData[jj] /= rhs(jj);
801 if (nx!=in_nx || ny!=in_ny || nz!=in_nz || nw!=in_nw)
804 const size_t nwxyz = nx*ny*nz*nw;
805 for (
size_t jj=0; jj<nwxyz; jj++)
#define AT
Definition: IOExceptions.h:28
The template class Array4D is a 4D Array (Tensor) able to hold any type of object as datatype.
Definition: Array4D.h:39
void abs()
Definition: Array4D.h:529
Array4D()
Definition: Array4D.h:254
bool operator!=(const Array4D< T > &) const
Operator that tests for inequality.
Definition: Array4D.h:811
size_t nx
Definition: Array4D.h:204
size_t getCount() const
returns the number of points contained in the grid. If setNodataHandling(IOUtils::RAW_NODATA),...
Definition: Array4D.h:514
bool checkEpsilonEquality(const Array4D< double > &rhs, const double &epsilon) const
Definition: Array4D.h:555
friend std::ostream & operator<<(std::ostream &os, const Array4D< P > &array)
Definition: Array4D.h:431
Array4D< T > & operator/=(const T &rhs)
Definition: Array4D.h:784
const std::string toString() const
Definition: Array4D.h:412
void size(size_t &anw, size_t &anx, size_t &any, size_t &anz) const
Definition: Array4D.h:376
size_t getNz() const
Definition: Array4D.h:399
size_t ny
Definition: Array4D.h:205
size_t size() const
Definition: Array4D.h:383
Array4D< T > & operator=(const T &value)
Definition: Array4D.h:569
bool keep_nodata
Definition: Array4D.h:209
void resize(const size_t &anw, const size_t &anx, const size_t &any, const size_t &anz)
Definition: Array4D.h:354
const Array4D< T > getAbs() const
returns the grid of the absolute value of values contained in the grid
Definition: Array4D.h:547
bool empty() const
Definition: Array4D.h:408
std::vector< T > vecData
The actual objects are stored in a one-dimensional vector.
Definition: Array4D.h:202
T & operator()(const size_t &i)
Definition: Array4D.h:212
Array4D< T > & operator-=(const T &rhs)
Definition: Array4D.h:672
size_t getNy() const
Definition: Array4D.h:395
const Array4D< T > operator+(const T &rhs) const
Definition: Array4D.h:629
void fill(const Array4D< T > &i_array4D, const size_t &i_nw, const size_t &i_nx, const size_t &i_ny, const size_t &i_nz, const size_t &i_sizeW, const size_t &i_sizeX, const size_t &i_sizeY, const size_t &i_sizeZ)
A method that can be used to insert a subplane into an existing Array4D object that is passed as i_ar...
Definition: Array4D.h:302
void clear()
Definition: Array4D.h:403
Array4D< T > & operator*=(const T &rhs)
Definition: Array4D.h:721
void subset(const Array4D< T > &i_array4D, const size_t &i_nw, const size_t &i_nx, const size_t &i_ny, const size_t &i_nz, const size_t &i_sizeW, const size_t &i_sizeX, const size_t &i_sizeY, const size_t &i_sizeZ)
Definition: Array4D.h:266
size_t nwnx
Definition: Array4D.h:207
size_t nz
Definition: Array4D.h:206
bool operator==(const Array4D< T > &) const
Operator that tests for equality.
Definition: Array4D.h:798
const Array4D< T > operator/(const T &rhs) const
Definition: Array4D.h:790
size_t getNx() const
Definition: Array4D.h:391
size_t getNw() const
Definition: Array4D.h:387
size_t nwnxny
Definition: Array4D.h:208
bool getKeepNodata()
get how to process nodata values (ie: as nodata or as normal numbers)
Definition: Array4D.h:350
const Array4D< T > operator*(const T &rhs) const
Definition: Array4D.h:741
T getMax() const
returns the maximum value contained in the grid
Definition: Array4D.h:473
void setKeepNodata(const bool i_keep_nodata)
set how to process nodata values (ie: as nodata or as normal numbers)
Definition: Array4D.h:346
friend std::istream & operator>>(std::istream &is, Array4D< P > &array)
Definition: Array4D.h:441
size_t nw
Definition: Array4D.h:203
const Array4D< T > operator-(const T &rhs) const
Definition: Array4D.h:678
T getMin() const
returns the minimum value contained in the grid
Definition: Array4D.h:454
Array4D< T > & operator+=(const T &rhs)
Definition: Array4D.h:609
T getMean() const
returns the mean value contained in the grid
Definition: Array4D.h:492
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:258
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:468
std::ostream & operator<<(std::ostream &os, const Config &cfg)
Definition: Config.cc:433