[ismrmrd] 10/281: First version of README file with basic documentation
Ghislain Vaillant
ghisvail-guest at moszumanska.debian.org
Wed Jan 14 20:00:49 UTC 2015
This is an automated email from the git hooks/post-receive script.
ghisvail-guest pushed a commit to annotated tag ismrmrd0.5
in repository ismrmrd.
commit 8b4f677441c0dac8a0f006e82d83ba90cf5cd982
Author: Michael S. Hansen <michael.hansen at nih.gov>
Date: Fri Aug 10 21:55:57 2012 -0400
First version of README file with basic documentation
---
README.html | 829 +++++++++++++++++++++++++++++++++++++++++++++
doc/README.rst | 265 ++++++++++++++-
ismrmrd.h | 4 +-
ismrmrd_hdf5_datatypes.h | 2 +-
main.cpp | 6 +-
schema/ismrmrd.xsd | 2 +-
schema/ismrmrd_example.xml | 100 +++---
7 files changed, 1132 insertions(+), 76 deletions(-)
diff --git a/README.html b/README.html
new file mode 100644
index 0000000..d35a3b8
--- /dev/null
+++ b/README.html
@@ -0,0 +1,829 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.8.1: http://docutils.sourceforge.net/" />
+<title>Magnetic Resonance Raw Data Standard</title>
+<style type="text/css">
+
+/*
+:Author: David Goodger (goodger at python.org)
+:Id: $Id: html4css1.css 7056 2011-06-17 10:50:48Z milde $
+:Copyright: This stylesheet has been placed in the public domain.
+
+Default cascading style sheet for the HTML output of Docutils.
+
+See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
+customize this style sheet.
+*/
+
+/* used to remove borders from tables and images */
+.borderless, table.borderless td, table.borderless th {
+ border: 0 }
+
+table.borderless td, table.borderless th {
+ /* Override padding for "table.docutils td" with "! important".
+ The right padding separates the table cells. */
+ padding: 0 0.5em 0 0 ! important }
+
+.first {
+ /* Override more specific margin styles with "! important". */
+ margin-top: 0 ! important }
+
+.last, .with-subtitle {
+ margin-bottom: 0 ! important }
+
+.hidden {
+ display: none }
+
+a.toc-backref {
+ text-decoration: none ;
+ color: black }
+
+blockquote.epigraph {
+ margin: 2em 5em ; }
+
+dl.docutils dd {
+ margin-bottom: 0.5em }
+
+object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
+ overflow: hidden;
+}
+
+/* Uncomment (and remove this text!) to get bold-faced definition list terms
+dl.docutils dt {
+ font-weight: bold }
+*/
+
+div.abstract {
+ margin: 2em 5em }
+
+div.abstract p.topic-title {
+ font-weight: bold ;
+ text-align: center }
+
+div.admonition, div.attention, div.caution, div.danger, div.error,
+div.hint, div.important, div.note, div.tip, div.warning {
+ margin: 2em ;
+ border: medium outset ;
+ padding: 1em }
+
+div.admonition p.admonition-title, div.hint p.admonition-title,
+div.important p.admonition-title, div.note p.admonition-title,
+div.tip p.admonition-title {
+ font-weight: bold ;
+ font-family: sans-serif }
+
+div.attention p.admonition-title, div.caution p.admonition-title,
+div.danger p.admonition-title, div.error p.admonition-title,
+div.warning p.admonition-title {
+ color: red ;
+ font-weight: bold ;
+ font-family: sans-serif }
+
+/* Uncomment (and remove this text!) to get reduced vertical space in
+ compound paragraphs.
+div.compound .compound-first, div.compound .compound-middle {
+ margin-bottom: 0.5em }
+
+div.compound .compound-last, div.compound .compound-middle {
+ margin-top: 0.5em }
+*/
+
+div.dedication {
+ margin: 2em 5em ;
+ text-align: center ;
+ font-style: italic }
+
+div.dedication p.topic-title {
+ font-weight: bold ;
+ font-style: normal }
+
+div.figure {
+ margin-left: 2em ;
+ margin-right: 2em }
+
+div.footer, div.header {
+ clear: both;
+ font-size: smaller }
+
+div.line-block {
+ display: block ;
+ margin-top: 1em ;
+ margin-bottom: 1em }
+
+div.line-block div.line-block {
+ margin-top: 0 ;
+ margin-bottom: 0 ;
+ margin-left: 1.5em }
+
+div.sidebar {
+ margin: 0 0 0.5em 1em ;
+ border: medium outset ;
+ padding: 1em ;
+ background-color: #ffffee ;
+ width: 40% ;
+ float: right ;
+ clear: right }
+
+div.sidebar p.rubric {
+ font-family: sans-serif ;
+ font-size: medium }
+
+div.system-messages {
+ margin: 5em }
+
+div.system-messages h1 {
+ color: red }
+
+div.system-message {
+ border: medium outset ;
+ padding: 1em }
+
+div.system-message p.system-message-title {
+ color: red ;
+ font-weight: bold }
+
+div.topic {
+ margin: 2em }
+
+h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
+h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
+ margin-top: 0.4em }
+
+h1.title {
+ text-align: center }
+
+h2.subtitle {
+ text-align: center }
+
+hr.docutils {
+ width: 75% }
+
+img.align-left, .figure.align-left, object.align-left {
+ clear: left ;
+ float: left ;
+ margin-right: 1em }
+
+img.align-right, .figure.align-right, object.align-right {
+ clear: right ;
+ float: right ;
+ margin-left: 1em }
+
+img.align-center, .figure.align-center, object.align-center {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+.align-left {
+ text-align: left }
+
+.align-center {
+ clear: both ;
+ text-align: center }
+
+.align-right {
+ text-align: right }
+
+/* reset inner alignment in figures */
+div.align-right {
+ text-align: inherit }
+
+/* div.align-center * { */
+/* text-align: left } */
+
+ol.simple, ul.simple {
+ margin-bottom: 1em }
+
+ol.arabic {
+ list-style: decimal }
+
+ol.loweralpha {
+ list-style: lower-alpha }
+
+ol.upperalpha {
+ list-style: upper-alpha }
+
+ol.lowerroman {
+ list-style: lower-roman }
+
+ol.upperroman {
+ list-style: upper-roman }
+
+p.attribution {
+ text-align: right ;
+ margin-left: 50% }
+
+p.caption {
+ font-style: italic }
+
+p.credits {
+ font-style: italic ;
+ font-size: smaller }
+
+p.label {
+ white-space: nowrap }
+
+p.rubric {
+ font-weight: bold ;
+ font-size: larger ;
+ color: maroon ;
+ text-align: center }
+
+p.sidebar-title {
+ font-family: sans-serif ;
+ font-weight: bold ;
+ font-size: larger }
+
+p.sidebar-subtitle {
+ font-family: sans-serif ;
+ font-weight: bold }
+
+p.topic-title {
+ font-weight: bold }
+
+pre.address {
+ margin-bottom: 0 ;
+ margin-top: 0 ;
+ font: inherit }
+
+pre.literal-block, pre.doctest-block, pre.math {
+ margin-left: 2em ;
+ margin-right: 2em }
+
+span.classifier {
+ font-family: sans-serif ;
+ font-style: oblique }
+
+span.classifier-delimiter {
+ font-family: sans-serif ;
+ font-weight: bold }
+
+span.interpreted {
+ font-family: sans-serif }
+
+span.option {
+ white-space: nowrap }
+
+span.pre {
+ white-space: pre }
+
+span.problematic {
+ color: red }
+
+span.section-subtitle {
+ /* font-size relative to parent (h1..h6 element) */
+ font-size: 80% }
+
+table.citation {
+ border-left: solid 1px gray;
+ margin-left: 1px }
+
+table.docinfo {
+ margin: 2em 4em }
+
+table.docutils {
+ margin-top: 0.5em ;
+ margin-bottom: 0.5em }
+
+table.footnote {
+ border-left: solid 1px black;
+ margin-left: 1px }
+
+table.docutils td, table.docutils th,
+table.docinfo td, table.docinfo th {
+ padding-left: 0.5em ;
+ padding-right: 0.5em ;
+ vertical-align: top }
+
+table.docutils th.field-name, table.docinfo th.docinfo-name {
+ font-weight: bold ;
+ text-align: left ;
+ white-space: nowrap ;
+ padding-left: 0 }
+
+h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
+h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
+ font-size: 100% }
+
+ul.auto-toc {
+ list-style-type: none }
+
+</style>
+</head>
+<body>
+<div class="document" id="magnetic-resonance-raw-data-standard">
+<h1 class="title">Magnetic Resonance Raw Data Standard</h1>
+
+<p>DRAFT - Version 0.1 - July 2012</p>
+<div class="section" id="todo">
+<h1>TODO</h1>
+<ul>
+<li><p class="first">Make More Example Datasets</p>
+<blockquote>
+<ul class="simple">
+<li>Radial</li>
+<li>Diffusion</li>
+<li>Phase contrast flow</li>
+</ul>
+</blockquote>
+</li>
+<li><p class="first">Flag definitions.</p>
+<blockquote>
+<ul class="simple">
+<li>Do we need more flags?</li>
+</ul>
+</blockquote>
+</li>
+<li><p class="first">Converters for vendor raw data</p>
+<blockquote>
+<ul class="simple">
+<li>Siemens (Hansen)</li>
+<li>Philips (Kozerke? Boernert?)</li>
+<li>GE (Hargreaves?)</li>
+<li>Bruker (Hansen?)</li>
+</ul>
+</blockquote>
+</li>
+</ul>
+</div>
+<div class="section" id="change-log">
+<h1>Change log</h1>
+<p>August 2012 - First draft.</p>
+</div>
+<div class="section" id="preamble">
+<h1>Preamble</h1>
+<p>A prerequisite for sharing magnetic resonance (imaging) reconstruction algorithms and code is a common raw data format. This document describes such a common raw data format and attempts to capture all the data fields that are require to describe enough details about the magnetic resonance experiment to reconstruct images from the data.</p>
+<p>This standard was developed by a subcommittee of the ISMRM Sedona 2013 workshop. Comments and requests for additions/modifications can be sent to:</p>
+<ul class="simple">
+<li>Michael S. Hansen (<a class="reference external" href="mailto:michael.hansen@nih.gov">michael.hansen@nih.gov</a>)</li>
+<li>Wally Block (<a class="reference external" href="mailto:wblock@cae.wisc.edu">wblock@cae.wisc.edu</a>)</li>
+<li>Mark Griswold (<a class="reference external" href="mailto:mag46@case.edu">mag46@case.edu</a>)</li>
+<li>Brian Hargreaves (<a class="reference external" href="mailto:bah@stanford.edu">bah@stanford.edu</a>)</li>
+<li>Peter Boernert (<a class="reference external" href="mailto:peter.boernert@philips.com">peter.boernert@philips.com</a>)</li>
+</ul>
+</div>
+<div class="section" id="overview">
+<h1>Overview</h1>
+<p>The raw data format combines a mix of flexible data structures (XML header) and fixed structures (equivalent to C-structs). A raw data set consist of 2 sections:</p>
+<ol class="arabic simple">
+<li>A flexible XML format document that can contain an arbitrary number of fields and accomodate everything from simple values (b-values, etc.) to entire vendor protocols, etc. This purpose of this XML document is to provide parameters that may be meaningful for some experiments but not for others. This XML format is defined by an XML Schema Definition file (ismrmrd.xsd).</li>
+<li>Raw data section. This section contains all the acquired data in the experiment. Each data item is preceeded by a C-struct with encoding numbers, etc. Following this data header is a channel header and data for each acquired channel. The raw data headers are defined in a C/C++ header file (ismrmrd.h)</li>
+</ol>
+<div class="section" id="flexible-data-header">
+<h2>Flexible Data Header</h2>
+<p>The flexible data structure is defined by the xml schema definition in <tt class="docutils literal">schema/ismrmrd.xsd</tt> (<a class="reference internal" href="#schema">schema</a> is included in appendix below).</p>
+<p>An example of an XML file for a Cartesian 3D acquisition could look like:</p>
+<pre class="literal-block">
+<?xml version="1.0"?>
+<ismrmrdHeader xmlns="http://www.ismrm.org/ISMRMRD" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:schemaLocation="http://www.ismrm.org/ISMRMRD ismrmrd.xsd">
+ <subjectInformation>
+ <patientName>phantom</patientName>
+ <patientWeight_kg>70.3068</patientWeight_kg>
+ </subjectInformation>
+ <acquisitionSystemInformation>
+ <systemVendor>SIEMENS</systemVendor>
+ <systemModel>Avanto</systemModel>
+ <systemFieldStrength_T>1.494</systemFieldStrength_T>
+ <receiverChannels>32</receiverChannels>
+ </acquisitionSystemInformation>
+ <experimentalConditions>
+ <H1resonanceFrequency_Hz>63642459</H1resonanceFrequency_Hz>
+ </experimentalConditions>
+ <encoding>
+ <trajectory>cartesian</trajectory>
+ <encodedSpace>
+ <matrixSize>
+ <x>256</x>
+ <y>140</y>
+ <z>80</z>
+ </matrixSize>
+ <fieldOfView_mm>
+ <x>600</x>
+ <y>328.153125</y>
+ <z>160</z>
+ </fieldOfView_mm>
+ </encodedSpace>
+ <reconSpace>
+ <matrixSize>
+ <x>128</x>
+ <y>116</y>
+ <z>64</z>
+ </matrixSize>
+ <fieldOfView_mm>
+ <x>300</x>
+ <y>271.875</y>
+ <z>128</z>
+ </fieldOfView_mm>
+ </reconSpace>
+ <encodingLimits>
+ <kspace_encoding_step_1>
+ <minimum>0</minimum>
+ <maximum>83</maximum>
+ <center>28</center>
+ </kspace_encoding_step_1>
+ <kspace_encoding_step_2>
+ <minimum>0</minimum>
+ <maximum>45</maximum>
+ <center>20</center>
+ </kspace_encoding_step_2>
+ <slice>
+ <minimum>0</minimum>
+ <maximum>0</maximum>
+ <center>0</center>
+ </slice>
+ </encodingLimits>
+ </encoding>
+ <sequenceTiming>
+ <TR>4.6</TR>
+ <TE>2.35</TE>
+ <TI>300</TI>
+ </sequenceTiming>
+</ismrmrdHeader>
+
+
+</pre>
+<p>The most critical elements for image reconstruction are contained in the <tt class="docutils literal"><encoding></tt> section of the document, which describes the encoded spaced and also the target reconstructed space. Along with the <tt class="docutils literal"><encodingLimits></tt> this section allows the reconstruction program to determine matrix sizes, oversampling factors, partial fourier, etc. In the example above, data is acquired with two-fold oversampling in the r [...]
+<pre class="literal-block">
+0 70 139
+|-------------------------------------|-------------------------------------------|
+ ****************************************************
+ ^ ^ ^
+ 0 28 83
+</pre>
+<p>After FFT, only the central 116 lines are kept, i.e. there is a reduced field of view in the phase encoding direction. Center and encoding limits for the readout dimension is not given in the XML header. This is to accomodate sequences where the center of the readout may change from readout to readout (alternating directions of readout). There is a field on the individual data headers (see below) to indicate the center of the readout.</p>
+<p>An experiment can have multiple encoding spaces and it is possible to indicate on each acquired data readout, which encoding space the data belongs to (see below).</p>
+<p>In addition to the defined field in the xml header, it is possible to add an arbitrary number of user defined parameters to accomodate special sequence parameters. Please consult the xml <a class="reference internal" href="#schema">schema</a> to see how user parameters are defined. Briefly, the XML header can have a section at the end which looks like:</p>
+<pre class="literal-block">
+<userParameters>
+ <userParameterLong>
+ <name>MyVar1</name><value>1003</value>
+ </userParameterLong>
+ <userParameterLong>
+ <name>MyVar2</name><value>1999</value>
+ </userParameterLong>
+ <userParameterDouble>
+ <name>MyDoubleVar</name><value>87.6676</value>
+ </userParameterDouble>
+</userParameters>
+</pre>
+</div>
+<div class="section" id="fixed-data-structures">
+<h2>Fixed Data structures</h2>
+<p>Each acquisition is preceeded by the following fixed layout structure:</p>
+<pre class="literal-block">
+ 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[3]; //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[16]; //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[3]; //Three-dimensional spatial offsets from isocenter
+ float quaternion[4]; //Angulation of acquisition
+ float patient_table_position[3]; //Patient table off-center
+ EncodingCounters idx; //Encoding loop counters, see above
+ int32_t user_int[8]; //Free user parameters
+ float user_float[8]; //Free user parameters
+ };
+
+</pre>
+<p>Where EncodingCounters are defined as:</p>
+<pre class="literal-block">
+ 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[8]; //Free user parameters
+ };
+
+</pre>
+<p>The interpretation of some of these fields may vary from sequence to sequence, i.e. for a Cartesian sequence, <tt class="docutils literal">kspace_encode_step_1</tt> would be the phase encoding step, for a spiral sequence where phase encoding direction does not make sense, it would be the spiral interleave number. The <tt class="docutils literal">encoding_space_ref</tt> enables the user to tie an acquisition to a specific encoding space (see above) in case there are multiple, e.g. in s [...]
+<p>The flags field is a bitmask, which in principle can be used freely by the user, but suggested flag values are given in <tt class="docutils literal">ismrmrd.h</tt>, it is recommended not to use already designated flag bits for custom purposes. Ther are a set of bits reserved for prototyping (bits 57-64), please see <tt class="docutils literal">ismrmrd.h</tt> for details.</p>
+<p>The header contains a <tt class="docutils literal">trajectory_dimensions</tt> field. If the value of this field is larger than 0, it means that trajectories are stored with each invidual acquisition. For a 2D acquisition, the <tt class="docutils literal">trajectory_dimensions</tt> would typically be 2 and the convention (for memory layout) is that the header is followed immediately by the trajectory before the complex data. There is an example of how this memory layout could be implem [...]
+<pre class="literal-block">
+class Acquisition
+{
+
+//....
+
+AcquisitionHeader head_; //Header, see above
+
+float* traj_; //Trajectory, elements = head_.trajectory_dimensions*head_.number_of_samples
+ // [kx,ky,kx,ky.....] (for head_.trajectory_dimensions = 2)
+ // [kx,ky,kz,kx,ky,kz,.....] (for head_.trajectory_dimensions = 3)
+
+float* data_; //Actual data, elements = head_.number_of_samples*head_.active_channels*2
+ // [re,im,re,im,.....,re,im,re,im,.....,re,im,re,im,.....]
+ // ---channel 1-------channel 2---------channel 3-----
+
+};
+</pre>
+<p>This suggested memory layout is only a suggestion. The HDF5 interface (see below) can be used to read the data into many different datastructures. In fact, the user can choose to read only part of the header or not read the data, etc.</p>
+</div>
+</div>
+<div class="section" id="file-storage">
+<h1>File Storage</h1>
+<p>The ISMRM Raw Data format is stored in HDF5 format. Details on this format can be found at the <a class="reference external" href="http://www.hdfgroup.org/HDF5/">HDF5</a> website. Briefly it is a hierarchical dataformat (much like a file system), which can contain multiple variable organized in groups (like folders in a file system). The variables can contain arrays of data values, custom defined structs, or simple text fields. It is the convention (but not a requirement) that the ISM [...]
+<pre class="literal-block">
+>> data = h5read('simple_gre.h5', '/dataset/data');
+>> data
+
+data =
+
+head: [1x1 struct]
+traj: {1x1281 cell}
+data: {1x1281 cell}
+
+ >> data.head
+
+ ans =
+
+ version: [1x1281 uint16]
+ flags: [1x1281 uint64]
+ measurement_uid: [1x1281 uint32]
+ scan_counter: [1x1281 uint32]
+ acquisition_time_stamp: [1x1281 uint32]
+ physiology_time_stamp: [3x1281 uint32]
+ number_of_samples: [1x1281 uint16]
+ available_channels: [1x1281 uint16]
+ active_channels: [1x1281 uint16]
+ channel_mask: [16x1281 uint64]
+ discard_pre: [1x1281 uint16]
+ discard_post: [1x1281 uint16]
+ center_sample: [1x1281 uint16]
+ encoding_space_ref: [1x1281 uint16]
+ trajectory_dimensions: [1x1281 uint16]
+ sample_time_us: [1x1281 single]
+ position: [3x1281 single]
+ quaternion: [4x1281 single]
+ patient_table_position: [3x1281 single]
+ idx: [1x1 struct]
+ user_int: [8x1281 int32]
+ user_float: [8x1281 single]
+
+ >>
+</pre>
+<p>The HDF5 file format can be access from C, C++, and java using the libraries provided on the HDF5 website. The ISMRMRD distribution also comes with some C++ wrappers that can be used for easy access (read and write) from C++ programs. See below.</p>
+</div>
+<div class="section" id="c-support-library">
+<h1>C++ Support Library</h1>
+<p>To enable easy prototyping of C++ software using the ISMRMRD data format, a simple C++ wrapper class is provided (defined in <tt class="docutils literal">ismrmrd_hdf5.h</tt>):</p>
+<pre class="literal-block">
+class EXPORTISMRMRD IsmrmrdDataset
+{
+ public:
+ IsmrmrdDataset(const char* filename, const char* groupname, bool create_file_if_needed = true);
+ int appendAcquisition(Acquisition* a);
+ int writeHeader(std::string& xml);
+
+ boost::shared_ptr<std::string> readHeader();
+ boost::shared_ptr<Acquisition> readAcquisition(unsigned long index = 0);
+ unsigned long getNumberOfAcquisitions();
+ };
+</pre>
+<p>Using this wrapper, C++ applications can be programmed as:</p>
+<pre class="literal-block">
+boost::shared_ptr<ISMRMRD::IsmrmrdDataset> ismrmrd_dataset(new ISMRMRD::IsmrmrdDataset(hdf5_in_data_file,hdf5_in_group));
+boost::shared_ptr<std::string> xml_config = ismrmrd_dataset->readHeader();
+
+//Do something with the header
+
+unsigned long acquisitions = ismrmrd_dataset->getNumberOfAcquisitions();
+
+for (unsigned long int i = 0; i < acquisitions; i++) {
+ boost::shared_ptr<ISMRMRD::Acquisition> acq_tmp = ismrmrd_dataset->readAcquisition(i);
+ //Do something with the data
+}
+</pre>
+<p>Since the XML part of the header is defined in the <tt class="docutils literal">schema/ismrmrd.xsd</tt> file, it is possible to use XML data binding tools such as CodeSynthesys XSD to generate a C++ class representation of the header for easy access to the fields. The <tt class="docutils literal">cmake</tt> build files that accompany the ISMRMRD distribution automatically tries to find CodeSynthesis XSD and generate such a binding. With the C++ representation of the header it can be p [...]
+<pre class="literal-block">
+xml_schema::properties props;
+props.schema_location ("http://www.ismrm.org/ISMRMRD",std::string("/full/path/to/ismrmrd.xsd"));
+std::istringstream str_stream(xml, std::stringstream::in);
+boost::shared_ptr<ISMRMRD::ismrmrdHeader> cfg;
+
+try {
+ cfg = boost::shared_ptr<ISMRMRD::ismrmrdHeader>(ISMRMRD::ismrmrdHeader_ (str_stream,0,props));
+} catch (const xml_schema::exception& e) {
+ std::cout << "Failed to parse XML Parameters: " << e.what() << std::endl;
+}
+
+//Use the configuration, e.g.:
+std::cout << "Number of encoding spaces: " << cfg->encoding().size() << std::endl;
+</pre>
+<p>Again, this is not a requirement for using the ISMRMRD format, the XML can be parsed with numerous other xml parsing libraries. The schema file <tt class="docutils literal">schema/ismrmrd.xsd</tt> gives the user the option of validating the XML header before parsing, which is recommeded to reduce the chance of hard to detect errors in your code due to missing or malformed parameters.</p>
+</div>
+<div class="section" id="matlab-example-code-and-datasets">
+<h1>Matlab Example Code and Datasets</h1>
+<p>The <tt class="docutils literal">examples</tt> folder contains datasets and some matlab code to illustrate simple interaction with the ISMRMRD data format. For instance, to reconstruct a 2D Cartesian acquisition (10 image repetitions), type (from the <tt class="docutils literal">examples/matlab</tt> folder):</p>
+<pre class="literal-block">
+>> images = simple_cartesian_recon('../data/simple_gre.h5');
+Reconstructing image 1....done
+Reconstructing image 2....done
+Reconstructing image 3....done
+Reconstructing image 4....done
+Reconstructing image 5....done
+Reconstructing image 6....done
+Reconstructing image 7....done
+Reconstructing image 8....done
+Reconstructing image 9....done
+Reconstructing image 10....done
+>>
+</pre>
+<p>You should see one of the reconstructed images display. An example is also given of a 3D acquisition with partial Fourier, phase and slice oversampling, etc. Reconstruct this dataset with:</p>
+<pre class="literal-block">
+>> images = simple_cartesian_recon('../data/3D_partial_fourier.h5');
+Reconstructing image 1....done
+</pre>
+<p>The center slice of the volume should be displayed at the end of the reconstruction.</p>
+<p>Finally, there is also a spiral dataset. This dataset illustrates how the flexible section of the <tt class="docutils literal"><trajectoryDescription></tt> can be used to add user defined parameters and an identifier to describe the trajectory. This dataset is also an example of storing the trajectory with the data for direct reconstruction. Reconstruct this dataset with:</p>
+<pre class="literal-block">
+>> images = simple_spiral_recon('../data/simple_spiral.h5');
+Reconstructing image 1....done
+Reconstructing image 2....done
+Reconstructing image 3....done
+Reconstructing image 4....done
+Reconstructing image 5....done
+Reconstructing image 6....done
+Reconstructing image 7....done
+Reconstructing image 8....done
+Reconstructing image 9....done
+Reconstructing image 10....done
+>>
+</pre>
+</div>
+<div class="section" id="appendix">
+<h1>Appendix</h1>
+<div class="section" id="xml-schema-definition">
+<h2>XML Schema Definition</h2>
+<pre class="literal-block" id="schema">
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<xs:schema xmlns="http://www.ismrm.org/ISMRMRD" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www.ismrm.org/ISMRMRD">
+
+ <xs:element name="ismrmrdHeader">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element maxOccurs="1" minOccurs="0" name="subjectInformation" type="subjectInformationType"/>
+ <xs:element maxOccurs="1" minOccurs="0" name="acquisitionSystemInformation" type="acquisitionSystemInformationType"/>
+ <xs:element maxOccurs="1" minOccurs="1" name="experimentalConditions" type="experimentalConditionsType"/>
+ <xs:element maxOccurs="65535" minOccurs="1" name="encoding">
+ <xs:complexType>
+ <xs:all>
+ <xs:element maxOccurs="1" minOccurs="1" name="encodedSpace" type="encodingSpaceType"/>
+ <xs:element maxOccurs="1" minOccurs="1" name="reconSpace" type="encodingSpaceType"/>
+ <xs:element maxOccurs="1" minOccurs="1" name="encodingLimits" type="encodingLimitsType"/>
+ <xs:element maxOccurs="1" minOccurs="1" name="trajectory" type="trajectoryType"/>
+ <xs:element maxOccurs="1" minOccurs="0" name="trajectoryDescription" type="trajectoryDescriptionType"/>
+ </xs:all>
+ </xs:complexType>
+ </xs:element>
+ <xs:element maxOccurs="1" minOccurs="0" name="sequenceTiming" type="sequenceTimingType"/>
+ <xs:element maxOccurs="1" minOccurs="0" name="userParameters">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element maxOccurs="unbounded" minOccurs="0" name="userParameterLong" type="userParameterLongType"/>
+ <xs:element maxOccurs="unbounded" minOccurs="0" name="userParameterDouble" type="userParameterDoubleType"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:complexType name="subjectInformationType">
+ <xs:all>
+ <xs:element minOccurs="0" name="patientName" type="xs:string"/>
+ <xs:element minOccurs="0" name="patientWeight_kg" type="xs:float"/>
+ </xs:all>
+ </xs:complexType>
+
+ <xs:complexType name="experimentalConditionsType">
+ <xs:all>
+ <xs:element name="H1resonanceFrequency_Hz" type="xs:long"/>
+ </xs:all>
+ </xs:complexType>
+
+ <xs:complexType name="acquisitionSystemInformationType">
+ <xs:all>
+ <xs:element minOccurs="0" name="systemVendor" type="xs:string"/>
+ <xs:element minOccurs="0" name="systemModel" type="xs:string"/>
+ <xs:element minOccurs="0" name="systemFieldStrength_T" type="xs:float"/>
+ <xs:element minOccurs="0" name="receiverChannels" type="xs:unsignedShort"/>
+ </xs:all>
+ </xs:complexType>
+
+ <xs:complexType name="encodingSpaceType">
+ <xs:all>
+ <xs:element name="matrixSize">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element default="1" maxOccurs="1" minOccurs="1" name="x" type="xs:unsignedShort"/>
+ <xs:element default="1" maxOccurs="1" minOccurs="1" name="y" type="xs:unsignedShort"/>
+ <xs:element default="1" maxOccurs="1" minOccurs="1" name="z" type="xs:unsignedShort"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="fieldOfView_mm">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element maxOccurs="1" minOccurs="1" name="x" type="xs:float"/>
+ <xs:element maxOccurs="1" minOccurs="1" name="y" type="xs:float"/>
+ <xs:element maxOccurs="1" minOccurs="1" name="z" type="xs:float"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ </xs:all>
+ </xs:complexType>
+
+ <xs:complexType name="limitType">
+ <xs:all>
+ <xs:element default="0" name="minimum" type="xs:unsignedShort"/>
+ <xs:element default="0" name="maximum" type="xs:unsignedShort"/>
+ <xs:element default="0" name="center" type="xs:unsignedShort"/>
+ </xs:all>
+ </xs:complexType>
+
+ <xs:complexType name="encodingLimitsType">
+ <xs:all>
+ <xs:element maxOccurs="1" minOccurs="0" name="kspace_encoding_step_0" type="limitType"/>
+ <xs:element maxOccurs="1" minOccurs="0" name="kspace_encoding_step_1" type="limitType"/>
+ <xs:element maxOccurs="1" minOccurs="0" name="kspace_encoding_step_2" type="limitType"/>
+ <xs:element maxOccurs="1" minOccurs="0" name="average" type="limitType"/>
+ <xs:element maxOccurs="1" minOccurs="0" name="slice" type="limitType"/>
+ <xs:element maxOccurs="1" minOccurs="0" name="contrast" type="limitType"/>
+ <xs:element maxOccurs="1" minOccurs="0" name="phase" type="limitType"/>
+ <xs:element maxOccurs="1" minOccurs="0" name="repetition" type="limitType"/>
+ <xs:element maxOccurs="1" minOccurs="0" name="set" type="limitType"/>
+ <xs:element maxOccurs="1" minOccurs="0" name="segment" type="limitType"/>
+ </xs:all>
+ </xs:complexType>
+
+ <xs:simpleType name="trajectoryType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="cartesian"/>
+ <xs:enumeration value="epi"/>
+ <xs:enumeration value="radial"/>
+ <xs:enumeration value="goldenangle"/>
+ <xs:enumeration value="spiral"/>
+ <xs:enumeration value="other"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="trajectoryDescriptionType">
+ <xs:sequence>
+ <xs:element maxOccurs="1" minOccurs="1" name="identifier" type="xs:string"/>
+ <xs:element maxOccurs="unbounded" minOccurs="0" name="userParameterLong" type="userParameterLongType"/>
+ <xs:element maxOccurs="unbounded" minOccurs="0" name="userParameterDouble" type="userParameterDoubleType"/>
+ <xs:element maxOccurs="1" minOccurs="0" name="comment" type="xs:string"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="sequenceTimingType">
+ <xs:sequence>
+ <xs:element minOccurs="1" maxOccurs="unbounded" type="xs:float" name="TR"/>
+ <xs:element minOccurs="1" maxOccurs="unbounded" type="xs:float" name="TE"/>
+ <xs:element minOccurs="0" maxOccurs="unbounded" type="xs:float" name="TI"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="userParameterLongType">
+ <xs:all>
+ <xs:element name="name" type="xs:string"/>
+ <xs:element name="value" type="xs:long"/>
+ </xs:all>
+ </xs:complexType>
+
+ <xs:complexType name="userParameterDoubleType">
+ <xs:all>
+ <xs:element name="name" type="xs:string"/>
+ <xs:element name="value" type="xs:double"/>
+ </xs:all>
+ </xs:complexType>
+</xs:schema>
+
+</pre>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/doc/README.rst b/doc/README.rst
index b1c41da..628ac1a 100644
--- a/doc/README.rst
+++ b/doc/README.rst
@@ -6,11 +6,8 @@ DRAFT - Version 0.1 - July 2012
TODO
-------------------------
-* Make Example Datasets
+* Make More Example Datasets
- - Cartesian 2D/3D
- - Partial Fourier
- - Spiral
- Radial
- Diffusion
- Phase contrast flow
@@ -38,24 +35,264 @@ A prerequisite for sharing magnetic resonance (imaging) reconstruction algorithm
This standard was developed by a subcommittee of the ISMRM Sedona 2013 workshop. Comments and requests for additions/modifications can be sent to:
-Michael S. Hansen, Chair (michael.hansen at nih.gov)
-Wally Block (wblock at cae.wisc.edu)
-Mark Griswold (mag46 at case.edu)
-Brian Hargreaves (bah at stanford.edu)
-Peter Boernert (peter.boernert at philips.com)
+* Michael S. Hansen (michael.hansen at nih.gov)
+* Wally Block (wblock at cae.wisc.edu)
+* Mark Griswold (mag46 at case.edu)
+* Brian Hargreaves (bah at stanford.edu)
+* Peter Boernert (peter.boernert at philips.com)
Overview
---------
-The raw data format combines a mix of flexible data structures (XML) and fixed structures (equivalent to C-structs). A raw data sey consist of 3 sections:
+The raw data format combines a mix of flexible data structures (XML header) and fixed structures (equivalent to C-structs). A raw data set consist of 2 sections:
-1. A flexible XML format document that can contain an arbitrary number of fields and accomodate everything from simple values (b-values, etc.) to entire vendor protocols, etc. This purpose of this XML document is to provide parameters that may be meaningful for some experiments but not for others.
-2. A fixed struct describing encoding limits. This is a C-struct which describes minimum, maximum, and center encoding indices for all encoded dimensions.
-3. Raw data section. This section contains all the acquired data in the experiment. Each data item is preceeded by a C-struct with encoding number, etc. Following this data header is a channel header and data for each acquired channel.
+1. A flexible XML format document that can contain an arbitrary number of fields and accomodate everything from simple values (b-values, etc.) to entire vendor protocols, etc. This purpose of this XML document is to provide parameters that may be meaningful for some experiments but not for others. This XML format is defined by an XML Schema Definition file (ismrmrd.xsd).
+2. Raw data section. This section contains all the acquired data in the experiment. Each data item is preceeded by a C-struct with encoding numbers, etc. Following this data header is a channel header and data for each acquired channel. The raw data headers are defined in a C/C++ header file (ismrmrd.h)
+
+Flexible Data Header
+.....................
+
+The flexible data structure is defined by the xml schema definition in ``schema/ismrmrd.xsd`` (schema_ is included in appendix below).
+
+An example of an XML file for a Cartesian 3D acquisition could look like:
+
+.. include:: ../schema/ismrmrd_example.xml
+ :literal:
+
+The most critical elements for image reconstruction are contained in the ``<encoding>`` section of the document, which describes the encoded spaced and also the target reconstructed space. Along with the ``<encodingLimits>`` this section allows the reconstruction program to determine matrix sizes, oversampling factors, partial fourier, etc. In the example above, data is acquired with two-fold oversampling in the read-out (``x``) direction, which is reflected in the larger matrix size in [...]
+
+::
+
+ 0 70 139
+ |-------------------------------------|-------------------------------------------|
+ ****************************************************
+ ^ ^ ^
+ 0 28 83
+
+After FFT, only the central 116 lines are kept, i.e. there is a reduced field of view in the phase encoding direction. Center and encoding limits for the readout dimension is not given in the XML header. This is to accomodate sequences where the center of the readout may change from readout to readout (alternating directions of readout). There is a field on the individual data headers (see below) to indicate the center of the readout.
+
+An experiment can have multiple encoding spaces and it is possible to indicate on each acquired data readout, which encoding space the data belongs to (see below).
+
+In addition to the defined field in the xml header, it is possible to add an arbitrary number of user defined parameters to accomodate special sequence parameters. Please consult the xml schema_ to see how user parameters are defined. Briefly, the XML header can have a section at the end which looks like:
+
+::
+
+ <userParameters>
+ <userParameterLong>
+ <name>MyVar1</name><value>1003</value>
+ </userParameterLong>
+ <userParameterLong>
+ <name>MyVar2</name><value>1999</value>
+ </userParameterLong>
+ <userParameterDouble>
+ <name>MyDoubleVar</name><value>87.6676</value>
+ </userParameterDouble>
+ </userParameters>
Fixed Data structures
-----------------------
+......................
+
+Each acquisition is preceeded by the following fixed layout structure:
+
+.. include:: ../ismrmrd.h
+ :literal:
+ :start-line: 116
+ :end-line: 141
+
+Where EncodingCounters are defined as:
+
+.. include:: ../ismrmrd.h
+ :literal:
+ :start-line: 100
+ :end-line: 112
+
+The interpretation of some of these fields may vary from sequence to sequence, i.e. for a Cartesian sequence, ``kspace_encode_step_1`` would be the phase encoding step, for a spiral sequence where phase encoding direction does not make sense, it would be the spiral interleave number. The ``encoding_space_ref`` enables the user to tie an acquisition to a specific encoding space (see above) in case there are multiple, e.g. in situations where a calibration scan may be integrated in the acq [...]
+
+The flags field is a bitmask, which in principle can be used freely by the user, but suggested flag values are given in ``ismrmrd.h``, it is recommended not to use already designated flag bits for custom purposes. Ther are a set of bits reserved for prototyping (bits 57-64), please see ``ismrmrd.h`` for details.
+
+The header contains a ``trajectory_dimensions`` field. If the value of this field is larger than 0, it means that trajectories are stored with each invidual acquisition. For a 2D acquisition, the ``trajectory_dimensions`` would typically be 2 and the convention (for memory layout) is that the header is followed immediately by the trajectory before the complex data. There is an example of how this memory layout could be implemented with a C++ class in the ``ismrmrd.h`` file:
+
+::
+
+ class Acquisition
+ {
+
+ //....
+
+ AcquisitionHeader head_; //Header, see above
+
+ float* traj_; //Trajectory, elements = head_.trajectory_dimensions*head_.number_of_samples
+ // [kx,ky,kx,ky.....] (for head_.trajectory_dimensions = 2)
+ // [kx,ky,kz,kx,ky,kz,.....] (for head_.trajectory_dimensions = 3)
+
+ float* data_; //Actual data, elements = head_.number_of_samples*head_.active_channels*2
+ // [re,im,re,im,.....,re,im,re,im,.....,re,im,re,im,.....]
+ // ---channel 1-------channel 2---------channel 3-----
+
+ };
+
+This suggested memory layout is only a suggestion. The HDF5 interface (see below) can be used to read the data into many different datastructures. In fact, the user can choose to read only part of the header or not read the data, etc.
+
+File Storage
+-------------
+
+The ISMRM Raw Data format is stored in HDF5 format. Details on this format can be found at the HDF5_ website. Briefly it is a hierarchical dataformat (much like a file system), which can contain multiple variable organized in groups (like folders in a file system). The variables can contain arrays of data values, custom defined structs, or simple text fields. It is the convention (but not a requirement) that the ISMRMRD datasets are stored in a group called ``/dataset``. The XML configur [...]
::
+
+ >> data = h5read('simple_gre.h5', '/dataset/data');
+ >> data
+
+ data =
+
+ head: [1x1 struct]
+ traj: {1x1281 cell}
+ data: {1x1281 cell}
+
+ >> data.head
+
+ ans =
+
+ version: [1x1281 uint16]
+ flags: [1x1281 uint64]
+ measurement_uid: [1x1281 uint32]
+ scan_counter: [1x1281 uint32]
+ acquisition_time_stamp: [1x1281 uint32]
+ physiology_time_stamp: [3x1281 uint32]
+ number_of_samples: [1x1281 uint16]
+ available_channels: [1x1281 uint16]
+ active_channels: [1x1281 uint16]
+ channel_mask: [16x1281 uint64]
+ discard_pre: [1x1281 uint16]
+ discard_post: [1x1281 uint16]
+ center_sample: [1x1281 uint16]
+ encoding_space_ref: [1x1281 uint16]
+ trajectory_dimensions: [1x1281 uint16]
+ sample_time_us: [1x1281 single]
+ position: [3x1281 single]
+ quaternion: [4x1281 single]
+ patient_table_position: [3x1281 single]
+ idx: [1x1 struct]
+ user_int: [8x1281 int32]
+ user_float: [8x1281 single]
+
+ >>
+
+The HDF5 file format can be access from C, C++, and java using the libraries provided on the HDF5 website. The ISMRMRD distribution also comes with some C++ wrappers that can be used for easy access (read and write) from C++ programs. See below.
+
+.. _HDF5: http://www.hdfgroup.org/HDF5/
+
+C++ Support Library
+--------------------
+
+To enable easy prototyping of C++ software using the ISMRMRD data format, a simple C++ wrapper class is provided (defined in ``ismrmrd_hdf5.h``):
+
+::
+
+ class EXPORTISMRMRD IsmrmrdDataset
+ {
+ public:
+ IsmrmrdDataset(const char* filename, const char* groupname, bool create_file_if_needed = true);
+ int appendAcquisition(Acquisition* a);
+ int writeHeader(std::string& xml);
+
+ boost::shared_ptr<std::string> readHeader();
+ boost::shared_ptr<Acquisition> readAcquisition(unsigned long index = 0);
+ unsigned long getNumberOfAcquisitions();
+ };
+
+
+Using this wrapper, C++ applications can be programmed as:
+
+::
+
+ boost::shared_ptr<ISMRMRD::IsmrmrdDataset> ismrmrd_dataset(new ISMRMRD::IsmrmrdDataset(hdf5_in_data_file,hdf5_in_group));
+ boost::shared_ptr<std::string> xml_config = ismrmrd_dataset->readHeader();
+
+ //Do something with the header
+
+ unsigned long acquisitions = ismrmrd_dataset->getNumberOfAcquisitions();
+
+ for (unsigned long int i = 0; i < acquisitions; i++) {
+ boost::shared_ptr<ISMRMRD::Acquisition> acq_tmp = ismrmrd_dataset->readAcquisition(i);
+ //Do something with the data
+ }
+
+Since the XML part of the header is defined in the ``schema/ismrmrd.xsd`` file, it is possible to use XML data binding tools such as CodeSynthesys XSD to generate a C++ class representation of the header for easy access to the fields. The ``cmake`` build files that accompany the ISMRMRD distribution automatically tries to find CodeSynthesis XSD and generate such a binding. With the C++ representation of the header it can be parsed with something like:
+
+::
+
+ xml_schema::properties props;
+ props.schema_location ("http://www.ismrm.org/ISMRMRD",std::string("/full/path/to/ismrmrd.xsd"));
+ std::istringstream str_stream(xml, std::stringstream::in);
+ boost::shared_ptr<ISMRMRD::ismrmrdHeader> cfg;
+
+ try {
+ cfg = boost::shared_ptr<ISMRMRD::ismrmrdHeader>(ISMRMRD::ismrmrdHeader_ (str_stream,0,props));
+ } catch (const xml_schema::exception& e) {
+ std::cout << "Failed to parse XML Parameters: " << e.what() << std::endl;
+ }
+
+ //Use the configuration, e.g.:
+ std::cout << "Number of encoding spaces: " << cfg->encoding().size() << std::endl;
+
+Again, this is not a requirement for using the ISMRMRD format, the XML can be parsed with numerous other xml parsing libraries. The schema file ``schema/ismrmrd.xsd`` gives the user the option of validating the XML header before parsing, which is recommeded to reduce the chance of hard to detect errors in your code due to missing or malformed parameters.
+
+Matlab Example Code and Datasets
+--------------------------------
+
+The ``examples`` folder contains datasets and some matlab code to illustrate simple interaction with the ISMRMRD data format. For instance, to reconstruct a 2D Cartesian acquisition (10 image repetitions), type (from the ``examples/matlab`` folder):
+
+::
+
+ >> images = simple_cartesian_recon('../data/simple_gre.h5');
+ Reconstructing image 1....done
+ Reconstructing image 2....done
+ Reconstructing image 3....done
+ Reconstructing image 4....done
+ Reconstructing image 5....done
+ Reconstructing image 6....done
+ Reconstructing image 7....done
+ Reconstructing image 8....done
+ Reconstructing image 9....done
+ Reconstructing image 10....done
+ >>
+
+You should see one of the reconstructed images display. An example is also given of a 3D acquisition with partial Fourier, phase and slice oversampling, etc. Reconstruct this dataset with:
+
+::
+
+ >> images = simple_cartesian_recon('../data/3D_partial_fourier.h5');
+ Reconstructing image 1....done
+
+The center slice of the volume should be displayed at the end of the reconstruction.
+
+Finally, there is also a spiral dataset. This dataset illustrates how the flexible section of the ``<trajectoryDescription>`` can be used to add user defined parameters and an identifier to describe the trajectory. This dataset is also an example of storing the trajectory with the data for direct reconstruction. Reconstruct this dataset with:
+
+::
+
+ >> images = simple_spiral_recon('../data/simple_spiral.h5');
+ Reconstructing image 1....done
+ Reconstructing image 2....done
+ Reconstructing image 3....done
+ Reconstructing image 4....done
+ Reconstructing image 5....done
+ Reconstructing image 6....done
+ Reconstructing image 7....done
+ Reconstructing image 8....done
+ Reconstructing image 9....done
+ Reconstructing image 10....done
+ >>
+
+Appendix
+---------
+
+XML Schema Definition
+......................
+.. _schema:
+
+.. include:: ../schema/ismrmrd.xsd
+ :literal:
+
diff --git a/ismrmrd.h b/ismrmrd.h
index 4b10bbc..7d29d65 100644
--- a/ismrmrd.h
+++ b/ismrmrd.h
@@ -133,8 +133,8 @@ namespace ISMRMRD
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[3]; //Three-dimensional spatial offsets from isocenter
- float quarternion[4]; //Angulation of acquisition
- float patient_table_position[3]; //Patient table off-center
+ float quaternion[4]; //Angulation of acquisition
+ float patient_table_position[3]; //Patient table off-center
EncodingCounters idx; //Encoding loop counters, see above
int32_t user_int[8]; //Free user parameters
float user_float[8]; //Free user parameters
diff --git a/ismrmrd_hdf5_datatypes.h b/ismrmrd_hdf5_datatypes.h
index a3f07fa..dd0b368 100644
--- a/ismrmrd_hdf5_datatypes.h
+++ b/ismrmrd_hdf5_datatypes.h
@@ -74,7 +74,7 @@ template <> boost::shared_ptr<DataType> getIsmrmrdHDF5Type<AcquisitionHeader>()
dims[0] = 4;
boost::shared_ptr<DataType> quaterion_array_type(new ArrayType(PredType::NATIVE_FLOAT, 1, &dims[0]));
- ret->insertMember( "quarternion", HOFFSET(AcquisitionHeader, quarternion), *quaterion_array_type);
+ ret->insertMember( "quaternion", HOFFSET(AcquisitionHeader, quaternion), *quaterion_array_type);
dims[0] = 3;
boost::shared_ptr<DataType> table_array_type(new ArrayType(PredType::NATIVE_FLOAT, 1, &dims[0]));
diff --git a/main.cpp b/main.cpp
index a7577dc..509667a 100644
--- a/main.cpp
+++ b/main.cpp
@@ -14,9 +14,9 @@ int main (int argc, char* argv[])
std::cout << "Number of encoding spaces: " << s->encoding().size() << std::endl;
for (ismrmrdHeader::encoding_sequence::iterator i (s->encoding().begin ()); i != s->encoding().end(); ++i) {
- std::cout << "FOV: " << i->encodedSpace().fieldOfView_m().x()
- << ", " << i->encodedSpace().fieldOfView_m().y()
- << ", " << i->encodedSpace().fieldOfView_m().z() << std::endl;
+ std::cout << "FOV: " << i->encodedSpace().fieldOfView_mm().x()
+ << ", " << i->encodedSpace().fieldOfView_mm().y()
+ << ", " << i->encodedSpace().fieldOfView_mm().z() << std::endl;
}
}
catch (const xml_schema::exception& e) {
diff --git a/schema/ismrmrd.xsd b/schema/ismrmrd.xsd
index 4633b55..3e7be4c 100644
--- a/schema/ismrmrd.xsd
+++ b/schema/ismrmrd.xsd
@@ -64,7 +64,7 @@
</xs:sequence>
</xs:complexType>
</xs:element>
- <xs:element name="fieldOfView_m">
+ <xs:element name="fieldOfView_mm">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="1" minOccurs="1" name="x" type="xs:float"/>
diff --git a/schema/ismrmrd_example.xml b/schema/ismrmrd_example.xml
index 6886ad6..c59ff27 100644
--- a/schema/ismrmrd_example.xml
+++ b/schema/ismrmrd_example.xml
@@ -1,76 +1,66 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ismrmrdHeader xsi:schemaLocation="http://www.ismrm.org/ISMRMRD ismrmrd.xsd"
- xmlns="http://www.ismrm.org/ISMRMRD"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:xs="http://www.w3.org/2001/XMLSchema">
-
+<?xml version="1.0"?>
+<ismrmrdHeader xmlns="http://www.ismrm.org/ISMRMRD" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:schemaLocation="http://www.ismrm.org/ISMRMRD ismrmrd.xsd">
<subjectInformation>
- <patientName>Anonymous</patientName>
- <patientWeight_kg>74.7</patientWeight_kg>
+ <patientName>phantom</patientName>
+ <patientWeight_kg>70.3068</patientWeight_kg>
</subjectInformation>
-
<acquisitionSystemInformation>
- <systemVendor>Siemens</systemVendor>
+ <systemVendor>SIEMENS</systemVendor>
<systemModel>Avanto</systemModel>
- <systemFieldStrength_T>1.5</systemFieldStrength_T>
+ <systemFieldStrength_T>1.494</systemFieldStrength_T>
+ <receiverChannels>32</receiverChannels>
</acquisitionSystemInformation>
-
<experimentalConditions>
- <H1resonanceFrequencyHz>63500000</H1resonanceFrequencyHz>
+ <H1resonanceFrequency_Hz>63642459</H1resonanceFrequency_Hz>
</experimentalConditions>
-
<encoding>
<trajectory>cartesian</trajectory>
- <encodingLimits>
- <kspace_encoding_step_1>
- <minimum>0</minimum>
- <maximum>96</maximum>
- <center>48</center>
- </kspace_encoding_step_1>
- </encodingLimits>
-
<encodedSpace>
<matrixSize>
<x>256</x>
- <y>96</y>
- <z>1</z>
+ <y>140</y>
+ <z>80</z>
</matrixSize>
- <fieldOfView_m>
- <x>0.600</x>
- <y>0.230</y>
- <z>0.006</z>
- </fieldOfView_m>
+ <fieldOfView_mm>
+ <x>600</x>
+ <y>328.153125</y>
+ <z>160</z>
+ </fieldOfView_mm>
</encodedSpace>
-
<reconSpace>
<matrixSize>
<x>128</x>
- <y>96</y>
- <z>1</z>
+ <y>116</y>
+ <z>64</z>
</matrixSize>
-
- <fieldOfView_m>
- <x>0.300</x>
- <y>0.230</y>
- <z>0.006</z>
- </fieldOfView_m>
+ <fieldOfView_mm>
+ <x>300</x>
+ <y>271.875</y>
+ <z>128</z>
+ </fieldOfView_mm>
</reconSpace>
+ <encodingLimits>
+ <kspace_encoding_step_1>
+ <minimum>0</minimum>
+ <maximum>83</maximum>
+ <center>28</center>
+ </kspace_encoding_step_1>
+ <kspace_encoding_step_2>
+ <minimum>0</minimum>
+ <maximum>45</maximum>
+ <center>20</center>
+ </kspace_encoding_step_2>
+ <slice>
+ <minimum>0</minimum>
+ <maximum>0</maximum>
+ <center>0</center>
+ </slice>
+ </encodingLimits>
</encoding>
-
- <userParameters>
- <userParameterLong>
- <name>MySpecialParameter1</name>
- <value>724873268</value>
- </userParameterLong>
-
- <userParameterLong>
- <name>AnotherSpecialParameter</name>
- <value>19238719</value>
- </userParameterLong>
-
- <userParameterDouble>
- <name>ADoubleParameter</name>
- <value>76238.878437</value>
- </userParameterDouble>
- </userParameters>
+ <sequenceTiming>
+ <TR>4.6</TR>
+ <TE>2.35</TE>
+ <TI>300</TI>
+ </sequenceTiming>
</ismrmrdHeader>
+
--
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