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 long int mask = (1 << 18)) :
135 ignore_(mask), max_(8*
sizeof(mask)) {}
136 void set(
unsigned long long int mask)
140 void ignore(
unsigned int i)
142 if (i < 1 || i > max_)
144 unsigned long 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 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 long int one = 1;
159 return ignore_ & (one << (i - 1));
161 unsigned long long int bits()
const
165 bool ignored(
unsigned long long int bits)
const
167 return bits & ignore_;
169 std::string bits_string()
const
171 unsigned int size = max_;
172 unsigned long long int one = 1;
173 unsigned long 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 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);
312 static complex_float_t min(
const ISMRMRD::Acquisition& acq_x);
316 (
const ISMRMRD::Acquisition& acq_x, ISMRMRD::Acquisition& acq_y);
320 (
const ISMRMRD::Acquisition& acq_x, ISMRMRD::Acquisition& acq_y, complex_float_t y);
324 (
const ISMRMRD::Acquisition& acq_x, ISMRMRD::Acquisition& acq_y, complex_float_t y);
328 (
const ISMRMRD::Acquisition& acq_x, ISMRMRD::Acquisition& acq_y);
332 (
const ISMRMRD::Acquisition& acq_x, ISMRMRD::Acquisition& acq_y);
334 (
const ISMRMRD::Acquisition& acq_x, ISMRMRD::Acquisition& acq_y, complex_float_t y);
338 (
const ISMRMRD::Acquisition& acq_x, ISMRMRD::Acquisition& acq_y);
340 (
const ISMRMRD::Acquisition& acq_x, ISMRMRD::Acquisition& acq_y, complex_float_t y);
343 (
const ISMRMRD::Acquisition& acq_x, ISMRMRD::Acquisition& acq_y);
345 (
const ISMRMRD::Acquisition& acq_x, ISMRMRD::Acquisition& acq_y, complex_float_t y);
348 (
const ISMRMRD::Acquisition& acq_x, ISMRMRD::Acquisition& acq_y);
351 (
const ISMRMRD::Acquisition& acq_x, ISMRMRD::Acquisition& acq_y);
354 (
const ISMRMRD::Acquisition& acq_x, ISMRMRD::Acquisition& acq_y);
357 (
const ISMRMRD::Acquisition& acq_x, ISMRMRD::Acquisition& acq_y);
361 (
const ISMRMRD::Acquisition& acq_x, ISMRMRD::Acquisition& acq_y);
362 static float norm(
const ISMRMRD::Acquisition& acq_x);
365 static void ismrmrd_par_info(
const char* par,
int* output)
383 output[1] = ISMRMRD::ISMRMRD_Constants::ISMRMRD_PHYS_STAMPS;
385 output[1] = ISMRMRD::ISMRMRD_Constants::ISMRMRD_CHANNEL_MASKS;
394 output[1] = ISMRMRD::ISMRMRD_Constants::ISMRMRD_USER_INTS;
396 output[1] = ISMRMRD::ISMRMRD_Constants::ISMRMRD_USER_FLOATS;
399 static void ismrmrd_par_value(ISMRMRD::Acquisition& acq,
400 const char* name,
unsigned long long int* v)
403 *v = ((
unsigned int)acq.version());
405 *v = ((
unsigned long long int)acq.flags());
407 *v = ((
unsigned int)acq.measurement_uid());
409 *v = ((
unsigned int)acq.scan_counter());
411 *v = ((
unsigned int)acq.acquisition_time_stamp());
413 *v = ((
unsigned int)acq.number_of_samples());
415 *v = ((
unsigned int)acq.available_channels());
417 *v = ((
unsigned int)acq.active_channels());
419 *v = ((
unsigned int)acq.discard_pre());
421 *v = ((
unsigned int)acq.discard_post());
423 *v = ((
unsigned int)acq.center_sample());
425 *v = ((
unsigned int)acq.encoding_space_ref());
427 *v = ((
unsigned int)acq.trajectory_dimensions());
429 *v = ((
unsigned int)acq.idx().kspace_encode_step_1);
431 *v = ((
unsigned int)acq.idx().kspace_encode_step_2);
433 *v = ((
unsigned int)acq.idx().average);
435 *v = ((
unsigned int)acq.idx().slice);
437 *v = ((
unsigned int)acq.idx().contrast);
439 *v = ((
unsigned int)acq.idx().phase);
441 *v = ((
unsigned int)acq.idx().repetition);
443 *v = ((
unsigned int)acq.idx().set);
445 *v = ((
unsigned int)acq.idx().segment);
447 int n = ISMRMRD::ISMRMRD_Constants::ISMRMRD_PHYS_STAMPS;
448 const uint32_t* pts = acq.physiology_time_stamp();
449 for (
int i = 0; i < n; i++)
450 v[i] = (
unsigned int)pts[i];
453 int n = ISMRMRD::ISMRMRD_Constants::ISMRMRD_CHANNEL_MASKS;
454 const uint64_t* pts = acq.channel_mask();
455 for (
int i = 0; i < n; i++)
456 v[i] = (
unsigned long long int)pts[i];
460 static void ismrmrd_par_value(ISMRMRD::Acquisition& acq,
461 const char* name,
float* v)
464 *v = acq.sample_time_us();
466 float* u = acq.position();
467 for (
int i = 0; i < 3; i++)
471 float* u = acq.read_dir();
472 for (
int i = 0; i < 3; i++)
476 float* u = acq.phase_dir();
477 for (
int i = 0; i < 3; i++)
481 float* u = acq.slice_dir();
482 for (
int i = 0; i < 3; i++)
486 float* u = acq.patient_table_position();
487 for (
int i = 0; i < 3; i++)
498 const std::tuple<unsigned short,unsigned short,unsigned short> min_max_ctr)
500 ISMRMRD::IsmrmrdHeader hdr = this->acquisitions_info().get_IsmrmrdHeader();
501 ISMRMRD::EncodingLimits enc_limits = hdr.encoding[0].encodingLimits;
503 ISMRMRD::Limit limit;
504 limit.minimum = std::get<0>(min_max_ctr);
505 limit.maximum = std::get<1>(min_max_ctr);
506 limit.center = std::get<2>(min_max_ctr);
509 enc_limits.kspace_encoding_step_1.get() = limit;
511 enc_limits.kspace_encoding_step_2.get() = limit;
513 enc_limits.average.get() = limit;
515 enc_limits.slice.get() = limit;
517 enc_limits.contrast.get() = limit;
519 enc_limits.phase.get() = limit;
521 enc_limits.repetition.get() = limit;
523 enc_limits.set.get() = limit;
525 enc_limits.segment.get() = limit;
527 throw std::runtime_error(
"You passed a name that is not an encoding limit.");
529 hdr.encoding[0].encodingLimits = enc_limits;
530 std::stringstream serialised_hdr;
531 ISMRMRD::serialize(hdr, serialised_hdr);
535 std::tuple<unsigned short,unsigned short,unsigned short>
536 get_encoding_limits(
const std::string& name)
const
538 ISMRMRD::IsmrmrdHeader hdr = this->acquisitions_info().get_IsmrmrdHeader();
539 ISMRMRD::EncodingLimits enc_limits = hdr.encoding[0].encodingLimits;
541 ISMRMRD::Limit limit;
544 limit = enc_limits.kspace_encoding_step_1.get();
546 limit = enc_limits.kspace_encoding_step_2.get();
548 limit = enc_limits.average.get();
550 limit = enc_limits.slice.get();
552 limit = enc_limits.contrast.get();
554 limit = enc_limits.phase.get();
556 limit = enc_limits.repetition.get();
558 limit = enc_limits.set.get();
560 limit = enc_limits.segment.get();
562 throw std::runtime_error(
"You passed a name that is not an encoding limit.");
564 return std::make_tuple(limit.minimum, limit.maximum, limit.center);
569 virtual void empty() = 0;
570 virtual void take_over(MRAcquisitionData&) = 0;
573 virtual unsigned int number()
const = 0;
575 virtual gadgetron::shared_ptr<ISMRMRD::Acquisition>
576 get_acquisition_sptr(
unsigned int num) = 0;
577 virtual int get_acquisition(
unsigned int,
578 ISMRMRD::Acquisition&)
const = 0;
579 virtual void set_acquisition(
unsigned int,
580 ISMRMRD::Acquisition&) = 0;
581 virtual void append_acquisition(ISMRMRD::Acquisition& acq) = 0;
583 virtual void copy_acquisitions_info(
const MRAcquisitionData& ac) = 0;
584 virtual void copy_acquisitions_data(
const MRAcquisitionData& ac) = 0;
587 virtual gadgetron::unique_ptr<MRAcquisitionData> new_acquisitions_container() = 0;
588 virtual MRAcquisitionData*
589 same_acquisitions_container(
const AcquisitionsInfo& info)
const = 0;
591 virtual void set_data(
const complex_float_t* z,
int all = 1) = 0;
592 virtual void get_data(complex_float_t* z,
int all = 1);
594 virtual void set_user_floats(
float const *
const z,
int const idx);
596 virtual bool is_complex()
const
603 virtual void sum(
void* ptr)
const;
604 virtual void max(
void* ptr)
const;
605 virtual void min(
void* ptr)
const;
606 virtual void dot(
const DataContainer& dc,
void* ptr)
const;
607 complex_float_t dot(
const DataContainer& a_x)
614 const void* ptr_a,
const DataContainer& a_x,
615 const void* ptr_b,
const DataContainer& a_y);
617 const DataContainer& a_x,
const DataContainer& a_a,
618 const DataContainer& a_y,
const DataContainer& a_b);
623 axpby(ptr_a, a_x, ptr_b, a_y);
633 virtual void multiply(
const DataContainer& x,
const void* y);
643 virtual float norm()
const;
645 virtual void write(
const std::string &filename)
const;
649 void(*f)(
const ISMRMRD::Acquisition&, ISMRMRD::Acquisition&));
650 void semibinary_op(
const DataContainer& a_x, complex_float_t y,
651 void(*f)(
const ISMRMRD::Acquisition&, ISMRMRD::Acquisition&, complex_float_t));
653 void(*f)(
const ISMRMRD::Acquisition&, ISMRMRD::Acquisition&));
656 void set_acquisitions_info(std::string info) { acqs_info_ = info; }
657 void set_acquisitions_info(
const AcquisitionsInfo info) { acqs_info_ = info;}
658 IgnoreMask ignore_mask()
const {
return ignore_mask_; }
659 void set_ignore_mask(IgnoreMask ignore_mask)
const { ignore_mask_= ignore_mask; }
661 ISMRMRD::TrajectoryType get_trajectory_type()
const;
663 void set_trajectory_type(
const ISMRMRD::TrajectoryType type);
665 void set_trajectory(
const uint16_t traj_dim,
float* traj)
667 ISMRMRD::Acquisition acq;
668 for(
int i=0; i<number(); ++i)
670 get_acquisition(i, acq);
671 const uint16_t num_samples = acq.number_of_samples();
672 const uint16_t num_channels = acq.active_channels();
673 acq.resize(num_samples,num_channels,traj_dim);
674 int const offset = i*traj_dim*num_samples;
675 acq.setTraj(traj + offset);
676 set_acquisition(i, acq);
680 gadgetron::unique_ptr<MRAcquisitionData> clone()
const
682 return gadgetron::unique_ptr<MRAcquisitionData>(this->clone_impl());
685 bool undersampled()
const;
686 int get_acquisitions_dimensions(
size_t ptr_dim)
const;
687 void get_kspace_dimensions(std::vector<size_t>& dims)
const;
688 uint16_t get_trajectory_dimensions(
void)
const;
692 bool sorted()
const {
return sorted_; }
693 void set_sorted(
bool sorted) { sorted_ = sorted; }
714 virtual std::vector<int> get_flagged_acquisitions_index
715 (
const std::vector<ISMRMRD::ISMRMRD_AcquisitionFlags> flags)
const;
716 virtual std::vector<int> get_slice_encoding_index
717 (
const unsigned kspace_encode_step_2)
const;
719 virtual void get_subset(
MRAcquisitionData& subset,
const std::vector<int> subset_idx)
const;
720 virtual void set_subset(
const MRAcquisitionData &subset,
const std::vector<int> subset_idx);
722 std::vector<int> index() {
return index_; }
723 const std::vector<int>& index()
const {
return index_; }
725 int index(
int i)
const
727 const std::size_t ni = index_.size();
728 if (i < 0 || (ni > 0 &&
static_cast<std::size_t
>(i) >= ni)
729 ||
static_cast<unsigned>(i) >= number())
730 THROW(
"Aquisition number is out of range");
747 void read(
const std::string& filename_ismrmrd_with_ext,
int all = 0);
750 bool sorted_ =
false;
751 std::vector<int> index_;
752 std::vector<KSpaceSubset> sorting_;
753 AcquisitionsInfo acqs_info_;
755 mutable IgnoreMask ignore_mask_;
759 static gadgetron::shared_ptr<MRAcquisitionData> acqs_templ_;
761 virtual MRAcquisitionData* clone_impl()
const = 0;
779 this->set_ignore_mask(ignore_mask);
780 this->
read(filename_with_ext, all);
785 this->set_ignore_mask(ignore_mask);
788 virtual void empty();
790 virtual unsigned int number()
const {
return (
unsigned int)acqs_.size(); }
791 virtual unsigned int items()
const {
return (
unsigned int)acqs_.size(); }
792 virtual void append_acquisition(ISMRMRD::Acquisition& acq)
794 acqs_.push_back(gadgetron::shared_ptr<ISMRMRD::Acquisition>
795 (
new ISMRMRD::Acquisition(acq)));
797 virtual gadgetron::shared_ptr<ISMRMRD::Acquisition>
798 get_acquisition_sptr(
unsigned int num)
800 int ind = index(num);
803 virtual int get_acquisition(
unsigned int num,
804 ISMRMRD::Acquisition& acq)
const
807 int ind = index(num);
809 if (ignore_mask.ignored(acq.flags()))
813 virtual void set_acquisition(
unsigned int num, ISMRMRD::Acquisition& acq)
815 int ind = index(num);
820 acqs_info_ = ac.acquisitions_info();
823 virtual void set_data(
const complex_float_t* z,
int all = 1);
834 (gadgetron::shared_ptr<DataContainer>(ptr));
836 virtual gadgetron::unique_ptr<MRAcquisitionData>
837 new_acquisitions_container()
839 return gadgetron::unique_ptr<MRAcquisitionData>
844 std::vector<gadgetron::shared_ptr<ISMRMRD::Acquisition> > acqs_;
846 virtual void conjugate_impl();
860 virtual void empty() = 0;
861 virtual unsigned int number()
const = 0;
862 virtual gadgetron::shared_ptr<ImageWrap> sptr_image_wrap
863 (
unsigned int im_num) = 0;
864 virtual gadgetron::shared_ptr<const ImageWrap> sptr_image_wrap
865 (
unsigned int im_num)
const = 0;
868 virtual void append(
int image_data_type,
void* ptr_image) = 0;
869 virtual void append(
const ImageWrap& iw) = 0;
870 virtual void append(gadgetron::shared_ptr<ImageWrap> sptr_iw) = 0;
871 virtual gadgetron::shared_ptr<ISMRMRDImageData> abs()
const = 0;
872 virtual gadgetron::shared_ptr<ISMRMRDImageData> real()
const = 0;
873 virtual void clear_data() = 0;
874 virtual void set_image_type(
int imtype) = 0;
875 virtual void get_data(complex_float_t* data)
const;
876 virtual void set_data(
const complex_float_t* data);
877 virtual void get_real_data(
float* data)
const;
878 virtual void set_real_data(
const float* data);
879 virtual int read(std::string filename, std::string variable =
"",
int iv = -1);
880 virtual void write(
const std::string &filename,
const std::string &groupname,
const bool dicom)
const;
881 virtual void write(
const std::string &filename)
const
883 size_t size = filename.size();
884 std::string suff = filename.substr(size - 4, 4);
885 if (suff == std::string(
".dcm")) {
886 std::string prefix = filename.substr(0, size - 4);
887 this->write(prefix,
"",
true);
890 auto found = filename.find_last_of(
"/\\");
891 auto slash_found = found;
892 if (found == std::string::npos)
893 found = filename.find_last_of(
".");
895 found = filename.substr(found + 1).find_last_of(
".");
896 if (found == std::string::npos)
897 this->write(filename +
".h5",
"",
false);
899 std::string ext = filename.substr(slash_found + found + 1);
900 if (ext == std::string(
".h5"))
901 this->write(filename,
"",
false);
903 std::cerr <<
"WARNING: writing ISMRMRD images to "
904 << ext <<
"-files not implemented, "
905 <<
"please convert to Nifti images\n";
909 virtual Dimensions dimensions()
const
922 virtual void get_image_dimensions(
unsigned int im_num,
int* dim)
const
924 if (im_num >= number())
925 dim[0] = dim[1] = dim[2] = dim[3] = 0;
926 const ImageWrap& iw = image_wrap(im_num);
929 bool check_dimension_consistency()
const
931 size_t const num_dims = 4;
932 std::vector<int> first_img_dims(num_dims), temp_img_dims(num_dims);
934 this->get_image_dimensions(0, &first_img_dims[0]);
936 bool dims_match =
true;
937 for(
int i=1; i<number(); ++i)
939 this->get_image_dimensions(0, &temp_img_dims[0]);
940 dims_match *= (first_img_dims == temp_img_dims);
944 virtual gadgetron::shared_ptr<ISMRMRDImageData>
945 new_images_container()
const = 0;
946 virtual gadgetron::shared_ptr<ISMRMRDImageData>
947 clone(
const char* attr,
const char* target) = 0;
948 virtual int image_data_type(
unsigned int im_num)
const
950 return image_wrap(im_num).type();
952 virtual size_t num_data_elm()
const
954 return image_wrap(0).num_data_elm();
957 virtual float norm()
const;
959 virtual void sum(
void* ptr)
const;
960 virtual void max(
void* ptr)
const;
961 virtual void min(
void* ptr)
const;
970 ComplexFloat_ a(*
static_cast<const complex_float_t*
>(ptr_a));
971 ComplexFloat_ b(*
static_cast<const complex_float_t*
>(ptr_b));
972 xapyb_(a_x, a, a_y, b);
978 ComplexFloat_ a(*
static_cast<const complex_float_t*
>(ptr_a));
980 xapyb_(a_x, a, a_y, b);
996 xapyb_(a_x, a, a_y, b);
1016 complex_float_t(*f)(complex_float_t, complex_float_t));
1019 complex_float_t(*f)(complex_float_t, complex_float_t));
1020 void unary_op(
const DataContainer& a_x, complex_float_t(*f)(complex_float_t));
1023 void scale(
float s);
1031 complex_float_t a,
const DataContainer& a_x,
1032 complex_float_t b,
const DataContainer& a_y)
1034 axpby(&a, a_x, &b, a_y);
1037 const DataContainer& a_x, complex_float_t a,
1038 const DataContainer& a_y, complex_float_t b)
1040 xapyb(a_x, &a, a_y, &b);
1042 gadgetron::unique_ptr<ISMRMRDImageData> clone()
const
1044 return gadgetron::unique_ptr<ISMRMRDImageData>(this->
clone_impl());
1047 virtual void sort() = 0;
1048 bool sorted()
const {
return sorted_; }
1049 void set_sorted(
bool sorted) { sorted_ = sorted; }
1050 std::vector<int> index() {
return index_; }
1051 const std::vector<int>& index()
const {
return index_; }
1052 int index(
int i)
const
1054 const std::size_t ni = index_.size();
1055 if (i < 0 || (ni > 0 &&
static_cast<std::size_t
>(i) >= ni) ||
static_cast<unsigned>(i) >= number())
1056 THROW(
"Image number is out of range. You tried to look up an image number that is not inside the container.");
1062 ImageWrap& image_wrap(
unsigned int im_num)
1064 gadgetron::shared_ptr<ImageWrap> sptr_iw = sptr_image_wrap(im_num);
1067 const ImageWrap& image_wrap(
unsigned int im_num)
const
1069 const gadgetron::shared_ptr<const ImageWrap>& sptr_iw =
1070 sptr_image_wrap(im_num);
1080 std::vector<int> index_;
1087 class ComplexFloat_ {
1089 ComplexFloat_(complex_float_t v) : v_(v) {}
1090 unsigned int number()
const
1094 complex_float_t image_wrap(
unsigned int i)
1098 size_t num_data_elm()
1106 template<
class A,
class B>
1107 void xapyb_(
const DataContainer& a_x, A& a,
const DataContainer& a_y, B& b)
1109 SIRF_DYNAMIC_CAST(
const ISMRMRDImageData, x, a_x);
1110 SIRF_DYNAMIC_CAST(
const ISMRMRDImageData, y, a_y);
1111 unsigned int nx = x.number();
1112 unsigned int na = a.number();
1113 unsigned int ny = y.number();
1114 unsigned int nb = b.number();
1118 THROW(
"ImageData sizes mismatch in axpby");
1119 if (na > 0 && na != nx)
1120 THROW(
"ImageData sizes mismatch in axpby");
1121 if (nb > 0 && nb != nx)
1122 THROW(
"ImageData sizes mismatch in axpby");
1123 unsigned int n = number();
1126 THROW(
"ImageData sizes mismatch in axpby");
1127 for (
unsigned int i = 0; i < nx; i++)
1128 image_wrap(i).xapyb(x.image_wrap(i), a.image_wrap(i),
1129 y.image_wrap(i), b.image_wrap(i));
1132 for (
unsigned int i = 0; i < nx; i++) {
1133 const ImageWrap& u = x.image_wrap(i);
1134 const ImageWrap& v = y.image_wrap(i);
1136 w.xapyb(u, a.image_wrap(i), v, b.image_wrap(i));
1145 typedef ISMRMRDImageData GadgetronImageData;
1159 typedef std::vector<gadgetron::shared_ptr<ImageWrap> >::iterator
1161 typedef std::vector<gadgetron::shared_ptr<ImageWrap> >::const_iterator
1162 ImageWrapIter_const;
1166 iw_(iw), n_(n), i_(i), iter_(it), end_((**iw).end())
1169 iter_(iter.iter_), end_(iter.end_), sptr_iter_(iter.sptr_iter_)
1178 sptr_iter_ = iter.sptr_iter_;
1181 virtual bool operator==(
const BaseIter& ai)
const
1183 SIRF_DYNAMIC_CAST(
const Iterator, i, ai);
1184 return iter_ == i.iter_;
1186 virtual bool operator!=(
const BaseIter& ai)
const
1188 SIRF_DYNAMIC_CAST(
const Iterator, i, ai);
1189 return iter_ != i.iter_;
1193 if (i_ >= n_ || (i_ == n_ - 1 && iter_ == end_))
1194 throw std::out_of_range(
"cannot advance out-of-range iterator");
1196 if (iter_ == end_ && i_ < n_ - 1) {
1199 iter_ = (**iw_).begin();
1200 end_ = (**iw_).end();
1206 sptr_iter_.reset(
new Iterator(*
this));
1207 if (i_ >= n_ || (i_ == n_ - 1 && iter_ == end_))
1208 throw std::out_of_range(
"cannot advance out-of-range iterator");
1210 if (iter_ == end_ && i_ < n_ - 1) {
1213 iter_ = (**iw_).begin();
1214 end_ = (**iw_).end();
1220 if (i_ >= n_ || (i_ == n_ - 1 && iter_ == end_))
1221 throw std::out_of_range
1222 (
"cannot dereference out-of-range iterator");
1232 gadgetron::shared_ptr<Iterator> sptr_iter_;
1239 iw_(iw), n_(n), i_(i), iter_(it), end_((**iw).end_const())
1242 n_(iter.n_), i_(iter.i_),
1243 iter_(iter.iter_), end_(iter.end_), sptr_iter_(iter.sptr_iter_)
1252 sptr_iter_ = iter.sptr_iter_;
1258 return iter_ == i.iter_;
1263 return iter_ != i.iter_;
1267 if (i_ >= n_ || (i_ == n_ - 1 && iter_ == end_))
1268 throw std::out_of_range(
"cannot advance out-of-range iterator");
1270 if (iter_ == end_ && i_ < n_ - 1) {
1273 iter_ = (**iw_).begin_const();
1274 end_ = (**iw_).end_const();
1293 const NumRef& operator*()
const
1295 if (i_ >= n_ || (i_ == n_ - 1 && iter_ == end_))
1296 throw std::out_of_range
1297 (
"cannot dereference out-of-range iterator");
1304 ImageWrapIter_const iw_;
1310 gadgetron::shared_ptr<Iterator_const> sptr_iter_;
1329 const char* target);
1330 virtual void empty()
1334 virtual unsigned int items()
const
1336 return (
unsigned int)images_.size();
1338 virtual unsigned int number()
const
1340 return (
unsigned int)images_.size();
1342 virtual void append(
int image_data_type,
void* ptr_image)
1344 images_.push_back(gadgetron::shared_ptr<ImageWrap>
1345 (
new ImageWrap(image_data_type, ptr_image)));
1347 virtual void append(CFImage& img)
1349 void* vptr_img =
new CFImage(img);
1350 this->append(7, vptr_img);
1352 virtual void append(
const ImageWrap& iw)
1354 images_.push_back(gadgetron::shared_ptr<ImageWrap>(
new ImageWrap(iw)));
1356 virtual void append(gadgetron::shared_ptr<ImageWrap> sptr_iw)
1358 images_.push_back(sptr_iw);
1360 virtual gadgetron::shared_ptr<GadgetronImageData> abs()
const;
1361 virtual gadgetron::shared_ptr<GadgetronImageData> real()
const;
1362 virtual void clear_data()
1364 std::vector<gadgetron::shared_ptr<ImageWrap> > empty_data;
1365 images_.swap(empty_data);
1367 virtual void sort();
1368 virtual gadgetron::shared_ptr<ImageWrap> sptr_image_wrap
1369 (
unsigned int im_num)
1371 int i = index(im_num);
1372 return images_.at(i);
1374 virtual gadgetron::shared_ptr<const ImageWrap> sptr_image_wrap
1375 (
unsigned int im_num)
const
1377 int i = index(im_num);
1378 return images_.at(i);
1395 (gadgetron::shared_ptr<DataContainer>(new_images_container()));
1397 virtual gadgetron::shared_ptr<GadgetronImageData> new_images_container()
const
1399 gadgetron::shared_ptr<GadgetronImageData> sptr_img
1400 ((GadgetronImageData*)
new GadgetronImagesVector());
1404 virtual gadgetron::shared_ptr<GadgetronImageData>
1405 clone(
const char* attr,
const char* target)
1407 return gadgetron::shared_ptr<GadgetronImageData>
1408 (
new GadgetronImagesVector(*
this, attr, target));
1411 virtual Iterator& begin()
1413 ImageWrapIter iw = images_.begin();
1414 begin_.reset(
new Iterator(iw, images_.size(), 0, (**iw).begin()));
1417 virtual Iterator& end()
1419 ImageWrapIter iw = images_.begin();
1420 int n = images_.size();
1421 for (
int i = 0; i < n - 1; i++)
1423 end_.reset(
new Iterator(iw, n, n - 1, (**iw).end()));
1426 virtual Iterator_const& begin()
const
1428 ImageWrapIter_const iw = images_.begin();
1430 (
new Iterator_const(iw, images_.size(), 0, (**iw).begin_const()));
1431 return *begin_const_;
1433 virtual Iterator_const& end()
const
1435 ImageWrapIter_const iw = images_.begin();
1436 int n = images_.size();
1437 for (
int i = 0; i < n - 1; i++)
1440 (
new Iterator_const(iw, n, n - 1, (**iw).end_const()));
1443 virtual void set_image_type(
int image_type);
1444 virtual void get_data(complex_float_t* data)
const;
1445 virtual void set_data(
const complex_float_t* data);
1446 virtual void get_real_data(
float* data)
const;
1447 virtual void set_real_data(
const float* data);
1450 std::unique_ptr<GadgetronImagesVector>
clone()
const
1452 return std::unique_ptr<GadgetronImagesVector>(this->clone_impl());
1474 std::vector<gadgetron::shared_ptr<ImageWrap> > images_;
1475 mutable gadgetron::shared_ptr<Iterator> begin_;
1476 mutable gadgetron::shared_ptr<Iterator> end_;
1477 mutable gadgetron::shared_ptr<Iterator_const> begin_const_;
1478 mutable gadgetron::shared_ptr<Iterator_const> end_const_;
1492 std::unique_ptr<MRAcquisitionData> extract_calibration_data(
const MRAcquisitionData& ad)
const;
1493 gadgetron::shared_ptr<FourierEncoding> sptr_enc_;
1520 throw std::runtime_error(
"This has not been implemented yet.");
1523 void set_csm_smoothness(
int s)
1525 csm_smoothness_ = s;
1527 void set_csm_conv_kernel_size(
int w)
1529 csm_conv_kernel_halfsize_ = w;
1540 CFImage get_csm_as_cfimage(
size_t const i)
const;
1541 CFImage get_csm_as_cfimage(
const KSpaceSubset::TagType tag,
const int offset)
const;
1544 void get_dim(
size_t const num_csm,
int* dim)
const
1546 GadgetronImagesVector::get_image_dimensions(num_csm, dim);
1557 void calculate_csm(ISMRMRD::NDArray<complex_float_t>& cm, ISMRMRD::NDArray<float>& img, ISMRMRD::NDArray<complex_float_t>& csm);
1560 int csm_smoothness_ = 0;
1561 int csm_conv_kernel_halfsize_ = 1;
1562 void smoothen_(
int nx,
int ny,
int nz,
int nc, complex_float_t* u, complex_float_t* v,
1565 void mask_noise_(
int nx,
int ny,
int nz,
float* u,
float noise,
int* mask);
1566 float max_diff_(
int nx,
int ny,
int nz,
int nc,
float small_grad, complex_float_t* u, complex_float_t* v);
1567 float max_(
int nx,
int ny,
int nz,
float* u);
1571 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:775
A coil images container based on the GadgetronImagesVector class.
Definition: gadgetron_data_containers.h:1487
A coil sensitivities container based on the GadgetronImagesVector class.
Definition: gadgetron_data_containers.h:1511
Abstract data container with numerical operations.
Definition: DataContainer.h:58
Definition: gadgetron_data_containers.h:1235
Definition: gadgetron_data_containers.h:1163
A vector implementation of the abstract Gadgetron image data container class.
Definition: gadgetron_data_containers.h:1155
virtual bool is_complex() const
Is complex?
Definition: gadgetron_data_containers.cpp:2316
virtual void set_up_geom_info()
Populate the geometrical info metadata (from the image's own metadata)
Definition: gadgetron_data_containers.cpp:2417
virtual void reorient(const VoxelisedGeometricalInfo3D &geom_info_out)
Reorient image. Requires that dimensions match.
Definition: gadgetron_data_containers.cpp:2324
std::unique_ptr< GadgetronImagesVector > clone() const
Clone and return as unique pointer.
Definition: gadgetron_data_containers.h:1450
void print_header(const unsigned im_num)
Print header info.
Definition: gadgetron_data_containers.cpp:2279
Abstract Gadgetron image data container class.
Definition: gadgetron_data_containers.h:855
virtual void min(void *ptr) const
calculates the value of this container's element with the smallest real part
Definition: gadgetron_data_containers.cpp:1519
void set_meta_data(const AcquisitionsInfo &acqs_info)
Set the meta data.
Definition: gadgetron_data_containers.cpp:2055
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:974
virtual void conjugate_impl()
we assume data to be real, complex data containers must override this
Definition: gadgetron_data_containers.cpp:2000
virtual void multiply(const DataContainer &x, const DataContainer &y)
*this = the elementwise product x*y
Definition: gadgetron_data_containers.cpp:1642
virtual void exp(const DataContainer &x)
*this = the elementwise exp(x)
Definition: gadgetron_data_containers.cpp:1728
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:966
virtual void minimum(const DataContainer &x, const DataContainer &y)
*this = the elementwise min(x, y)
Definition: gadgetron_data_containers.cpp:1692
virtual float norm() const
returns the norm of this container viewed as a vector
Definition: gadgetron_data_containers.cpp:1763
virtual void maximum(const DataContainer &x, const DataContainer &y)
*this = the elementwise max(x, y)
Definition: gadgetron_data_containers.cpp:1674
virtual void sqrt(const DataContainer &x)
*this = the elementwise sqrt(x)
Definition: gadgetron_data_containers.cpp:1742
virtual void log(const DataContainer &x)
*this = the elementwise log(x)
Definition: gadgetron_data_containers.cpp:1735
virtual void max(void *ptr) const
calculates the value of this container's element with the largest real part
Definition: gadgetron_data_containers.cpp:1503
virtual void divide(const DataContainer &x, const DataContainer &y)
*this = the elementwise ratio x / y
Definition: gadgetron_data_containers.cpp:1666
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:990
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:1476
virtual void add(const DataContainer &x, const void *ptr_y)
*this = the sum x + y with scalar y
Definition: gadgetron_data_containers.cpp:1658
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:1535
virtual void power(const DataContainer &x, const DataContainer &y)
*this = the elementwise pow(x, y)
Definition: gadgetron_data_containers.cpp:1710
virtual void sign(const DataContainer &x)
*this = the elementwise sign(x)
Definition: gadgetron_data_containers.cpp:1749
const AcquisitionsInfo & get_meta_data() const
Get the meta data.
Definition: gadgetron_data_containers.h:1076
virtual void sum(void *ptr) const
below all void* are actually complex_float_t*
Definition: gadgetron_data_containers.cpp:1490
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:1423
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:1442
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:619
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:1191
std::vector< KSpaceSubset > get_kspace_sorting() const
Function to get the all KSpaceSubset's of the MRAcquisitionData.
Definition: gadgetron_data_containers.h:703
virtual float norm() const
returns the norm of this container viewed as a vector
Definition: gadgetron_data_containers.cpp:1105
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:1221
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:497
Definition: ANumRef.h:140
Definition: GeometricalInfo.h:50
Specification file for a wrapper class for ISMRMRD::Image.
Abstract base class for SIRF image data.
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