[med-svn] [Git][med-team/ismrmrd][upstream] New upstream version 1.4.2.1

Nilesh Patra gitlab at salsa.debian.org
Sat Sep 19 22:14:41 BST 2020



Nilesh Patra pushed to branch upstream at Debian Med / ismrmrd


Commits:
8eaca132 by Nilesh Patra at 2020-09-20T01:51:54+05:30
New upstream version 1.4.2.1
- - - - -


18 changed files:

- + .cirrus.yml
- − .travis.yml
- CMakeLists.txt
- cmake/ISMRMRDConfig.cmake.in
- examples/c/main.c
- include/ismrmrd/ismrmrd.h
- include/ismrmrd/meta.h
- include/ismrmrd/waveform.h
- include/ismrmrd/xml.h
- libsrc/dataset.c
- libsrc/ismrmrd.c
- libsrc/ismrmrd.cpp
- libsrc/meta.cpp
- libsrc/waveform.cpp
- tests/CMakeLists.txt
- tests/test_main.cpp
- utilities/CMakeLists.txt
- utilities/generate_cartesian_shepp_logan.cpp


Changes:

=====================================
.cirrus.yml
=====================================
@@ -0,0 +1,24 @@
+build_task:
+  container:
+    image: gadgetron/ubuntu1604_base
+  # build_cache:
+  #   folder: build
+  make_script:
+    - mkdir build
+    - cd build
+    - cmake ..
+    - make -j
+window_task:
+  env:
+    PATH: $PATH ;C:\Program Files\CMake\bin
+    CIRRUS_SHELL: powershell
+  windows_container:
+    image: gradientsoftware/gadgetron-windows
+  make_script:
+    - mkdir build
+    - cd build
+    - cmake .. -DCMAKE_TOOLCHAIN_FILE=C:\vcpkg\scripts\buildsystems\vcpkg.cmake -G "Visual Studio 15 2017 Win64"
+    - cmake --build . --config Release
+
+
+


=====================================
.travis.yml deleted
=====================================
@@ -1,18 +0,0 @@
-language: cpp
-
-compiler:
-    - gcc
-    - clang
-
-before_install:
-    - sudo apt-get update
-install:
-    - sudo apt-get install libboost-all-dev libhdf5-serial-dev h5utils doxygen
-
-before_script:
-    - mkdir build
-    - cd build
-    - cmake --version
-    - cmake ..
-
-script: make && make check


=====================================
CMakeLists.txt
=====================================
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.8)
+cmake_minimum_required(VERSION 2.8.12)
 foreach(p
     CMP0025 # CMake 3.0 Compiler id for Apple Clang is now ``AppleClang``.
     CMP0042 # CMake 3.0 ``MACOSX_RPATH`` is enabled by default.
@@ -19,14 +19,14 @@ set (ISMRMRD_CMAKE_DIR ${PROJECT_SOURCE_DIR}/cmake CACHE PATH
 
 # command line options
 option(USE_SYSTEM_PUGIXML "Use pugixml installed on the system" OFF)
+option(USE_HDF5_DATASET_SUPPORT "Compile with support for reading and writing datasets to HDF5 files" ON)
+option(BUILD_TESTS "Build unit tests " ON)
+option(BUILD_UTILITIES "Build utilities tests " ON)
+option(BUILD_EXAMPLES "Build examples tests " ON)
 
 # and include it to the search list
 list(APPEND CMAKE_MODULE_PATH ${ISMRMRD_CMAKE_DIR})
 
-# whether to install dependencies
-if (WIN32)
-    option(ISMRMRD_INSTALL_DEPENDENCIES "Install ismrmrd dependencies in windows" Off)
-endif ()
 
 # set the build type to Release if not specified
 if(NOT CMAKE_BUILD_TYPE)
@@ -64,7 +64,7 @@ endif ()
 # For more information see http://semver.org/
 set(ISMRMRD_VERSION_MAJOR 1)
 set(ISMRMRD_VERSION_MINOR 4)
-set(ISMRMRD_VERSION_PATCH 0)
+set(ISMRMRD_VERSION_PATCH 2)
 set(ISMRMRD_VERSION_STRING ${ISMRMRD_VERSION_MAJOR}.${ISMRMRD_VERSION_MINOR}.${ISMRMRD_VERSION_PATCH})
 set(ISMRMRD_SOVERSION ${ISMRMRD_VERSION_MAJOR}.${ISMRMRD_VERSION_MINOR})
 
@@ -106,18 +106,27 @@ endif()
 
 
 # Find HDF5 for dataset support
-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_INCLUDE_DIRS})
-    set (ISMRMRD_DATASET_LIBRARIES ${HDF5_LIBRARIES})
+
+if (USE_HDF5_DATASET_SUPPORT)
+    if (VCPKG_TARGET_TRIPLET) #VCPKG HDF5 is packaged differently.
+        find_package(HDF5 CONFIG COMPONENTS C shared REQUIRED)
+        set(HDF5_C_LIBRARIES hdf5::hdf5-shared)
+    else ()
+        find_package(HDF5 COMPONENTS C REQUIRED)
+    endif ()
+    set(ISMRMRD_DATASET_SUPPORT true)
+    set(ISMRMRD_DATASET_SOURCES libsrc/dataset.c libsrc/dataset.cpp)
+    set(ISMRMRD_DATASET_INCLUDE_DIR ${HDF5_INCLUDE_DIRS})
+    set(ISMRMRD_DATASET_LIBRARIES ${HDF5_C_LIBRARIES})
     add_definitions(${HDF5_DEFINITIONS})
-	include_directories(${HDF5_INCLUDE_DIRS})
+    include_directories(${HDF5_INCLUDE_DIRS})
+    message("HDF5 found at: ${HDF5_INCLUDE_DIR}")
+    message("HDF5 found at: ${HDF5_C_LIBRARIES}")
+
 else ()
-    set (ISMRMRD_DATASET_SUPPORT false)
-    message (WARNING "HDF5 not found. Dataset and file support unavailable!")
+    set(ISMRMRD_DATASET_SUPPORT false)
+    message(WARNING " Dataset and file support unavailable!")
 endif ()
 
 # Generate the version.h header file
@@ -144,15 +153,6 @@ install(FILES ${CMAKE_BINARY_DIR}/include/ismrmrd/version.h DESTINATION include/
 
 #  ---   Main Library  (begin) ----
 # in windows, install the HDF5 dependencies
-if (HDF5_FOUND AND WIN32 AND ISMRMRD_INSTALL_DEPENDENCIES)
-    if(DEFINED ENV{HDF5_ROOT})
-        set(HDF5_BIN_DIR $ENV{HDF5_ROOT}/bin)
-    else ()
-        set(HDF5_BIN_DIR ${HDF5_C_INCLUDE_DIR}/../bin)
-    endif ()
-    message("Install hdf5 libraries from ${HDF5_BIN_DIR} ")
-    install( DIRECTORY ${HDF5_BIN_DIR} DESTINATION bin/.. FILES_MATCHING PATTERN "*.dll" )
-endif ()
 
 # include directories for main library
 set(ISMRMRD_TARGET_INCLUDE_DIRS
@@ -174,30 +174,38 @@ set(ISMRMRD_TARGET_SOURCES
 set(ISMRMRD_TARGET_LINK_LIBS ${ISMRMRD_DATASET_LIBRARIES})
 
 # optional handling of system-installed pugixml
-if(USE_SYSTEM_PUGIXML)
-  find_package(PugiXML)
-  if(PugiXML_FOUND)
-    message("Found system pugixml: ${PugiXML_INCLUDE_DIR} ${PugiXML_LIBRARY}")
-    list(APPEND ISMRMRD_TARGET_INCLUDE_DIRS ${PugiXML_INCLUDE_DIR})
-    list(APPEND ISMRMRD_TARGET_LINK_LIBS ${PugiXML_LIBRARY})
-  else()
-    message(FATAL_ERROR "Pugixml library not found on the system, try without "
-    "setting USE_SYSTEM_PUGIXML to use the version provided in the source "
-    "tree.")
-  endif()
-  list(APPEND ISMRMRD_TARGET_INCLUDE_DIRS ${PugiXML_INCLUDE_DIR})
-  list(APPEND ISMRMRD_TARGET_LINK_LIBS ${PugiXML_LIBRARY})
-else()
-  list(APPEND ISMRMRD_TARGET_SOURCES libsrc/pugixml.cpp)
-endif()
+if (USE_SYSTEM_PUGIXML)
+
+    if (VCPKG_TARGET_TRIPLET) #VCPKG .
+        find_package(PugiXML CONFIG REQUIRED)
+        list(APPEND ISMRMRD_TARGET_LINK_LIBS pugixml)
+    else ()
+        find_package(PugiXML REQUIRED)
+
+        message("Found system pugixml: ${PugiXML_INCLUDE_DIR} ${PugiXML_LIBRARY}")
+        list(APPEND ISMRMRD_TARGET_INCLUDE_DIRS ${PugiXML_INCLUDE_DIR})
+        list(APPEND ISMRMRD_TARGET_LINK_LIBS ${PugiXML_LIBRARY})
+        list(APPEND ISMRMRD_TARGET_INCLUDE_DIRS ${PugiXML_INCLUDE_DIR})
+        list(APPEND ISMRMRD_TARGET_LINK_LIBS ${PugiXML_LIBRARY})
+    endif ()
+else ()
+    list(APPEND ISMRMRD_TARGET_SOURCES libsrc/pugixml.cpp)
+endif ()
 
 # main library
 include_directories(${ISMRMRD_TARGET_INCLUDE_DIRS})
 add_library(ismrmrd SHARED ${ISMRMRD_TARGET_SOURCES})
+add_library(ismrmrd::ismrmrd ALIAS ismrmrd)
 set_target_properties(ismrmrd PROPERTIES
   VERSION ${ISMRMRD_VERSION_STRING}
   SOVERSION ${ISMRMRD_SOVERSION}
 )
+
+set_target_properties(ismrmrd
+  PROPERTIES
+  EXPORT_NAME ISMRMRD
+  INTERFACE_INCLUDE_DIRECTORIES $<INSTALL_INTERFACE:include>)
+
 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 libraries
@@ -224,13 +232,17 @@ install(FILES cmake/FindFFTW3.cmake DESTINATION share/ismrmrd/cmake COMPONENT De
 # process subdirectories
 add_subdirectory(doc)
 
-add_subdirectory(utilities)
-if (HDF5_FOUND)
+if (BUILD_UTILITIES)
+  add_subdirectory(utilities)
+endif()
+
+
+if (HDF5_FOUND AND BUILD_EXAMPLES)
     add_subdirectory(examples/c)
 endif ()
 
 # TODO: make this work on Windows
-if (NOT WIN32)
+if (BUILD_TESTS)
     add_subdirectory(tests)
 endif ()
 
@@ -239,17 +251,9 @@ install(DIRECTORY matlab DESTINATION share/ismrmrd )
 
 #--- Create cmake package for downstream projects
 #
-##- include(CMakePackageConfigHelpers)
-##- write_basic_package_version_file(
-##-   "${CMAKE_CURRENT_BINARY_DIR}/ISMRMRDConfigVersion.cmake"
-##-   VERSION ${ISMRMRD_VERSION_STRING}
-##-   COMPATIBILITY AnyNewerVersion
-##- )
-
-##- export(EXPORT ISMRMRDTargets
-##-  FILE "${CMAKE_CURRENT_BINARY_DIR}/ISMRMRDTargets.cmake"
-##-  NAMESPACE ISMRMRD
-##-)
+
+include(CMakePackageConfigHelpers)
+set(INSTALL_CONFIGDIR lib/cmake/ISMRMRD)
 
 set(CONFIG_ISMRMRD_SCHEMA_DIR   ${ISMRMRD_SCHEMA_DIR})
 set(CONFIG_ISMRMRD_TARGET_INCLUDE_DIRS ${ISMRMRD_TARGET_INCLUDE_DIRS})
@@ -264,34 +268,47 @@ 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
+
+configure_package_config_file(cmake/ISMRMRDConfig.cmake.in
   "${CMAKE_CURRENT_BINARY_DIR}/InstallFiles/ISMRMRDConfig.cmake"
-  @ONLY
-)
+  INSTALL_DESTINATION ${INSTALL_CONFIGDIR})
 
-set(ConfigPackageLocation lib/cmake/ISMRMRD)
-install(
-  FILES
-    "${CMAKE_CURRENT_BINARY_DIR}/InstallFiles/ISMRMRDConfig.cmake"
-#--    "${CMAKE_CURRENT_BINARY_DIR}/ISMRMRDConfigVersion.cmake"
-  DESTINATION
-    ${ConfigPackageLocation}
-  COMPONENT
-    Devel
-)
+write_basic_package_version_file(
+  "${CMAKE_CURRENT_BINARY_DIR}/ISMRMRDConfigVersion.cmake"
+  VERSION ${ISMRMRD_VERSION_STRING}
+  COMPATIBILITY SameMajorVersion
+  )
+
+# Write a CMake file with all the targets information
+# (not for installing, but for external project to import targets from the
+#  current build tree)
+if(CMAKE_VERSION VERSION_LESS 3.0)
+  export(TARGETS ismrmrd
+    FILE ${CMAKE_CURRENT_BINARY_DIR}/ISMRMRDTargets.cmake
+    NAMESPACE ISMRMRD::
+    )
+else()
+  export(EXPORT ISMRMRDTargets
+    FILE ${CMAKE_CURRENT_BINARY_DIR}/ISMRMRDTargets.cmake
+    NAMESPACE ISMRMRD::
+    )
+endif()
 
-install(
-  FILES
-    cmake/FindFFTW3.cmake
-  DESTINATION
-    ${ConfigPackageLocation}
-  COMPONENT
-    Devel
-)
-  
+install(EXPORT ISMRMRDTargets
+  FILE ISMRMRDTargets.cmake
+  NAMESPACE ISMRMRD::
+  DESTINATION ${INSTALL_CONFIGDIR}
+  )
+
+install(FILES
+  "${CMAKE_CURRENT_BINARY_DIR}/ISMRMRDConfigVersion.cmake"
+  "${CMAKE_CURRENT_BINARY_DIR}/InstallFiles/ISMRMRDConfig.cmake"
+  DESTINATION ${INSTALL_CONFIGDIR}
+  COMPONENT Devel)
+
+export(PACKAGE ISMRMRD)
+ 
 # Create package
 string(TOLOWER ${PROJECT_NAME} PROJECT_NAME_LOWER)
 include(${ISMRMRD_CMAKE_DIR}/ismrmrd_cpack.cmake)


=====================================
cmake/ISMRMRDConfig.cmake.in
=====================================
@@ -4,14 +4,12 @@
 #
 # This file is configured by ISMRMRD and used by the UseISMRMRD.cmake module
 # to load ISMRMRD's settings for an external project.
- at ISMRMRD_CONFIG_CODE@
 
-##- include(${CMAKE_CURRENT_LIST_DIR}/ISMRMRDConfigVersion.cmake)
+ at PACKAGE_INIT@
 
-# The ISMRMRD version number
-set(ISMRMRD_VERSION_MAJOR "@ISMRMRD_VERSION_MAJOR@")
-set(ISMRMRD_VERSION_MINOR "@ISMRMRD_VERSION_MINOR@")
-set(ISMRMRD_VERSION_PATCH "@ISMRMRD_VERSION_PATCH@")
+get_filename_component(ISMRMRD_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
+
+include(${ISMRMRD_CMAKE_DIR}/ISMRMRDConfigVersion.cmake)
 
 #   ISMRMRD_SCHEMA_DIR   - where to find ismrmrd.xsd 
 set(ISMRMRD_SCHEMA_DIR   "@CONFIG_ISMRMRD_SCHEMA_DIR@")
@@ -22,8 +20,39 @@ set(ISMRMRD_LIBRARY_DIRS "@CONFIG_ISMRMRD_LIBRARY_DIRS@")
 #   ISMRMRD_LIBRARIES    - i.e. ismrmrd
 set(ISMRMRD_LIBRARIES    "@ISMRMRD_LIBRARIES@")
 
+set(USE_SYSTEM_PUGIXML @USE_SYSTEM_PUGIXML@)
+
 ## 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@")
+
+# ------------------------------------------------------------------------------
+
+include(CMakeFindDependencyMacro)
+
+list(INSERT CMAKE_MODULE_PATH 0 ${ISMRMRD_CMAKE_DIR})
+
+if(USE_SYSTEM_PUGIXML)
+  find_package(PugiXML CONFIG)
+  if (NOT PUGIXML_FOUND)
+    find_dependency(PugiXML)
+  endif()
+endif()
+
+if(CMAKE_VERSION VERSION_LESS 3.9)
+  # CMake <= 3.8 find_dependency does not support COMPONENTS
+  find_package(HDF5 COMPONENTS C)
+else()
+  find_dependency(HDF5 COMPONENTS C)
+endif()
+
+list(REMOVE_AT CMAKE_MODULE_PATH 0)
+
+# ==============================================================================
+
+set_and_check(ISMRMRDTargets "${ISMRMRD_CMAKE_DIR}/ISMRMRDTargets.cmake")
+include(${ISMRMRDTargets})
+
+# ==============================================================================


=====================================
examples/c/main.c
=====================================
@@ -14,6 +14,12 @@ void myerror(const char *file, int line, const char *func, int code, const char
 int main(void)
 {
 
+
+    printf("%i %i %i %i %i %i %i %i %i \n",HOFFSET(ISMRMRD_WaveformHeader, version),HOFFSET(ISMRMRD_WaveformHeader, flags),
+           HOFFSET(ISMRMRD_WaveformHeader, measurement_uid),HOFFSET(ISMRMRD_WaveformHeader, scan_counter),
+           HOFFSET(ISMRMRD_WaveformHeader, time_stamp),HOFFSET(ISMRMRD_WaveformHeader, number_of_samples),
+           HOFFSET(ISMRMRD_WaveformHeader, channels),HOFFSET(ISMRMRD_WaveformHeader, sample_time_us),HOFFSET(ISMRMRD_WaveformHeader, waveform_id));
+    printf("Size %i \n",sizeof(ISMRMRD_WaveformHeader));
     /* Declarations */
     int nacq_write, n, k, c;
     ISMRMRD_Dataset dataset1;


=====================================
include/ismrmrd/ismrmrd.h
=====================================
@@ -162,6 +162,7 @@ enum ISMRMRD_AcquisitionFlags {
     ISMRMRD_ACQ_IS_RTFEEDBACK_DATA                  = 28,
     ISMRMRD_ACQ_IS_SURFACECOILCORRECTIONSCAN_DATA   = 29,
 
+
     ISMRMRD_ACQ_COMPRESSION1                        = 53,
     ISMRMRD_ACQ_COMPRESSION2                        = 54,
     ISMRMRD_ACQ_COMPRESSION3                        = 55,
@@ -420,13 +421,13 @@ bool ismrmrd_pop_error(char **file, int *line, char **func,
  *  @{
  */
 /** Calculates the determinant of the matrix and return the sign */
-EXPORTISMRMRD int ismrmrd_sign_of_directions(float read_dir[3], float phase_dir[3], float slice_dir[3]);
+EXPORTISMRMRD int ismrmrd_sign_of_directions(float const read_dir[3], float const phase_dir[3], float const slice_dir[3]);
 
 /** Creates a normalized quaternion from a 3x3 rotation matrix */
-EXPORTISMRMRD void ismrmrd_directions_to_quaternion(float read_dir[3], float phase_dir[3], float slice_dir[3], float quat[4]);
+EXPORTISMRMRD void ismrmrd_directions_to_quaternion(float const read_dir[3], float const phase_dir[3], float const slice_dir[3], float quat[4]);
 
 /** Converts a quaternion of the form | a b c d | to a 3x3 rotation matrix */
-EXPORTISMRMRD void ismrmrd_quaternion_to_directions(float quat[4], float read_dir[3], float phase_dir[3], float slice_dir[3]);
+EXPORTISMRMRD void ismrmrd_quaternion_to_directions(float const quat[4], float read_dir[3], float phase_dir[3], float slice_dir[3]);
 /** @} */
 
 #pragma pack(pop) /* Restore old alignment */
@@ -442,10 +443,14 @@ std::string build_exception_string(void);
 /// Some typedefs to beautify the namespace
 typedef  ISMRMRD_EncodingCounters EncodingCounters;
 
+
 /** @addtogroup cxxapi
  *  @{
  */
 
+
+bool operator==(const EncodingCounters& ec1, const EncodingCounters& ec2);
+
 /// Allowed data types for Images and NDArrays
 template <typename T> EXPORTISMRMRD ISMRMRD_DataTypes get_data_type();
 
@@ -476,14 +481,17 @@ public:
     // Constructors
     AcquisitionHeader();
 
+
+    bool operator==(const AcquisitionHeader& acq) const;
+
     // Flag methods
-    bool isFlagSet(const ISMRMRD_AcquisitionFlags val);
+    bool isFlagSet(const ISMRMRD_AcquisitionFlags val) const;
     void setFlag(const ISMRMRD_AcquisitionFlags val);
     void clearFlag(const ISMRMRD_AcquisitionFlags val);
     void clearAllFlags();
 
     // Channel mask methods
-    bool isChannelActive(uint16_t channel_id);
+    bool isChannelActive(uint16_t channel_id) const;
     void setChannelActive(uint16_t channel_id);
     void setChannelNotActive(uint16_t channel_id);
     void setAllChannelsNotActive();


=====================================
include/ismrmrd/meta.h
=====================================
@@ -16,247 +16,248 @@
 #include <stdexcept>
 #include <stdio.h>
 
-namespace ISMRMRD
-{
-  /*
-    The serialized version of the structues would look like this
-    
-    <?xml version="1.0"?>
-    <ismrmrdMeta>
-       <!-- String value type -->
-       <meta>
-          <name>parameter1</name>
-	  <value>value_string</value>
-       </meta>
-
-       <!-- Integer value type -->
-       <meta>
-          <name>parameter1</name>
-	  <value>677797</value>
-       </meta>
-
-       <!-- Arrays can have mixed value types -->
-       <meta>
-          <name>parameter1</name>
-	  <value>1.456</value>
-	  <value>66797</value>
-	  <value>hsjdhaks</value>
-       </meta>
-    </ismrmrdMeta>
-   */
-
-
-  /**
-     This class can represent a meta data value of any
-     type and it guarantees that any value will have a
-     representation as any type.
-
-     The class uses std::string internally to store the 
-     string representation of the value but this std::string
-     is never exposed on the class interface and so it should not 
-     need to be exported in Windows. For now, this class can be header only.
-   */
-  class MetaValue
-  {
-
-  public:
-    /** Default constructor */
-    MetaValue()
-    {
-      set(0L);
-    }
-
-    ///Null terminated string constructor
-    MetaValue(const char* s)
-    {
-      set(s);
-    }
-
-    ///Long constructor
-    MetaValue(long l)
-    {
-      set(l);
-    }
-
-    ///Long constructor
-    MetaValue(double d)
-    {
-      set(d);
-    }
-
-
-    ///Assignment operator for string
-    MetaValue& operator=(const char * s) 
-    {
-      set(s);
-      return *this;
-    }
-
-    ///Assignment operator for long
-    MetaValue& operator=(long l) 
-    {
-      set(l);
-      return *this;
-    }
-
-    ///Assignment operator for double
-    MetaValue& operator=(double d) 
-    {
-      set(d);
-      return *this;
-    }
-
-    ///Get the ingeter representation of the value
-    long as_long() const
-    {
-      return l_;
-    }
-
-    ///Get the floating point representation of the value
-    double as_double() const
-    {
-      return d_;
-    }
-    
-    ///get the C string representation of the value
-    const char* as_str() const
-    {
-      return s_.c_str();
-    }
-
-
-  protected:
-    long l_;
-    double d_;
-    std::string s_;
-
-    void set(const char* s)
-    {
-      s_ = std::string(s);
-      sscanf(s_.c_str(),"%ld",&l_);
-      sscanf(s_.c_str(),"%lf",&d_);      
-    }
-
-    void set(long l)
-    {
-      l_ = l;
-      d_ = static_cast<double>(l_);
-      std::stringstream strstream;
-      strstream << l_;
-      strstream >> s_;
-    }
-
-    void set(double d)
-    {
-      d_ = d;
-      l_ = static_cast<long>(d_);
-      std::stringstream strstream;
-      strstream << d_;
-      strstream >> s_;
-    }
-  };
-
-  class MetaContainer;
-
-  EXPORTISMRMRD void deserialize(const char* xml, MetaContainer& h);
-  EXPORTISMRMRD void serialize(MetaContainer& h, std::ostream& o);
-
-  /// Meta Container
-  class MetaContainer
-  {
-    typedef std::map< std::string, std::vector<MetaValue> > map_t;
-
-    friend void EXPORTISMRMRD serialize(MetaContainer& h, std::ostream& o);
-
-  public:
-    MetaContainer()
-    {
-
-    }
+namespace ISMRMRD {
+    /*
+      The serialized version of the structues would look like this
+
+      <?xml version="1.0"?>
+      <ismrmrdMeta>
+         <!-- String value type -->
+         <meta>
+            <name>parameter1</name>
+        <value>value_string</value>
+         </meta>
+
+         <!-- Integer value type -->
+         <meta>
+            <name>parameter1</name>
+        <value>677797</value>
+         </meta>
+
+         <!-- Arrays can have mixed value types -->
+         <meta>
+            <name>parameter1</name>
+        <value>1.456</value>
+        <value>66797</value>
+        <value>hsjdhaks</value>
+         </meta>
+      </ismrmrdMeta>
+     */
+
 
     /**
-       This function sets the parameter with name @name to 
-       value @value. The set function assumes the parameter
-       will have a single value and wipes out any array that might be there.
-       
-       There is an @append function for appending to an existing array.
+       This class can represent a meta data value of any
+       type and it guarantees that any value will have a
+       representation as any type.
+
+       The class uses std::string internally to store the
+       string representation of the value but this std::string
+       is never exposed on the class interface and so it should not
+       need to be exported in Windows. For now, this class can be header only.
      */
-    template <class T> void set(const char* name, T value)
-    {
-      MetaValue v(value);
-      map_[std::string(name)] = std::vector<MetaValue>(1,value);
-    }
-
-   
-    template <class T> void append(const char* name, T value)
-    {
-      map_t::iterator it = map_.find(std::string(name));      
-      if (it == map_.end()) {
-	set(name, value);
-      } else {
-	MetaValue v(value);
-	it->second.push_back(v);
-      }
-    }
-
-    /// Return number of values of a particular parameter
-    size_t length(const char* name) const
-    {
-      map_t::const_iterator it = map_.find(std::string(name));
-      if (it != map_.end()) {
-	return it->second.size();
-      }
-      return 0;
-    }
-
-    /// Return value number @index of the parameter @name as long
-    long as_long(const char* name, size_t index = 0) const
-    {
-      return value(name,index).as_long();
-    }
-
-    /// Return value number @index of the parameter @name as double
-    double as_double(const char* name, size_t index = 0) const
-    {
-      return value(name,index).as_double();
-    }
-    
-    /// Return value number @index of the parameter @name as string
-    const char* as_str(const char* name, size_t index = 0) const
-    {
-      return value(name,index).as_str();
-    }
-
-    const MetaValue& value(const char* name, size_t index = 0) const
-    {
-      map_t::const_iterator it = map_.find(std::string(name));
-      if (it == map_.end()) {
-	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");
-      }
-      return it->second[index];
-    }
-
-    bool empty()
-    {
-        return map_.empty();
-    }
-
-  protected:
-    map_t map_; 
-  };
-
-  //Template function instantiations
-  /*
-  template void MetaContainer::set<const char*>(const char* name, const char* value);
-  template void MetaContainer::set<long>(const char* name, long value);
-  template void MetaContainer::set<double>(const char* name, double);
-  template void MetaContainer::append<const char*>(const char* name, const char* value);
-  template void MetaContainer::append<long>(const char* name, long value);
-  template void MetaContainer::append<double>(const char* name, double);
-  */
+    class MetaValue {
+
+    public:
+        /** Default constructor */
+        MetaValue() {
+            set(0L);
+        }
+
+        ///Null terminated string constructor
+        MetaValue(const char *s) {
+            set(s);
+        }
+
+        ///Long constructor
+        MetaValue(long l) {
+            set(l);
+        }
+
+        ///Long constructor
+        MetaValue(double d) {
+            set(d);
+        }
+
+
+        ///Assignment operator for string
+        MetaValue &operator=(const char *s) {
+            set(s);
+            return *this;
+        }
+
+        ///Assignment operator for long
+        MetaValue &operator=(long l) {
+            set(l);
+            return *this;
+        }
+
+        ///Assignment operator for double
+        MetaValue &operator=(double d) {
+            set(d);
+            return *this;
+        }
+
+        ///Get the ingeter representation of the value
+        long as_long() const {
+            return l_;
+        }
+
+        ///Get the floating point representation of the value
+        double as_double() const {
+            return d_;
+        }
+
+        ///get the C string representation of the value
+        const char *as_str() const {
+            return s_.c_str();
+        }
+
+
+    protected:
+        long l_;
+        double d_;
+        std::string s_;
+
+        void set(const char *s) {
+            s_ = std::string(s);
+            sscanf(s_.c_str(), "%ld", &l_);
+            sscanf(s_.c_str(), "%lf", &d_);
+        }
+
+        void set(long l) {
+            l_ = l;
+            d_ = static_cast<double>(l_);
+            std::stringstream strstream;
+            strstream << l_;
+            strstream >> s_;
+        }
+
+        void set(double d) {
+            d_ = d;
+            l_ = static_cast<long>(d_);
+            std::stringstream strstream;
+            strstream << d_;
+            strstream >> s_;
+        }
+    };
+
+    class MetaContainer;
+
+    EXPORTISMRMRD void deserialize(const char *xml, MetaContainer &h);
+
+    EXPORTISMRMRD void serialize(const MetaContainer &h, std::ostream &o);
+
+    /// Meta Container
+    class MetaContainer {
+    protected:
+        typedef std::map<std::string, std::vector<MetaValue> > map_t;
+
+    public:
+        MetaContainer() {
+
+        }
+
+        /**
+           This function sets the parameter with name @name to
+           value @value. The set function assumes the parameter
+           will have a single value and wipes out any array that might be there.
+
+           There is an @append function for appending to an existing array.
+         */
+        template<class T>
+        void set(const char *name, T value) {
+            MetaValue v(value);
+            map_[std::string(name)] = std::vector<MetaValue>(1, value);
+        }
+
+
+        template<class T>
+        void append(const char *name, T value) {
+            map_t::iterator it = map_.find(std::string(name));
+            if (it == map_.end()) {
+                set(name, value);
+            } else {
+                MetaValue v(value);
+                it->second.push_back(v);
+            }
+        }
+
+        void remove(const char *name) {
+            map_t::iterator it = map_.find(std::string(name));
+            if (it != map_.end()) {
+                map_.erase(it);
+            }
+        }
+
+        /// Return number of values of a particular parameter
+        size_t length(const char *name) const {
+            map_t::const_iterator it = map_.find(std::string(name));
+            if (it != map_.end()) {
+                return it->second.size();
+            }
+            return 0;
+        }
+
+        /// Return value number @index of the parameter @name as long
+        long as_long(const char *name, size_t index = 0) const {
+            return value(name, index).as_long();
+        }
+
+        /// Return value number @index of the parameter @name as double
+        double as_double(const char *name, size_t index = 0) const {
+            return value(name, index).as_double();
+        }
+
+        /// Return value number @index of the parameter @name as string
+        const char *as_str(const char *name, size_t index = 0) const {
+            return value(name, index).as_str();
+        }
+
+        const MetaValue &value(const char *name, size_t index = 0) const {
+            map_t::const_iterator it = map_.find(std::string(name));
+            if (it == map_.end()) {
+                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");
+            }
+            return it->second[index];
+        }
+
+        bool empty() const {
+            return map_.empty();
+        }
+
+        map_t::iterator begin() {
+            return map_.begin();
+        }
+
+        map_t::iterator end() {
+            return map_.end();
+        }
+
+        map_t::const_iterator begin() const  {
+            return map_.begin();
+        }
+
+        map_t::const_iterator end() const  {
+            return map_.end();
+        }
+
+
+    protected:
+        map_t map_;
+    };
+
+    //Template function instantiations
+    /*
+    template void MetaContainer::set<const char*>(const char* name, const char* value);
+    template void MetaContainer::set<long>(const char* name, long value);
+    template void MetaContainer::set<double>(const char* name, double);
+    template void MetaContainer::append<const char*>(const char* name, const char* value);
+    template void MetaContainer::append<long>(const char* name, long value);
+    template void MetaContainer::append<double>(const char* name, double);
+    */
 }
 
 /** @} */


=====================================
include/ismrmrd/waveform.h
=====================================
@@ -10,6 +10,8 @@
 #include <cstdint>
 namespace ISMRMRD {
 extern "C" {
+#else
+#include <stdint.h>
 #endif
 
 typedef struct ISMRMRD_WaveformHeader
@@ -71,6 +73,8 @@ EXPORTISMRMRD int ismrmrd_copy_waveform(ISMRMRD_Waveform* dest, const ISMRMRD_Wa
 
 		uint32_t* begin_data();
 		uint32_t* end_data();
+        const uint32_t* begin_data() const;
+		const uint32_t* end_data() const;
 		size_t size() const;
     };
 }


=====================================
include/ismrmrd/xml.h
=====================================
@@ -44,19 +44,27 @@ namespace ISMRMRD
       value_ = v;      
     }
 
-	const Optional& operator=(const Optional& o) {
+	Optional& operator=(const Optional& o) {
 		present_ = o.present_;
 		if (present_)
 			value_ = o.value_;	
 		return *this;
 	}
 
-    const Optional& operator=(const T& v) {
+    Optional& operator=(const T& v) {
       present_ = true;
       value_ = v;
       return *this;
     }
 
+     T* operator->() {
+      return &value_;
+    }
+
+    T& operator*() {
+      return value_;
+    }
+
     const T* operator->() const {
       return &value_;
     }
@@ -79,6 +87,15 @@ namespace ISMRMRD
       }
       return value_;
     }
+
+
+    const T& get() const  {
+      if (!present_) {
+	throw std::runtime_error("Access optional value, which has not been set");
+      }
+      return value_;
+    }
+
     
     T& operator()() {
       return get();


=====================================
libsrc/dataset.c
=====================================
@@ -922,7 +922,7 @@ int ismrmrd_init_dataset(ISMRMRD_Dataset *dset, const char *filename,
         return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "NULL Dataset parameter");
     }
 
-    /* Disable HDF5 automatic error printing */
+    /* Disable HDF5 automatic error prenting */
     H5Eset_auto2(H5E_DEFAULT, NULL, NULL);
 
     dset->filename = (char *) malloc(strlen(filename) + 1);


=====================================
libsrc/ismrmrd.c
=====================================
@@ -565,7 +565,7 @@ int ismrmrd_set_all_channels_off(uint64_t channel_mask[ISMRMRD_CHANNEL_MASKS]) {
     return ISMRMRD_NOERROR;
 }
     
-int ismrmrd_sign_of_directions(float read_dir[3], float phase_dir[3], float slice_dir[3]) {
+int ismrmrd_sign_of_directions(float const read_dir[3], float const phase_dir[3], float const 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];
@@ -581,8 +581,8 @@ int ismrmrd_sign_of_directions(float read_dir[3], float phase_dir[3], float slic
     }
 }
 
-void ismrmrd_directions_to_quaternion(float read_dir[3], float phase_dir[3],
-                                      float slice_dir[3], float quat[4]) {
+void ismrmrd_directions_to_quaternion(float const read_dir[3], float const phase_dir[3],
+                                      float const 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];
@@ -655,7 +655,7 @@ void ismrmrd_directions_to_quaternion(float read_dir[3], float phase_dir[3],
 }
 
 /* http://www.cs.princeton.edu/~gewang/projects/darth/stuff/quat_faq.html#Q54 */
-void ismrmrd_quaternion_to_directions(float quat[4], float read_dir[3],
+void ismrmrd_quaternion_to_directions(float const 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];
     


=====================================
libsrc/ismrmrd.cpp
=====================================
@@ -8,6 +8,21 @@
 
 namespace ISMRMRD {
 
+
+bool operator==(const EncodingCounters& ec1, const EncodingCounters& ec2){
+    return ec1.kspace_encode_step_1 == ec2.kspace_encode_step_1 &&
+        ec1.kspace_encode_step_2 == ec2.kspace_encode_step_2 &&
+        ec1.average == ec2.average &&
+        ec1.slice == ec2.slice &&
+        ec1.contrast == ec2.contrast &&
+        ec1.phase == ec2.phase &&
+        ec1.repetition == ec2.repetition &&
+        ec1.set == ec2.set &&
+        ec1.segment == ec2.segment &&
+        std::equal(std::begin(ec1.user),std::end(ec1.user),std::begin(ec2.user));
+
+
+}
 //
 // AcquisitionHeader class implementation
 //
@@ -19,7 +34,7 @@ AcquisitionHeader::AcquisitionHeader() {
 }
 
 // Flag methods
-bool AcquisitionHeader::isFlagSet(const ISMRMRD_AcquisitionFlags val) {
+bool AcquisitionHeader::isFlagSet(const ISMRMRD_AcquisitionFlags val) const {
     return ismrmrd_is_flag_set(flags, val);
 }
 
@@ -36,7 +51,7 @@ void AcquisitionHeader::clearAllFlags() {
 }
 
 // Channel mask methods
-bool AcquisitionHeader::isChannelActive(uint16_t channel_id) {
+bool AcquisitionHeader::isChannelActive(uint16_t channel_id) const {
     return ismrmrd_is_channel_on(channel_mask, channel_id);
 }
 void AcquisitionHeader::setChannelActive(uint16_t channel_id) {
@@ -49,6 +64,33 @@ void AcquisitionHeader::setAllChannelsNotActive() {
     ismrmrd_set_all_channels_off(channel_mask);
 }
 
+bool AcquisitionHeader::operator==(const AcquisitionHeader &hdr) const {
+
+    return version == hdr.version &&
+           flags == hdr.flags &&
+           measurement_uid == hdr.measurement_uid &&
+           scan_counter == hdr.scan_counter &&
+           acquisition_time_stamp == hdr.acquisition_time_stamp &&
+           std::equal(std::begin(physiology_time_stamp), std::end(physiology_time_stamp), std::begin(hdr.physiology_time_stamp)) &&
+           number_of_samples == hdr.number_of_samples &&
+           available_channels == hdr.available_channels &&
+           active_channels == hdr.active_channels &&
+           std::equal(std::begin(channel_mask), std::end(channel_mask), std::begin(hdr.channel_mask)) &&
+           discard_pre == hdr.discard_pre &&
+           discard_post == hdr.discard_post &&
+           center_sample == hdr.center_sample &&
+           encoding_space_ref == hdr.encoding_space_ref &&
+           trajectory_dimensions == hdr.trajectory_dimensions &&
+           sample_time_us == hdr.sample_time_us &&
+           std::equal(std::begin(position), std::end(position), std::begin(hdr.position)) &&
+           std::equal(std::begin(read_dir), std::end(read_dir), std::begin(hdr.read_dir)) &&
+           std::equal(std::begin(phase_dir), std::end(phase_dir), std::begin(hdr.phase_dir)) &&
+           std::equal(std::begin(slice_dir), std::end(slice_dir), std::begin(hdr.slice_dir)) &&
+           std::equal(std::begin(patient_table_position), std::end(patient_table_position), std::begin(hdr.patient_table_position)) &&
+           idx == hdr.idx &&
+           std::equal(std::begin(user_int), std::end(user_int), std::begin(hdr.user_int)) &&
+           std::equal(std::begin(user_int), std::end(user_int), std::begin(hdr.user_int));
+}
 
 //
 // Acquisition class Implementation
@@ -86,6 +128,7 @@ Acquisition & Acquisition::operator= (const Acquisition &other) {
     int err = 0;
     if (this != &other )
     {
+        ismrmrd_cleanup_acquisition(&acq);
         err = ismrmrd_init_acquisition(&acq);
         if (err) {
             throw std::runtime_error(build_exception_string());
@@ -385,6 +428,7 @@ template <typename T> Image<T> & Image<T>::operator= (const Image<T> &other)
     // Assignment makes a copy
     if (this != &other )
     {
+        ismrmrd_cleanup_image(&im);
         err = ismrmrd_init_image(&im);
         if (err) {
             throw std::runtime_error(build_exception_string());
@@ -417,7 +461,7 @@ template <typename T> void Image<T>::resize(uint16_t matrix_size_x,
     if (channels == 0) {
         channels = 1;
     }
-    
+
     im.head.matrix_size[0] = matrix_size_x;
     im.head.matrix_size[1] = matrix_size_y;
     im.head.matrix_size[2] = matrix_size_z;
@@ -602,10 +646,10 @@ template <typename T> float Image<T>::getReadDirectionZ() const
 
 template <typename T> void Image<T>::setReadDirectionZ(float z)
 {
-    im.head.read_dir[2] = z;    
+    im.head.read_dir[2] = z;
 }
 
-    
+
 template <typename T> void Image<T>::setPhaseDirection(float x, float y, float z)
 {
     im.head.phase_dir[0] = x;
@@ -679,7 +723,7 @@ template <typename T> void Image<T>::setSliceDirectionZ(float z)
 {
     im.head.slice_dir[2] = z;
 }
-    
+
 template <typename T> void Image<T>::setPatientTablePosition(float x, float y, float z)
 {
     im.head.patient_table_position[0] = x;
@@ -777,7 +821,7 @@ template <typename T> void  Image<T>::setPhase(uint16_t phase)
 {
     im.head.phase = phase;
 }
-    
+
 template <typename T> uint16_t Image<T>::getRepetition() const
 {
     return im.head.repetition;
@@ -848,7 +892,7 @@ template <typename T> void Image<T>::setImageSeriesIndex(uint16_t image_series_i
     im.head.image_series_index = image_series_index;
 }
 
-    
+
 // User parameters
 template <typename T> float Image<T>::getUserFloat(unsigned int index) const
 {
@@ -911,7 +955,7 @@ template <typename T> void Image<T>::setHead(const ImageHeader &other) {
     if (other.data_type != im.head.data_type) {
         throw std::runtime_error("Cannot assign a header of a different data type.");
     }
-    
+
     memcpy(&im.head, &other, sizeof(ImageHeader));
     if (ismrmrd_make_consistent_image(&im) != ISMRMRD_NOERROR) {
         throw std::runtime_error(build_exception_string());
@@ -954,7 +998,7 @@ template <typename T> void Image<T>::setAttributeString(const char *attr)
 
     // Set the null terminator and copy the string
     im.attribute_string[length] = '\0';
-    strncpy(im.attribute_string, attr, length);
+    strncpy(im.attribute_string, attr, length+1);
 }
 
 template <typename T> size_t Image<T>::getAttributeStringLength() const
@@ -1067,7 +1111,7 @@ template <typename T> ISMRMRD_DataTypes NDArray<T>::getDataType() const {
 template <typename T> uint16_t NDArray<T>::getNDim() const {
     return  arr.ndim;
 };
-    
+
 template <typename T> const size_t (&NDArray<T>::getDims())[ISMRMRD_NDARRAY_MAXDIM] {
     return arr.dims;
 };


=====================================
libsrc/meta.cpp
=====================================
@@ -2,58 +2,53 @@
 #include "pugixml.hpp"
 
 
-namespace ISMRMRD
-{
-  void deserialize(const char* xml, MetaContainer& h)
-  {
-    pugi::xml_document doc;
-    pugi::xml_parse_result result = doc.load(xml);
-    
-    if (!result) {
-      throw std::runtime_error("Unable to load ISMRMRD Meta XML document");
-    }
+namespace ISMRMRD {
+    void deserialize(const char *xml, MetaContainer &h) {
+        pugi::xml_document doc;
+        pugi::xml_parse_result result = doc.load(xml);
 
-    pugi::xml_node root = doc.child("ismrmrdMeta");
+        if (!result) {
+            throw std::runtime_error("Unable to load ISMRMRD Meta XML document");
+        }
 
-    if (!root) {
-      throw std::runtime_error("ismrmrdMeta tag not found in meta data header");
-    }
-    
-    pugi::xml_node meta = root.child("meta");
-    while (meta) {
-      pugi::xml_node name = meta.child("name");
-      pugi::xml_node value = meta.child("value");
-
-      if (!name || !value) {
-	std::runtime_error("Malformed metadata value");
-      }
-
-      while (value) {
-	h.append(name.child_value(),value.child_value());
-	value = value.next_sibling("value");
-      }
-
-      meta = meta.next_sibling("meta");
+        pugi::xml_node root = doc.child("ismrmrdMeta");
+
+        if (!root) {
+            throw std::runtime_error("ismrmrdMeta tag not found in meta data header");
+        }
+
+        pugi::xml_node meta = root.child("meta");
+        while (meta) {
+            pugi::xml_node name = meta.child("name");
+            pugi::xml_node value = meta.child("value");
+
+            if (!name || !value) {
+                std::runtime_error("Malformed metadata value");
+            }
+
+            while (value) {
+                h.append(name.child_value(), value.child_value());
+                value = value.next_sibling("value");
+            }
+
+            meta = meta.next_sibling("meta");
+        }
     }
-  }
-
-  void serialize(MetaContainer& h, std::ostream& o)
-  {
-    pugi::xml_document doc;
-    pugi::xml_node root = doc.append_child("ismrmrdMeta");
-    
-    MetaContainer::map_t::iterator it = h.map_.begin();
-    while (it != h.map_.end()) {
-      pugi::xml_node meta = root.append_child("meta");
-      pugi::xml_node name = meta.append_child("name");
-      name.append_child(pugi::node_pcdata).set_value(it->first.c_str());
-      for (unsigned int i = 0; i < it->second.size(); i++) {
-	pugi::xml_node name = meta.append_child("value");
-	name.append_child(pugi::node_pcdata).set_value(it->second[i].as_str());
-      }
-      it++;
+
+    void serialize(const MetaContainer &h, std::ostream &o) {
+        pugi::xml_document doc;
+        pugi::xml_node root = doc.append_child("ismrmrdMeta");
+
+        for (auto &node : h) {
+            pugi::xml_node meta = root.append_child("meta");
+            pugi::xml_node name = meta.append_child("name");
+            name.append_child(pugi::node_pcdata).set_value(node.first.c_str());
+            for (unsigned int i = 0; i < node.second.size(); i++) {
+                pugi::xml_node name = meta.append_child("value");
+                name.append_child(pugi::node_pcdata).set_value(node.second[i].as_str());
+            }
+        }
+        doc.save(o);
     }
-    doc.save(o);
-  }
 
 }


=====================================
libsrc/waveform.cpp
=====================================
@@ -3,6 +3,7 @@
 //
 
 #include <cstring>
+#include <cstdlib>
 #include "ismrmrd/waveform.h"
 #include <algorithm>
 #include <ismrmrd/ismrmrd.h>
@@ -29,6 +30,14 @@ uint32_t* ISMRMRD::Waveform::end_data() {
 	return data + this->size();
 }
 
+const uint32_t* ISMRMRD::Waveform::begin_data() const {
+	return data;
+}
+
+const uint32_t* ISMRMRD::Waveform::end_data() const {
+	return data + this->size();
+}
+
 ISMRMRD::Waveform::Waveform() {
     ismrmrd_init_waveform(this);
 }
@@ -40,7 +49,7 @@ ISMRMRD::Waveform::Waveform(const Waveform &other) {
 	if (datasize == 0)
 		this->data = NULL;
 	else {
-		this->data = new uint32_t[datasize];
+		this->data = (uint32_t *)malloc(datasize* sizeof(uint32_t));
 		memcpy(this->data, other.data, other.size() * sizeof(uint32_t));
 	}
 


=====================================
tests/CMakeLists.txt
=====================================
@@ -5,6 +5,10 @@ if (NOT Boost_UNIT_TEST_FRAMEWORK_FOUND)
     return()
 endif ()
 
+if (NOT Boost_USE_STATIC_LIBS)
+    add_definitions(-DBOOST_TEST_DYN_LINK)
+endif()
+
 include_directories(${CMAKE_SOURCE_DIR}/include ${CMAKE_BINARY_DIR}/include ${Boost_INCLUDE_DIR})
 
 add_executable(test_ismrmrd


=====================================
tests/test_main.cpp
=====================================
@@ -1,4 +1,3 @@
-#define BOOST_TEST_DYN_LINK
 #define BOOST_TEST_MODULE "ISMRMRD Unit Tests"
 #include <boost/test/unit_test.hpp>
 


=====================================
utilities/CMakeLists.txt
=====================================
@@ -40,31 +40,21 @@ if (HDF5_FOUND)
         add_executable(ismrmrd_generate_cartesian_shepp_logan
             generate_cartesian_shepp_logan.cpp
             ismrmrd_phantom.cpp)
-        if(WIN32)
-            target_link_libraries( ismrmrd_generate_cartesian_shepp_logan
-                ismrmrd
-                ${FFTW3_LIBRARIES})
-        else()
-            target_link_libraries( ismrmrd_generate_cartesian_shepp_logan
-                ismrmrd
-                ${Boost_PROGRAM_OPTIONS_LIBRARY}
-                ${FFTW3_LIBRARIES})
-        endif()
+        target_link_libraries( ismrmrd_generate_cartesian_shepp_logan
+            ismrmrd
+            ${Boost_PROGRAM_OPTIONS_LIBRARY}
+            ${FFTW3_LIBRARIES})
+        
         install(TARGETS ismrmrd_generate_cartesian_shepp_logan DESTINATION bin)
 
         # Shepp-Logan phantom
         add_executable(ismrmrd_recon_cartesian_2d
             recon_cartesian_2d.cpp)
-        if(WIN32)
-            target_link_libraries( ismrmrd_recon_cartesian_2d
-                ismrmrd
-                ${FFTW3_LIBRARIES})
-        else()
-            target_link_libraries( ismrmrd_recon_cartesian_2d
-                ismrmrd
-                ${Boost_PROGRAM_OPTIONS_LIBRARY}
-                ${FFTW3_LIBRARIES})
-        endif()
+		target_link_libraries( ismrmrd_recon_cartesian_2d
+            ismrmrd
+            ${Boost_PROGRAM_OPTIONS_LIBRARY}
+            ${FFTW3_LIBRARIES})
+
         install(TARGETS ismrmrd_recon_cartesian_2d DESTINATION bin)
 
     else()


=====================================
utilities/generate_cartesian_shepp_logan.cpp
=====================================
@@ -36,6 +36,7 @@ int main(int argc, char** argv)
 	unsigned int ros;           //Readout ovesampling
 	unsigned int repetitions;
 	unsigned int acc_factor;
+	unsigned int cal_width; // Calibration area width (readouts)
 	float noise_level;
 	std::string outfile;
 	std::string dataset;
@@ -49,8 +50,9 @@ int main(int argc, char** argv)
 	    ("coils,c", po::value<unsigned int>(&ncoils)->default_value(8), "Number of Coils")
 	    ("oversampling,O", po::value<unsigned int>(&ros)->default_value(2), "Readout oversampling")
 	    ("repetitions,r", po::value<unsigned int>(&repetitions)->default_value(1), "Repetitions")
-	    ("acceleration,a", po::value<unsigned int>(&acc_factor)->default_value(1), "Acceleration factor")
-	    ("noise-level,n", po::value<float>(&noise_level)->default_value(0.05f,"0.05"), "Noise Level")
+		("acceleration,a", po::value<unsigned int>(&acc_factor)->default_value(1), "Acceleration factor")
+		("calibration-width,w", po::value<unsigned int>(&cal_width)->default_value(0), "Callibration area width")
+		("noise-level,n", po::value<float>(&noise_level)->default_value(0.05f,"0.05"), "Noise Level")
 	    ("output,o", po::value<std::string>(&outfile)->default_value("testdata.h5"), "Output File Name")
 	    ("dataset,d", po::value<std::string>(&dataset)->default_value("dataset"), "Output Dataset Name")
 	    ("noise-calibration,C", po::value<bool>(&noise_calibration)->zero_tokens(), "Add noise calibration")
@@ -116,6 +118,9 @@ int main(int argc, char** argv)
         acq.available_channels() = ncoils;
 	acq.center_sample() = (readout>>1);
 
+	int hw = cal_width/2;
+	int from = matrix_size / 2 - hw;
+	int till = matrix_size / 2 + hw - 1;
 
         for (unsigned int r = 0; r < repetitions; r++) {
             for (unsigned int a = 0; a < acc_factor; a++) {
@@ -123,17 +128,27 @@ int main(int argc, char** argv)
                 fft2c(cm);
 
                 add_noise(cm,noise_level);
-                for (size_t i = a; i < matrix_size; i+=acc_factor) {
-                    acq.clearAllFlags();
-                    
+                for (size_t i = 0; i < matrix_size; i++) {
+
+                    if ((i - a)%acc_factor && !(i >= from && i <= till))
+                        continue; // skip this readout
+
                     //Set some flags
+                    acq.clearAllFlags();
                     if (i == a) {
                         acq.setFlag(ISMRMRD_ACQ_FIRST_IN_SLICE);
                     }
-                    if (i >= (matrix_size-acc_factor)) {
+                    else if (i >= (matrix_size-acc_factor)) {
                         acq.setFlag(ISMRMRD_ACQ_LAST_IN_SLICE);
                     }
-                    acq.idx().kspace_encode_step_1 = i;
+                    else if (i >= from && i <= till) {
+                        if ((i - a) % acc_factor)
+                            acq.setFlag(ISMRMRD_ACQ_IS_PARALLEL_CALIBRATION);
+                        else
+                            acq.setFlag(ISMRMRD_ACQ_IS_PARALLEL_CALIBRATION_AND_IMAGING);
+                    }
+
+					acq.idx().kspace_encode_step_1 = i;
                     acq.idx().repetition = r*acc_factor + a;
                     acq.sample_time_us() = 5.0;
                     for (size_t c = 0; c < ncoils; c++) {



View it on GitLab: https://salsa.debian.org/med-team/ismrmrd/-/commit/8eaca132350557d91f9b58110347622ddaf7fead

-- 
View it on GitLab: https://salsa.debian.org/med-team/ismrmrd/-/commit/8eaca132350557d91f9b58110347622ddaf7fead
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/debian-med-commit/attachments/20200919/8102e1ba/attachment-0001.html>


More information about the debian-med-commit mailing list