32 #include <nifti1_io.h>
38 #include "sirf/common/ANumRef.h"
39 #include "sirf/common/ImageData.h"
40 #include <_reg_tools.h>
76 template<
class dataType>
85 Iterator(dataType *iter) : _iter(iter)
98 virtual bool operator==(
const BaseIter& an_iter)
const
101 return _iter == iter._iter;
103 virtual bool operator!=(
const BaseIter& an_iter)
const
106 return _iter != iter._iter;
110 dataType& v = *_iter;
125 _ref.copy(iter._ref);
136 return _iter == iter._iter;
141 return _iter != iter._iter;
143 virtual const FloatRef& operator*()
const
145 const dataType& v = *_iter;
146 _ref.set_ptr((
void*)&v);
150 const dataType *_iter;
179 template<
class inputType>
185 if (
typeid(inputType) ==
typeid(
bool)) this->
set_up_data(DT_BINARY);
186 else if (
typeid(inputType) ==
typeid(
signed char)) this->
set_up_data(DT_INT8);
187 else if (
typeid(inputType) ==
typeid(
signed short)) this->
set_up_data(DT_INT16);
188 else if (
typeid(inputType) ==
typeid(
signed int)) this->
set_up_data(DT_INT32);
189 else if (
typeid(inputType) ==
typeid(
float)) this->
set_up_data(DT_FLOAT32);
190 else if (
typeid(inputType) ==
typeid(
double)) this->
set_up_data(DT_FLOAT64);
191 else if (
typeid(inputType) ==
typeid(
unsigned char)) this->
set_up_data(DT_UINT8);
192 else if (
typeid(inputType) ==
typeid(
unsigned short)) this->
set_up_data(DT_UINT16);
193 else if (
typeid(inputType) ==
typeid(
unsigned int)) this->
set_up_data(DT_UINT32);
194 else if (
typeid(inputType) ==
typeid(
signed long long)) this->
set_up_data(DT_INT64);
195 else if (
typeid(inputType) ==
typeid(
unsigned long long)) this->
set_up_data(DT_UINT64);
196 else if (
typeid(inputType) ==
typeid(
long double)) this->
set_up_data(DT_FLOAT128);
198 std::stringstream ss;
199 ss <<
"NiftiImageData constructor from raw array: ";
200 ss <<
typeid (inputType).name();
201 ss <<
" (bytes per voxel: ";
202 ss <<
sizeof(inputType) <<
").";
203 throw std::runtime_error(ss.str());
207 this->
_data[i] = dataType(data[i]);
220 static void construct_NiftiImageData_from_complex_im(std::shared_ptr<NiftiImageData> &out_real_sptr, std::shared_ptr<NiftiImageData> &out_imag_sptr,
const std::shared_ptr<const ImageData> in_sptr);
319 float operator()(
const int x,
const int y,
const int z,
const int t=0,
const int u=0,
const int v=0,
const int w=0)
const;
322 float &
operator()(
const int x,
const int y,
const int z,
const int t=0,
const int u=0,
const int v=0,
const int w=0);
335 virtual void write(
const std::string &filename,
const int datatype)
const;
338 virtual void write(
const std::string &filename)
const { this->
write(filename,-1); }
362 void fill(
const float v);
365 void fill(
const dataType *v);
383 static void print_headers(
const std::vector<const NiftiImageData*> &ims);
386 void crop(
const int min_index[7],
const int max_index[7]);
389 void pad(
const int min_index[7],
const int max_index[7],
const dataType val = 0);
413 static void dump_headers(
const std::vector<const NiftiImageData*> &ims);
417 static void dump_nifti_element(
const std::vector<const NiftiImageData*> &ims,
const std::string &name,
const T &call_back);
421 static void dump_nifti_element(
const std::vector<const NiftiImageData*> &ims,
const std::string &name,
const T &call_back,
const unsigned num_elems);
425 static std::string get_nifti_element(
const std::vector<const NiftiImageData*> &ims,
const std::string &name,
const T &call_back);
427 static std::string get_nifti_element(
const std::vector<const NiftiImageData*> &ims,
const std::string &name,
const T &call_back,
const unsigned num_elems);
434 void kernel_convolution(
const float sigma, NREG_CONV_KERNEL_TYPE conv_type = GAUSSIAN_KERNEL);
456 enum NiftiImageDataType { _general, _3D, _3DTensor, _3DDisp, _3DDef};
458 enum MathsType { ADD, sub, mul, div};
479 void maths(
const float val,
const MathsType type);
482 static void open_nifti_image(std::shared_ptr<nifti_image> &image,
const std::string &filename);
485 static void copy_nifti_image(std::shared_ptr<nifti_image> &output_image_sptr,
const std::shared_ptr<nifti_image> &image_to_copy_sptr);
490 void change_datatype(
const int datatype);
493 template<
typename newType>
496 if (im.
get_raw_nifti_sptr()->datatype == DT_BINARY)
return change_datatype<newType,bool> (im);
497 if (im.
get_raw_nifti_sptr()->datatype == DT_INT8)
return change_datatype<newType,signed char> (im);
498 if (im.
get_raw_nifti_sptr()->datatype == DT_INT16)
return change_datatype<newType,signed short> (im);
499 if (im.
get_raw_nifti_sptr()->datatype == DT_INT32)
return change_datatype<newType,signed int> (im);
500 if (im.
get_raw_nifti_sptr()->datatype == DT_FLOAT32)
return change_datatype<newType,float> (im);
501 if (im.
get_raw_nifti_sptr()->datatype == DT_FLOAT64)
return change_datatype<newType,double> (im);
502 if (im.
get_raw_nifti_sptr()->datatype == DT_UINT8)
return change_datatype<newType,unsigned char> (im);
503 if (im.
get_raw_nifti_sptr()->datatype == DT_UINT16)
return change_datatype<newType,unsigned short> (im);
504 if (im.
get_raw_nifti_sptr()->datatype == DT_UINT32)
return change_datatype<newType,unsigned int> (im);
505 if (im.
get_raw_nifti_sptr()->datatype == DT_INT64)
return change_datatype<newType,signed long long> (im);
506 if (im.
get_raw_nifti_sptr()->datatype == DT_UINT64)
return change_datatype<newType,unsigned long long>(im);
507 if (im.
get_raw_nifti_sptr()->datatype == DT_FLOAT128)
return change_datatype<newType,long double> (im);
509 std::stringstream ss;
510 ss <<
"change_datatype not implemented for your data type: ";
512 ss <<
" (bytes per voxel: ";
514 throw std::runtime_error(ss.str());
518 template<
typename newType,
typename oldType>
522 if (
typeid (newType) ==
typeid(oldType))
528 oldType *originalArray =
static_cast<oldType*
>(malloc(im->nvox*im->nbyper));
529 memcpy(originalArray, im->data, im->nvox*im->nbyper);
534 if (
typeid(newType) ==
typeid(
bool)) im->datatype = DT_BINARY;
535 else if (
typeid(newType) ==
typeid(
signed char)) im->datatype = DT_INT8;
536 else if (
typeid(newType) ==
typeid(
signed short)) im->datatype = DT_INT16;
537 else if (
typeid(newType) ==
typeid(
signed int)) im->datatype = DT_INT32;
538 else if (
typeid(newType) ==
typeid(
float)) im->datatype = DT_FLOAT32;
539 else if (
typeid(newType) ==
typeid(
double)) im->datatype = DT_FLOAT64;
540 else if (
typeid(newType) ==
typeid(
unsigned char)) im->datatype = DT_UINT8;
541 else if (
typeid(newType) ==
typeid(
unsigned short)) im->datatype = DT_UINT16;
542 else if (
typeid(newType) ==
typeid(
unsigned int)) im->datatype = DT_UINT32;
543 else if (
typeid(newType) ==
typeid(
signed long long)) im->datatype = DT_INT64;
544 else if (
typeid(newType) ==
typeid(
unsigned long long)) im->datatype = DT_UINT64;
545 else if (
typeid(newType) ==
typeid(
long double)) im->datatype = DT_FLOAT128;
547 std::stringstream ss;
548 ss <<
"change_datatype not implemented for your new data type: ";
549 ss <<
typeid (newType).name();
550 ss <<
" (bytes per voxel: ";
551 ss <<
sizeof(newType) <<
").";
552 throw std::runtime_error(ss.str());
556 nifti_datatype_sizes(im->datatype, &im->nbyper, &im->swapsize);
559 im->data =
static_cast<void*
>(calloc(im->nvox,
sizeof(newType)));
560 newType *dataPtr =
static_cast<newType*
>(im->data);
561 for (
size_t i = 0; i < im->nvox; i++)
562 dataPtr[i] = newType(originalArray[i]);
573 std::unique_ptr<NiftiImageData>
clone()
const
575 return std::unique_ptr<NiftiImageData>(this->
clone_impl());
577 virtual Iterator& begin()
579 _begin.reset(
new Iterator(
_data));
582 virtual Iterator_const& begin()
const
584 _begin_const.reset(
new Iterator_const(
_data));
585 return *_begin_const;
587 virtual Iterator& end()
592 virtual Iterator_const& end()
const
623 unsigned int items()
const {
return 1; }
625 virtual void sum (
void* ptr)
const;
626 virtual void max (
void* ptr)
const;
627 virtual void dot (
const DataContainer& a_x,
void* ptr)
const;
628 virtual void axpby (
const void* ptr_a,
const DataContainer& a_x,
const void* ptr_b,
const DataContainer& a_y);
629 virtual void xapyb (
const DataContainer& a_x,
const void* ptr_a,
const DataContainer& a_y,
const void* ptr_b);
630 virtual void xapyb (
const DataContainer& a_x,
const DataContainer& a_a,
const DataContainer& a_y,
const DataContainer& a_b);
632 const DataContainer& a_x,
const void* ptr_a,
633 const DataContainer& a_y,
const DataContainer& a_b);
634 virtual float norm()
const;
635 virtual void multiply (
const DataContainer& a_x,
const DataContainer& a_y);
636 virtual void divide (
const DataContainer& a_x,
const DataContainer& a_y);
637 virtual void maximum(
const DataContainer& x,
const DataContainer& y);
638 virtual void minimum(
const DataContainer& x,
const DataContainer& y);
639 virtual void power(
const DataContainer& x,
const DataContainer& y);
640 virtual void multiply(
const DataContainer& a_x,
const void* a_y);
641 virtual void add(
const DataContainer& a_x,
const void* a_y);
642 virtual void maximum(
const DataContainer& x,
const void* a_y);
643 virtual void minimum(
const DataContainer& x,
const void* a_y);
644 virtual void power(
const DataContainer& x,
const void* a_y);
645 virtual void exp(
const DataContainer& x);
646 virtual void log(
const DataContainer& x);
647 virtual void sqrt(
const DataContainer& x);
648 virtual void sign(
const DataContainer& x);
649 virtual void abs(
const DataContainer& x);
651 virtual Dimensions dimensions()
const
664 void unary_op(
const DataContainer& a_x, dataType(*f)(dataType));
665 void semibinary_op(
const DataContainer& a_x,
const void* a_y, dataType(*f)(dataType, dataType));
666 void binary_op(
const DataContainer& a_x,
const DataContainer& a_y, dataType(*f)(dataType, dataType));
670 mutable std::shared_ptr<Iterator> _begin;
671 mutable std::shared_ptr<Iterator> _end;
672 mutable std::shared_ptr<Iterator_const> _begin_const;
673 mutable std::shared_ptr<Iterator_const> _end_const;
Definition: DataHandle.h:159
Definition: ImageData.h:52
Definition: ImageData.h:44
Definition: ImageData.h:38
Definition: NiftiImageData.h:118
Definition: NiftiImageData.h:83
Definition: NiftiImageData.h:78
static bool are_equal_to_given_accuracy(const NiftiImageData &im1, const NiftiImageData &im2, const float required_accuracy_compared_to_max)
Check if the norms of two images are equal to a given accuracy.
Definition: NiftiImageData.cpp:1680
float get_mean() const
Get mean.
Definition: NiftiImageData.cpp:437
static void dump_nifti_element(const std::vector< const NiftiImageData * > &ims, const std::string &name, const T &call_back)
Dump nifti element.
Definition: NiftiImageData.cpp:1264
NiftiImageData & operator*=(const float)
Multiplication operator.
Definition: NiftiImageData.cpp:292
virtual void exp(const DataContainer &x)
*this = the elementwise exp(x)
Definition: NiftiImageData.cpp:1996
static void construct_NiftiImageData_from_complex_im_imag_component(std::shared_ptr< NiftiImageData > &out_sptr, const std::shared_ptr< const ImageData > in_sptr)
Construct NiftiImageData from the imaginary component of a complex SIRF ImageData.
Definition: NiftiImageData.cpp:228
unsigned get_nan_count() const
Get nan count.
Definition: NiftiImageData.cpp:477
virtual void axpby(const void *ptr_a, const DataContainer &a_x, const void *ptr_b, const DataContainer &a_y)
*this = the linear combination of x and y
Definition: NiftiImageData.cpp:1776
virtual float norm() const
returns the norm of this container viewed as a vector
Definition: NiftiImageData.cpp:1856
virtual void write(const std::string &filename, const int datatype) const
Definition: NiftiImageData.cpp:383
float get_min() const
Get min.
Definition: NiftiImageData.cpp:427
friend NiftiImageData operator+(NiftiImageData lhs, const NiftiImageData &rhs)
Addition operator.
Definition: NiftiImageData.h:232
virtual void add(const DataContainer &a_x, const void *a_y)
*this = the sum x + y with scalar y
Definition: NiftiImageData.cpp:1941
float get_norm(const NiftiImageData &) const
Get norm.
Definition: NiftiImageData.cpp:521
int get_original_datatype() const
Get original datatype.
Definition: NiftiImageData.h:395
float * _data
Data.
Definition: NiftiImageData.h:464
friend NiftiImageData operator/(NiftiImageData lhs, const NiftiImageData &rhs)
Division operator.
Definition: NiftiImageData.h:300
friend NiftiImageData operator*(NiftiImageData lhs, const float val)
Multiplication operator.
Definition: NiftiImageData.h:274
virtual void multiply(const DataContainer &a_x, const DataContainer &a_y)
*this = the elementwise product x*y
Definition: NiftiImageData.cpp:1927
void fill(const float v)
Fill.
Definition: NiftiImageData.cpp:491
static void open_nifti_image(std::shared_ptr< nifti_image > &image, const std::string &filename)
Open nifti image.
Definition: NiftiImageData.cpp:646
const int * get_dimensions() const
Get data size in each dimension.
Definition: NiftiImageData.cpp:543
bool operator!=(const NiftiImageData &other) const
Equality operator.
Definition: NiftiImageData.cpp:258
NiftiImageData & operator=(const NiftiImageData &to_copy)
Assignment.
Definition: NiftiImageData.cpp:71
virtual void minimum(const DataContainer &x, const DataContainer &y)
*this = the elementwise min(x, y)
Definition: NiftiImageData.cpp:1969
virtual void abs(const DataContainer &x)
*this = the elementwise abs(x)
Definition: NiftiImageData.cpp:2020
virtual void maximum(const DataContainer &x, const DataContainer &y)
*this = the elementwise max(x, y)
Definition: NiftiImageData.cpp:1955
virtual void xapyb(const DataContainer &a_x, const void *ptr_a, const DataContainer &a_y, const void *ptr_b)
alternative interface to the above
Definition: NiftiImageData.cpp:1819
void set_up_data(const int original_datatype)
Set up datatype. Set to float if not already, store the original type.
Definition: NiftiImageData.cpp:997
virtual void divide(const DataContainer &a_x, const DataContainer &a_y)
*this = the elementwise ratio x / y
Definition: NiftiImageData.cpp:1948
static void dump_headers(const std::vector< const NiftiImageData * > &ims)
Dump info of multiple nifti images.
Definition: NiftiImageData.cpp:1152
friend NiftiImageData operator+(NiftiImageData lhs, const float val)
Addition operator.
Definition: NiftiImageData.h:252
float get_max() const
Get max.
Definition: NiftiImageData.cpp:417
virtual void write(const std::string &filename) const
Write.
Definition: NiftiImageData.h:338
void check_dimensions(const enum NiftiImageDataType image_type=_general)
Check dimensions. Don't require anything for this class.
Definition: NiftiImageData.cpp:555
virtual void sum(void *ptr) const
below all void* are actually float*
Definition: NiftiImageData.cpp:1753
void pad(const int min_index[7], const int max_index[7], const dataType val=0)
Pad image with value. Give number of voxels to increase in min and max directions....
Definition: NiftiImageData.cpp:867
void maths(const NiftiImageData &c, const MathsType type)
Add, subract image from another.
Definition: NiftiImageData.cpp:604
int get_1D_index(const int idx[7]) const
get 1D index from ND index
Definition: NiftiImageData.cpp:965
float operator()(const int index) const
Access data element via 1D index (const)
Definition: NiftiImageData.cpp:319
friend NiftiImageData operator-(NiftiImageData lhs, const float val)
Subtraction operator.
Definition: NiftiImageData.h:262
bool operator==(const NiftiImageData &other) const
Equality operator.
Definition: NiftiImageData.cpp:250
NiftiImageData & operator+=(const NiftiImageData &rhs)
Addition operator.
Definition: NiftiImageData.cpp:264
float get_sum() const
Get sum.
Definition: NiftiImageData.cpp:465
std::unique_ptr< NiftiImageData > clone() const
Clone and return as unique pointer.
Definition: NiftiImageData.h:573
NiftiImageData & operator/=(const float)
Division operator.
Definition: NiftiImageData.cpp:305
static void copy_nifti_image(std::shared_ptr< nifti_image > &output_image_sptr, const std::shared_ptr< nifti_image > &image_to_copy_sptr)
Copy nifti image.
Definition: NiftiImageData.cpp:664
bool is_initialised() const
Is the image initialised? (Should be unless default constructor was used.)
Definition: NiftiImageData.h:325
virtual void set_up_geom_info()
Set up the geometrical info. Use qform preferentially over sform.
Definition: NiftiImageData.cpp:2026
virtual void sign(const DataContainer &x)
*this = the elementwise sign(x)
Definition: NiftiImageData.cpp:2014
std::shared_ptr< nifti_image > _nifti_image
Image data as a nifti object.
Definition: NiftiImageData.h:461
virtual void dot(const DataContainer &a_x, void *ptr) const
calculates the dot product of this container with another one
Definition: NiftiImageData.cpp:1741
friend NiftiImageData operator*(NiftiImageData lhs, const NiftiImageData &rhs)
Multiplication operator.
Definition: NiftiImageData.h:281
bool is_in_bounds(const int index[7]) const
Point is in bounds?
Definition: NiftiImageData.cpp:1028
friend NiftiImageData operator-(NiftiImageData lhs, const NiftiImageData &rhs)
Subtraction operator.
Definition: NiftiImageData.h:242
NiftiImageData(const inputType *const data, const VoxelisedGeometricalInfo3D &geom, const bool is_tensor=false)
Construct from array.
Definition: NiftiImageData.h:180
virtual void sqrt(const DataContainer &x)
*this = the elementwise sqrt(x)
Definition: NiftiImageData.cpp:2008
virtual NiftiImageData * clone_impl() const
Clone helper function. Don't use.
Definition: NiftiImageData.h:612
virtual ~NiftiImageData()
Destructor.
Definition: NiftiImageData.h:158
static bool do_nifti_image_metadata_match(const NiftiImageData &im1, const NiftiImageData &im2, bool verbose)
Do nifti image metadatas match?
Definition: NiftiImageData.cpp:1076
void set_voxel_spacing(const float factors[3], const int interpolation_order)
Definition: NiftiImageData.cpp:1429
bool is_same_size(const NiftiImageData &im) const
Images are same size.
Definition: NiftiImageData.cpp:1043
NiftiImageData()
Constructor.
Definition: NiftiImageData.h:155
float get_variance() const
Get variance.
Definition: NiftiImageData.cpp:448
void kernel_convolution(const float sigma, NREG_CONV_KERNEL_TYPE conv_type=GAUSSIAN_KERNEL)
Kernel convolution.
Definition: NiftiImageData.cpp:1578
dataType get_inner_product(const NiftiImageData &other) const
Inner product of two images.
Definition: NiftiImageData.cpp:1671
void mirror_along_axis(const unsigned axis)
Mirror the image along a given axis (This will change handedness of image)
Definition: NiftiImageData.cpp:1660
float get_standard_deviation() const
Get standard deviation.
Definition: NiftiImageData.cpp:459
int _original_datatype
Original datatype.
Definition: NiftiImageData.h:467
static std::shared_ptr< nifti_image > create_from_geom_info(const VoxelisedGeometricalInfo3D &geom, const bool is_tensor=false, const NREG_TRANS_TYPE tensor_type=NREG_TRANS_TYPE::DEF_FIELD)
Create NiftiImageData from geometrical info.
Definition: NiftiImageData.cpp:127
void normalise_zero_and_one()
Normalise image between 0 and 1.
Definition: NiftiImageData.cpp:694
std::shared_ptr< const nifti_image > get_raw_nifti_sptr() const
Get image as nifti as const.
Definition: NiftiImageData.cpp:367
void flip_along_axis(const unsigned axis)
Flip the image along a given axis (Rotation of 180 degrees about axis)
Definition: NiftiImageData.cpp:1649
virtual void power(const DataContainer &x, const DataContainer &y)
*this = the elementwise pow(x, y)
Definition: NiftiImageData.cpp:1983
NiftiImageData & operator-=(const NiftiImageData &rhs)
Subtraction operator.
Definition: NiftiImageData.cpp:271
void standardise()
Standardise (subtract mean and divide by standard deviation).
Definition: NiftiImageData.cpp:704
static void print_headers(const std::vector< const NiftiImageData * > &ims)
Print multiple header info.
Definition: NiftiImageData.cpp:740
static void construct_NiftiImageData_from_complex_im_real_component(std::shared_ptr< NiftiImageData > &out_sptr, const std::shared_ptr< const ImageData > in_sptr)
Construct NiftiImageData from the real component of a complex SIRF ImageData.
Definition: NiftiImageData.cpp:216
static void construct_NiftiImageData_from_complex_im(std::shared_ptr< NiftiImageData > &out_real_sptr, std::shared_ptr< NiftiImageData > &out_imag_sptr, const std::shared_ptr< const ImageData > in_sptr)
Construct two NiftiImageData from a complex SIRF ImageData.
Definition: NiftiImageData.cpp:243
size_t get_num_voxels() const
Get total number of voxels.
Definition: NiftiImageData.cpp:549
virtual void log(const DataContainer &x)
*this = the elementwise log(x)
Definition: NiftiImageData.cpp:2002
void print_header() const
Print header info.
Definition: NiftiImageData.cpp:733
virtual void max(void *ptr) const
calculates the value of this container's element with the largest real part
Definition: NiftiImageData.cpp:1763
bool get_contains_nans() const
Does the image contain any NaNs?
Definition: NiftiImageData.h:437
void crop(const int min_index[7], const int max_index[7])
Crop. Set to -1 to leave unchanged.
Definition: NiftiImageData.cpp:747
Definition: GeometricalInfo.h:50
Abstract data container.
Definition: GeometricalInfo.cpp:141