NPL
Neurological Programs and Libraries
ndarray.h
Go to the documentation of this file.
1 /******************************************************************************
2  * Copyright 2014 Micah C Chambers (micahc.vt@gmail.com)
3  *
4  * NPL is free software: you can redistribute it and/or modify it under the
5  * terms of the BSD 2-Clause License available in LICENSE or at
6  * http://opensource.org/licenses/BSD-2-Clause
7  *
8  * @file ndarray.h
9  * @brief This file contains the definition for NDarray and its derived types.
10  * The derived types are templated over dimensionality and pixel type.
11  ******************************************************************************/
12 
13 #ifndef NDARRAY_H
14 #define NDARRAY_H
15 
16 #include "npltypes.h"
17 
18 #include "zlib.h"
19 
20 #include <cstddef>
21 #include <cmath>
22 #include <initializer_list>
23 #include <vector>
24 #include <cstdint>
25 #include <complex>
26 #include <cassert>
27 #include <memory>
28 
29 
30 namespace npl {
31 
32 /******************************************************************************
33  * Define Types
34  *****************************************************************************/
35 enum PixelT {UNKNOWN_TYPE=0, UINT8=2, INT16=4, INT32=8, FLOAT32=16,
36  COMPLEX64=32, CFLOAT=32, FLOAT64=64, RGB24=128, INT8=256, UINT16=512,
37  UINT32=768, INT64=1024, UINT64=1280, FLOAT128=1536, CDOUBLE=1792,
38  COMPLEX128=1792, CQUAD=2048, COMPLEX256=2048, RGBA32=2304 };
39 
40 class NDArray;
41 
46 const size_t MAXDIM = 10;
47 
48 /******************************************************************************
49  * Basic Functions.
50  ******************************************************************************/
51 
67 ptr<NDArray> createNDArray(size_t ndim, const size_t* size, PixelT ptype);
68 
79 ptr<NDArray> createNDArray(const std::vector<size_t>& dim, PixelT ptype);
80 
93 ptr<NDArray> createNDArray(size_t ndim, const size_t* size,
94  PixelT ptype, void* ptr, std::function<void(void*)> deleter);
95 
108 ptr<NDArray> createNDArray(const std::vector<size_t>& dim,
109  PixelT ptype, void* ptr, std::function<void(void*)> deleter);
110 
125  const int64_t* inROIL, const size_t* inROIZ, ptr<NDArray> out,
126  const int64_t* oROIL, const size_t* oROIZ, PixelT newtype);
127 
136 std::ostream& operator<<(std::ostream &out, const NDArray& img);
137 
145 std::string pixelTtoString(PixelT type);
146 
154 PixelT stringToPixelT(std::string type);
155 
158 /******************************************************************************
159  * Classes.
160  ******************************************************************************/
161 
165 class NDArray : public std::enable_shared_from_this<NDArray>
166 {
167 public:
168  /*
169  * get / set functions
170  */
171  // Get Address
172 
173  virtual size_t ndim() const = 0;
174  virtual size_t bytes() const = 0;
175  virtual size_t bytesper() const = 0;
176  virtual size_t elements() const = 0;
177  virtual size_t dim(size_t dir) const = 0;
178  virtual const size_t* dim() const = 0;
179 
185  virtual PixelT type() const = 0;
186 
193  bool floatType() const {
194  return type()==FLOAT32 || type()==FLOAT64 || type()==FLOAT128;
195  };
196 
203  bool complexType() const{
204  return type()==COMPLEX64|| type()==COMPLEX128|| type()==COMPLEX256;
205  };
206 
212  bool signedType() const {
213  return type()==INT8|| type()==INT16 || type()==INT32 || type()==INT64;
214  };
215 
222  bool unsignedType() const {
223  return type()==UINT8||type()==UINT16||type()==UINT32||type()==UINT64;
224  };
225 
226 
228  return shared_from_this();
229  };
230 
232  return shared_from_this();
233  };
234 
235  virtual void* data() = 0;
236  virtual const void* data() const = 0;
237 
243  virtual ptr<NDArray> copy() const = 0;
244 
250  virtual ptr<NDArray> createAnother() const = 0;
251 
263  virtual ptr<NDArray> createAnother(size_t newdims, const size_t* newsize,
264  PixelT newtype) const = 0;
265 
275  virtual ptr<NDArray> createAnother(PixelT newtype) const = 0;
276 
289  virtual ptr<NDArray> createAnother(size_t newdims,
290  const size_t* newsize) const = 0;
291 
303  virtual ptr<NDArray> copyCast(size_t newdims, const size_t* newsize,
304  PixelT newtype) const = 0;
305 
315  virtual ptr<NDArray> copyCast(PixelT newtype) const = 0;
316 
329  virtual ptr<NDArray> copyCast(size_t newdims,
330  const size_t* newsize) const = 0;
331 
343  virtual ptr<NDArray> extractCast(size_t len, const int64_t* index,
344  const size_t* size) const = 0;
345 
356  virtual ptr<NDArray> extractCast(size_t len, const size_t* size) const = 0;
357 
370  virtual ptr<NDArray> extractCast(size_t len,
371  const int64_t* index, const size_t* size, PixelT newtype) const = 0;
372 
384  virtual ptr<NDArray> extractCast(size_t len, const size_t* size,
385  PixelT newtype) const = 0;
386 
387  /********************************************
388  * Output Functions
389  *******************************************/
390 
399  virtual int write(std::string filename, double version = 1) const = 0;
400 
401  /********************************************
402  * Helper Functions
403  *******************************************/
404 
408  virtual void zero() = 0;
409 
410 // virtual int opself(const NDArray* right, double(*func)(double,double),
411 // bool elevR) = 0;
412 // virtual ptr<NDArray> opnew(const NDArray* right,
413 // double(*func)(double,double), bool elevR) = 0;
414 
415  virtual void* __getAddr(std::initializer_list<int64_t> index) const = 0;
416  virtual void* __getAddr(size_t len, const int64_t* index) const = 0;
417  virtual void* __getAddr(const std::vector<int64_t>& index) const = 0;
418  virtual void* __getAddr(int64_t i) const = 0;
419  virtual void* __getAddr(int64_t x, int64_t y, int64_t z, int64_t t) const = 0;
420 
421  virtual int64_t getLinIndex(std::initializer_list<int64_t> index) const = 0;
422  virtual int64_t getLinIndex(size_t len, const int64_t* index) const = 0;
423  virtual int64_t getLinIndex(const std::vector<int64_t>& index) const = 0;
424  virtual int64_t getLinIndex(int64_t x, int64_t y, int64_t z, int64_t t) const = 0;
425 
432  virtual int64_t tlen() const = 0;
433 
434 protected:
435  NDArray() {} ;
436 
441  std::function<void(void*)> m_freefunc;
442 };
443 
444 
451 template <size_t D, typename T>
452 class NDArrayStore : public virtual NDArray
453 {
454 public:
460  NDArrayStore();
461 
470  NDArrayStore(const std::initializer_list<size_t>& dim);
471 
480  NDArrayStore(const std::vector<size_t>& dim);
481 
491  NDArrayStore(size_t len, const size_t* dim);
492 
507  NDArrayStore(size_t len, const size_t* dim, T* ptr,
508  const std::function<void(void*)>& deleter);
509 
511 
512  /*
513  * get / set functions
514  */
515  T& operator[](const int64_t* index);
516  T& operator[](const std::vector<int64_t>& index);
517  T& operator[](std::initializer_list<int64_t> index);
518  T& operator[](int64_t pixel);
519 
520  const T& operator[](const int64_t* index) const;
521  const T& operator[](const std::vector<int64_t>& index) const;
522  const T& operator[](std::initializer_list<int64_t> index) const;
523  const T& operator[](int64_t pixel) const;
524 
525  /*
526  * General Information
527  */
528  size_t ndim() const;
529  size_t bytes() const;
530  size_t bytesper() const;
531  size_t elements() const;
532  size_t dim(size_t dir) const;
533  const size_t* dim() const;
534 
541  void resize(const size_t dim[D]);
542 
549  void resize(std::initializer_list<size_t> dim);
550 
551  // return the pixel type
552  PixelT type() const;
553 
559  void* data() {return _m_data; };
560 
566  const void* data() const { return _m_data; };
567 
576  void graft(const size_t dim[D], T* ptr, const
577  std::function<void(void*)>& deleter);
578 
587  virtual int write(std::string filename, double version = 1) const;
588 
589  /**************************************************************************
590  * Duplication Functions
591  *************************************************************************/
592 
598  virtual ptr<NDArray> copy() const;
599 
605  virtual ptr<NDArray> createAnother() const;
606 
618  virtual ptr<NDArray> createAnother(size_t newdims, const size_t* newsize,
619  PixelT newtype) const;
620 
630  virtual ptr<NDArray> createAnother(PixelT newtype) const;
631 
644  virtual ptr<NDArray> createAnother(size_t newdims,
645  const size_t* newsize) const;
646 
659  virtual ptr<NDArray> copyCast(size_t newdims, const size_t* newsize,
660  PixelT newtype) const;
661 
671  virtual ptr<NDArray> copyCast(PixelT newtype) const;
672 
684  virtual ptr<NDArray> copyCast(size_t newdims, const size_t* newsize) const;
685 
699  virtual ptr<NDArray> extractCast(size_t len, const int64_t* index,
700  const size_t* size) const;
701 
715  virtual ptr<NDArray> extractCast(size_t len, const size_t* size) const;
716 
732  virtual ptr<NDArray> extractCast(size_t len,
733  const int64_t* index, const size_t* size, PixelT newtype) const;
734 
749  virtual ptr<NDArray> extractCast(size_t len, const size_t* size,
750  PixelT newtype) const;
751  /*
752  * Higher Level Operations
753  */
754 
758  void zero();
759 
760 // virtual int opself(const NDArray* right, double(*func)(double,double),
761 // bool elevR);
762 // virtual ptr<NDArray> opnew(const NDArray* right,
763 // double(*func)(double,double), bool elevR);
764 
765  inline virtual void* __getAddr(std::initializer_list<int64_t> index) const
766  {
767  return &_m_data[getLinIndex(index)];
768  };
769 
770  inline virtual void* __getAddr(size_t len, const int64_t* index) const
771  {
772  return &_m_data[getLinIndex(len, index)];
773  };
774 
775  inline virtual void* __getAddr(const std::vector<int64_t>& index) const
776  {
777  return &_m_data[getLinIndex(index)];
778  };
779 
780  inline virtual void* __getAddr(int64_t i) const
781  {
782  return &_m_data[i];
783  };
784  inline virtual void* __getAddr(int64_t x, int64_t y, int64_t z, int64_t t) const
785  {
786  return &_m_data[getLinIndex(x,y,z,t)];
787  };
788 
789  virtual int64_t getLinIndex(std::initializer_list<int64_t> index) const;
790  virtual int64_t getLinIndex(size_t len, const int64_t* index) const;
791  virtual int64_t getLinIndex(const std::vector<int64_t>& index) const;
792  virtual int64_t getLinIndex(int64_t x, int64_t y, int64_t z, int64_t t) const;
793 
800  virtual int64_t tlen() const {
801  if(D >= 3)
802  return _m_stride[2];
803  else
804  return 1;
805  };
806 
807  T* _m_data;
808  size_t _m_stride[D]; // steps between pixels
809  size_t _m_dim[D]; // overall image dimension
810 
811  protected:
812 
813  void updateStrides();
814 
815  virtual int writeNifti1Image(gzFile file) const;
816  virtual int writeNifti2Image(gzFile file) const;
817  virtual int writeNifti1Header(gzFile file) const;
818  virtual int writeNifti2Header(gzFile file) const;
819  virtual int writePixels(gzFile file) const;
820  virtual int writeJSON(gzFile file) const;
821  virtual int writeCSV(gzFile file) const;
822 };
823 
824 
825 #undef VIRTGETSET
826 #undef GETSET
827 
828 } //npl
829 
830 #endif
virtual ptr< NDArray > copy() const =0
Performs a deep copy of the entire array.
virtual const size_t * dim() const =0
virtual int64_t getLinIndex(std::initializer_list< int64_t > index) const
Definition: accessors.h:29
virtual void * __getAddr(int64_t i) const
Definition: ndarray.h:780
bool complexType() const
Returns true if the stored type is COMPLEX256, COMPLEX128, or COMPLEX64, ie is a complex floating poi...
Definition: ndarray.h:203
T & operator[](const int64_t *index)
size_t bytes() const
virtual int write(std::string filename, double version=1) const
Write the image to a nifti file.
virtual size_t bytesper() const =0
virtual void * data()=0
virtual int writePixels(gzFile file) const
void * data()
Returns a pointer to the data array. Be careful.
Definition: ndarray.h:559
virtual void zero()=0
Sets all elements to zero.
std::function< void(void *)> m_freefunc
The function which should be called when deleting data. By default this will just be delete[]...
Definition: ndarray.h:435
void zero()
Sets all elements to zero.
virtual int writeNifti1Image(gzFile file) const
virtual int writeNifti2Image(gzFile file) const
virtual ptr< NDArray > copyCast(size_t newdims, const size_t *newsize, PixelT newtype) const
Create a new array that is a copy of the input, possibly with new dimensions and pixeltype. The new array will have all overlapping pixels copied from the old array.
Pure virtual interface to interact with an ND array.
Definition: ndarray.h:165
virtual int writeNifti2Header(gzFile file) const
ptr< const NDArray > getConstPtr() const
Definition: ndarray.h:231
virtual void * __getAddr(size_t len, const int64_t *index) const
Definition: ndarray.h:770
const void * data() const
Returns a pointer to the data array. Be careful.
Definition: ndarray.h:566
void copyROI(ptr< const NDArray > in, const int64_t *inROIL, const size_t *inROIZ, ptr< NDArray > out, const int64_t *oROIL, const size_t *oROIZ, PixelT newtype)
Copy an roi from one image to another image. ROI's must be the same size.
PixelT type() const
Return enum PixelT type of pixels.
size_t bytesper() const
void resize(const size_t dim[D])
Changes the dimensions (size) of the image. This does not affect rank/dimensionality.
std::ostream & operator<<(std::ostream &os, const Matrix< D1, D2 > &b)
PixelT stringToPixelT(std::string type)
Returns a pixeltype as described by the string.
virtual int write(std::string filename, double version=1) const =0
Write the image to a nifti file.
PixelT
Definition: ndarray.h:35
virtual int64_t tlen() const =0
This function just returns the number of elements in a theoretical fourth dimension (ignoring orgnaiz...
bool signedType() const
Returns true if the stored type is a variant of signed integer .
Definition: ndarray.h:212
ptr< NDArray > createNDArray(size_t ndim, const size_t *size, PixelT ptype)
Creates a new NDArray with dimensions set by ndim, and size set by size. Output pixel type is decided...
virtual ptr< NDArray > createAnother() const =0
Creates an identical array, but does not initialize pixel values.
virtual void * __getAddr(std::initializer_list< int64_t > index) const
Definition: ndarray.h:765
virtual PixelT type() const =0
Return enum PixelT type of pixels.
virtual int64_t getLinIndex(std::initializer_list< int64_t > index) const =0
bool floatType() const
Returns true if the stored type is FLOAT32, FLOAT64, or FLOAT128, ie is a pure float type...
Definition: ndarray.h:193
virtual int writeJSON(gzFile file) const
virtual void * __getAddr(int64_t x, int64_t y, int64_t z, int64_t t) const
Definition: ndarray.h:784
size_t _m_stride[D]
Definition: ndarray.h:808
virtual int writeCSV(gzFile file) const
std::shared_ptr< T > ptr
Make the shared_ptr name shorter...
Definition: npltypes.h:42
size_t ndim() const
NDArrayStore()
Constructor with initializer list. Orientation will be default (direction = identity, spacing = 1, origin = 0).
virtual ptr< NDArray > createAnother() const
Creates an identical array, but does not initialize pixel values.
bool unsignedType() const
Returns true if the stored type is a variant of unsigned signed integer.
Definition: ndarray.h:222
const size_t MAXDIM
Defines the maximum supported dimension by image, used for stack-allocations.
Definition: ndarray.h:46
virtual ptr< NDArray > extractCast(size_t len, const int64_t *index, const size_t *size) const
Create a new array that is a copy of the input, possibly with new dimensions or size. The new array will have all overlapping pixels copied from the old array. The new array will have the same pixel type as the input array.
virtual void * __getAddr(std::initializer_list< int64_t > index) const =0
virtual ptr< NDArray > copyCast(size_t newdims, const size_t *newsize, PixelT newtype) const =0
Create a new array that is a copy of the input, possibly with new dimensions and pixeltype. The new array will have all overlapping pixels copied from the old array.
void graft(const size_t dim[D], T *ptr, const std::function< void(void *)> &deleter)
Grafts data of the given dimensions into the image, effectively changing the image size...
ptr< NDArray > getPtr()
Definition: ndarray.h:227
virtual size_t bytes() const =0
std::string pixelTtoString(PixelT type)
Returns a string that is a descrption of the pixel type.
const size_t * dim() const
virtual void * __getAddr(const std::vector< int64_t > &index) const
Definition: ndarray.h:775
virtual int writeNifti1Header(gzFile file) const
virtual size_t ndim() const =0
virtual int64_t tlen() const
This function just returns the number of elements in a theoretical fourth dimension (ignoring orgnaiz...
Definition: ndarray.h:800
virtual ptr< NDArray > copy() const
Performs a deep copy of the entire array.
size_t _m_dim[D]
Definition: ndarray.h:809
Basic storage unity for ND array. Creates a big chunk of memory.
Definition: ndarray.h:452
virtual size_t elements() const =0
virtual ptr< NDArray > extractCast(size_t len, const int64_t *index, const size_t *size) const =0
extracts a region of this image. Zeros in the size variable indicate dimension to be removed...
size_t elements() const