[ismrmrd] 05/177: Starting to flesh out C interface.
Ghislain Vaillant
ghisvail-guest at moszumanska.debian.org
Wed Jan 14 20:01:55 UTC 2015
This is an automated email from the git hooks/post-receive script.
ghisvail-guest pushed a commit to annotated tag v1.1.0.beta.1
in repository ismrmrd.
commit d27929d26c8e376ebcd248dab53591e48db37590
Author: Souheil Inati <souheil.inati at nih.gov>
Date: Sat Jul 19 22:41:07 2014 -0400
Starting to flesh out C interface.
---
ismrmrd.c | 382 +++++++++++++
ismrmrd.h | 1419 +++++++++-------------------------------------
ismrmrd_hdf5.h | 8 +-
ismrmrd_hdf5_datatypes.h | 345 +----------
4 files changed, 667 insertions(+), 1487 deletions(-)
diff --git a/ismrmrd.c b/ismrmrd.c
new file mode 100644
index 0000000..e64b854
--- /dev/null
+++ b/ismrmrd.c
@@ -0,0 +1,382 @@
+#include <ismrmrd.h>
+
+#ifdef __cplusplus
+namespace ISMRMRD
+{
+extern "C" {
+#endif
+
+ /**********************/
+ /* Acquisition Header */
+ /**********************/
+ void InitAcquisitionHeader(AcquisitionHeader* hdr)
+ {
+ memset(hdr, 0, sizeof(AcquisitionHeader));
+ hdr->version = ISMRMRD_VERSION;
+ hdr->number_of_samples = 0;
+ hdr->available_channels = 1;
+ hdr->active_channels = 1;
+ }
+
+ /***************/
+ /* Acquisition */
+ /***************/
+ void InitAcquisition(Acquisition* acq) {
+ InitAcquisitionHeader(&(acq->head));
+ acq->traj = NULL;
+ acq->data = NULL;
+ }
+
+ void CopyAcquisition(Acquisition* acqdest, const Acquisition* acqsource) {
+ memcpy(&(acqdest->head), &(acqsource->head), sizeof(AcquisitionHeader));
+ MakeConsistentAcquisition(acqdest);
+ memcpy(&(acqdest->traj), &(acqsource->traj), acqdest->head.number_of_samples * acqdest->head.trajectory_dimensions * sizeof(acqdest->traj));
+ memcpy(&(acqdest->data), &(acqsource->data), acqdest->head.number_of_samples * acqdest->head.active_channels * sizeof(acqdest->data));
+ }
+
+ void FreeAcquisition(Acquisition* acq) {
+ free(acq->data);
+ free(acq->traj);
+ free(acq);
+ }
+
+ void MakeConsistentAcquisition(Acquisition* acq) {
+ if (acq->head.available_channels < acq->head.active_channels) {
+ acq->head.available_channels = acq->head.active_channels;
+ }
+
+ int num_traj = acq->head.number_of_samples * acq->head.trajectory_dimensions;
+ if (num_traj > 0) {
+ acq->traj = (float *) realloc(acq->traj, num_traj * sizeof(acq->traj));
+ }
+
+ int num_data = acq->head.number_of_samples * acq->head.active_channels;
+ if (num_data > 0) {
+ acq->data = (complex_float_t *)realloc(acq->data, num_data * sizeof(acq->data));
+ }
+ }
+
+ /****************/
+ /* Image Header */
+ /****************/
+ void InitImageHeader(ImageHeader* hdr) {
+ memset(hdr, 0, sizeof(ImageHeader));
+ hdr->version = ISMRMRD_VERSION;
+ hdr->matrix_size[0] = 0;
+ hdr->matrix_size[1] = 1;
+ hdr->matrix_size[2] = 1;
+ hdr->channels = 1;
+ }
+
+
+ /*********/
+ /* Image */
+ /*********/
+ void InitImage(Image* im) {
+ InitImageHeader(&(im->head));
+ im->attribute_string = NULL;
+ im->data = NULL;
+ }
+
+ void FreeImage(Image* im) {
+ free(im->data);
+ free(im->attribute_string);
+ free(im);
+ }
+
+ int SizeOfImageData(const Image* im) {
+ int data_size = 0;
+ int num_data = im->head.matrix_size[0] * im->head.matrix_size[1] * im->head.matrix_size[2] * im->head.channels;
+ if (num_data > 0) {
+ switch (im->head.data_type) {
+ case DATA_UNSIGNED_SHORT:
+ data_size =num_data * sizeof(uint16_t);
+ break;
+ case DATA_SHORT:
+ data_size = num_data * sizeof(int16_t);
+ break;
+ case DATA_UNSIGNED_INT:
+ data_size = num_data * sizeof(uint32_t);
+ break;
+ case DATA_INT:
+ data_size = num_data * sizeof(int32_t);
+ break;
+ case DATA_FLOAT:
+ data_size = num_data * sizeof(float);
+ break;
+ case DATA_DOUBLE:
+ data_size = num_data * sizeof(double);
+ break;
+ case DATA_COMPLEX_FLOAT:
+ data_size = num_data * sizeof(complex_float_t);
+ break;
+ case DATA_COMPLEX_DOUBLE:
+ data_size = num_data * sizeof(complex_double_t);
+ break;
+ }
+ }
+ return data_size;
+ }
+
+ int SizeOfImageAttributeString(const Image* im) {
+ int attribute_string_size = 0;
+ if (im->head.attribute_string_len > 0) {
+ attribute_string_size = im->head.attribute_string_len * sizeof(im->attribute_string);
+ }
+ return attribute_string_size;
+ }
+
+ void MakeConsistentImage(Image* im) {
+ int attr_size = SizeOfImageAttributeString(im);
+ if (attr_size > 0) {
+ im->attribute_string = (char *) realloc(im->attribute_string, attr_size);
+ }
+ int data_size = SizeOfImageData(im);
+ if (data_size > 0) {
+ im->data = realloc(im->data, data_size);
+ }
+ }
+
+ void CopyImage(Image* imdest, const Image* imsource) {
+ memcpy(&(imdest->head), &(imsource->head), sizeof(ImageHeader));
+ MakeConsistentImage(imdest);
+ int attr_size = SizeOfImageAttributeString(imdest);
+ if (attr_size > 0) {
+ memcpy(&(imdest->attribute_string), &(imsource->attribute_string), attr_size);
+ }
+ int data_size = SizeOfImageData(imdest);
+ if (data_size > 0) {
+ memcpy(&(imdest->data), &(imsource->data), data_size);
+ }
+ }
+
+ /***********/
+ /* NDArray */
+ /***********/
+ void InitNDArray(NDArray* arr) {
+ arr->version = ISMRMRD_VERSION;
+ arr->data_type = 0; // no default data type
+ arr->ndim = 0;
+ for (int n=0; n<ISMRMRD_NDARRAY_MAXDIM; n++) {
+ arr->dims[n] = 1;
+ }
+ arr->data = NULL;
+ }
+
+ void FreeNDArray(NDArray* arr) {
+ free(arr->data);
+ free(arr);
+ }
+
+ int SizeOfNDArrayData(const NDArray* arr) {
+ int data_size = 0;
+ int num_data = 1;
+ for (int n=0; n<ISMRMRD_NDARRAY_MAXDIM; n++) {
+ num_data *= arr->dims[n];
+ }
+ if (num_data > 0) {
+ switch (arr->data_type) {
+ case DATA_UNSIGNED_SHORT:
+ data_size = num_data * sizeof(uint16_t);
+ break;
+ case DATA_SHORT:
+ data_size = num_data * sizeof(int16_t);
+ break;
+ case DATA_UNSIGNED_INT:
+ data_size = num_data * sizeof(uint32_t);
+ break;
+ case DATA_INT:
+ data_size = num_data * sizeof(int32_t);
+ break;
+ case DATA_FLOAT:
+ data_size = num_data * sizeof(float);
+ break;
+ case DATA_DOUBLE:
+ data_size = num_data * sizeof(double);
+ break;
+ case DATA_COMPLEX_FLOAT:
+ data_size= num_data * sizeof(complex_float_t);
+ break;
+ case DATA_COMPLEX_DOUBLE:
+ data_size = num_data * sizeof(complex_double_t);
+ break;
+ }
+ }
+ return data_size;
+ }
+
+ void MakeConsistentNDArray(NDArray* arr) {
+ int data_size = SizeOfNDArrayData(arr);
+ if (data_size > 0) {
+ arr->data = realloc(arr->data, data_size);
+ }
+ }
+
+ void CopyNDArray(NDArray* arrdest, const NDArray* arrsource) {
+ arrdest->version = arrsource->version;
+ arrdest->data_type = arrsource->data_type;
+ arrdest->ndim = arrsource->ndim;
+ for (int n=0; n<ISMRMRD_NDARRAY_MAXDIM; n++) {
+ arrdest->dims[n] = arrsource->dims[n];
+ }
+ MakeConsistentNDArray(arrdest);
+ int data_size = SizeOfNDArrayData(arrdest);
+ if (data_size > 0) {
+ memcpy(&(arrdest->data), &(arrsource->data), SizeOfNDArrayData(arrdest));
+ }
+ }
+
+
+ /******************************/
+ /* Flag convenience functions */
+ /******************************/
+ bool flags_is_set(const uint64_t flags, const uint64_t val) {
+ uint64_t bitmask = 1;
+ bitmask = (bitmask << (val-1));
+ return ((flags & bitmask) > 0);
+ }
+
+ void flags_set(uint64_t* flags, const uint64_t val) {
+ uint64_t bitmask = 1;
+ bitmask = (bitmask << (val-1));
+ *flags |= bitmask;
+ }
+
+ void flags_clear(uint64_t* flags, const uint64_t val) {
+ uint64_t bitmask = 1;
+ bitmask = (bitmask << (val-1));
+ if (flags_is_set(*flags, val)) {
+ *flags &= ~bitmask;
+ };
+ }
+
+ void flags_clear_all(uint64_t* flags) {
+ *flags = 0;
+ }
+
+ /******************************/
+ /* Quaternions and Rotations */
+ /******************************/
+
+ /**
+ * Calculates the determinant of the matrix and return the sign
+ */
+ int sign_of_directions(float read_dir[3], float phase_dir[3], float slice_dir[3])
+ {
+ float r11 = read_dir[0], r12 = phase_dir[0], r13 = slice_dir[0];
+ float r21 = read_dir[1], r22 = phase_dir[1], r23 = slice_dir[1];
+ float r31 = read_dir[2], r32 = phase_dir[2], r33 = slice_dir[2];
+
+ /* Determinant should be 1 or -1 */
+ float deti = (r11 * r22 * r33) + (r12 * r23 * r31) + (r21 * r32 * r13) -
+ (r13 * r22 * r31) - (r12 * r21 * r33) - (r11 * r23 * r32);
+
+ if (deti < 0) {
+ return -1;
+ } else {
+ return 1;
+ }
+ }
+
+ /**
+ * Creates a normalized quaternion from a 3x3 rotation matrix
+ */
+ void directions_to_quaternion(float read_dir[3], float phase_dir[3],
+ float slice_dir[3], float quat[4])
+ {
+ float r11 = read_dir[0], r12 = phase_dir[0], r13 = slice_dir[0];
+ float r21 = read_dir[1], r22 = phase_dir[1], r23 = slice_dir[1];
+ float r31 = read_dir[2], r32 = phase_dir[2], r33 = slice_dir[2];
+
+ double a = 1, b = 0, c = 0, d = 0, s = 0;
+ double trace = 0;
+ double xd, yd, zd;
+
+ /* verify the sign of the rotation*/
+ if (sign_of_directions(read_dir, phase_dir, slice_dir) < 0) {
+ /* flip 3rd column */
+ r13 = -r13;
+ r23 = -r23;
+ r33 = -r33;
+ }
+
+ /* Compute quaternion parameters */
+ /* http://www.cs.princeton.edu/~gewang/projects/darth/stuff/quat_faq.html#Q55 */
+ trace = 1.0l + r11 + r22 + r33;
+ if (trace > 0.00001l) { /* simplest case */
+ s = sqrt(trace) * 2;
+ a = (r32 - r23) / s;
+ b = (r13 - r31) / s;
+ c = (r21 - r12) / s;
+ d = 0.25l * s;
+ } else {
+ /* trickier case...
+ * determine which major diagonal element has
+ * the greatest value... */
+ xd = 1.0 + r11 - (r22 + r33); /* 4**b**b */
+ yd = 1.0 + r22 - (r11 + r33); /* 4**c**c */
+ zd = 1.0 + r33 - (r11 + r22); /* 4**d**d */
+ /* if r11 is the greatest */
+ if (xd > 1.0) {
+ s = 2.0 * sqrt(xd);
+ a = 0.25l * s;
+ b = (r21 + r12) / s;
+ c = (r31 + r13) / s;
+ d = (r32 - r23) / s;
+ }
+ /* else if r22 is the greatest */
+ else if (yd > 1.0) {
+ s = 2.0 * sqrt(yd);
+ a = (r21 + r12) / s;
+ b = 0.25l * s;
+ c = (r32 + r23) / s;
+ d = (r13 - r31) / s;
+ }
+ /* else, r33 must be the greatest */
+ else {
+ s = 2.0 * sqrt(zd);
+ a = (r13 + r31) / s;
+ b = (r23 + r32) / s;
+ c = 0.25l * s;
+ d = (r21 - r12) / s;
+ }
+
+ if (a < 0.0l) {
+ b = -b;
+ c = -c;
+ d = -d;
+ a = -a;
+ }
+ }
+
+ quat[0] = (float)a; quat[1] = (float)b; quat[2] = (float)c; quat[3] = (float)d;
+ }
+
+ /**
+ * Converts a quaternion of the form | a b c d | to a
+ * 3x3 rotation matrix
+ *
+ * http://www.cs.princeton.edu/~gewang/projects/darth/stuff/quat_faq.html#Q54
+ */
+ void quaternion_to_directions(float quat[4], float read_dir[3],
+ float phase_dir[3], float slice_dir[3])
+ {
+ float a = quat[0], b = quat[1], c = quat[2], d = quat[3];
+
+ read_dir[0] = 1.0f - 2.0f * ( b*b + c*c );
+ phase_dir[0] = 2.0f * ( a*b - c*d );
+ slice_dir[0] = 2.0f * ( a*c + b*d );
+
+ read_dir[1] = 2.0f * ( a*b + c*d );
+ phase_dir[1] = 1.0f - 2.0f * ( a*a + c*c );
+ slice_dir[1] = 2.0f * ( b*c - a*d );
+
+ read_dir[2] = 2.0f * ( a*c - b*d );
+ phase_dir[2] = 2.0f * ( b*c + a*d );
+ slice_dir[2] = 1.0f - 2.0f * ( a*a + b*b );
+ }
+
+#ifdef __cplusplus
+} //End of extern C
+} //End of namespace
+#endif
diff --git a/ismrmrd.h b/ismrmrd.h
index 33defe4..d9db4cb 100644
--- a/ismrmrd.h
+++ b/ismrmrd.h
@@ -13,1198 +13,319 @@
#ifndef ISMRMRD_H
#define ISMRMRD_H
-/* Cross platform section for defining integer types */
-#ifndef ISMRMRD_HAS_BASIC_TYPES
+/* Language and Cross platform section for defining types */
+#ifdef __cplusplus
+
#ifdef _MSC_VER
+// MS C++ Compiler
typedef __int16 int16_t;
typedef unsigned __int16 uint16_t;
typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
+
#else
-#include <stdint.h>
-#include <math.h>
-#endif
+// non MS C++ compiler
+#include <cstdint>
#endif
-#ifdef __cplusplus
-#include <stdio.h>
-#include <string.h>
-#include <exception>
-#include <iostream>
-#include <vector>
-#include <valarray>
+#include <cstdlib>
+#include <cstring>
#include <complex>
-#include <assert.h>
-#endif
+#include <cmath>
+typedef std::complex<float> complex_float_t;
+typedef std::complex<double> complex_double_t;
-#pragma pack(push, 2) //Use 2 byte alignment
+#else
+// C99 compiler
+#include <stdint.h>
+#include <complex.h>
+#include <math.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdbool.h>
+typedef float complex complex_float_t;
+typedef double complex complex_double_t;
-#define ISMRMRD_VERSION 1
-#define ISMRMRD_POSITION_LENGTH 3
-#define ISMRMRD_DIRECTION_LENGTH 3
-#define ISMRMRD_USER_INTS 8
-#define ISMRMRD_USER_FLOATS 8
-#define ISMRMRD_PHYS_STAMPS 8 //TODO: This should be changed to 3 (Major impact)
-#define ISMRMRD_CHANNEL_MASKS 16
+#endif // __cplusplus
-#ifdef __cplusplus
-namespace ISMRMRD
-{
+#pragma pack(push, 2) // Use 2 byte alignment
+
+#define ISMRMRD_VERSION 1
+#define ISMRMRD_POSITION_LENGTH 3
+#define ISMRMRD_DIRECTION_LENGTH 3
+#define ISMRMRD_USER_INTS 8
+#define ISMRMRD_USER_FLOATS 8
+#define ISMRMRD_PHYS_STAMPS 3
+#define ISMRMRD_CHANNEL_MASKS 16
+#define ISMRMRD_NDARRAY_MAXDIM 7
-class FlagBit
-{
-public:
- FlagBit(unsigned short b)
- : bitmask_(0)
- {
- if (b > 0) {
- bitmask_ = 1;
- bitmask_ = (bitmask_ << (b-1));
- }
- }
-
- bool isSet(const uint64_t& m) const {
- return ((m & bitmask_)>0);
- }
-
- uint64_t bitmask_;
-
+#ifdef __cplusplus
+namespace ISMRMRD {
+#endif //__cplusplus
+
+/**************/
+/* Data Types */
+/**************/
+enum DataTypes {
+ DATA_UNSIGNED_SHORT = 1, // corresponds to uint16_t
+ DATA_SHORT, // corresponds to int16_t
+ DATA_UNSIGNED_INT, // corresponds to uint32_t
+ DATA_INT, // corresponds to int32_t
+ DATA_FLOAT, // corresponds to float
+ DATA_DOUBLE, // corresponds to double
+ DATA_COMPLEX_FLOAT, // corresponds to complex float
+ DATA_COMPLEX_DOUBLE, // corresponds to complex double
};
-#endif //__cplusplus
+
+/****************/
+/* Acquisitions */
+/****************/
/** ACQUISITION FLAGS */
enum AcquisitionFlags {
- /* Looping indicators */
- ACQ_FIRST_IN_ENCODE_STEP1 = 1,
- ACQ_LAST_IN_ENCODE_STEP1 = 2,
- ACQ_FIRST_IN_ENCODE_STEP2 = 3,
- ACQ_LAST_IN_ENCODE_STEP2 = 4,
- ACQ_FIRST_IN_AVERAGE = 5,
- ACQ_LAST_IN_AVERAGE = 6,
- ACQ_FIRST_IN_SLICE = 7,
- ACQ_LAST_IN_SLICE = 8,
- ACQ_FIRST_IN_CONTRAST = 9,
- ACQ_LAST_IN_CONTRAST = 10,
- ACQ_FIRST_IN_PHASE = 11,
- ACQ_LAST_IN_PHASE = 12,
- ACQ_FIRST_IN_REPETITION = 13,
- ACQ_LAST_IN_REPETITION = 14,
- ACQ_FIRST_IN_SET = 15,
- ACQ_LAST_IN_SET = 16,
- ACQ_FIRST_IN_SEGMENT = 17,
- ACQ_LAST_IN_SEGMENT = 18,
- ACQ_IS_NOISE_MEASUREMENT = 19,
- ACQ_IS_PARALLEL_CALIBRATION = 20,
- ACQ_IS_PARALLEL_CALIBRATION_AND_IMAGING = 21,
- ACQ_IS_REVERSE = 22,
- ACQ_IS_NAVIGATION_DATA = 23,
- ACQ_IS_PHASECORR_DATA = 24,
- ACQ_LAST_IN_MEASUREMENT = 25,
- ACQ_IS_HPFEEDBACK_DATA = 26,
- ACQ_IS_DUMMYSCAN_DATA = 27,
- ACQ_IS_RTFEEDBACK_DATA = 28,
- ACQ_IS_SURFACECOILCORRECTIONSCAN_DATA = 29,
-
- ACQ_USER1 = 57,
- ACQ_USER2 = 58,
- ACQ_USER3 = 59,
- ACQ_USER4 = 60,
- ACQ_USER5 = 61,
- ACQ_USER6 = 62,
- ACQ_USER7 = 63,
- ACQ_USER8 = 64
+ /* Looping indicators */
+ ACQ_FIRST_IN_ENCODE_STEP1 = 1,
+ ACQ_LAST_IN_ENCODE_STEP1 = 2,
+ ACQ_FIRST_IN_ENCODE_STEP2 = 3,
+ ACQ_LAST_IN_ENCODE_STEP2 = 4,
+ ACQ_FIRST_IN_AVERAGE = 5,
+ ACQ_LAST_IN_AVERAGE = 6,
+ ACQ_FIRST_IN_SLICE = 7,
+ ACQ_LAST_IN_SLICE = 8,
+ ACQ_FIRST_IN_CONTRAST = 9,
+ ACQ_LAST_IN_CONTRAST = 10,
+ ACQ_FIRST_IN_PHASE = 11,
+ ACQ_LAST_IN_PHASE = 12,
+ ACQ_FIRST_IN_REPETITION = 13,
+ ACQ_LAST_IN_REPETITION = 14,
+ ACQ_FIRST_IN_SET = 15,
+ ACQ_LAST_IN_SET = 16,
+ ACQ_FIRST_IN_SEGMENT = 17,
+ ACQ_LAST_IN_SEGMENT = 18,
+ ACQ_IS_NOISE_MEASUREMENT = 19,
+ ACQ_IS_PARALLEL_CALIBRATION = 20,
+ ACQ_IS_PARALLEL_CALIBRATION_AND_IMAGING = 21,
+ ACQ_IS_REVERSE = 22,
+ ACQ_IS_NAVIGATION_DATA = 23,
+ ACQ_IS_PHASECORR_DATA = 24,
+ ACQ_LAST_IN_MEASUREMENT = 25,
+ ACQ_IS_HPFEEDBACK_DATA = 26,
+ ACQ_IS_DUMMYSCAN_DATA = 27,
+ ACQ_IS_RTFEEDBACK_DATA = 28,
+ ACQ_IS_SURFACECOILCORRECTIONSCAN_DATA = 29,
+ ACQ_USER1 = 57,
+ ACQ_USER2 = 58,
+ ACQ_USER3 = 59,
+ ACQ_USER4 = 60,
+ ACQ_USER5 = 61,
+ ACQ_USER6 = 62,
+ ACQ_USER7 = 63,
+ ACQ_USER8 = 64
};
/**
- Struct used for keeping track of typical loop counters in MR experiment.
-
- */
+ Struct used for keeping track of typical loop counters in MR experiment.
+*/
typedef struct EncodingCounters {
- uint16_t kspace_encode_step_1; /**< e.g. phase encoding line number */
- uint16_t kspace_encode_step_2; /**< e.g. partition encodning number */
- uint16_t average; /**< e.g. signal average number */
- uint16_t slice; /**< e.g. imaging slice number */
- uint16_t contrast; /**< e.g. echo number in multi-echo */
- uint16_t phase; /**< e.g. cardiac phase number */
- uint16_t repetition; /**< e.g. dynamic number for dynamic scanning */
- uint16_t set; /**< e.g. flow encodning set */
- uint16_t segment; /**< e.g. segment number for segmented acquisition */
- uint16_t user[ISMRMRD_USER_INTS]; /**< Free user parameters */
+ uint16_t kspace_encode_step_1; /**< e.g. phase encoding line number */
+ uint16_t kspace_encode_step_2; /**< e.g. partition encodning number */
+ uint16_t average; /**< e.g. signal average number */
+ uint16_t slice; /**< e.g. imaging slice number */
+ uint16_t contrast; /**< e.g. echo number in multi-echo */
+ uint16_t phase; /**< e.g. cardiac phase number */
+ uint16_t repetition; /**< e.g. dynamic number for dynamic scanning */
+ uint16_t set; /**< e.g. flow encodning set */
+ uint16_t segment; /**< e.g. segment number for segmented acquisition */
+ uint16_t user[ISMRMRD_USER_INTS]; /**< Free user parameters */
} EncodingCounters;
/**
- Header for each MR acquisition.
- */
-typedef struct AcquisitionHeader
-{
- uint16_t version; /**< First unsigned int indicates the version */
- uint64_t flags; /**< bit field with flags */
- uint32_t measurement_uid; /**< Unique ID for the measurement */
- uint32_t scan_counter; /**< Current acquisition number in the measurement */
- uint32_t acquisition_time_stamp; /**< Acquisition clock */
- uint32_t physiology_time_stamp[ISMRMRD_PHYS_STAMPS]; /**< Physiology time stamps, e.g. ecg, breating, etc. */
- uint16_t number_of_samples; /**< Number of samples acquired */
- uint16_t available_channels; /**< Available coils */
- uint16_t active_channels; /**< Active coils on current acquisiton */
- uint64_t channel_mask[ISMRMRD_CHANNEL_MASKS]; /**< Mask to indicate which channels are active. Support for 1024 channels */
- uint16_t discard_pre; /**< Samples to be discarded at the beginning of acquisition */
- uint16_t discard_post; /**< Samples to be discarded at the end of acquisition */
- uint16_t center_sample; /**< Sample at the center of k-space */
- uint16_t encoding_space_ref; /**< Reference to an encoding space, typically only one per acquisition */
- uint16_t trajectory_dimensions; /**< Indicates the dimensionality of the trajectory vector (0 means no trajectory) */
- float sample_time_us; /**< Time between samples in micro seconds, sampling BW */
- float position[ISMRMRD_POSITION_LENGTH]; /**< Three-dimensional spatial offsets from isocenter */
- float read_dir[ISMRMRD_DIRECTION_LENGTH]; /**< Directional cosines of the readout/frequency encoding */
- float phase_dir[ISMRMRD_DIRECTION_LENGTH]; /**< Directional cosines of the phase */
- float slice_dir[ISMRMRD_DIRECTION_LENGTH]; /**< Directional cosines of the slice direction */
- float patient_table_position[ISMRMRD_POSITION_LENGTH]; /**< Patient table off-center */
- EncodingCounters idx; /**< Encoding loop counters, see above */
- int32_t user_int[ISMRMRD_USER_INTS]; /**< Free user parameters */
- float user_float[ISMRMRD_USER_FLOATS]; /**< Free user parameters */
+ Header for each MR acquisition.
+*/
+typedef struct AcquisitionHeader {
+ uint16_t version; /**< First unsigned int indicates the version */
+ uint64_t flags; /**< bit field with flags */
+ uint32_t measurement_uid; /**< Unique ID for the measurement */
+ uint32_t scan_counter; /**< Current acquisition number in the measurement */
+ uint32_t acquisition_time_stamp; /**< Acquisition clock */
+ uint32_t physiology_time_stamp[ISMRMRD_PHYS_STAMPS]; /**< Physiology time
+ stamps, e.g. ecg,
+ breating, etc. */
+ uint16_t number_of_samples; /**< Number of samples acquired */
+ uint16_t available_channels; /**< Available coils */
+ uint16_t active_channels; /**< Active coils on current acquisiton */
+ uint64_t
+ channel_mask
+ [ISMRMRD_CHANNEL_MASKS]; /**< Mask to indicate which channels are
+ active. Support for 1024 channels */
+ uint16_t discard_pre; /**< Samples to be discarded at the beginning of
+ acquisition */
+ uint16_t
+ discard_post; /**< Samples to be discarded at the end of acquisition */
+ uint16_t center_sample; /**< Sample at the center of k-space */
+ uint16_t encoding_space_ref; /**< Reference to an encoding space, typically
+ only one per acquisition */
+ uint16_t trajectory_dimensions; /**< Indicates the dimensionality of the
+ trajectory vector (0 means no trajectory)
+ */
+ float
+ sample_time_us; /**< Time between samples in micro seconds, sampling BW */
+ float position[ISMRMRD_POSITION_LENGTH]; /**< Three-dimensional spatial
+ offsets from isocenter */
+ float read_dir[ISMRMRD_DIRECTION_LENGTH]; /**< Directional cosines of the
+ readout/frequency encoding */
+ float phase_dir[ISMRMRD_DIRECTION_LENGTH]; /**< Directional cosines of the
+ phase */
+ float slice_dir[ISMRMRD_DIRECTION_LENGTH]; /**< Directional cosines of the
+ slice direction */
+ float patient_table_position[ISMRMRD_POSITION_LENGTH]; /**< Patient table
+ off-center */
+ EncodingCounters idx; /**< Encoding loop counters, see above */
+ int32_t user_int[ISMRMRD_USER_INTS]; /**< Free user parameters */
+ float user_float[ISMRMRD_USER_FLOATS]; /**< Free user parameters */
} AcquisitionHeader;
-enum ImageDataType
-{
- DATA_FLOAT = 1,
- DATA_DOUBLE,
- DATA_COMPLEX_FLOAT,
- DATA_COMPLEX_DOUBLE,
- DATA_UNSIGNED_SHORT
-};
+/* Initialize an Acquisition Header */
+void initAcquisitionHeader(AcquisitionHeader* hdr);
-enum ImageType
-{
- TYPE_MAGNITUDE = 1,
- TYPE_PHASE,
- TYPE_REAL,
- TYPE_IMAG,
- TYPE_COMPLEX
+/**
+ Individual MR acquisition.
+*/
+typedef struct Acquisition {
+ AcquisitionHeader head; /**< Header, see above */
+ float* traj;
+ complex_float_t* data;
+} Acquisition;
+
+void initAcquisition(Acquisition* acq);
+void copyAcquisition(Acquisition* acqdest, const Acquisition* acqsource);
+void freeAcquisition(Acquisition* acq);
+void makeConsistentAcquisition(Acquisition* acq);
+
+/**********/
+/* Images */
+/**********/
+
+enum ImageType {
+ TYPE_MAGNITUDE = 1,
+ TYPE_PHASE,
+ TYPE_REAL,
+ TYPE_IMAG,
+ TYPE_COMPLEX
};
/** IMAGE FLAGS */
enum ImageFlags {
- IMAGE_IS_NAVIGATION_DATA = 23,
-
- IMAGE_USER1 = 57,
- IMAGE_USER2 = 58,
- IMAGE_USER3 = 59,
- IMAGE_USER4 = 60,
- IMAGE_USER5 = 61,
- IMAGE_USER6 = 62,
- IMAGE_USER7 = 63,
- IMAGE_USER8 = 64
+ IMAGE_IS_NAVIGATION_DATA = 23,
+ IMAGE_USER1 = 57,
+ IMAGE_USER2 = 58,
+ IMAGE_USER3 = 59,
+ IMAGE_USER4 = 60,
+ IMAGE_USER5 = 61,
+ IMAGE_USER6 = 62,
+ IMAGE_USER7 = 63,
+ IMAGE_USER8 = 64
};
/**
- * Definition of ISMRM Raw Data Image structure
+ * Header for each Image
*/
-typedef struct ImageHeader
-{
- uint16_t version; /**< First unsigned int indicates the version */
- uint64_t flags; /**< bit field with flags */
- uint32_t measurement_uid; /**< Unique ID for the measurement */
- uint16_t matrix_size[3]; /**< Pixels in the 3 spatial dimensions */
- float field_of_view[3]; /**< Size (in mm) of the 3 spatial dimensions */
- uint16_t channels; /**< Number of receive channels */
- float position[ISMRMRD_POSITION_LENGTH]; /**< Three-dimensional spatial offsets from isocenter */
- float read_dir[ISMRMRD_DIRECTION_LENGTH]; /**< Directional cosines of the readout/frequency encoding */
- float phase_dir[ISMRMRD_DIRECTION_LENGTH]; /**< Directional cosines of the phase */
- float slice_dir[ISMRMRD_DIRECTION_LENGTH]; /**< Directional cosines of the slice direction */
- float patient_table_position[ISMRMRD_POSITION_LENGTH]; /**< Patient table off-center */
- uint16_t average; /**< e.g. signal average number */
- uint16_t slice; /**< e.g. imaging slice number */
- uint16_t contrast; /**< e.g. echo number in multi-echo */
- uint16_t phase; /**< e.g. cardiac phase number */
- uint16_t repetition; /**< e.g. dynamic number for dynamic scanning */
- uint16_t set; /**< e.g. flow encodning set */
- uint32_t acquisition_time_stamp; /**< Acquisition clock */
- uint32_t physiology_time_stamp[ISMRMRD_PHYS_STAMPS]; /**< Physiology time stamps, e.g. ecg, breating, etc. */
- uint16_t image_data_type; /**< e.g. unsigned short, float, complex float, etc. */
- uint16_t image_type; /**< e.g. magnitude, phase, complex, real, imag, etc. */
- uint16_t image_index; /**< e.g. image number in series of images */
- uint16_t image_series_index; /**< e.g. series number */
- int32_t user_int[ISMRMRD_USER_INTS]; /**< Free user parameters */
- float user_float[ISMRMRD_USER_FLOATS]; /**< Free user parameters */
+typedef struct ImageHeader {
+ uint16_t version; /**< First unsigned int indicates the version */
+ uint16_t data_type; /**< e.g. unsigned short, float, complex float, etc. */
+ uint64_t flags; /**< bit field with flags */
+ uint32_t measurement_uid; /**< Unique ID for the measurement */
+ uint16_t matrix_size[3]; /**< Pixels in the 3 spatial dimensions */
+ float field_of_view[3]; /**< Size (in mm) of the 3 spatial dimensions */
+ uint16_t channels; /**< Number of receive channels */
+ float position[ISMRMRD_POSITION_LENGTH]; /**< Three-dimensional spatial
+ offsets from isocenter */
+ float read_dir[ISMRMRD_DIRECTION_LENGTH]; /**< Directional cosines of the
+ readout/frequency encoding */
+ float phase_dir[ISMRMRD_DIRECTION_LENGTH]; /**< Directional cosines of the
+ phase */
+ float slice_dir[ISMRMRD_DIRECTION_LENGTH]; /**< Directional cosines of the
+ slice direction */
+ float patient_table_position[ISMRMRD_POSITION_LENGTH]; /**< Patient table
+ off-center */
+ uint16_t average; /**< e.g. signal average number */
+ uint16_t slice; /**< e.g. imaging slice number */
+ uint16_t contrast; /**< e.g. echo number in multi-echo */
+ uint16_t phase; /**< e.g. cardiac phase number */
+ uint16_t repetition; /**< e.g. dynamic number for dynamic scanning */
+ uint16_t set; /**< e.g. flow encodning set */
+ uint32_t acquisition_time_stamp; /**< Acquisition clock */
+ uint32_t physiology_time_stamp[ISMRMRD_PHYS_STAMPS]; /**< Physiology time
+ stamps, e.g. ecg,
+ breating, etc. */
+ uint16_t image_type; /**< e.g. magnitude, phase, complex, real, imag, etc. */
+ uint16_t image_index; /**< e.g. image number in series of images */
+ uint16_t image_series_index; /**< e.g. series number */
+ int32_t user_int[ISMRMRD_USER_INTS]; /**< Free user parameters */
+ float user_float[ISMRMRD_USER_FLOATS]; /**< Free user parameters */
+ uint32_t attribute_string_len; /**< Length of attributes string */
} ImageHeader;
-#ifdef __cplusplus
-/**
- * Container for generic array. This structure is used through the HDF5 file interaction.
- */
-template <typename T> class NDArrayContainer {
-
-public:
- NDArrayContainer() {}
-
- /**
- * @brief Construct with dimensions and data
- */
- NDArrayContainer(const std::vector<unsigned int>& dimensions) {
- dimensions_ = dimensions;
- data_.resize(elements());
- }
-
- /**
- * @brief Construct with dimensions and data
- */
- NDArrayContainer(const std::vector<unsigned int>& dimensions, const T* d) {
- dimensions_ = dimensions;
- data_.resize(elements());
- memcpy(&data_[0],d,sizeof(T)*elements());
- }
-
- /**
- * @brief Construct with dimensions and preset value
- */
- NDArrayContainer(const std::vector<unsigned int>& dimensions, const std::valarray<T>& t) {
- dimensions_ = dimensions;
- data_.resize(elements());
- data_ = t;
- }
-
- virtual ~NDArrayContainer() {}
-
- std::vector<unsigned int> dimensions_; /**< Array with dimensions of the array. First dimension is fastest moving in the array */
- std::valarray<T> data_; /**< The data itself. A vector is used here for easy memory management */
-
- size_t elements() const {
- if (dimensions_.size() == 0) {
- return 0;
- }
- size_t elements = 1;
- std::vector<unsigned int>::const_iterator it = dimensions_.begin();
- while (it != dimensions_.end()) {
- elements *= *(it++);
- }
- return elements;
- }
-
- T& operator[] (const size_t& p) {
- return data_[p];
- }
-
- T operator[] (const size_t& p) const {
- return data_[p];
- }
-
- void resize (const size_t& s) {
- data_.resize(s);
- }
-
- void resize (const size_t& s, const T& t) {
- data_.resize(s,t);
- }
-
- bool is_consistent() const {
- return (elements() == data_.size());
- }
-
- size_t ndims() const {
- size_t i = 1, n_dimensions = 1;
- for (; i < dimensions_.size(); i++)
- n_dimensions += (size_t) (dimensions_[i] > 1);
- return n_dimensions;
- }
-
-};
+void initImageHeader(ImageHeader* hdr);
/**
- * Container for an image (header and data)
+ * An individual Image
*/
-template <typename T>
-class Image {
-
-public:
- Image(unsigned int matrix_size_x = 0,
- unsigned int matrix_size_y = 1,
- unsigned int matrix_size_z = 1,
- unsigned int channels = 1)
- {
- memset(&head_,0,sizeof(ImageHeader));
- head_.version = ISMRMRD_VERSION;
- head_.matrix_size[0] = matrix_size_x;
- head_.matrix_size[1] = matrix_size_y;
- head_.matrix_size[2] = matrix_size_z;
- head_.channels = channels;
- setSpecificDataType();
- makeConsistent();
- }
-
-
- Image(const Image& a) { // copy constructor
- if (this != &a) {
- head_ = a.head_;
- this->data_ = a.data_;
- makeConsistent();
- }
- }
-
- Image& operator=(const Image& a) {
- if (this != &a) {
- head_ = a.head_;
- this->data_ = a.data_;
- makeConsistent();
- }
- return *this;
- }
-
- ~Image() {}
-
- bool isFlagSet(FlagBit& f) const {
- return f.isSet(head_.flags);
- }
-
- void setFlag(FlagBit& f) {
- head_.flags |= f.bitmask_;
- }
-
- size_t getNumberOfElements() const {
- return head_.matrix_size[0]*
- head_.matrix_size[1]*
- head_.matrix_size[2]*
- head_.channels;
- }
-
-
- uint32_t getAcquisitionTimeStamp() const {
- return head_.acquisition_time_stamp;
- }
-
- void setAcquisitionTimeStamp(uint32_t acquisitionTimeStamp) {
- head_.acquisition_time_stamp = acquisitionTimeStamp;
- }
-
- uint16_t getAverage() const {
- return head_.average;
- }
-
- void setAverage(uint16_t average) {
- this->head_.average = average;
- }
-
- uint16_t getChannels() const {
- return head_.channels;
- }
-
- void setChannels(uint16_t channels) {
- this->head_.channels = channels;
- }
-
- uint16_t getContrast() const {
- return head_.contrast;
- }
-
- void setContrast(uint16_t contrast) {
- this->head_.contrast = contrast;
- }
-
- float getFieldOfViewX() const {
- return head_.field_of_view[0];
- }
-
- void setFieldOfViewX(float f) {
- head_.field_of_view[0] = f;
- }
-
- float getFieldOfViewY() const {
- return head_.field_of_view[1];
- }
-
- void setFieldOfViewY(float f) {
- head_.field_of_view[1] = f;
- }
-
- float getFieldOfViewZ() const {
- return head_.field_of_view[2];
- }
-
- void setFieldOfViewZ(float f) {
- head_.field_of_view[2] = f;
- }
-
- uint64_t getFlags() const {
- return head_.flags;
- }
-
- void setFlags(uint64_t flags) {
- this->head_.flags = flags;
- }
-
- uint16_t getImageDataType() const {
- return head_.image_data_type;
- }
-
- void setImageDataType(uint16_t imageDataType) {
- head_.image_data_type = imageDataType;
- }
-
- uint16_t getImageIndex() const {
- return head_.image_index;
- }
-
- void setImageIndex(uint16_t imageIndex) {
- head_.image_index = imageIndex;
- }
-
- uint16_t getImageSeriesIndex() const {
- return head_.image_series_index;
- }
-
- void setImageSeriesIndex(uint16_t imageSeriesIndex) {
- head_.image_series_index = imageSeriesIndex;
- }
-
- uint16_t getImageType() const {
- return head_.image_type;
- }
-
- void setImageType(uint16_t imageType) {
- head_.image_type = imageType;
- }
-
- uint16_t getMatrixSizeX() const {
- return head_.matrix_size[0];
- }
-
- void setMatrixSizeX(uint16_t s) {
- head_.matrix_size[0] = s;
- makeConsistent();
- }
-
- uint16_t getMatrixSizeY() const {
- return head_.matrix_size[1];
- }
-
- void setMatrixSizeY(uint16_t s) {
- head_.matrix_size[1] = s;
- makeConsistent();
- }
-
- uint16_t getMatrixSizeZ() const {
- return head_.matrix_size[2];
- }
-
- void setMatrixSizeZ(uint16_t s) {
- head_.matrix_size[2] = s;
- makeConsistent();
- }
-
-
- uint32_t getMeasurementUid() const {
- return head_.measurement_uid;
- }
-
- void setMeasurementUid(uint32_t measurementUid) {
- head_.measurement_uid = measurementUid;
- }
-
- const float getPatientTablePosition(unsigned int axis) const {
- if (axis < ISMRMRD_POSITION_LENGTH) {
- return head_.patient_table_position[axis];
- }
- return 0;
- }
-
- void setPatientTablePosition(unsigned int axis, float value) {
- if (axis < ISMRMRD_POSITION_LENGTH) {
- head_.patient_table_position[axis] = value;
- }
- }
-
- const uint32_t getPhysiologyTimeStamp(unsigned int stamp_id) const {
- if (stamp_id < ISMRMRD_PHYS_STAMPS) {
- return head_.physiology_time_stamp[stamp_id];
- }
- return 0;
- }
-
- void setPhysiologyTimeStamp(unsigned int stamp_id, uint32_t value){
- if (stamp_id < ISMRMRD_PHYS_STAMPS) {
- head_.physiology_time_stamp[stamp_id] = value;
- }
- }
-
- const float getPosition(unsigned int axis) const {
- if (axis < ISMRMRD_POSITION_LENGTH) {
- return head_.position[axis];
- }
- return 0;
- }
-
- void setPosition(unsigned int axis, float value){
- if (axis < ISMRMRD_POSITION_LENGTH) {
- head_.position[axis] = value;
- }
- }
-
- const float getReadDirection(unsigned int index) const {
- if (index < ISMRMRD_DIRECTION_LENGTH) {
- return head_.read_dir[index];
- }
- return 0;
- }
-
- void setReadDirection(unsigned int index, float value) {
- if (index < ISMRMRD_DIRECTION_LENGTH) {
- head_.read_dir[index] = value;
- }
- }
-
- const float getPhaseDirection(unsigned int index) const {
- if (index < ISMRMRD_DIRECTION_LENGTH) {
- return head_.phase_dir[index];
- }
- return 0;
- }
-
- void setPhaseDirection(unsigned int index, float value) {
- if (index < ISMRMRD_DIRECTION_LENGTH) {
- head_.phase_dir[index] = value;
- }
- }
-
- const float getSliceDirection(unsigned int index) const {
- if (index < ISMRMRD_DIRECTION_LENGTH) {
- return head_.slice_dir[index];
- }
- return 0;
- }
-
- void setSliceDirection(unsigned int index, float value) {
- if (index < ISMRMRD_DIRECTION_LENGTH) {
- head_.slice_dir[index] = value;
- }
- }
-
- uint16_t getPhase() const {
- return head_.phase;
- }
-
- void setPhase(uint16_t phase) {
- this->head_.phase = phase;
- }
-
-
- uint16_t getRepetition() const {
- return head_.repetition;
- }
-
- void setRepetition(uint16_t repetition) {
- this->head_.repetition = repetition;
- }
-
- uint16_t getSet() const {
- return head_.set;
- }
-
- void setSet(uint16_t set) {
- this->head_.set = set;
- }
-
- uint16_t getSlice() const {
- return head_.slice;
- }
-
- void setSlice(uint16_t slice) {
- this->head_.slice = slice;
- }
-
- const float getUserFloat(unsigned int index) const {
- if (index < ISMRMRD_USER_FLOATS) {
- return head_.user_float[index];
- }
- return 0.0f;
- }
-
- void setUserFloat(unsigned int index, float value) {
- if (index < ISMRMRD_USER_FLOATS) {
- head_.user_float[index] = value;
- }
- }
-
- const int32_t getUserInt(unsigned int index) const {
- if (index < ISMRMRD_USER_INTS) {
- return head_.user_int[index];
- }
- return 0;
- }
-
- void setUserInt(unsigned int index, int32_t value) {
- if (index < ISMRMRD_USER_INTS) {
- head_.user_int[index] = value;
- }
- }
-
- uint16_t getVersion() const {
- return head_.version;
- }
-
- void setVersion(uint16_t version) {
- this->head_.version = version;
- }
-
- const std::valarray<T>& getData() const {
- return data_;
- }
-
- void setData(const std::valarray<T>& data) {
- data_ = data;
- }
-
- const ImageHeader& getHead() const {
- return head_;
- }
-
- void setHead(const ImageHeader& head) {
- head_ = head;
- makeConsistent();
- }
-
- T& operator[] (const size_t& p) {
- return data_[p];
- }
-
- T operator[] (const size_t& p) const {
- return data_[p];
- }
-
-
-protected:
- ImageHeader head_; /**< ImageHeader as defined above */
- std::valarray<T> data_;
- void makeConsistent() {
- if (getNumberOfElements() != data_.size()) {
- data_.resize(getNumberOfElements());
- }
- }
-
- void setSpecificDataType();
-
-};
-
-template <> inline void Image<float>::setSpecificDataType() {
- head_.image_data_type = DATA_FLOAT;
-}
-
-template <> inline void Image<double>::setSpecificDataType() {
- head_.image_data_type = DATA_DOUBLE;
-}
-
-template <> inline void Image< std::complex<float> >::setSpecificDataType() {
- head_.image_data_type = DATA_COMPLEX_FLOAT;
-}
-
-template <> inline void Image< std::complex<double> >::setSpecificDataType() {
- head_.image_data_type = DATA_COMPLEX_DOUBLE;
-}
-
-template <> inline void Image< unsigned short >::setSpecificDataType() {
- head_.image_data_type = DATA_UNSIGNED_SHORT;
-}
-
-
-
-/**
- * @brief Single acquisition
- */
-
-/* TODO:
- * - Move data and traj to protected
- * - Check data and traj sizes when assigning number of samples, active channels, traj dimensions
- * - Check active channels when assigning channel bits
- * - Assign channel bits when assiging number of channels
- * - Change Image to have encapsulation
- * - Make Image Data Type Consistent with field.
- * - Test, test, test.
- */
-class Acquisition {
-
-public:
- Acquisition()
- : traj_(), data_() {
- memset(&head_,0,sizeof(AcquisitionHeader));
- head_.version = ISMRMRD_VERSION;
- }
-
- ~Acquisition() {}
-
- Acquisition (const Acquisition& a) { // copy constructor
- if (this != &a) {
- head_ = a.head_;
- data_.resize(a.data_.size());
- memcpy(&data_[0],&a.data_[0],sizeof(float)*a.data_.size());
- traj_.resize(a.traj_.size());
- memcpy(&traj_[0],&a.traj_[0],sizeof(float)*a.traj_.size());
- }
- }
-
- Acquisition& operator=(const Acquisition& a) {
- if (this != &a) {
- head_ = a.head_;
- data_.resize(a.data_.size());
- memcpy(&data_[0],&a.data_[0],sizeof(float)*a.data_.size());
- traj_.resize(a.traj_.size());
- memcpy(&traj_[0],&a.traj_[0],sizeof(float)*a.traj_.size());
- }
- return *this;
- }
-
- const AcquisitionHeader& getHead() {
- return head_;
- }
-
- void setHead(const AcquisitionHeader& h) {
- head_ = h;
- makeConsistent();
- }
-
- bool isFlagSet(const FlagBit& f) const {
- return f.isSet(head_.flags);
- }
-
- void setFlag(const FlagBit& f) {
- head_.flags |= f.bitmask_;
- }
-
- uint32_t getAcquisitionTimeStamp() const {
- return head_.acquisition_time_stamp;
- }
-
- void setAcquisitionTimeStamp(uint32_t acquisitionTimeStamp) {
- head_.acquisition_time_stamp = acquisitionTimeStamp;
- }
-
- uint16_t getActiveChannels() const {
- return head_.active_channels;
- }
-
- void setActiveChannels(uint16_t activeChannels) {
- head_.active_channels = activeChannels;
- makeConsistent();
- }
-
- uint16_t getAvailableChannels() const {
- return head_.available_channels;
- }
-
- void setAvailableChannels(uint16_t availableChannels) {
- head_.available_channels = availableChannels;
- }
-
- uint16_t getCenterSample() const {
- return head_.center_sample;
- }
-
- void setCenterSample(uint16_t centerSample) {
- head_.center_sample = centerSample;
- }
-
- bool isChannelActive(unsigned int channel_id) {
- if (channel_id < 64*ISMRMRD_CHANNEL_MASKS) {
- unsigned int mask_idx = channel_id>>6;
- unsigned int mask_bit = channel_id-mask_idx*64;
- return ((head_.channel_mask[mask_idx] & ( (uint64_t)1 << mask_bit)) > 0);
- }
- return false;
- }
-
- void setChannelActive(unsigned int channel_id) {
- if (channel_id < 64*ISMRMRD_CHANNEL_MASKS) {
- unsigned int mask_idx = channel_id>>6;
- unsigned int mask_bit = channel_id-mask_idx*64;
- head_.channel_mask[mask_idx] |= ( (uint64_t)1 << mask_bit);
- }
- }
-
- unsigned int getActiveChannelBits() {
- unsigned int bits = 0;
- for (unsigned int i = 0; i < ISMRMRD_CHANNEL_MASKS*64; i++) {
- if (isChannelActive(i)) {
- bits++;
- }
- }
- return bits;
- }
-
- uint16_t getDiscardPost() const {
- return head_.discard_post;
- }
-
- void setDiscardPost(uint16_t discardPost) {
- head_.discard_post = discardPost;
- }
-
- uint16_t getDiscardPre() const {
- return head_.discard_pre;
- }
-
- void setDiscardPre(uint16_t discardPre) {
- head_.discard_pre = discardPre;
- }
-
- uint16_t getEncodingSpaceRef() const {
- return head_.encoding_space_ref;
- }
-
- void setEncodingSpaceRef(uint16_t encodingSpaceRef) {
- head_.encoding_space_ref = encodingSpaceRef;
- }
-
- uint64_t getFlags() const {
- return head_.flags;
- }
-
- void setFlags(uint64_t flags) {
- this->head_.flags = flags;
- }
-
- EncodingCounters& getIdx() {
- return head_.idx;
- }
-
- void setIdx(const EncodingCounters& idx) {
- this->head_.idx = idx;
- }
-
- uint32_t getMeasurementUid() const {
- return head_.measurement_uid;
- }
-
- void setMeasurementUid(uint32_t measurementUid) {
- head_.measurement_uid = measurementUid;
- }
-
- uint16_t getNumberOfSamples() const {
- return head_.number_of_samples;
- }
-
- void setNumberOfSamples(uint16_t numberOfSamples) {
- head_.number_of_samples = numberOfSamples;
- makeConsistent();
- }
-
- const float getPatientTablePosition(unsigned int axis) const {
- if (axis < ISMRMRD_POSITION_LENGTH) {
- return head_.patient_table_position[axis];
- }
- return 0;
- }
-
- void setPatientTablePosition(unsigned int axis, float value) {
- if (axis < ISMRMRD_POSITION_LENGTH) {
- head_.patient_table_position[axis] = value;
- }
- }
-
- const uint32_t getPhysiologyTimeStamp(unsigned int stamp_id) const {
- if (stamp_id < ISMRMRD_PHYS_STAMPS) {
- return head_.physiology_time_stamp[stamp_id];
- }
- return 0;
- }
-
- void setPhysiologyTimeStamp(unsigned int stamp_id, uint32_t value){
- if (stamp_id < ISMRMRD_PHYS_STAMPS) {
- head_.physiology_time_stamp[stamp_id] = value;
- }
- }
-
- const float getPosition(unsigned int axis) const {
- if (axis < ISMRMRD_POSITION_LENGTH) {
- return head_.position[axis];
- }
- return 0;
- }
-
- void setPosition(unsigned int axis, float value){
- if (axis < ISMRMRD_POSITION_LENGTH) {
- head_.position[axis] = value;
- }
- }
-
- const float getReadDirection(unsigned int index) const {
- if (index < ISMRMRD_DIRECTION_LENGTH) {
- return head_.read_dir[index];
- }
- return 0;
- }
-
- void setReadDirection(unsigned int index, float value) {
- if (index < ISMRMRD_DIRECTION_LENGTH) {
- head_.read_dir[index] = value;
- }
- }
-
- const float getPhaseDirection(unsigned int index) const {
- if (index < ISMRMRD_DIRECTION_LENGTH) {
- return head_.phase_dir[index];
- }
- return 0;
- }
-
- void setPhaseDirection(unsigned int index, float value) {
- if (index < ISMRMRD_DIRECTION_LENGTH) {
- head_.phase_dir[index] = value;
- }
- }
-
- const float getSliceDirection(unsigned int index) const {
- if (index < ISMRMRD_DIRECTION_LENGTH) {
- return head_.slice_dir[index];
- }
- return 0;
- }
-
- void setSliceDirection(unsigned int index, float value) {
- if (index < ISMRMRD_DIRECTION_LENGTH) {
- head_.slice_dir[index] = value;
- }
- }
-
- float getSampleTimeUs() const {
- return head_.sample_time_us;
- }
-
- void setSampleTimeUs(float sampleTimeUs) {
- head_.sample_time_us = sampleTimeUs;
- }
-
- uint32_t getScanCounter() const {
- return head_.scan_counter;
- }
-
- void setScanCounter(uint32_t scanCounter) {
- head_.scan_counter = scanCounter;
- }
-
- uint16_t getTrajectoryDimensions() const {
- return head_.trajectory_dimensions;
- }
-
- void setTrajectoryDimensions(uint16_t trajectoryDimensions) {
- head_.trajectory_dimensions = trajectoryDimensions;
- makeConsistent();
- }
-
- const float getUserFloat(unsigned int index) const {
- if (index < ISMRMRD_USER_FLOATS) {
- return head_.user_float[index];
- }
- return 0.0f;
- }
-
- void setUserFloat(unsigned int index, float value) {
- if (index < ISMRMRD_USER_FLOATS) {
- head_.user_float[index] = value;
- }
- }
-
- const int32_t getUserInt(unsigned int index) const {
- if (index < ISMRMRD_USER_INTS) {
- return head_.user_int[index];
- }
- return 0;
- }
-
- void setUserInt(unsigned int index, int32_t value) {
- if (index < ISMRMRD_USER_INTS) {
- head_.user_int[index] = value;
- }
- }
-
- uint16_t getVersion() const {
- return head_.version;
- }
-
- void setVersion(uint16_t version) {
- this->head_.version = version;
- }
-
- const std::valarray<float>& getData() const {
- return data_;
- }
-
- void setData(const std::valarray<float>& data) {
- data_ = data;
- }
-
- const std::valarray<float>& getTraj() const {
- return traj_;
- }
-
- void setTraj(const std::valarray<float>& traj) {
- traj_ = traj;
- }
-
- float& operator[] (const size_t& p) {
- return data_[p];
- }
-
- float operator[] (const size_t& p) const {
- return data_[p];
- }
-
-protected:
- size_t calcTrajLength() {
- return head_.trajectory_dimensions*head_.number_of_samples;
- }
-
- size_t calcDataLength() {
- return head_.active_channels*head_.number_of_samples*2;
- }
-
-
- void makeConsistent() {
- if (head_.active_channels > head_.available_channels) {
- head_.available_channels = head_.active_channels;
- }
- if (calcTrajLength() != traj_.size()) {
- traj_.resize(calcTrajLength());
- }
- if (calcDataLength() != data_.size()) {
- data_.resize(calcDataLength());
- }
- }
-
- AcquisitionHeader head_; /**< Header, see above */
- std::valarray<float> traj_;
- std::valarray<float> data_;
-
-};
-
-#endif //__cplusplus
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-/**
- * Calculates the determinant of the matrix and return the sign
- */
-static int sign_of_directions(float read_dir[3], float phase_dir[3], float slice_dir[3])
-{
- float r11 = read_dir[0], r12 = phase_dir[0], r13 = slice_dir[0];
- float r21 = read_dir[1], r22 = phase_dir[1], r23 = slice_dir[1];
- float r31 = read_dir[2], r32 = phase_dir[2], r33 = slice_dir[2];
-
- /* Determinant should be 1 or -1 */
- float deti = (r11 * r22 * r33) + (r12 * r23 * r31) + (r21 * r32 * r13) -
- (r13 * r22 * r31) - (r12 * r21 * r33) - (r11 * r23 * r32);
-
- if (deti < 0) {
- return -1;
- } else {
- return 1;
- }
-}
-
-/**
- * Creates a normalized quaternion from a 3x3 rotation matrix
- */
-static void directions_to_quaternion(float read_dir[3], float phase_dir[3],
- float slice_dir[3], float quat[4])
-{
- float r11 = read_dir[0], r12 = phase_dir[0], r13 = slice_dir[0];
- float r21 = read_dir[1], r22 = phase_dir[1], r23 = slice_dir[1];
- float r31 = read_dir[2], r32 = phase_dir[2], r33 = slice_dir[2];
-
- double a = 1, b = 0, c = 0, d = 0, s = 0;
- double trace = 0;
- double xd, yd, zd;
-
- /* verify the sign of the rotation*/
- if (sign_of_directions(read_dir, phase_dir, slice_dir) < 0) {
- /* flip 3rd column */
- r13 = -r13;
- r23 = -r23;
- r33 = -r33;
- }
-
- /* Compute quaternion parameters */
- /* http://www.cs.princeton.edu/~gewang/projects/darth/stuff/quat_faq.html#Q55 */
- trace = 1.0l + r11 + r22 + r33;
- if (trace > 0.00001l) { /* simplest case */
- s = sqrt(trace) * 2;
- a = (r32 - r23) / s;
- b = (r13 - r31) / s;
- c = (r21 - r12) / s;
- d = 0.25l * s;
- } else {
- /* trickier case...
- * determine which major diagonal element has
- * the greatest value... */
- xd = 1.0 + r11 - (r22 + r33); /* 4**b**b */
- yd = 1.0 + r22 - (r11 + r33); /* 4**c**c */
- zd = 1.0 + r33 - (r11 + r22); /* 4**d**d */
- /* if r11 is the greatest */
- if (xd > 1.0) {
- s = 2.0 * sqrt(xd);
- a = 0.25l * s;
- b = (r21 + r12) / s;
- c = (r31 + r13) / s;
- d = (r32 - r23) / s;
- }
- /* else if r22 is the greatest */
- else if (yd > 1.0) {
- s = 2.0 * sqrt(yd);
- a = (r21 + r12) / s;
- b = 0.25l * s;
- c = (r32 + r23) / s;
- d = (r13 - r31) / s;
- }
- /* else, r33 must be the greatest */
- else {
- s = 2.0 * sqrt(zd);
- a = (r13 + r31) / s;
- b = (r23 + r32) / s;
- c = 0.25l * s;
- d = (r21 - r12) / s;
- }
-
- if (a < 0.0l) {
- b = -b;
- c = -c;
- d = -d;
- a = -a;
- }
- }
-
- quat[0] = (float)a; quat[1] = (float)b; quat[2] = (float)c; quat[3] = (float)d;
-}
-
-/**
- * Converts a quaternion of the form | a b c d | to a
- * 3x3 rotation matrix
- *
- * http://www.cs.princeton.edu/~gewang/projects/darth/stuff/quat_faq.html#Q54
- */
-static void quaternion_to_directions(float quat[4], float read_dir[3],
- float phase_dir[3], float slice_dir[3])
-{
- float a = quat[0], b = quat[1], c = quat[2], d = quat[3];
-
- read_dir[0] = 1.0f - 2.0f * ( b*b + c*c );
- phase_dir[0] = 2.0f * ( a*b - c*d );
- slice_dir[0] = 2.0f * ( a*c + b*d );
-
- read_dir[1] = 2.0f * ( a*b + c*d );
- phase_dir[1] = 1.0f - 2.0f * ( a*a + c*c );
- slice_dir[1] = 2.0f * ( b*c - a*d );
-
- read_dir[2] = 2.0f * ( a*c - b*d );
- phase_dir[2] = 2.0f * ( b*c + a*d );
- slice_dir[2] = 1.0f - 2.0f * ( a*a + b*b );
-}
-
-#ifdef __cplusplus
-}
-#endif
+typedef struct Image {
+ ImageHeader head;
+ void* data;
+ char* attribute_string;
+} Image;
+
+void initImage(Image* im);
+void freeImage(Image* im);
+void makeConsistentImage(Image* im);
+
+/************/
+/* NDArrays */
+/************/
+
+typedef struct NDArray {
+ uint16_t version; /**< First unsigned int indicates the version */
+ uint16_t data_type; /**< e.g. unsigned short, float, complex float, etc. */
+ uint16_t ndim; /**< Number of dimensions */
+ uint16_t dims[ISMRMRD_NDARRAY_MAXDIM]; /**< Dimensions */
+ void* data; /**< pointer to data array */
+} NDArray;
+
+void initNDArray(NDArray* arr);
+void freeNDArray(NDArray* arr);
+void makeConsistentNDArray(NDArray* arr);
+
+/*********/
+/* Flags */
+/*********/
+bool flags_is_set(const uint64_t flags, const uint64_t val);
+void flags_set(uint64_t* flags, const uint64_t val);
+void flags_clear(uint64_t* flags, const uint64_t val);
+void flags_clear_all(uint64_t* flags);
+
+/*****************************/
+/* Rotations and Quaternions */
+/*****************************/
+/* Calculates the determinant of the matrix and return the sign */
+intsign_of_directions(float read_dir[3], float phase_dir[3],
+ float slice_dir[3]);
+
+/* Creates a normalized quaternion from a 3x3 rotation matrix */
+voiddirections_to_quaternion(float read_dir[3], float phase_dir[3],
+ float slice_dir[3], float quat[4]);
+
+/* Converts a quaternion of the form | a b c d | to a 3x3 rotation matrix */
+voidquaternion_to_directions(float quat[4], float read_dir[3],
+ float phase_dir[3], float slice_dir[3]);
#ifdef __cplusplus
-} //End of ISMRMRD namespace
-#endif //__cplusplus
+} // End of ISMRMRD namespace
+#endif //__cplusplus
-#pragma pack(pop) //Restore old alignment
+#pragma pack(pop) // Restore old alignment
-#endif //ISMRMRD_H
+#endif // ISMRMRD_H
diff --git a/ismrmrd_hdf5.h b/ismrmrd_hdf5.h
index 75e733b..3e29858 100644
--- a/ismrmrd_hdf5.h
+++ b/ismrmrd_hdf5.h
@@ -14,11 +14,11 @@
#include <boost/thread.hpp>
-#include <H5Cpp.h>
+#include <hdf5.h>
-#ifndef H5_NO_NAMESPACE
-using namespace H5;
-#endif
+//#ifndef H5_NO_NAMESPACE
+//using namespace H5;
+//#endif
namespace ISMRMRD
diff --git a/ismrmrd_hdf5_datatypes.h b/ismrmrd_hdf5_datatypes.h
index 09e3e69..c57df8f 100644
--- a/ismrmrd_hdf5_datatypes.h
+++ b/ismrmrd_hdf5_datatypes.h
@@ -4,7 +4,7 @@
#include "ismrmrd.h"
-#include <H5Cpp.h>
+#include <hdf5.h>
#include <boost/shared_ptr.hpp>
@@ -12,9 +12,9 @@
#include <complex>
#include <string>
-#ifndef H5_NO_NAMESPACE
- using namespace H5;
-#endif
+//#ifndef H5_NO_NAMESPACE
+// using namespace H5;
+//#endif
namespace ISMRMRD
{
@@ -121,43 +121,43 @@ namespace ISMRMRD
template <> inline hid_t IsmrmrdHDF5TypeContainer::getIsmrmrdHDF5ArrayType< uint16_t, 3 >() {
std::vector<hsize_t> dims(1,3);
- hid_t t = H5Tarray_create(H5T_NATIVE_UINT16, 1, &dims[0], NULL);
+ hid_t t = H5Tarray_create(H5T_NATIVE_UINT16, 1, &dims[0]);
return t;
}
template <> inline hid_t IsmrmrdHDF5TypeContainer::getIsmrmrdHDF5ArrayType< uint16_t, ISMRMRD_USER_INTS >() {
std::vector<hsize_t> dims(1,ISMRMRD_USER_INTS);
- hid_t t = H5Tarray_create(H5T_NATIVE_UINT16, 1, &dims[0], NULL);
+ hid_t t = H5Tarray_create(H5T_NATIVE_UINT16, 1, &dims[0]);
return t;
}
template <> inline hid_t IsmrmrdHDF5TypeContainer::getIsmrmrdHDF5ArrayType< uint32_t, 3 >() { //TODO: The 3 should be replace with ISMRMRD_PHYS_TIME_STAMPS when that is corrected
std::vector<hsize_t> dims(1,3);//TODO: Replace when header is updated
- hid_t t = H5Tarray_create(H5T_NATIVE_UINT32, 1, &dims[0], NULL);
+ hid_t t = H5Tarray_create(H5T_NATIVE_UINT32, 1, &dims[0]);
return t;
}
template <> inline hid_t IsmrmrdHDF5TypeContainer::getIsmrmrdHDF5ArrayType< int32_t, ISMRMRD_USER_INTS >() {
std::vector<hsize_t> dims(1,ISMRMRD_USER_INTS);
- hid_t t = H5Tarray_create(H5T_NATIVE_INT32, 1, &dims[0], NULL);
+ hid_t t = H5Tarray_create(H5T_NATIVE_INT32, 1, &dims[0]);
return t;
}
template <> inline hid_t IsmrmrdHDF5TypeContainer::getIsmrmrdHDF5ArrayType< uint64_t, ISMRMRD_CHANNEL_MASKS >() {
std::vector<hsize_t> dims(1,ISMRMRD_CHANNEL_MASKS);
- hid_t t = H5Tarray_create(H5T_NATIVE_UINT64, 1, &dims[0], NULL);
+ hid_t t = H5Tarray_create(H5T_NATIVE_UINT64, 1, &dims[0]);
return t;
}
template <> inline hid_t IsmrmrdHDF5TypeContainer::getIsmrmrdHDF5ArrayType< float, ISMRMRD_POSITION_LENGTH >() {
std::vector<hsize_t> dims(1,ISMRMRD_POSITION_LENGTH);
- hid_t t = H5Tarray_create(H5T_NATIVE_FLOAT, 1, &dims[0], NULL);
+ hid_t t = H5Tarray_create(H5T_NATIVE_FLOAT, 1, &dims[0]);
return t;
}
template <> inline hid_t IsmrmrdHDF5TypeContainer::getIsmrmrdHDF5ArrayType< float, ISMRMRD_USER_FLOATS >() {
std::vector<hsize_t> dims(1,ISMRMRD_USER_FLOATS);
- hid_t t = H5Tarray_create(H5T_NATIVE_FLOAT, 1, &dims[0], NULL);
+ hid_t t = H5Tarray_create(H5T_NATIVE_FLOAT, 1, &dims[0]);
return t;
}
@@ -343,327 +343,4 @@ namespace ISMRMRD
}
/* HDF5 C Interface (end) */
-template <typename T> boost::shared_ptr<DataType> getIsmrmrdHDF5Type();
-
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type<float>()
-{
- boost::shared_ptr<DataType> ret(new DataType(H5Tcopy(H5T_NATIVE_FLOAT)));
- return ret;
-}
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type<double>()
-{
- boost::shared_ptr<DataType> ret(new DataType(H5Tcopy(H5T_NATIVE_DOUBLE)));
- return ret;
-}
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type<char>()
-{
- boost::shared_ptr<DataType> ret(new DataType(H5Tcopy(H5T_NATIVE_CHAR)));
- return ret;
-}
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type< std::complex<float> >()
-{
- CompType* ct = new CompType(sizeof( std::complex<float> ));
- ct->insertMember( "real", 0, PredType::NATIVE_FLOAT);
- ct->insertMember( "imag", sizeof(float), PredType::NATIVE_FLOAT);
- boost::shared_ptr<DataType> ret(ct);
- return ret;
-}
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type< std::complex<double> >()
-{
- CompType* ct = new CompType(sizeof( std::complex<double> ));
- ct->insertMember( "real", 0, PredType::NATIVE_DOUBLE);
- ct->insertMember( "imag", sizeof(double), PredType::NATIVE_DOUBLE);
- boost::shared_ptr<DataType> ret(ct);
- return ret;
-}
-
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type< unsigned short >()
-{
- boost::shared_ptr<DataType> ret(new DataType(H5Tcopy(H5T_NATIVE_USHORT)));
- return ret;
-}
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type<EncodingCounters>()
-{
-
- boost::shared_ptr<CompType> ret = boost::shared_ptr<CompType>(new CompType(sizeof(EncodingCounters)));
-
- ret->insertMember( "kspace_encode_step_1", HOFFSET(EncodingCounters, kspace_encode_step_1), PredType::NATIVE_UINT16);
- ret->insertMember( "kspace_encode_step_2", HOFFSET(EncodingCounters, kspace_encode_step_2), PredType::NATIVE_UINT16);
- ret->insertMember( "average", HOFFSET(EncodingCounters, average), PredType::NATIVE_UINT16);
- ret->insertMember( "slice", HOFFSET(EncodingCounters, slice), PredType::NATIVE_UINT16);
- ret->insertMember( "contrast", HOFFSET(EncodingCounters, contrast), PredType::NATIVE_UINT16);
- ret->insertMember( "phase", HOFFSET(EncodingCounters, phase), PredType::NATIVE_UINT16);
- ret->insertMember( "repetition", HOFFSET(EncodingCounters, repetition), PredType::NATIVE_UINT16);
- ret->insertMember( "set", HOFFSET(EncodingCounters, set), PredType::NATIVE_UINT16);
- ret->insertMember( "segment", HOFFSET(EncodingCounters, segment), PredType::NATIVE_UINT16);
-
- std::vector<hsize_t> dims(1,8);
- boost::shared_ptr<DataType> array_type(new ArrayType(PredType::NATIVE_UINT16, 1, &dims[0]));
- ret->insertMember( "user", HOFFSET(EncodingCounters, user), *array_type);
-
- return ret;
-};
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type<AcquisitionHeader>()
-{
- boost::shared_ptr<CompType> ret = boost::shared_ptr<CompType>(new CompType(sizeof(AcquisitionHeader)));
- ret->insertMember( "version", HOFFSET(AcquisitionHeader, version), PredType::NATIVE_UINT16);
- ret->insertMember( "flags", HOFFSET(AcquisitionHeader, flags), PredType::NATIVE_UINT64);
- ret->insertMember( "measurement_uid", HOFFSET(AcquisitionHeader, measurement_uid), PredType::NATIVE_UINT32);
- ret->insertMember( "scan_counter", HOFFSET(AcquisitionHeader, scan_counter), PredType::NATIVE_UINT32);
- ret->insertMember( "acquisition_time_stamp", HOFFSET(AcquisitionHeader, acquisition_time_stamp), PredType::NATIVE_UINT32);
-
- // TODO: change ISMRMRD_PHYS_STAMPS to 3 (Major change)
- // we should use the size defines and not hard coded numbers.
- std::vector<hsize_t> dims(1,3);
- boost::shared_ptr<DataType> array_type(new ArrayType(PredType::NATIVE_UINT32, 1, &dims[0]));
- ret->insertMember( "physiology_time_stamp", HOFFSET(AcquisitionHeader, physiology_time_stamp), *array_type);
-
- ret->insertMember( "number_of_samples", HOFFSET(AcquisitionHeader, number_of_samples), PredType::NATIVE_UINT16);
- ret->insertMember( "available_channels", HOFFSET(AcquisitionHeader, available_channels), PredType::NATIVE_UINT16);
- ret->insertMember( "active_channels", HOFFSET(AcquisitionHeader, active_channels), PredType::NATIVE_UINT16);
-
- dims[0] = 16;
- boost::shared_ptr<DataType> mask_array_type(new ArrayType(PredType::NATIVE_UINT64, 1, &dims[0]));
- ret->insertMember( "channel_mask", HOFFSET(AcquisitionHeader, channel_mask), *mask_array_type);
- ret->insertMember( "discard_pre", HOFFSET(AcquisitionHeader, discard_pre), PredType::NATIVE_UINT16);
- ret->insertMember( "discard_post", HOFFSET(AcquisitionHeader, discard_post), PredType::NATIVE_UINT16);
- ret->insertMember( "center_sample", HOFFSET(AcquisitionHeader, center_sample), PredType::NATIVE_UINT16);
- ret->insertMember( "encoding_space_ref", HOFFSET(AcquisitionHeader, encoding_space_ref), PredType::NATIVE_UINT16);
- ret->insertMember( "trajectory_dimensions", HOFFSET(AcquisitionHeader, trajectory_dimensions), PredType::NATIVE_UINT16);
- ret->insertMember( "sample_time_us", HOFFSET(AcquisitionHeader, sample_time_us), PredType::NATIVE_FLOAT);
-
- dims[0] = 3;
- boost::shared_ptr<DataType> position_array_type(new ArrayType(PredType::NATIVE_FLOAT, 1, &dims[0]));
- ret->insertMember( "position", HOFFSET(AcquisitionHeader, position), *position_array_type);
-
- dims[0] = 3;
- boost::shared_ptr<DataType> read_dir_array_type(new ArrayType(PredType::NATIVE_FLOAT, 1, &dims[0]));
- ret->insertMember( "read_dir", HOFFSET(AcquisitionHeader, read_dir), *read_dir_array_type);
-
- dims[0] = 3;
- boost::shared_ptr<DataType> phase_dir_array_type(new ArrayType(PredType::NATIVE_FLOAT, 1, &dims[0]));
- ret->insertMember( "phase_dir", HOFFSET(AcquisitionHeader, phase_dir), *phase_dir_array_type);
-
- dims[0] = 3;
- boost::shared_ptr<DataType> slice_dir_array_type(new ArrayType(PredType::NATIVE_FLOAT, 1, &dims[0]));
- ret->insertMember( "slice_dir", HOFFSET(AcquisitionHeader, slice_dir), *slice_dir_array_type);
-
- dims[0] = 3;
- boost::shared_ptr<DataType> table_array_type(new ArrayType(PredType::NATIVE_FLOAT, 1, &dims[0]));
- ret->insertMember( "patient_table_position", HOFFSET(AcquisitionHeader, patient_table_position), *table_array_type);
-
- boost::shared_ptr<DataType> ec_type = getIsmrmrdHDF5Type<EncodingCounters>();
- ret->insertMember( "idx", HOFFSET(AcquisitionHeader, idx), *ec_type);
-
- dims[0] = 8;
- boost::shared_ptr<DataType> user_int_array_type(new ArrayType(PredType::NATIVE_INT32, 1, &dims[0]));
- ret->insertMember( "user_int", HOFFSET(AcquisitionHeader, user_int), *user_int_array_type);
-
- dims[0] = 8;
- boost::shared_ptr<DataType> user_float_array_type(new ArrayType(PredType::NATIVE_FLOAT, 1, &dims[0]));
- ret->insertMember( "user_float", HOFFSET(AcquisitionHeader, user_float), *user_float_array_type);
-
- return ret;
-
-}
-
-
-struct complex_t
-{
- float real;
- float imag;
-};
-
-struct double_complex_t
-{
- double real;
- double imag;
-};
-
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type<complex_t>()
-{
- boost::shared_ptr<CompType> ret = boost::shared_ptr<CompType>(new CompType(sizeof(complex_t)));
- ret->insertMember( "real", HOFFSET(complex_t,real), PredType::NATIVE_FLOAT);
- ret->insertMember( "imag", HOFFSET(complex_t,imag), PredType::NATIVE_FLOAT);
- return ret;
-}
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type<double_complex_t>()
-{
- boost::shared_ptr<CompType> ret = boost::shared_ptr<CompType>(new CompType(sizeof(double_complex_t)));
- ret->insertMember( "real", HOFFSET(complex_t,real), PredType::NATIVE_DOUBLE);
- ret->insertMember( "imag", HOFFSET(complex_t,imag), PredType::NATIVE_DOUBLE);
- return ret;
-}
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type<AcquisitionHeader_with_data>()
-{
- boost::shared_ptr<CompType> ret = boost::shared_ptr<CompType>(new CompType(sizeof(AcquisitionHeader_with_data)));
-
- boost::shared_ptr<DataType> head_type = getIsmrmrdHDF5Type<AcquisitionHeader>();
- //boost::shared_ptr<DataType> cxvdatatype = getIsmrmrdHDF5Type<complex_t>();
- //cxvdatatype = boost::shared_ptr<DataType>(new DataType(H5Tvlen_create (cxvdatatype->getId())));
- boost::shared_ptr<DataType> realvdatatype = boost::shared_ptr<DataType>(new DataType(H5Tvlen_create (PredType::NATIVE_FLOAT.getId())));
-
- ret->insertMember( "head", HOFFSET(AcquisitionHeader_with_data,head), *head_type);
- ret->insertMember( "traj", HOFFSET(AcquisitionHeader_with_data,traj), *realvdatatype);
- ret->insertMember( "data", HOFFSET(AcquisitionHeader_with_data,data), *realvdatatype);
- return ret;
-}
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type<ImageHeader>()
-{
-
- boost::shared_ptr<CompType> ret = boost::shared_ptr<CompType>(new CompType(sizeof(ImageHeader)));
-
- ret->insertMember( "version", HOFFSET(ImageHeader, version), PredType::NATIVE_UINT16);
- ret->insertMember( "flags", HOFFSET(ImageHeader, flags), PredType::NATIVE_UINT64);
- ret->insertMember( "measurement_uid", HOFFSET(ImageHeader, measurement_uid), PredType::NATIVE_UINT32);
-
- std::vector<hsize_t> dims(1,0);
-
- dims[0] = 3;
- boost::shared_ptr<DataType> mat_size_array_type(new ArrayType(PredType::NATIVE_UINT16, 1, &dims[0]));
- ret->insertMember( "matrix_size", HOFFSET(ImageHeader, matrix_size), *mat_size_array_type);
-
- dims[0] = 3;
- boost::shared_ptr<DataType> fov_array_type(new ArrayType(PredType::NATIVE_FLOAT, 1, &dims[0]));
- ret->insertMember( "field_of_view", HOFFSET(ImageHeader, field_of_view), *fov_array_type);
-
- ret->insertMember( "channels", HOFFSET(ImageHeader, channels), PredType::NATIVE_UINT16);
-
- dims[0] = 3;
- boost::shared_ptr<DataType> position_array_type(new ArrayType(PredType::NATIVE_FLOAT, 1, &dims[0]));
- ret->insertMember( "position", HOFFSET(ImageHeader, position), *position_array_type);
-
- dims[0] = 3;
- boost::shared_ptr<DataType> read_dir_array_type(new ArrayType(PredType::NATIVE_FLOAT, 1, &dims[0]));
- ret->insertMember( "read_dir", HOFFSET(ImageHeader, read_dir), *read_dir_array_type);
-
- dims[0] = 3;
- boost::shared_ptr<DataType> phase_dir_array_type(new ArrayType(PredType::NATIVE_FLOAT, 1, &dims[0]));
- ret->insertMember( "phase_dir", HOFFSET(ImageHeader, phase_dir), *phase_dir_array_type);
-
- dims[0] = 3;
- boost::shared_ptr<DataType> slice_dir_array_type(new ArrayType(PredType::NATIVE_FLOAT, 1, &dims[0]));
- ret->insertMember( "slice_dir", HOFFSET(ImageHeader, slice_dir), *slice_dir_array_type);
-
- dims[0] = 3;
- boost::shared_ptr<DataType> table_array_type(new ArrayType(PredType::NATIVE_FLOAT, 1, &dims[0]));
- ret->insertMember( "patient_table_position", HOFFSET(ImageHeader, patient_table_position), *table_array_type);
-
-
- ret->insertMember( "average", HOFFSET(ImageHeader, average), PredType::NATIVE_UINT16);
- ret->insertMember( "slice", HOFFSET(ImageHeader, slice), PredType::NATIVE_UINT16);
- ret->insertMember( "contrast", HOFFSET(ImageHeader, contrast), PredType::NATIVE_UINT16);
- ret->insertMember( "phase", HOFFSET(ImageHeader, phase), PredType::NATIVE_UINT16);
- ret->insertMember( "repetition", HOFFSET(ImageHeader, repetition), PredType::NATIVE_UINT16);
- ret->insertMember( "set", HOFFSET(ImageHeader, set), PredType::NATIVE_UINT16);
- ret->insertMember( "acquisition_time_stamp", HOFFSET(ImageHeader, acquisition_time_stamp), PredType::NATIVE_UINT32);
-
- // TODO: ISMRMRD_PHYS_STAMPS should be 3 (Major change)
- // we should use the size defines and not hard coded numbers.
- dims[0] = 3;
- boost::shared_ptr<DataType> array_type(new ArrayType(PredType::NATIVE_UINT32, 1, &dims[0]));
- ret->insertMember( "physiology_time_stamp", HOFFSET(ImageHeader, physiology_time_stamp), *array_type);
-
- ret->insertMember( "image_data_type", HOFFSET(ImageHeader, image_data_type), PredType::NATIVE_UINT16);
- ret->insertMember( "image_type", HOFFSET(ImageHeader, image_type), PredType::NATIVE_UINT16);
- ret->insertMember( "image_index", HOFFSET(ImageHeader, image_index), PredType::NATIVE_UINT16);
- ret->insertMember( "image_series_index", HOFFSET(ImageHeader, image_series_index), PredType::NATIVE_UINT16);
-
- dims[0] = 8;
- boost::shared_ptr<DataType> user_int_array_type(new ArrayType(PredType::NATIVE_INT32, 1, &dims[0]));
- ret->insertMember( "user_int", HOFFSET(ImageHeader, user_int), *user_int_array_type);
-
- dims[0] = 8;
- boost::shared_ptr<DataType> user_float_array_type(new ArrayType(PredType::NATIVE_FLOAT, 1, &dims[0]));
- ret->insertMember( "user_float", HOFFSET(ImageHeader, user_float), *user_float_array_type);
-
- return ret;
-}
-
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type<ImageHeader_with_data<float> >()
-{
- boost::shared_ptr<CompType> ret = boost::shared_ptr<CompType>(new CompType(sizeof(ImageHeader_with_data<float>)));
- boost::shared_ptr<DataType> head_type = getIsmrmrdHDF5Type<ImageHeader>();
- boost::shared_ptr<DataType> vdatatype = getIsmrmrdHDF5Type<float>();
- vdatatype = boost::shared_ptr<DataType>(new DataType(H5Tvlen_create (vdatatype->getId())));
- ret->insertMember( "head", HOFFSET(ImageHeader_with_data<float>,head), *head_type);
- ret->insertMember( "data", HOFFSET(ImageHeader_with_data<float>,data), *vdatatype);
- return ret;
-}
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type<ImageHeader_with_data<double> >()
-{
- boost::shared_ptr<CompType> ret = boost::shared_ptr<CompType>(new CompType(sizeof(ImageHeader_with_data<double>)));
- boost::shared_ptr<DataType> head_type = getIsmrmrdHDF5Type<ImageHeader>();
- boost::shared_ptr<DataType> vdatatype = getIsmrmrdHDF5Type<double>();
- vdatatype = boost::shared_ptr<DataType>(new DataType(H5Tvlen_create (vdatatype->getId())));
- ret->insertMember( "head", HOFFSET(ImageHeader_with_data<double>,head), *head_type);
- ret->insertMember( "data", HOFFSET(ImageHeader_with_data<double>,data), *vdatatype);
- return ret;
-}
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type<ImageHeader_with_data<unsigned short> >()
-{
- boost::shared_ptr<CompType> ret = boost::shared_ptr<CompType>(new CompType(sizeof(ImageHeader_with_data<unsigned short>)));
- boost::shared_ptr<DataType> head_type = getIsmrmrdHDF5Type<ImageHeader>();
- boost::shared_ptr<DataType> vdatatype = getIsmrmrdHDF5Type<unsigned short>();
- vdatatype = boost::shared_ptr<DataType>(new DataType(H5Tvlen_create (vdatatype->getId())));
- ret->insertMember( "head", HOFFSET(ImageHeader_with_data<unsigned short>,head), *head_type);
- ret->insertMember( "data", HOFFSET(ImageHeader_with_data<unsigned short>,data), *vdatatype);
- return ret;
-}
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type<ImageHeader_with_data<complex_t> >()
-{
- boost::shared_ptr<CompType> ret = boost::shared_ptr<CompType>(new CompType(sizeof(ImageHeader_with_data<complex_t>)));
- boost::shared_ptr<DataType> head_type = getIsmrmrdHDF5Type<ImageHeader>();
- boost::shared_ptr<DataType> vdatatype = getIsmrmrdHDF5Type<complex_t>();
- vdatatype = boost::shared_ptr<DataType>(new DataType(H5Tvlen_create (vdatatype->getId())));
- ret->insertMember( "head", HOFFSET(ImageHeader_with_data<complex_t>,head), *head_type);
- ret->insertMember( "data", HOFFSET(ImageHeader_with_data<complex_t>,data), *vdatatype);
- return ret;
-}
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type<ImageHeader_with_data<double_complex_t> >()
-{
- boost::shared_ptr<CompType> ret = boost::shared_ptr<CompType>(new CompType(sizeof(ImageHeader_with_data<double_complex_t>)));
- boost::shared_ptr<DataType> head_type = getIsmrmrdHDF5Type<ImageHeader>();
- boost::shared_ptr<DataType> vdatatype = getIsmrmrdHDF5Type<double_complex_t>();
- vdatatype = boost::shared_ptr<DataType>(new DataType(H5Tvlen_create (vdatatype->getId())));
- ret->insertMember( "head", HOFFSET(ImageHeader_with_data<double_complex_t>,head), *head_type);
- ret->insertMember( "data", HOFFSET(ImageHeader_with_data<double_complex_t>,data), *vdatatype);
- return ret;
-}
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type<ImageHeader_with_data< std::complex<float> > >()
-{
- return getIsmrmrdHDF5Type<ImageHeader_with_data<complex_t> >();
-}
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type<ImageHeader_with_data< std::complex<double> > >()
-{
- return getIsmrmrdHDF5Type<ImageHeader_with_data<double_complex_t> >();
-}
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type<std::string>()
-{
- boost::shared_ptr<DataType> ret(new StrType(0, H5T_VARIABLE));
- return ret;
-}
-
-}
-
#endif /* ISMRMRD_HDF5_DATATYPES_H_ */
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/ismrmrd.git
More information about the debian-science-commits
mailing list