33 #ifndef GADGETRON_DATA_CONTAINERS
34 #define GADGETRON_DATA_CONTAINERS
42 #include <ismrmrd/ismrmrd.h>
43 #include <ismrmrd/dataset.h>
45 #include "sirf/common/DataContainer.h"
46 #include "sirf/common/ImageData.h"
47 #include "sirf/common/multisort.h"
48 #include "sirf/Gadgetron/cgadgetron_shared_ptr.h"
51 #include "sirf/iUtilities/LocalisedException.h"
54 #define SIRF_DYNAMIC_CAST(T, X, Y) T& X = dynamic_cast<T&>(Y)
64 class FourierEncoding;
65 class CartesianFourierEncoding;
66 #if GADGETRON_TOOLBOXES_AVAILABLE
67 class RPEFourierEncoding;
93 const char* c_str()
const {
return data_.c_str(); }
94 operator std::string&() {
return data_; }
95 operator const std::string&()
const {
return data_; }
96 bool empty()
const {
return data_.empty(); }
97 const ISMRMRD::IsmrmrdHeader& get_IsmrmrdHeader()
const
105 void deserialize()
const
108 { header_ = ISMRMRD::IsmrmrdHeader();
109 ISMRMRD::deserialize(data_.c_str(), header_);
114 mutable ISMRMRD::IsmrmrdHeader header_;
115 mutable bool have_header_;
134 IgnoreMask(
unsigned long int mask = (1 << 18)) :
135 ignore_(mask), max_(8*
sizeof(mask)) {}
136 void set(
unsigned long int mask)
140 void ignore(
unsigned int i)
142 if (i < 1 || i > max_)
144 unsigned long int one = 1;
145 ignore_ = ignore_ | (one << (i - 1));
147 void ignore_not(
unsigned int i)
149 if (i < 1 || i > max_)
151 unsigned long int one = 1;
152 ignore_ = ignore_ & ~(one << (i - 1));
154 bool bit(
unsigned int i)
const
156 if (i < 1 || i > max_)
158 unsigned long int one = 1;
159 return ignore_ & (one << (i - 1));
161 unsigned long int bits()
const
165 bool ignored(
unsigned long int bits)
const
167 return bits & ignore_;
169 std::string bits_string()
const
171 unsigned int size = max_;
172 unsigned long int one = 1;
173 unsigned long int bitmask = (one << (size - 1));
174 std::stringstream str;
175 for (
unsigned int i = 0; i < size; i++) {
176 if (ignore_ & (bitmask >> i))
180 if ((i + 1) % 4 == 0)
187 unsigned long int ignore_;
204 static int const num_kspace_dims_ = 7 + ISMRMRD::ISMRMRD_Constants::ISMRMRD_USER_INTS;
208 typedef std::array<int, num_kspace_dims_> TagType;
209 typedef std::vector<int> SetType;
212 for(
int i=0; i<num_kspace_dims_; ++i)
223 this->idx_set_ = idx_set;
226 TagType get_tag(
void)
const {
return tag_;}
227 SetType get_idx_set(
void)
const {
return idx_set_;}
228 void add_idx_to_set(
size_t const idx){this->idx_set_.push_back(idx);}
230 bool is_first_set()
const {
231 bool is_first= (tag_[0] == 0);
234 for(
int dim=2; dim<num_kspace_dims_; ++dim)
235 is_first *= (tag_[dim] == 0);
240 static void print_tag(
const TagType& tag);
241 static void print_acquisition_tag(ISMRMRD::Acquisition acq);
282 static void binary_op
283 (
const ISMRMRD::Acquisition& acq_x, ISMRMRD::Acquisition& acq_y,
284 complex_float_t (*f)(complex_float_t, complex_float_t));
285 static void semibinary_op
286 (
const ISMRMRD::Acquisition& acq_x, ISMRMRD::Acquisition& acq_y, complex_float_t y,
287 complex_float_t(*f)(complex_float_t, complex_float_t));
289 (
const ISMRMRD::Acquisition& acq_x, ISMRMRD::Acquisition& acq_y,
290 complex_float_t(*f)(complex_float_t));
293 (complex_float_t a,
const ISMRMRD::Acquisition& acq_x,
294 complex_float_t b, ISMRMRD::Acquisition& acq_y);
296 (
const ISMRMRD::Acquisition& acq_x, complex_float_t a,
297 ISMRMRD::Acquisition& acq_y, complex_float_t b);
299 (
const ISMRMRD::Acquisition& acq_x, complex_float_t a,
300 ISMRMRD::Acquisition& acq_y,
const ISMRMRD::Acquisition& acq_b);
302 (
const ISMRMRD::Acquisition& acq_x,
const ISMRMRD::Acquisition& acq_a,
303 ISMRMRD::Acquisition& acq_y,
const ISMRMRD::Acquisition& acq_b);
306 static complex_float_t dot
307 (
const ISMRMRD::Acquisition& acq_x,
const ISMRMRD::Acquisition& acq_y);
309 static complex_float_t sum(
const ISMRMRD::Acquisition& acq_x);
311 static complex_float_t max(
const ISMRMRD::Acquisition& acq_x);
315 (
const ISMRMRD::Acquisition& acq_x, ISMRMRD::Acquisition& acq_y);
319 (
const ISMRMRD::Acquisition& acq_x, ISMRMRD::Acquisition& acq_y, complex_float_t y);
323 (
const ISMRMRD::Acquisition& acq_x, ISMRMRD::Acquisition& acq_y, complex_float_t y);
327 (
const ISMRMRD::Acquisition& acq_x, ISMRMRD::Acquisition& acq_y);
331 (
const ISMRMRD::Acquisition& acq_x, ISMRMRD::Acquisition& acq_y);
333 (
const ISMRMRD::Acquisition& acq_x, ISMRMRD::Acquisition& acq_y, complex_float_t y);
337 (
const ISMRMRD::Acquisition& acq_x, ISMRMRD::Acquisition& acq_y);
339 (
const ISMRMRD::Acquisition& acq_x, ISMRMRD::Acquisition& acq_y, complex_float_t y);
342 (
const ISMRMRD::Acquisition& acq_x, ISMRMRD::Acquisition& acq_y);
344 (
const ISMRMRD::Acquisition& acq_x, ISMRMRD::Acquisition& acq_y, complex_float_t y);
347 (
const ISMRMRD::Acquisition& acq_x, ISMRMRD::Acquisition& acq_y);
350 (
const ISMRMRD::Acquisition& acq_x, ISMRMRD::Acquisition& acq_y);
353 (
const ISMRMRD::Acquisition& acq_x, ISMRMRD::Acquisition& acq_y);
356 (
const ISMRMRD::Acquisition& acq_x, ISMRMRD::Acquisition& acq_y);
360 (
const ISMRMRD::Acquisition& acq_x, ISMRMRD::Acquisition& acq_y);
361 static float norm(
const ISMRMRD::Acquisition& acq_x);
364 static void ismrmrd_par_info(
const char* par,
int* output)
382 output[1] = ISMRMRD::ISMRMRD_Constants::ISMRMRD_PHYS_STAMPS;
384 output[1] = ISMRMRD::ISMRMRD_Constants::ISMRMRD_CHANNEL_MASKS;
393 output[1] = ISMRMRD::ISMRMRD_Constants::ISMRMRD_USER_INTS;
395 output[1] = ISMRMRD::ISMRMRD_Constants::ISMRMRD_USER_FLOATS;
398 static void ismrmrd_par_value(ISMRMRD::Acquisition& acq,
399 const char* name,
unsigned long long int* v)
402 *v = ((
unsigned int)acq.version());
404 *v = ((
unsigned long long int)acq.flags());
406 *v = ((
unsigned int)acq.measurement_uid());
408 *v = ((
unsigned int)acq.scan_counter());
410 *v = ((
unsigned int)acq.acquisition_time_stamp());
412 *v = ((
unsigned int)acq.number_of_samples());
414 *v = ((
unsigned int)acq.available_channels());
416 *v = ((
unsigned int)acq.active_channels());
418 *v = ((
unsigned int)acq.discard_pre());
420 *v = ((
unsigned int)acq.discard_post());
422 *v = ((
unsigned int)acq.center_sample());
424 *v = ((
unsigned int)acq.encoding_space_ref());
426 *v = ((
unsigned int)acq.trajectory_dimensions());
428 *v = ((
unsigned int)acq.idx().kspace_encode_step_1);
430 *v = ((
unsigned int)acq.idx().kspace_encode_step_2);
432 *v = ((
unsigned int)acq.idx().average);
434 *v = ((
unsigned int)acq.idx().slice);
436 *v = ((
unsigned int)acq.idx().contrast);
438 *v = ((
unsigned int)acq.idx().phase);
440 *v = ((
unsigned int)acq.idx().repetition);
442 *v = ((
unsigned int)acq.idx().set);
444 *v = ((
unsigned int)acq.idx().segment);
446 int n = ISMRMRD::ISMRMRD_Constants::ISMRMRD_PHYS_STAMPS;
447 const uint32_t* pts = acq.physiology_time_stamp();
448 for (
int i = 0; i < n; i++)
449 v[i] = (
unsigned int)pts[i];
452 int n = ISMRMRD::ISMRMRD_Constants::ISMRMRD_CHANNEL_MASKS;
453 const uint64_t* pts = acq.channel_mask();
454 for (
int i = 0; i < n; i++)
455 v[i] = (
unsigned long long int)pts[i];
459 static void ismrmrd_par_value(ISMRMRD::Acquisition& acq,
460 const char* name,
float* v)
463 *v = acq.sample_time_us();
465 float* u = acq.position();
466 for (
int i = 0; i < 3; i++)
470 float* u = acq.read_dir();
471 for (
int i = 0; i < 3; i++)
475 float* u = acq.phase_dir();
476 for (
int i = 0; i < 3; i++)
480 float* u = acq.slice_dir();
481 for (
int i = 0; i < 3; i++)
485 float* u = acq.patient_table_position();
486 for (
int i = 0; i < 3; i++)
497 const std::tuple<unsigned short,unsigned short,unsigned short> min_max_ctr)
499 ISMRMRD::IsmrmrdHeader hdr = this->acquisitions_info().get_IsmrmrdHeader();
500 ISMRMRD::EncodingLimits enc_limits = hdr.encoding[0].encodingLimits;
502 ISMRMRD::Limit limit;
503 limit.minimum = std::get<0>(min_max_ctr);
504 limit.maximum = std::get<1>(min_max_ctr);
505 limit.center = std::get<2>(min_max_ctr);
508 enc_limits.kspace_encoding_step_1.get() = limit;
510 enc_limits.kspace_encoding_step_2.get() = limit;
512 enc_limits.average.get() = limit;
514 enc_limits.slice.get() = limit;
516 enc_limits.contrast.get() = limit;
518 enc_limits.phase.get() = limit;
520 enc_limits.repetition.get() = limit;
522 enc_limits.set.get() = limit;
524 enc_limits.segment.get() = limit;
526 throw std::runtime_error(
"You passed a name that is not an encoding limit.");
528 hdr.encoding[0].encodingLimits = enc_limits;
529 std::stringstream serialised_hdr;
530 ISMRMRD::serialize(hdr, serialised_hdr);
534 std::tuple<unsigned short,unsigned short,unsigned short>
535 get_encoding_limits(
const std::string& name)
const
537 ISMRMRD::IsmrmrdHeader hdr = this->acquisitions_info().get_IsmrmrdHeader();
538 ISMRMRD::EncodingLimits enc_limits = hdr.encoding[0].encodingLimits;
540 ISMRMRD::Limit limit;
543 limit = enc_limits.kspace_encoding_step_1.get();
545 limit = enc_limits.kspace_encoding_step_2.get();
547 limit = enc_limits.average.get();
549 limit = enc_limits.slice.get();
551 limit = enc_limits.contrast.get();
553 limit = enc_limits.phase.get();
555 limit = enc_limits.repetition.get();
557 limit = enc_limits.set.get();
559 limit = enc_limits.segment.get();
561 throw std::runtime_error(
"You passed a name that is not an encoding limit.");
563 return std::make_tuple(limit.minimum, limit.maximum, limit.center);
568 virtual void empty() = 0;
569 virtual void take_over(MRAcquisitionData&) = 0;
572 virtual unsigned int number()
const = 0;
574 virtual gadgetron::shared_ptr<ISMRMRD::Acquisition>
575 get_acquisition_sptr(
unsigned int num) = 0;
576 virtual int get_acquisition(
unsigned int,
577 ISMRMRD::Acquisition&)
const = 0;
578 virtual void set_acquisition(
unsigned int,
579 ISMRMRD::Acquisition&) = 0;
580 virtual void append_acquisition(ISMRMRD::Acquisition& acq) = 0;
582 virtual void copy_acquisitions_info(
const MRAcquisitionData& ac) = 0;
583 virtual void copy_acquisitions_data(
const MRAcquisitionData& ac) = 0;
586 virtual gadgetron::unique_ptr<MRAcquisitionData> new_acquisitions_container() = 0;
587 virtual MRAcquisitionData*
588 same_acquisitions_container(
const AcquisitionsInfo& info)
const = 0;
590 virtual void set_data(
const complex_float_t* z,
int all = 1) = 0;
591 virtual void get_data(complex_float_t* z,
int all = 1);
593 virtual void set_user_floats(
float const *
const z,
int const idx);
595 virtual bool is_complex()
const
602 virtual void sum(
void* ptr)
const;
603 virtual void max(
void* ptr)
const;
604 virtual void dot(
const DataContainer& dc,
void* ptr)
const;
605 complex_float_t dot(
const DataContainer& a_x)
612 const void* ptr_a,
const DataContainer& a_x,
613 const void* ptr_b,
const DataContainer& a_y);
615 const DataContainer& a_x,
const DataContainer& a_a,
616 const DataContainer& a_y,
const DataContainer& a_b);
621 axpby(ptr_a, a_x, ptr_b, a_y);
631 virtual void multiply(
const DataContainer& x,
const void* y);
641 virtual float norm()
const;
643 virtual void write(
const std::string &filename)
const;
647 void(*f)(
const ISMRMRD::Acquisition&, ISMRMRD::Acquisition&));
648 void semibinary_op(
const DataContainer& a_x, complex_float_t y,
649 void(*f)(
const ISMRMRD::Acquisition&, ISMRMRD::Acquisition&, complex_float_t));
651 void(*f)(
const ISMRMRD::Acquisition&, ISMRMRD::Acquisition&));
654 void set_acquisitions_info(std::string info) { acqs_info_ = info; }
655 void set_acquisitions_info(
const AcquisitionsInfo info) { acqs_info_ = info;}
656 IgnoreMask ignore_mask()
const {
return ignore_mask_; }
657 void set_ignore_mask(IgnoreMask ignore_mask)
const { ignore_mask_= ignore_mask; }
659 ISMRMRD::TrajectoryType get_trajectory_type()
const;
661 void set_trajectory_type(
const ISMRMRD::TrajectoryType type);
663 void set_trajectory(
const uint16_t traj_dim,
float* traj)
665 ISMRMRD::Acquisition acq;
666 for(
int i=0; i<number(); ++i)
668 get_acquisition(i, acq);
669 const uint16_t num_samples = acq.number_of_samples();
670 const uint16_t num_channels = acq.active_channels();
671 acq.resize(num_samples,num_channels,traj_dim);
672 int const offset = i*traj_dim*num_samples;
673 acq.setTraj(traj + offset);
674 set_acquisition(i, acq);
678 gadgetron::unique_ptr<MRAcquisitionData> clone()
const
680 return gadgetron::unique_ptr<MRAcquisitionData>(this->clone_impl());
683 bool undersampled()
const;
684 int get_acquisitions_dimensions(
size_t ptr_dim)
const;
685 void get_kspace_dimensions(std::vector<size_t>& dims)
const;
686 uint16_t get_trajectory_dimensions(
void)
const;
690 bool sorted()
const {
return sorted_; }
691 void set_sorted(
bool sorted) { sorted_ = sorted; }
712 virtual std::vector<int> get_flagged_acquisitions_index
713 (
const std::vector<ISMRMRD::ISMRMRD_AcquisitionFlags> flags)
const;
714 virtual std::vector<int> get_slice_encoding_index
715 (
const unsigned kspace_encode_step_2)
const;
717 virtual void get_subset(
MRAcquisitionData& subset,
const std::vector<int> subset_idx)
const;
718 virtual void set_subset(
const MRAcquisitionData &subset,
const std::vector<int> subset_idx);
720 std::vector<int> index() {
return index_; }
721 const std::vector<int>& index()
const {
return index_; }
723 int index(
int i)
const
725 const std::size_t ni = index_.size();
726 if (i < 0 || (ni > 0 &&
static_cast<std::size_t
>(i) >= ni)
727 ||
static_cast<unsigned>(i) >= number())
728 THROW(
"Aquisition number is out of range");
745 void read(
const std::string& filename_ismrmrd_with_ext,
int all = 0);
748 bool sorted_ =
false;
749 std::vector<int> index_;
750 std::vector<KSpaceSubset> sorting_;
751 AcquisitionsInfo acqs_info_;
753 mutable IgnoreMask ignore_mask_;
757 static gadgetron::shared_ptr<MRAcquisitionData> acqs_templ_;
759 virtual MRAcquisitionData* clone_impl()
const = 0;
777 this->set_ignore_mask(ignore_mask);
778 this->
read(filename_with_ext, all);
783 this->set_ignore_mask(ignore_mask);
786 virtual void empty();
788 virtual unsigned int number()
const {
return (
unsigned int)acqs_.size(); }
789 virtual unsigned int items()
const {
return (
unsigned int)acqs_.size(); }
790 virtual void append_acquisition(ISMRMRD::Acquisition& acq)
792 acqs_.push_back(gadgetron::shared_ptr<ISMRMRD::Acquisition>
793 (
new ISMRMRD::Acquisition(acq)));
795 virtual gadgetron::shared_ptr<ISMRMRD::Acquisition>
796 get_acquisition_sptr(
unsigned int num)
798 int ind = index(num);
801 virtual int get_acquisition(
unsigned int num,
802 ISMRMRD::Acquisition& acq)
const
805 int ind = index(num);
807 if (ignore_mask.ignored(acq.flags()))
811 virtual void set_acquisition(
unsigned int num, ISMRMRD::Acquisition& acq)
813 int ind = index(num);
818 acqs_info_ = ac.acquisitions_info();
821 virtual void set_data(
const complex_float_t* z,
int all = 1);
832 (gadgetron::shared_ptr<DataContainer>(ptr));
834 virtual gadgetron::unique_ptr<MRAcquisitionData>
835 new_acquisitions_container()
837 return gadgetron::unique_ptr<MRAcquisitionData>
842 std::vector<gadgetron::shared_ptr<ISMRMRD::Acquisition> > acqs_;
844 virtual void conjugate_impl();
858 virtual void empty() = 0;
859 virtual unsigned int number()
const = 0;
860 virtual gadgetron::shared_ptr<ImageWrap> sptr_image_wrap
861 (
unsigned int im_num) = 0;
862 virtual gadgetron::shared_ptr<const ImageWrap> sptr_image_wrap
863 (
unsigned int im_num)
const = 0;
866 virtual void append(
int image_data_type,
void* ptr_image) = 0;
867 virtual void append(
const ImageWrap& iw) = 0;
868 virtual void append(gadgetron::shared_ptr<ImageWrap> sptr_iw) = 0;
869 virtual gadgetron::shared_ptr<ISMRMRDImageData> abs()
const = 0;
870 virtual gadgetron::shared_ptr<ISMRMRDImageData> real()
const = 0;
871 virtual void clear_data() = 0;
872 virtual void set_image_type(
int imtype) = 0;
873 virtual void get_data(complex_float_t* data)
const;
874 virtual void set_data(
const complex_float_t* data);
875 virtual void get_real_data(
float* data)
const;
876 virtual void set_real_data(
const float* data);
877 virtual int read(std::string filename, std::string variable =
"",
int iv = -1);
878 virtual void write(
const std::string &filename,
const std::string &groupname,
const bool dicom)
const;
879 virtual void write(
const std::string &filename)
const
881 size_t size = filename.size();
882 std::string suff = filename.substr(size - 4, 4);
883 if (suff == std::string(
".dcm")) {
884 std::string prefix = filename.substr(0, size - 4);
885 this->write(prefix,
"",
true);
888 auto found = filename.find_last_of(
"/\\");
889 auto slash_found = found;
890 if (found == std::string::npos)
891 found = filename.find_last_of(
".");
893 found = filename.substr(found + 1).find_last_of(
".");
894 if (found == std::string::npos)
895 this->write(filename +
".h5",
"",
false);
897 std::string ext = filename.substr(slash_found + found + 1);
898 if (ext == std::string(
".h5"))
899 this->write(filename,
"",
false);
901 std::cerr <<
"WARNING: writing ISMRMRD images to "
902 << ext <<
"-files not implemented, "
903 <<
"please convert to Nifti images\n";
907 virtual Dimensions dimensions()
const
920 virtual void get_image_dimensions(
unsigned int im_num,
int* dim)
const
922 if (im_num >= number())
923 dim[0] = dim[1] = dim[2] = dim[3] = 0;
924 const ImageWrap& iw = image_wrap(im_num);
927 bool check_dimension_consistency()
const
929 size_t const num_dims = 4;
930 std::vector<int> first_img_dims(num_dims), temp_img_dims(num_dims);
932 this->get_image_dimensions(0, &first_img_dims[0]);
934 bool dims_match =
true;
935 for(
int i=1; i<number(); ++i)
937 this->get_image_dimensions(0, &temp_img_dims[0]);
938 dims_match *= (first_img_dims == temp_img_dims);
942 virtual gadgetron::shared_ptr<ISMRMRDImageData>
943 new_images_container()
const = 0;
944 virtual gadgetron::shared_ptr<ISMRMRDImageData>
945 clone(
const char* attr,
const char* target) = 0;
946 virtual int image_data_type(
unsigned int im_num)
const
948 return image_wrap(im_num).type();
950 virtual size_t num_data_elm()
const
952 return image_wrap(0).num_data_elm();
955 virtual float norm()
const;
957 virtual void sum(
void* ptr)
const;
958 virtual void max(
void* ptr)
const;
967 ComplexFloat_ a(*
static_cast<const complex_float_t*
>(ptr_a));
968 ComplexFloat_ b(*
static_cast<const complex_float_t*
>(ptr_b));
969 xapyb_(a_x, a, a_y, b);
975 ComplexFloat_ a(*
static_cast<const complex_float_t*
>(ptr_a));
977 xapyb_(a_x, a, a_y, b);
993 xapyb_(a_x, a, a_y, b);
1013 complex_float_t(*f)(complex_float_t, complex_float_t));
1016 complex_float_t(*f)(complex_float_t, complex_float_t));
1017 void unary_op(
const DataContainer& a_x, complex_float_t(*f)(complex_float_t));
1020 void scale(
float s);
1028 complex_float_t a,
const DataContainer& a_x,
1029 complex_float_t b,
const DataContainer& a_y)
1031 axpby(&a, a_x, &b, a_y);
1034 const DataContainer& a_x, complex_float_t a,
1035 const DataContainer& a_y, complex_float_t b)
1037 xapyb(a_x, &a, a_y, &b);
1039 gadgetron::unique_ptr<ISMRMRDImageData> clone()
const
1041 return gadgetron::unique_ptr<ISMRMRDImageData>(this->
clone_impl());
1044 virtual void sort() = 0;
1045 bool sorted()
const {
return sorted_; }
1046 void set_sorted(
bool sorted) { sorted_ = sorted; }
1047 std::vector<int> index() {
return index_; }
1048 const std::vector<int>& index()
const {
return index_; }
1049 int index(
int i)
const
1051 const std::size_t ni = index_.size();
1052 if (i < 0 || (ni > 0 &&
static_cast<std::size_t
>(i) >= ni) ||
static_cast<unsigned>(i) >= number())
1053 THROW(
"Image number is out of range. You tried to look up an image number that is not inside the container.");
1059 ImageWrap& image_wrap(
unsigned int im_num)
1061 gadgetron::shared_ptr<ImageWrap> sptr_iw = sptr_image_wrap(im_num);
1064 const ImageWrap& image_wrap(
unsigned int im_num)
const
1066 const gadgetron::shared_ptr<const ImageWrap>& sptr_iw =
1067 sptr_image_wrap(im_num);
1077 std::vector<int> index_;
1084 class ComplexFloat_ {
1086 ComplexFloat_(complex_float_t v) : v_(v) {}
1087 unsigned int number()
const
1091 complex_float_t image_wrap(
unsigned int i)
1095 size_t num_data_elm()
1103 template<
class A,
class B>
1104 void xapyb_(
const DataContainer& a_x, A& a,
const DataContainer& a_y, B& b)
1106 SIRF_DYNAMIC_CAST(
const ISMRMRDImageData, x, a_x);
1107 SIRF_DYNAMIC_CAST(
const ISMRMRDImageData, y, a_y);
1108 unsigned int nx = x.number();
1109 unsigned int na = a.number();
1110 unsigned int ny = y.number();
1111 unsigned int nb = b.number();
1115 THROW(
"ImageData sizes mismatch in axpby");
1116 if (na > 0 && na != nx)
1117 THROW(
"ImageData sizes mismatch in axpby");
1118 if (nb > 0 && nb != nx)
1119 THROW(
"ImageData sizes mismatch in axpby");
1120 unsigned int n = number();
1123 THROW(
"ImageData sizes mismatch in axpby");
1124 for (
unsigned int i = 0; i < nx; i++)
1125 image_wrap(i).xapyb(x.image_wrap(i), a.image_wrap(i),
1126 y.image_wrap(i), b.image_wrap(i));
1129 for (
unsigned int i = 0; i < nx; i++) {
1130 const ImageWrap& u = x.image_wrap(i);
1131 const ImageWrap& v = y.image_wrap(i);
1133 w.xapyb(u, a.image_wrap(i), v, b.image_wrap(i));
1142 typedef ISMRMRDImageData GadgetronImageData;
1156 typedef std::vector<gadgetron::shared_ptr<ImageWrap> >::iterator
1158 typedef std::vector<gadgetron::shared_ptr<ImageWrap> >::const_iterator
1159 ImageWrapIter_const;
1163 iw_(iw), n_(n), i_(i), iter_(it), end_((**iw).end())
1166 iter_(iter.iter_), end_(iter.end_), sptr_iter_(iter.sptr_iter_)
1175 sptr_iter_ = iter.sptr_iter_;
1178 virtual bool operator==(
const BaseIter& ai)
const
1180 SIRF_DYNAMIC_CAST(
const Iterator, i, ai);
1181 return iter_ == i.iter_;
1183 virtual bool operator!=(
const BaseIter& ai)
const
1185 SIRF_DYNAMIC_CAST(
const Iterator, i, ai);
1186 return iter_ != i.iter_;
1190 if (i_ >= n_ || (i_ == n_ - 1 && iter_ == end_))
1191 throw std::out_of_range(
"cannot advance out-of-range iterator");
1193 if (iter_ == end_ && i_ < n_ - 1) {
1196 iter_ = (**iw_).begin();
1197 end_ = (**iw_).end();
1203 sptr_iter_.reset(
new Iterator(*
this));
1204 if (i_ >= n_ || (i_ == n_ - 1 && iter_ == end_))
1205 throw std::out_of_range(
"cannot advance out-of-range iterator");
1207 if (iter_ == end_ && i_ < n_ - 1) {
1210 iter_ = (**iw_).begin();
1211 end_ = (**iw_).end();
1217 if (i_ >= n_ || (i_ == n_ - 1 && iter_ == end_))
1218 throw std::out_of_range
1219 (
"cannot dereference out-of-range iterator");
1229 gadgetron::shared_ptr<Iterator> sptr_iter_;
1236 iw_(iw), n_(n), i_(i), iter_(it), end_((**iw).end_const())
1239 n_(iter.n_), i_(iter.i_),
1240 iter_(iter.iter_), end_(iter.end_), sptr_iter_(iter.sptr_iter_)
1249 sptr_iter_ = iter.sptr_iter_;
1255 return iter_ == i.iter_;
1260 return iter_ != i.iter_;
1264 if (i_ >= n_ || (i_ == n_ - 1 && iter_ == end_))
1265 throw std::out_of_range(
"cannot advance out-of-range iterator");
1267 if (iter_ == end_ && i_ < n_ - 1) {
1270 iter_ = (**iw_).begin_const();
1271 end_ = (**iw_).end_const();
1290 const NumRef& operator*()
const
1292 if (i_ >= n_ || (i_ == n_ - 1 && iter_ == end_))
1293 throw std::out_of_range
1294 (
"cannot dereference out-of-range iterator");
1301 ImageWrapIter_const iw_;
1307 gadgetron::shared_ptr<Iterator_const> sptr_iter_;
1326 const char* target);
1327 virtual void empty()
1331 virtual unsigned int items()
const
1333 return (
unsigned int)images_.size();
1335 virtual unsigned int number()
const
1337 return (
unsigned int)images_.size();
1339 virtual void append(
int image_data_type,
void* ptr_image)
1341 images_.push_back(gadgetron::shared_ptr<ImageWrap>
1342 (
new ImageWrap(image_data_type, ptr_image)));
1344 virtual void append(CFImage& img)
1346 void* vptr_img =
new CFImage(img);
1347 this->append(7, vptr_img);
1349 virtual void append(
const ImageWrap& iw)
1351 images_.push_back(gadgetron::shared_ptr<ImageWrap>(
new ImageWrap(iw)));
1353 virtual void append(gadgetron::shared_ptr<ImageWrap> sptr_iw)
1355 images_.push_back(sptr_iw);
1357 virtual gadgetron::shared_ptr<GadgetronImageData> abs()
const;
1358 virtual gadgetron::shared_ptr<GadgetronImageData> real()
const;
1359 virtual void clear_data()
1361 std::vector<gadgetron::shared_ptr<ImageWrap> > empty_data;
1362 images_.swap(empty_data);
1364 virtual void sort();
1365 virtual gadgetron::shared_ptr<ImageWrap> sptr_image_wrap
1366 (
unsigned int im_num)
1368 int i = index(im_num);
1369 return images_.at(i);
1371 virtual gadgetron::shared_ptr<const ImageWrap> sptr_image_wrap
1372 (
unsigned int im_num)
const
1374 int i = index(im_num);
1375 return images_.at(i);
1392 (gadgetron::shared_ptr<DataContainer>(new_images_container()));
1394 virtual gadgetron::shared_ptr<GadgetronImageData> new_images_container()
const
1396 gadgetron::shared_ptr<GadgetronImageData> sptr_img
1397 ((GadgetronImageData*)
new GadgetronImagesVector());
1401 virtual gadgetron::shared_ptr<GadgetronImageData>
1402 clone(
const char* attr,
const char* target)
1404 return gadgetron::shared_ptr<GadgetronImageData>
1405 (
new GadgetronImagesVector(*
this, attr, target));
1408 virtual Iterator& begin()
1410 ImageWrapIter iw = images_.begin();
1411 begin_.reset(
new Iterator(iw, images_.size(), 0, (**iw).begin()));
1414 virtual Iterator& end()
1416 ImageWrapIter iw = images_.begin();
1417 int n = images_.size();
1418 for (
int i = 0; i < n - 1; i++)
1420 end_.reset(
new Iterator(iw, n, n - 1, (**iw).end()));
1423 virtual Iterator_const& begin()
const
1425 ImageWrapIter_const iw = images_.begin();
1427 (
new Iterator_const(iw, images_.size(), 0, (**iw).begin_const()));
1428 return *begin_const_;
1430 virtual Iterator_const& end()
const
1432 ImageWrapIter_const iw = images_.begin();
1433 int n = images_.size();
1434 for (
int i = 0; i < n - 1; i++)
1437 (
new Iterator_const(iw, n, n - 1, (**iw).end_const()));
1440 virtual void set_image_type(
int image_type);
1441 virtual void get_data(complex_float_t* data)
const;
1442 virtual void set_data(
const complex_float_t* data);
1443 virtual void get_real_data(
float* data)
const;
1444 virtual void set_real_data(
const float* data);
1447 std::unique_ptr<GadgetronImagesVector>
clone()
const
1449 return std::unique_ptr<GadgetronImagesVector>(this->clone_impl());
1471 std::vector<gadgetron::shared_ptr<ImageWrap> > images_;
1472 mutable gadgetron::shared_ptr<Iterator> begin_;
1473 mutable gadgetron::shared_ptr<Iterator> end_;
1474 mutable gadgetron::shared_ptr<Iterator_const> begin_const_;
1475 mutable gadgetron::shared_ptr<Iterator_const> end_const_;
1489 std::unique_ptr<MRAcquisitionData> extract_calibration_data(
const MRAcquisitionData& ad)
const;
1490 gadgetron::shared_ptr<FourierEncoding> sptr_enc_;
1517 throw std::runtime_error(
"This has not been implemented yet.");
1520 void set_csm_smoothness(
int s)
1522 csm_smoothness_ = s;
1524 void set_csm_conv_kernel_size(
int w)
1526 csm_conv_kernel_halfsize_ = w;
1537 CFImage get_csm_as_cfimage(
size_t const i)
const;
1538 CFImage get_csm_as_cfimage(
const KSpaceSubset::TagType tag,
const int offset)
const;
1541 void get_dim(
size_t const num_csm,
int* dim)
const
1543 GadgetronImagesVector::get_image_dimensions(num_csm, dim);
1554 void calculate_csm(ISMRMRD::NDArray<complex_float_t>& cm, ISMRMRD::NDArray<float>& img, ISMRMRD::NDArray<complex_float_t>& csm);
1557 int csm_smoothness_ = 0;
1558 int csm_conv_kernel_halfsize_ = 1;
1559 void smoothen_(
int nx,
int ny,
int nz,
int nc, complex_float_t* u, complex_float_t* v,
1562 void mask_noise_(
int nx,
int ny,
int nz,
float* u,
float noise,
int* mask);
1563 float max_diff_(
int nx,
int ny,
int nz,
int nc,
float small_grad, complex_float_t* u, complex_float_t* v);
1564 float max_(
int nx,
int ny,
int nz,
float* u);
1568 void match_img_header_to_acquisition(CFImage& img,
const ISMRMRD::Acquisition& acq);
Definition: DataHandle.h:159
Definition: gadgetron_data_containers.h:70
A vector implementation of the abstract MR acquisition data container class.
Definition: gadgetron_data_containers.h:773
A coil images container based on the GadgetronImagesVector class.
Definition: gadgetron_data_containers.h:1484
A coil sensitivities container based on the GadgetronImagesVector class.
Definition: gadgetron_data_containers.h:1508
Definition: DataContainer.h:42
Definition: gadgetron_data_containers.h:1232
Definition: gadgetron_data_containers.h:1160
A vector implementation of the abstract Gadgetron image data container class.
Definition: gadgetron_data_containers.h:1152
virtual bool is_complex() const
Is complex?
Definition: gadgetron_data_containers.cpp:2251
virtual void set_up_geom_info()
Populate the geometrical info metadata (from the image's own metadata)
Definition: gadgetron_data_containers.cpp:2352
virtual void reorient(const VoxelisedGeometricalInfo3D &geom_info_out)
Reorient image. Requires that dimensions match.
Definition: gadgetron_data_containers.cpp:2259
std::unique_ptr< GadgetronImagesVector > clone() const
Clone and return as unique pointer.
Definition: gadgetron_data_containers.h:1447
void print_header(const unsigned im_num)
Print header info.
Definition: gadgetron_data_containers.cpp:2214
Abstract Gadgetron image data container class.
Definition: gadgetron_data_containers.h:853
void set_meta_data(const AcquisitionsInfo &acqs_info)
Set the meta data.
Definition: gadgetron_data_containers.cpp:1990
virtual void xapyb(const DataContainer &a_x, const void *ptr_a, const DataContainer &a_y, const DataContainer &a_b)
*this = elementwise sum of x*a and elementwise y*b
Definition: gadgetron_data_containers.h:971
virtual void conjugate_impl()
we assume data to be real, complex data containers must override this
Definition: gadgetron_data_containers.cpp:1935
virtual void multiply(const DataContainer &x, const DataContainer &y)
*this = the elementwise product x*y
Definition: gadgetron_data_containers.cpp:1577
virtual void exp(const DataContainer &x)
*this = the elementwise exp(x)
Definition: gadgetron_data_containers.cpp:1663
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: gadgetron_data_containers.h:963
virtual void minimum(const DataContainer &x, const DataContainer &y)
*this = the elementwise min(x, y)
Definition: gadgetron_data_containers.cpp:1627
virtual float norm() const
returns the norm of this container viewed as a vector
Definition: gadgetron_data_containers.cpp:1698
virtual void maximum(const DataContainer &x, const DataContainer &y)
*this = the elementwise max(x, y)
Definition: gadgetron_data_containers.cpp:1609
virtual void sqrt(const DataContainer &x)
*this = the elementwise sqrt(x)
Definition: gadgetron_data_containers.cpp:1677
virtual void log(const DataContainer &x)
*this = the elementwise log(x)
Definition: gadgetron_data_containers.cpp:1670
virtual void max(void *ptr) const
calculates the value of this container's element with the largest real part
Definition: gadgetron_data_containers.cpp:1454
virtual void divide(const DataContainer &x, const DataContainer &y)
*this = the elementwise ratio x / y
Definition: gadgetron_data_containers.cpp:1601
virtual void xapyb(const DataContainer &a_x, const DataContainer &a_a, const DataContainer &a_y, const DataContainer &a_b)
*this = elementwise sum of two elementwise products x*a and y*b
Definition: gadgetron_data_containers.h:987
virtual ISMRMRDImageData * clone_impl() const =0
Clone helper function. Don't use.
virtual void dot(const DataContainer &dc, void *ptr) const
calculates the dot product of this container with another one
Definition: gadgetron_data_containers.cpp:1427
virtual void add(const DataContainer &x, const void *ptr_y)
*this = the sum x + y with scalar y
Definition: gadgetron_data_containers.cpp:1593
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: gadgetron_data_containers.cpp:1470
virtual void power(const DataContainer &x, const DataContainer &y)
*this = the elementwise pow(x, y)
Definition: gadgetron_data_containers.cpp:1645
virtual void sign(const DataContainer &x)
*this = the elementwise sign(x)
Definition: gadgetron_data_containers.cpp:1684
const AcquisitionsInfo & get_meta_data() const
Get the meta data.
Definition: gadgetron_data_containers.h:1073
virtual void sum(void *ptr) const
below all void* are actually complex_float_t*
Definition: gadgetron_data_containers.cpp:1441
Class enabling ignoring acquisitions with certain ISMRMRD acquisition flags.
Definition: gadgetron_data_containers.h:132
Definition: ImageData.h:52
Definition: ImageData.h:44
Definition: ImageData.h:38
Definition: gadgetron_image_wrap.h:179
Definition: gadgetron_image_wrap.h:108
Wrapper for ISMRMRD::Image.
Definition: gadgetron_image_wrap.h:106
Class to keep track of order in k-space.
Definition: gadgetron_data_containers.h:203
static TagType get_tag_from_img(const CFImage &img)
Function to get k-space dimension tag from an ISMRMRD::Image.
Definition: gadgetron_data_containers.cpp:1374
static TagType get_tag_from_acquisition(ISMRMRD::Acquisition acq)
Function to get k-space dimension tag from an ISMRMRD::Acquisition.
Definition: gadgetron_data_containers.cpp:1393
Abstract MR acquisition data container class.
Definition: gadgetron_data_containers.h:276
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: gadgetron_data_containers.h:617
std::vector< KSpaceSubset::SetType > get_kspace_order() const
Function to get the indices of the acquisitions belonging to different dimensions of k-space.
Definition: gadgetron_data_containers.cpp:1142
std::vector< KSpaceSubset > get_kspace_sorting() const
Function to get the all KSpaceSubset's of the MRAcquisitionData.
Definition: gadgetron_data_containers.h:701
virtual float norm() const
returns the norm of this container viewed as a vector
Definition: gadgetron_data_containers.cpp:1056
void read(const std::string &filename_ismrmrd_with_ext, int all=0)
Reader for ISMRMRD::Acquisition from ISMRMRD file. In case the ISMRMRD::Dataset constructor throws an...
Definition: gadgetron_data_containers.cpp:99
void organise_kspace()
Function to go through Acquisitions and assign them to their k-space dimension.
Definition: gadgetron_data_containers.cpp:1172
void set_encoding_limits(const std::string &name, const std::tuple< unsigned short, unsigned short, unsigned short > min_max_ctr)
Setter for the encoding limits in the header of the acquisition. inputs: name, name of k-space dimens...
Definition: gadgetron_data_containers.h:496
Definition: ANumRef.h:140
Definition: GeometricalInfo.h:50
Specification file for a wrapper class for ISMRMRD::Image.
Abstract data container.
Definition: GeometricalInfo.cpp:141
bool iequals(const std::string &a, const std::string &b)
Case insensitive string comparison, replaces boost::iequals.
Definition: iequals.cpp:7