Commit 378037d1 authored by Andreas Tille's avatar Andreas Tille

Update upstream source from tag 'upstream/1.4.0'

Update to upstream version '1.4.0'
with Debian dir 31d29a1a54b4483f8d3135599d3360b23b1f50ae
parents 03634663 cae5506e
......@@ -3,6 +3,8 @@
*.so
build/
.DS_Store
.idea/
.project
.cproject
# autogenerated
cmake/cpack_options.cmake
......@@ -49,7 +49,7 @@ if (WIN32)
add_definitions(-D__func__=__FUNCTION__)
else ()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -Wall")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++11")
endif ()
# --- VERSIONING (begin) ----
......@@ -63,12 +63,12 @@ endif ()
#in the utility libraries, that don't affect the data format itself.
# For more information see http://semver.org/
set(ISMRMRD_VERSION_MAJOR 1)
set(ISMRMRD_VERSION_MINOR 3)
set(ISMRMRD_VERSION_PATCH 3)
set(ISMRMRD_VERSION_MINOR 4)
set(ISMRMRD_VERSION_PATCH 0)
set(ISMRMRD_VERSION_STRING ${ISMRMRD_VERSION_MAJOR}.${ISMRMRD_VERSION_MINOR}.${ISMRMRD_VERSION_PATCH})
set(ISMRMRD_SOVERSION ${ISMRMRD_VERSION_MAJOR}.${ISMRMRD_VERSION_MINOR})
set(ISMRMRD_XML_SCHEMA_SHA1 "9b899c6ad806bc2388c70461d6e5affe5cc6d750")
set(ISMRMRD_XML_SCHEMA_SHA1 "275129288d0c5ec39ee11bf8f78f952ae1dcec76")
#Remove line breaks and white space that does not change the meaning of the schema
file(STRINGS ${CMAKE_SOURCE_DIR}/schema/ismrmrd.xsd SCHEMA_STRINGS) #Read all strings from file
......@@ -106,13 +106,15 @@ endif()
# Find HDF5 for dataset support
find_package(HDF5 1.8 COMPONENTS C)
find_package(HDF5 COMPONENTS C)
if (HDF5_FOUND)
set (ISMRMRD_DATASET_SUPPORT true)
set (ISMRMRD_DATASET_SOURCES libsrc/dataset.c libsrc/dataset.cpp)
set (ISMRMRD_DATASET_INCLUDE_DIR ${HDF5_C_INCLUDE_DIR})
set (ISMRMRD_DATASET_INCLUDE_DIR ${HDF5_INCLUDE_DIRS})
set (ISMRMRD_DATASET_LIBRARIES ${HDF5_LIBRARIES})
add_definitions(${HDF5_DEFINITIONS})
include_directories(${HDF5_INCLUDE_DIRS})
else ()
set (ISMRMRD_DATASET_SUPPORT false)
message (WARNING "HDF5 not found. Dataset and file support unavailable!")
......@@ -164,6 +166,8 @@ set(ISMRMRD_TARGET_SOURCES
libsrc/ismrmrd.cpp
libsrc/xml.cpp
libsrc/meta.cpp
libsrc/waveform.cpp
libsrc/waveform.c
${ISMRMRD_DATASET_SOURCES}
)
......@@ -196,7 +200,7 @@ set_target_properties(ismrmrd PROPERTIES
)
target_link_libraries(ismrmrd ${ISMRMRD_TARGET_LINK_LIBS})
list(APPEND ISMRMRD_LIBRARIES ismrmrd) # Add to list of libraries to be found
list(APPEND ISMRMRD_LIBRARY_DIRS ${CMAKE_BINARY_DIR} ) # Add to list of directories to find libaries
list(APPEND ISMRMRD_LIBRARY_DIRS ${CMAKE_BINARY_DIR} ) # Add to list of directories to find libraries
# install the main library
install(TARGETS ismrmrd EXPORT ISMRMRDTargets
......@@ -258,6 +262,11 @@ configure_file(cmake/ISMRMRDConfig.cmake.in
set(CONFIG_ISMRMRD_SCHEMA_DIR ${CMAKE_INSTALL_PREFIX}/share/ismrmrd/schema)
set(CONFIG_ISMRMRD_TARGET_INCLUDE_DIRS ${CMAKE_INSTALL_PREFIX}/include)
set(CONFIG_ISMRMRD_LIBRARY_DIRS ${CMAKE_INSTALL_PREFIX}/lib)
if (ISMRMRD_DATASET_SUPPORT)
list(APPEND CONFIG_ISMRMRD_TARGET_INCLUDE_DIRS ${HDF5_INCLUDE_DIRS})
list(APPEND CONFIG_ISMRMRD_LIBRARY_DIRS ${HDF5_LIBRARY_DIRS})
list(APPEND ISMRMRD_LIBRARIES ${HDF5_LIBRARIES})
endif ()
configure_file(cmake/ISMRMRDConfig.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/InstallFiles/ISMRMRDConfig.cmake"
@ONLY
......@@ -274,6 +283,15 @@ install(
Devel
)
install(
FILES
cmake/FindFFTW3.cmake
DESTINATION
${ConfigPackageLocation}
COMPONENT
Devel
)
# Create package
string(TOLOWER ${PROJECT_NAME} PROJECT_NAME_LOWER)
include(${ISMRMRD_CMAKE_DIR}/ismrmrd_cpack.cmake)
......
......@@ -78,14 +78,14 @@ if (WIN32)
string(TOUPPER ${_lib} _LIB)
find_library(${_LIB}_LIBRARY lib${_lib}-3
find_library(${_LIB}_LIBRARY NAMES lib${_lib}-3 lib${_lib}
HINTS $ENV{FFTW3_ROOT_DIR} PATH_SUFFIXES lib)
mark_as_advanced(${_LIB}_LIBRARY)
list(APPEND FFTW3_LIBRARIES ${${_LIB}_LIBRARY})
list(APPEND _check_list ${_LIB}_LIBRARY)
endforeach()
message("FFTW3 WINDOWS libraries: " ${FFTW3_LIBRARIES})
message(STATUS "FFTW3 WINDOWS libraries: " ${FFTW3_LIBRARIES})
else ()
foreach(_lib ${_libraries})
......@@ -99,7 +99,7 @@ else ()
list(APPEND _check_list ${_LIB}_LIBRARY)
endforeach()
message("FFTW3 UNIX libraries: " ${FFTW3_LIBRARIES})
message(STATUS "FFTW3 UNIX libraries: " ${FFTW3_LIBRARIES})
endif ()
# Search for the header file.
......
......@@ -14,16 +14,16 @@ set(ISMRMRD_VERSION_MINOR "@ISMRMRD_VERSION_MINOR@")
set(ISMRMRD_VERSION_PATCH "@ISMRMRD_VERSION_PATCH@")
# ISMRMRD_SCHEMA_DIR - where to find ismrmrd.xsd
set(ISMRMRD_SCHEMA_DIR @CONFIG_ISMRMRD_SCHEMA_DIR@)
set(ISMRMRD_SCHEMA_DIR "@CONFIG_ISMRMRD_SCHEMA_DIR@")
# ISMRMRD_INCLUDE_DIR - where to find ismrmrd.h, etc.
set(ISMRMRD_INCLUDE_DIRS @CONFIG_ISMRMRD_TARGET_INCLUDE_DIRS@)
set(ISMRMRD_INCLUDE_DIRS "@CONFIG_ISMRMRD_TARGET_INCLUDE_DIRS@")
# ISMRMRD_LIBRARY_DIRS - where to search for libraries
set(ISMRMRD_LIBRARY_DIRS @CONFIG_ISMRMRD_LIBRARY_DIRS@)
set(ISMRMRD_LIBRARY_DIRS "@CONFIG_ISMRMRD_LIBRARY_DIRS@")
# ISMRMRD_LIBRARIES - i.e. ismrmrd
set(ISMRMRD_LIBRARIES @ISMRMRD_LIBRARIES@)
set(ISMRMRD_LIBRARIES "@ISMRMRD_LIBRARIES@")
## For backwards compatibility use existing variable name
## Include directories can be lists, and should be plural
## to conform with naming schemes in many other cmake packages
set(ISMRMRD_INCLUDE_DIR @CONFIG_ISMRMRD_TARGET_INCLUDE_DIRS@)
set(ISMRMRD_LIB_DIR @CONFIG_ISMRMRD_LIBRARY_DIRS@)
set(ISMRMRD_INCLUDE_DIR "@CONFIG_ISMRMRD_TARGET_INCLUDE_DIRS@")
set(ISMRMRD_LIB_DIR "@CONFIG_ISMRMRD_LIBRARY_DIRS@")
......@@ -1075,7 +1075,7 @@ HTML_STYLESHEET =
# cascading style sheets that are included after the standard style sheets
# created by doxygen. Using this option one can overrule certain style aspects.
# This is preferred over using HTML_STYLESHEET since it does not replace the
# standard style sheet and is therefor more robust against future updates.
# standard style sheet and is therefore more robust against future updates.
# Doxygen will copy the style sheet files to the output directory.
# Note: The order of the extra stylesheet files is of importance (e.g. the last
# stylesheet in the list overrules the setting of the previous ones in the
......@@ -1618,8 +1618,8 @@ EXTRA_PACKAGES =
# Note: Only use a user-defined header if you know what you are doing! The
# following commands have a special meaning inside the header: $title,
# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
# $projectbrief, $projectlogo. Doxygen will replace $title with the empy string,
# for the replacement values of the other commands the user is refered to
# $projectbrief, $projectlogo. Doxygen will replace $title with the empty string,
# for the replacement values of the other commands the user is referred to
# HTML_HEADER.
# This tag requires that the tag GENERATE_LATEX is set to YES.
......
......@@ -75,7 +75,7 @@ Linux installation
The dependencies mentioned above should be included in most linux distributions. On Ubuntu you can install all required dependencies with::
sudo apt-get install libhdf5-serial-dev h5utils cmake cmake-curses-gui libboost-all-dev doxygen git
sudo apt-get install libhdf5-serial-dev h5utils cmake cmake-curses-gui libboost-all-dev libfftw3-dev doxygen git
After installation of dependencies, the library can be installed with:
......@@ -390,7 +390,7 @@ To reconstruct this synthetic dataset, you can use the test reconstruction appli
Matlab Example Code and Datasets
--------------------------------
The ``examples`` folder contains some matlab code to illustrate simple interaction with the ISMRMRD data format. The examples use test data sets, wich can be downloaded from the Github website_. Go to the ``examples/data`` folder and type the following to download the data::
The ``examples`` folder contains some matlab code to illustrate simple interaction with the ISMRMRD data format. The examples use test data sets, which can be downloaded from the Github website_. Go to the ``examples/data`` folder and type the following to download the data::
wget https://sourceforge.net/projects/ismrmrd/files/data/3D_partial_fourier.h5
wget https://sourceforge.net/projects/ismrmrd/files/data/simple_gre.h5
......
......@@ -3,13 +3,7 @@ project(ISMRMRD-C-EXAMPLE)
# if building this example as a standalone project
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
if(NOT DEFINED ENV{ISMRMRD_HOME})
message(FATAL_ERROR "ISMRMRD_HOME environment variable must be defined")
endif()
list(APPEND CMAKE_MODULE_PATH "$ENV{ISMRMRD_HOME}/share/ismrmrd/cmake")
find_package(Ismrmrd REQUIRED)
find_package(ISMRMRD REQUIRED)
# otherwise, building it as part of ISMRMRD itself
else()
......
......@@ -88,7 +88,7 @@ catch
nContrasts = 1;
end
% TODO add the other possibilites
% TODO add the other possibilities
%% Read all the data
% Reading can be done one acquisition (or chunk) at a time,
......
......@@ -9,6 +9,7 @@
#define ISMRMRD_DATASET_H
#include "ismrmrd/ismrmrd.h"
#include "ismrmrd/waveform.h"
#include <hdf5.h>
#ifdef __cplusplus
......@@ -83,6 +84,22 @@ EXPORTISMRMRD int ismrmrd_read_acquisition(const ISMRMRD_Dataset *dset, uint32_t
*/
EXPORTISMRMRD uint32_t ismrmrd_get_number_of_acquisitions(const ISMRMRD_Dataset *dset);
/**
* Appends and waveform data to the dataset.
*
* Please consult @See ISMRMRD_Waveform struct for details.
*/
EXPORTISMRMRD int ismrmrd_append_waveform(const ISMRMRD_Dataset *dset, const ISMRMRD_Waveform *wav);
/**
* Reads the wveformith the specified index from the dataset.
*/
EXPORTISMRMRD int ismrmrd_read_waveform(const ISMRMRD_Dataset *dset, uint32_t index, ISMRMRD_Waveform* wav);
/**
* Return the number of waveforms in the dataset.
*/
EXPORTISMRMRD uint32_t ismrmrd_get_number_of_waveforms(const ISMRMRD_Dataset *dset);
/**
* Appends an Image to the variable named varname in the dataset.
*
......@@ -166,6 +183,10 @@ public:
template <typename T> void readNDArray(const std::string &var, uint32_t index, NDArray<T> &arr);
uint32_t getNumberOfNDArrays(const std::string &var);
//Waveforms
void appendWaveform(const Waveform &wav);
void readWaveform(uint32_t index, Waveform & wav);
uint32_t getNumberOfWaveforms();
protected:
ISMRMRD_Dataset dset_;
};
......
......@@ -59,7 +59,7 @@ typedef double complex complex_double_t;
/* Booleans - part of C++ */
#ifndef __cplusplus
#ifdef _MSC_VER /* MS C compiler */
#if defined (_MSC_VER) && (_MSC_VER < 1800) /* old MS C compiler */
typedef int bool;
#define false 0
#define true 1
......
......@@ -60,7 +60,7 @@ namespace ISMRMRD
{
public:
/** Default construtor */
/** Default constructor */
MetaValue()
{
set(0L);
......@@ -166,7 +166,7 @@ namespace ISMRMRD
{
typedef std::map< std::string, std::vector<MetaValue> > map_t;
friend void serialize(MetaContainer& h, std::ostream& o);
friend void EXPORTISMRMRD serialize(MetaContainer& h, std::ostream& o);
public:
MetaContainer()
......@@ -231,7 +231,7 @@ namespace ISMRMRD
{
map_t::const_iterator it = map_.find(std::string(name));
if (it == map_.end()) {
throw std::runtime_error("Attempting to access unkown parameter");
throw std::runtime_error("Attempting to access unknown parameter");
}
if (index >= it->second.size()) {
throw std::runtime_error("Attempting to access indexed value out of bounds");
......
//
// Created by dch on 26/02/18.
//
#ifndef ISMRMRD_WAVEFORM_H
#define ISMRMRD_WAVEFORM_H
#include "export.h"
#ifdef __cplusplus
#include <cstdint>
namespace ISMRMRD {
extern "C" {
#endif
typedef struct ISMRMRD_WaveformHeader
{
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;
/**< Number of the acquisition after this waveform */
uint32_t time_stamp;
/**< Time stamp of the waveform */
uint16_t number_of_samples;
/**< Number of samples acquired */
uint16_t channels;
/**< Available channels */
float sample_time_us;
/**< Time between samples in micro seconds */
uint16_t waveform_id;
/**< Id matching the types specified in the xml header */
} ISMRMRD_WaveformHeader;
typedef struct ISMRMRD_Waveform
{
ISMRMRD_WaveformHeader head;
uint32_t *data;
} ISMRMRD_Waveform;
EXPORTISMRMRD int ismrmrd_make_consistent_waveform(ISMRMRD_Waveform* wav);
EXPORTISMRMRD int ismrmrd_size_of_waveform_data(const ISMRMRD_Waveform* wav);
EXPORTISMRMRD ISMRMRD_Waveform* ismrmrd_create_waveform();
EXPORTISMRMRD int ismrmrd_free_waveform(ISMRMRD_Waveform*);
EXPORTISMRMRD int ismrmrd_init_waveform(ISMRMRD_Waveform*);
EXPORTISMRMRD int ismrmrd_init_waveformheader(ISMRMRD_WaveformHeader* header);
EXPORTISMRMRD int ismrmrd_copy_waveform(ISMRMRD_Waveform* dest, const ISMRMRD_Waveform* src);
#ifdef __cplusplus
}
struct EXPORTISMRMRD WaveformHeader : public ISMRMRD_WaveformHeader {
// Flag methods
bool isFlagSet(const uint64_t val);
void setFlag(const uint64_t val);
void clearFlag(const uint64_t val);
void clearAllFlags();
};
struct EXPORTISMRMRD Waveform : public ISMRMRD_Waveform {
Waveform();
Waveform(const Waveform &other);
Waveform(Waveform&& other);
Waveform(uint16_t number_of_samples, uint16_t available_channels);
~Waveform();
Waveform & operator=(const Waveform &other);
Waveform & operator=(Waveform &&other);
uint32_t* begin_data();
uint32_t* end_data();
size_t size() const;
};
}
#endif
#endif //ISMRMRD_WAVEFORM_H_H
......@@ -44,6 +44,13 @@ namespace ISMRMRD
value_ = v;
}
const Optional& operator=(const Optional& o) {
present_ = o.present_;
if (present_)
value_ = o.value_;
return *this;
}
const Optional& operator=(const T& v) {
present_ = true;
value_ = v;
......@@ -289,12 +296,21 @@ namespace ISMRMRD
Optional<std::string> interleavingDimension;
};
enum class TrajectoryType {
CARTESIAN,
EPI,
RADIAL,
GOLDENANGLE,
SPIRAL,
OTHER
};
struct Encoding
{
EncodingSpace encodedSpace;
EncodingSpace reconSpace;
EncodingLimits encodingLimits;
std::string trajectory;
TrajectoryType trajectory;
Optional<TrajectoryDescription> trajectoryDescription;
Optional<ParallelImaging> parallelImaging;
Optional<long> echoTrainLength;
......@@ -310,6 +326,22 @@ namespace ISMRMRD
Optional<std::vector<float> > echo_spacing;
};
enum class WaveformType {
ECG,
PULSE,
RESPIRATORY,
TRIGGER,
GRADIENTWAVEFORM,
OTHER
};
struct WaveformInformation{
std::string waveformName;
WaveformType waveformType;
Optional<UserParameters> userParameters;
};
struct IsmrmrdHeader
{
Optional<long> version;
......@@ -320,7 +352,8 @@ namespace ISMRMRD
ExperimentalConditions experimentalConditions;
std::vector<Encoding> encoding;
Optional<SequenceParameters> sequenceParameters;
Optional<UserParameters> userParameters;
Optional<UserParameters> userParameters;
std::vector<WaveformInformation> waveformInformation;
};
......
......@@ -11,6 +11,7 @@
#endif /* __cplusplus */
#include <hdf5.h>
#include <ismrmrd/waveform.h>
#include "ismrmrd/dataset.h"
#ifdef __cplusplus
......@@ -152,13 +153,19 @@ static int delete_var(const ISMRMRD_Dataset *dset, const char *var) {
/*********************************************/
/* Private (Static) Functions for HDF5 Types */
/*********************************************/
typedef struct HDF5_Acquisition
typedef struct HDF5_Acquisiton
{
ISMRMRD_AcquisitionHeader head;
hvl_t traj;
hvl_t data;
} HDF5_Acquisition;
typedef struct HDF5_Waveform
{
ISMRMRD_WaveformHeader head;
hvl_t data;
} HDF5_Waveform;
static hid_t get_hdf5type_uint16(void) {
hid_t datatype = H5Tcopy(H5T_NATIVE_UINT16);
return datatype;
......@@ -260,6 +267,8 @@ static hid_t get_hdf5type_encoding(void) {
return datatype;
}
static hid_t get_hdf5type_acquisitionheader(void) {
hid_t datatype;
herr_t h5status;
......@@ -424,7 +433,58 @@ static hid_t get_hdf5type_image_attribute_string(void) {
}
return datatype;
}
static hid_t get_hdf5type_waveformheader(void) {
hid_t datatype;
herr_t h5status;
datatype = H5Tcreate(H5T_COMPOUND, sizeof(ISMRMRD_WaveformHeader));
h5status = H5Tinsert(datatype, "version", HOFFSET(ISMRMRD_WaveformHeader, version), H5T_NATIVE_UINT16);
h5status = H5Tinsert(datatype, "flags", HOFFSET(ISMRMRD_WaveformHeader, flags), H5T_NATIVE_UINT64);
h5status = H5Tinsert(datatype, "measurement_uid", HOFFSET(ISMRMRD_WaveformHeader, measurement_uid), H5T_NATIVE_UINT32);
h5status = H5Tinsert(datatype, "scan_counter", HOFFSET(ISMRMRD_WaveformHeader, scan_counter), H5T_NATIVE_UINT32);
h5status = H5Tinsert(datatype, "time_stamp", HOFFSET(ISMRMRD_WaveformHeader, time_stamp ), H5T_NATIVE_UINT32);
h5status = H5Tinsert(datatype, "number_of_samples", HOFFSET(ISMRMRD_WaveformHeader, number_of_samples), H5T_NATIVE_UINT16);
h5status = H5Tinsert(datatype, "channels", HOFFSET(ISMRMRD_WaveformHeader, channels), H5T_NATIVE_UINT16);
h5status = H5Tinsert(datatype, "sample_time_us", HOFFSET(ISMRMRD_WaveformHeader, sample_time_us), H5T_NATIVE_FLOAT);
h5status = H5Tinsert(datatype, "waveform_id", HOFFSET(ISMRMRD_WaveformHeader, waveform_id), H5T_NATIVE_UINT16);
/* Clean up */
if (h5status < 0) {
ISMRMRD_PUSH_ERR(ISMRMRD_FILEERROR, "Failed get waveform header data type");
}
return datatype;
}
static hid_t get_hdf5type_waveform(void) {
hid_t datatype, vartype, vlvartype;
herr_t h5status;
datatype = H5Tcreate(H5T_COMPOUND, sizeof(HDF5_Waveform));
vartype = get_hdf5type_waveformheader();
h5status = H5Tinsert(datatype, "head", HOFFSET(HDF5_Waveform, head), vartype);
if (h5status < 0) {
ISMRMRD_PUSH_ERR(ISMRMRD_FILEERROR, "Failed get waveform header data type");
}
H5Tclose(vartype);
vartype = get_hdf5type_uint32();
vlvartype = H5Tvlen_create(vartype);
h5status = H5Tinsert(datatype, "data", HOFFSET(HDF5_Waveform, data), vlvartype);
H5Tclose(vartype);
H5Tclose(vlvartype);
/* Store acquisition data as an array of floats */
if (h5status < 0) {
ISMRMRD_PUSH_ERR(ISMRMRD_FILEERROR, "Failed get waveform data type");
}
return datatype;
}
static hid_t get_hdf5type_ndarray(uint16_t data_type) {
hid_t hdfdatatype = -1;
......@@ -657,6 +717,12 @@ static int append_element(const ISMRMRD_Dataset * dset, const char * path,
offset[0] = hdfdims[0]-1;
filespace = H5Dget_space(dataset);
h5status = H5Sselect_hyperslab (filespace, H5S_SELECT_SET, offset, NULL, ext_dims, NULL);
if (h5status < 0) {
H5Ewalk2(H5E_DEFAULT, H5E_WALK_UPWARD, walk_hdf5_errors, NULL);
return ISMRMRD_PUSH_ERR(ISMRMRD_HDF5ERROR, "Failed to select hyperslab");
}
memspace = H5Screate_simple(rank, ext_dims, NULL);
free(hdfdims);
......@@ -1337,6 +1403,102 @@ int ismrmrd_read_image(const ISMRMRD_Dataset *dset, const char *varname,
return ISMRMRD_NOERROR;
}
int ismrmrd_append_waveform(const ISMRMRD_Dataset *dset, const ISMRMRD_Waveform *wav) {
int status;
char *path;
hid_t datatype;
HDF5_Waveform hdf5wav[1];
if (dset==NULL) {
return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Dataset pointer should not be NULL.");
}
if (wav==NULL) {
return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Acquisition pointer should not be NULL.");
}
/* The path to the acqusition data */
path = make_path(dset, "waveforms");
/* The acquisition datatype */
datatype = get_hdf5type_waveform();
/* Create the HDF5 version of the acquisition */
hdf5wav[0].head = wav->head;
hdf5wav[0].data.len = wav->head.number_of_samples * wav->head.channels;
hdf5wav[0].data.p = wav->data;
/* Write it */
status = append_element(dset, path, hdf5wav, datatype, 0, NULL);
if (status != ISMRMRD_NOERROR) {
return ISMRMRD_PUSH_ERR(ISMRMRD_FILEERROR, "Failed to append acquisition.");
}
free(path);
/* Clean up */
status = H5Tclose(datatype);
if (status < 0) {
H5Ewalk2(H5E_DEFAULT, H5E_WALK_UPWARD, walk_hdf5_errors, NULL);
return ISMRMRD_PUSH_ERR(ISMRMRD_HDF5ERROR, "Failed to close datatype.");
}
return ISMRMRD_NOERROR;
}
int ismrmrd_read_waveform(const ISMRMRD_Dataset *dset, uint32_t index, ISMRMRD_Waveform *wav)
{
hid_t datatype;
herr_t status;
HDF5_Waveform hdf5wav;
char *path;
if (dset==NULL) {
return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Dataset pointer should not be NULL.");
}
if (wav==NULL) {
return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Waveform pointer should not be NULL.");
}
/* The path to the acquisition data */
path = make_path(dset, "waveforms");
/* The acquisition datatype */
datatype = get_hdf5type_waveform();
status = read_element(dset, path, &hdf5wav, datatype, index);
memcpy(&wav->head, &hdf5wav.head, sizeof(ISMRMRD_WaveformHeader));
ismrmrd_make_consistent_waveform(wav);
memcpy(wav->data, hdf5wav.data.p, ismrmrd_size_of_waveform_data(wav));
/* clean up */
free(path);
free(hdf5wav.data.p);
status = H5Tclose(datatype);
if (status < 0) {
H5Ewalk2(H5E_DEFAULT, H5E_WALK_UPWARD, walk_hdf5_errors, NULL);
return ISMRMRD_PUSH_ERR(ISMRMRD_HDF5ERROR, "Failed to close datatype.");
}
return ISMRMRD_NOERROR;
}
uint32_t ismrmrd_get_number_of_waveforms(const ISMRMRD_Dataset *dset) {
char *path;
uint32_t numacq;
if (dset==NULL) {
ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Pointer should not be NULL.");
return 0;
}
/* The path to the acqusition data */
path = make_path(dset, "waveforms");
numacq = get_number_of_elements(dset, path);
free(path);
return numacq;
}
int ismrmrd_append_array(const ISMRMRD_Dataset *dset, const char *varname, const ISMRMRD_NDArray *arr) {
int status;
hid_t datatype;
......
......@@ -29,10 +29,7 @@ Dataset::Dataset(const char* filename, const char* groupname, bool create_file_i
// Destructor
Dataset::~Dataset()
{
int status = ismrmrd_close_dataset(&dset_);
if (status != ISMRMRD_NOERROR) {
throw std::runtime_error(build_exception_string());
}
ismrmrd_close_dataset(&dset_);
}
// XML Header
......@@ -57,14 +54,14 @@ void Dataset::readHeader(std::string& xmlstring){
// Acquisitions
void Dataset::appendAcquisition(const Acquisition &acq)
{
int status = ismrmrd_append_acquisition(&dset_, reinterpret_cast<const ISMRMRD_Acquisition*>(&acq));
int status = ismrmrd_append_acquisition(&dset_, &acq.acq);
if (status != ISMRMRD_NOERROR) {
throw std::runtime_error(build_exception_string());
}
}
void Dataset::readAcquisition(uint32_t index, Acquisition & acq) {
int status = ismrmrd_read_acquisition(&dset_, index, reinterpret_cast<ISMRMRD_Acquisition*>(&acq));
int status = ismrmrd_read_acquisition(&dset_, index, &acq.acq);
if (status != ISMRMRD_NOERROR) {
throw std::runtime_error(build_exception_string());
}
......@@ -93,6 +90,25 @@ void Dataset::appendImage(const std::string &var, const ISMRMRD_Image *im)
throw std::runtime_error(build_exception_string());
}
}
void Dataset::appendWaveform(const Waveform &wav) {
int status = ismrmrd_append_waveform(&dset_,&wav);
if (status != ISMRMRD_NOERROR){
throw std::runtime_error(build_exception_string());
}
}
void Dataset::readWaveform(uint32_t index, Waveform &wav) {
int status = ismrmrd_read_waveform(&dset_,index,&wav);
if (status != ISMRMRD_NOERROR){
throw std::runtime_error(build_exception_string());
}
}
uint32_t Dataset::getNumberOfWaveforms() {
return ismrmrd_get_number_of_waveforms(&dset_);
}
// Specific instantiations
template EXPORTISMRMRD void Dataset::appendImage(const std::string &var, const Image<uint16_t> &im);
template EXPORTISMRMRD void Dataset::appendImage(const std::string &var, const Image<int16_t> &im);
......
......@@ -99,9 +99,7 @@ Acquisition & Acquisition::operator= (const Acquisition &other) {
}
Acquisition::~Acquisition() {
if (ismrmrd_cleanup_acquisition(&acq) != ISMRMRD_NOERROR) {
throw std::runtime_error(build_exception_string());
}
ismrmrd_cleanup_acquisition(&acq);
}
// Accessors and mutators
......@@ -400,9 +398,7 @@ template <typename T> Image<T> & Image<T>::operator= (const Image<T> &other)
}
template <typename T> Image<T>::~Image() {
if (ismrmrd_cleanup_image(&im) != ISMRMRD_NOERROR) {
throw std::runtime_error(build_exception_string());
}
ismrmrd_cleanup_image(&im);
}
// Image dimensions
......@@ -1039,9 +1035,7 @@ template <typename T> NDArray<T>::NDArray(const NDArray<T> &other)
template <typename T> NDArray<T>::~NDArray()
{
if (ismrmrd_cleanup_ndarray(&arr) != ISMRMRD_NOERROR) {
throw std::runtime_error(build_exception_string());
}
ismrmrd_cleanup_ndarray(&arr);
}
template <typename T> NDArray<T> & NDArray<T>::operator= (const NDArray<T> &other)
......
//
// Created by dch on 28/02/18.
//
#include "ismrmrd/ismrmrd.h"
#include "ismrmrd/waveform.h"
#ifdef __cplusplus