[ismrmrd] 252/281: The new XML library can now deserialize and serialize
Ghislain Vaillant
ghisvail-guest at moszumanska.debian.org
Wed Jan 14 20:01:21 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 2f3e02a50982cd7636c1cbc68d07ef27a098a73b
Author: Michael S. Hansen <michael.hansen at nih.gov>
Date: Wed Aug 13 11:10:34 2014 -0400
The new XML library can now deserialize and serialize
---
xml/.gitignore | 1 +
xml/CMakeLists.txt | 24 +--
xml/ismrmrd_xml.cpp | 205 +++++++++++++++++++--
xml/ismrmrd_xml.h | 17 +-
...ump_ismrmrd_header.cpp => test_ismrmrd_xml.cpp} | 32 +++-
5 files changed, 230 insertions(+), 49 deletions(-)
diff --git a/xml/.gitignore b/xml/.gitignore
new file mode 100644
index 0000000..b81c795
--- /dev/null
+++ b/xml/.gitignore
@@ -0,0 +1 @@
+*.xml
\ No newline at end of file
diff --git a/xml/CMakeLists.txt b/xml/CMakeLists.txt
index 74e4d12..8a8202d 100644
--- a/xml/CMakeLists.txt
+++ b/xml/CMakeLists.txt
@@ -4,31 +4,17 @@ add_library(ismrmrd_xml SHARED
pugixml.cpp
)
-
-include_directories(${ISMRMRD_SOURCE_DIR})
-
-add_executable(dump_ismrmrd_header
- dump_ismrmrd_header.cpp
+add_executable(test_ismrmrd_xml
+ test_ismrmrd_xml.cpp
+ pugixml.cpp
)
-target_link_libraries(dump_ismrmrd_header
- ismrmrd
+target_link_libraries(test_ismrmrd_xml
ismrmrd_xml)
-if(WIN32)
- target_link_libraries(ismrmrd_xml optimized ${HDF5_hdf5_LIBRARY_RELEASE}
- optimized ${HDF5_hdf5_cpp_LIBRARY_RELEASE})
- target_link_libraries(ismrmrd_xml debug ${HDF5_hdf5_LIBRARY_DEBUG}
- debug ${HDF5_hdf5_cpp_LIBRARY_DEBUG})
- target_link_libraries(ismrmrd_xml ${Boost_LIBRARIES})
-else(WIN32)
- target_link_libraries(ismrmrd_xml ${HDF5_LIBRARIES} ${Boost_THREAD_LIBRARY}
- ${Boost_SYSTEM_LIBRARY})
-endif(WIN32)
-
install (FILES ismrmrd_xml.h
DESTINATION ${ISMRMRD_INSTALL_INCLUDE_DIR})
install (TARGETS ismrmrd_xml DESTINATION ${ISMRMRD_INSTALL_LIB_DIR})
-install (TARGETS dump_ismrmrd_header DESTINATION ${ISMRMRD_INSTALL_BIN_DIR})
+install (TARGETS test_ismrmrd_xml DESTINATION ${ISMRMRD_INSTALL_BIN_DIR})
diff --git a/xml/ismrmrd_xml.cpp b/xml/ismrmrd_xml.cpp
index 1aea1e1..a34aec0 100644
--- a/xml/ismrmrd_xml.cpp
+++ b/xml/ismrmrd_xml.cpp
@@ -23,9 +23,9 @@ namespace ISMRMRD
if (!fieldOfView_mm) {
throw std::runtime_error("fieldOfView_mm not found in encodingSpace");
} else {
- e.fieldOfView_mm.x = std::atoi(fieldOfView_mm.child_value("x"));
- e.fieldOfView_mm.y = std::atoi(fieldOfView_mm.child_value("y"));
- e.fieldOfView_mm.z = std::atoi(fieldOfView_mm.child_value("z"));
+ e.fieldOfView_mm.x = std::atof(fieldOfView_mm.child_value("x"));
+ e.fieldOfView_mm.y = std::atof(fieldOfView_mm.child_value("y"));
+ e.fieldOfView_mm.z = std::atof(fieldOfView_mm.child_value("z"));
}
return e;
@@ -155,8 +155,7 @@ namespace ISMRMRD
char buffer[10000];
memcpy(buffer,name.child_value(),strlen(name.child_value())+1);
- std::string tmp("BLAH");
- v.name = "BLAKKK";//xtmp;//std::string("BLAH");//name.child_value());
+ v.name = name.child_value();
v.value = std::atof(value.child_value());
r.push_back(v);
@@ -321,9 +320,9 @@ namespace ISMRMRD
while (measurementDependency) {
try {
MeasurementDependency d;
- d.dependencyID = parse_string(measurementDependency,"dependencyID");
+ d.measurementID = parse_string(measurementDependency,"measurementID");
d.dependencyType = parse_string(measurementDependency,"dependencyType");
- info.measurementDepencency.push_back(d);
+ info.measurementDependency.push_back(d);
} catch (std::runtime_error& e) {
std::cout << "Error parsing measurement dependency: " << e.what() << std::endl;
throw;
@@ -374,7 +373,7 @@ namespace ISMRMRD
DicomParameters p;
p.studyInstanceUID = parse_string(dicomParameters,"studyInstanceUID");
p.seriesInstanceUIDRoot = parse_optional_string(dicomParameters,"seriesInstanceUIDRoot");
- p.frameOfReference = parse_optional_string(dicomParameters,"frameOfReferenceUID");
+ p.frameOfReferenceUID = parse_optional_string(dicomParameters,"frameOfReferenceUID");
//This part of the schema is totally messed up and needs to be fixed, but for now we will just read it.
pugi::xml_node ri = dicomParameters.child("referencedImageSequemce");
@@ -393,7 +392,7 @@ namespace ISMRMRD
MRImageModule m;
m.imageType = parse_optional_string(mrimageModule,"imageType");
m.scanningSequence = parse_optional_string(mrimageModule, "scanningSequence");
- m.sequenceVartiant = parse_optional_string(mrimageModule, "sequenceVariant");
+ m.sequenceVariant = parse_optional_string(mrimageModule, "sequenceVariant");
m.scanOptions = parse_optional_string(mrimageModule, "scanOptions");
m.mrAcquisitionType = parse_optional_string(mrimageModule, "mrAcquisitionType");
m.echoTrainLength = parse_optional_long(mrimageModule, "echoTrainLength");
@@ -433,6 +432,13 @@ namespace ISMRMRD
o = std::string(buffer);
}
+ void to_string_val(const double& v, std::string& o)
+ {
+ char buffer[256];
+ sprintf(buffer,"%f",v);
+ o = std::string(buffer);
+ }
+
void to_string_val(const unsigned short& v, std::string& o)
{
char buffer[256];
@@ -440,7 +446,15 @@ namespace ISMRMRD
o = std::string(buffer);
}
- template <class T> void append_optional_node(pugi::xml_node& n, const char* child, const Optional<T>& v) {
+ void to_string_val(const long& v, std::string& o)
+ {
+ char buffer[256];
+ sprintf(buffer,"%ld",v);
+ o = std::string(buffer);
+ }
+
+ template <class T> void append_optional_node(pugi::xml_node& n, const char* child, const Optional<T>& v)
+ {
if (v) {
pugi::xml_node n2 = n.append_child(child);
std::string v_as_string;
@@ -449,20 +463,55 @@ namespace ISMRMRD
}
}
- template <class T> void append_node(pugi::xml_node& n, const char* child, const T& v) {
+ template <class T> void append_node(pugi::xml_node& n, const char* child, const T& v)
+ {
pugi::xml_node n2 = n.append_child(child);
std::string v_as_string;
- to_string_val(*v, v_as_string);
+ to_string_val(v, v_as_string);
n2.append_child(pugi::node_pcdata).set_value(v_as_string.c_str());
}
+ void append_encoding_space(pugi::xml_node& n, const char* child, const EncodingSpace& s)
+ {
+ pugi::xml_node n2 = n.append_child(child);
+ pugi::xml_node n3 = n2.append_child("matrixSize");
+ append_node(n3,"x",s.matrixSize.x);
+ append_node(n3,"y",s.matrixSize.y);
+ append_node(n3,"z",s.matrixSize.z);
+ n3 = n2.append_child("fieldOfView_mm");
+ append_node(n3,"x",s.fieldOfView_mm.x);
+ append_node(n3,"y",s.fieldOfView_mm.y);
+ append_node(n3,"z",s.fieldOfView_mm.z);
+ }
+
+ void append_encoding_limit(pugi::xml_node& n, const char* child, const Optional<Limit>& l)
+ {
+ if (l) {
+ pugi::xml_node n2 = n.append_child(child);
+ append_node(n2,"minimum",l->minimum);
+ append_node(n2,"maximum",l->maximum);
+ append_node(n2,"center",l->center);
+ }
+ }
+
+ template <class T>
+ void append_user_parameter(pugi::xml_node& n, const char* child,
+ const std::vector<T>& v)
+ {
+ for (size_t i = 0; i < v.size(); i++) {
+ pugi::xml_node n2 = n.append_child(child);
+ append_node(n2,"name",v[i].name);
+ append_node(n2,"value",v[i].value);
+ }
+ }
+
//End utility functions for serialization
void serialize(const IsmrmrdHeader& h, std::ostream& o)
{
pugi::xml_document doc;
pugi::xml_node root = doc.append_child();
- pugi::xml_node n1;
+ pugi::xml_node n1,n2;
pugi::xml_attribute a;
root.set_name("ismrmrdHeader");
@@ -489,6 +538,37 @@ namespace ISMRMRD
append_optional_node(n1,"patientGender",h.subjectInformation->patientGender);
}
+ if (h.studyInformation) {
+ n1 = root.append_child();
+ n1.set_name("studyInformation");
+ append_optional_node(n1,"studyDate",h.studyInformation->studyDate);
+ append_optional_node(n1,"studyTime",h.studyInformation->studyTime);
+ append_optional_node(n1,"studyID",h.studyInformation->studyID);
+ append_optional_node(n1,"accessionNumber",h.studyInformation->accessionNumber);
+ append_optional_node(n1,"referringPhysicianName",h.studyInformation->referringPhysicianName);
+ append_optional_node(n1,"studyDescription",h.studyInformation->studyDescription);
+ }
+
+ if (h.measurementInformation) {
+ n1 = root.append_child();
+ n1.set_name("measurementInformation");
+ append_optional_node(n1,"measurementID",h.measurementInformation->measurementID);
+ append_optional_node(n1,"seriesDate",h.measurementInformation->seriesDate);
+ append_optional_node(n1,"seriesTime",h.measurementInformation->seriesTime);
+ append_node(n1,"patientPosition",h.measurementInformation->patientPosition);
+ append_optional_node(n1,"initialSeriesNumber",h.measurementInformation->initialSeriesNumber);
+ append_optional_node(n1,"protocolName",h.measurementInformation->protocolName);
+ append_optional_node(n1,"seriesDescription",h.measurementInformation->seriesDescription);
+
+ for (size_t i = 0; i < h.measurementInformation->measurementDependency.size(); i++) {
+ n2 = n1.append_child();
+ n2.set_name("measurementDependency");
+ append_node(n2,"deoendencyType",h.measurementInformation->measurementDependency[i].dependencyType);
+ append_node(n2,"measurementID",h.measurementInformation->measurementDependency[i].measurementID);
+ }
+
+ }
+
if (h.acquisitionSystemInformation) {
n1 = root.append_child();
n1.set_name("acquisitionSystemInformation");
@@ -501,6 +581,105 @@ namespace ISMRMRD
append_optional_node(n1,"stationName",h.acquisitionSystemInformation->stationName);
}
+ n1 = root.append_child();
+ n1.set_name("experimentalConditions");
+ append_node(n1,"H1resonanceFrequency_Hz", h.experimentalConditions.H1resonanceFrequency_Hz);
+
+ if (!h.encoding.size()) {
+ throw std::runtime_error("Encoding array is empty. Invalid ISMRMRD header structure");
+ }
+
+ for (size_t i = 0; i < h.encoding.size(); i++) {
+ n1 = root.append_child("encoding");
+ append_encoding_space(n1,"encodedSpace",h.encoding[i].encodedSpace);
+ append_encoding_space(n1,"reconSpace",h.encoding[i].reconSpace);
+ n2 = n1.append_child("encodingLimits");
+ append_encoding_limit(n2,"kspace_encoding_step_0",h.encoding[i].encodingLimits.kspace_encoding_step_0);
+ append_encoding_limit(n2,"kspace_encoding_step_1",h.encoding[i].encodingLimits.kspace_encoding_step_1);
+ append_encoding_limit(n2,"kspace_encoding_step_2",h.encoding[i].encodingLimits.kspace_encoding_step_2);
+ append_encoding_limit(n2,"average",h.encoding[i].encodingLimits.average);
+ append_encoding_limit(n2,"slice",h.encoding[i].encodingLimits.slice);
+ append_encoding_limit(n2,"contrast",h.encoding[i].encodingLimits.contrast);
+ append_encoding_limit(n2,"phase",h.encoding[i].encodingLimits.phase);
+ append_encoding_limit(n2,"repetition",h.encoding[i].encodingLimits.repetition);
+ append_encoding_limit(n2,"set",h.encoding[i].encodingLimits.set);
+ append_encoding_limit(n2,"segment",h.encoding[i].encodingLimits.segment);
+ append_node(n1,"trajectory",h.encoding[i].trajectory);
+
+ if (h.encoding[i].trajectoryDescription) {
+ n2 = n1.append_child("trajectoryDescription");
+ append_node(n2,"identifier",h.encoding[i].trajectoryDescription->identifier);
+ append_user_parameter(n2,"userParameterLong",h.encoding[i].trajectoryDescription->userParameterLong);
+ append_user_parameter(n2,"userParameterDouble",h.encoding[i].trajectoryDescription->userParameterDouble);
+ append_optional_node(n2,"comment",h.encoding[i].trajectoryDescription->comment);
+ }
+ }
+
+ if (h.parallelImaging) {
+ n1 = root.append_child("parallelImaging");
+ n2 = n1.append_child("accelerationFactor");
+ append_node(n2,"kspace_encoding_step_1",h.parallelImaging->accelerationFactor.kspace_encoding_step_1);
+ append_node(n2,"kspace_encoding_step_2",h.parallelImaging->accelerationFactor.kspace_encoding_step_2);
+ append_optional_node(n1, "calibrationMode", h.parallelImaging->calibrationMode);
+ append_optional_node(n1, "interleavingDimension", h.parallelImaging->interleavingDimension);
+ }
+
+ if (h.sequenceParameters) {
+ n1 = root.append_child("sequenceParameters");
+ if (!h.sequenceParameters->TR.size()) {
+ throw std::runtime_error("TR section of sequenceParameters does not contain any values");
+ }
+ if (!h.sequenceParameters->TE.size()) {
+ throw std::runtime_error("TE section of sequenceParameters does not contain any values");
+ }
+
+ for (size_t i = 0; i < h.sequenceParameters->TR.size(); i++) {
+ append_node(n1,"TR",h.sequenceParameters->TR[i]);
+ }
+ for (size_t i = 0; i < h.sequenceParameters->TE.size(); i++) {
+ append_node(n1,"TE",h.sequenceParameters->TE[i]);
+ }
+ for (size_t i = 0; i < h.sequenceParameters->TI.size(); i++) {
+ append_node(n1,"TI",h.sequenceParameters->TI[i]);
+ }
+ }
+
+ if (h.dicomParameters) {
+ n1 = root.append_child("dicomParameters");
+ append_node(n1, "studyInstanceUID", h.dicomParameters->studyInstanceUID);
+ append_optional_node(n1, "seriesInstanceUIDRoot",h.dicomParameters->seriesInstanceUIDRoot);
+ append_optional_node(n1, "frameOfReferenceUID", h.dicomParameters->frameOfReferenceUID);
+
+ //TODO: Sort out stuff with this referenced image sequence. This is all messed up.
+ if (h.dicomParameters->referencedImageSequence.size()) {
+ n2 = n1.append_child("referencedImageSequence");
+ for (size_t i = 0; i < h.dicomParameters->referencedImageSequence.size(); i++) {
+ append_node(n2,"referencedSOPInstanceUID", h.dicomParameters->referencedImageSequence[i].referencedSOPInstanceUID);
+ }
+ }
+
+ if (h.dicomParameters->mrImageModule) {
+ n2 = n1.append_child("MRImageModule");
+ append_optional_node(n2,"imageType",h.dicomParameters->mrImageModule->imageType);
+ append_optional_node(n2,"scanningSequence",h.dicomParameters->mrImageModule->scanningSequence);
+ append_optional_node(n2,"sequenceVariant",h.dicomParameters->mrImageModule->sequenceVariant);
+ append_optional_node(n2,"scanOptions",h.dicomParameters->mrImageModule->scanOptions);
+ append_optional_node(n2,"mrAcquisitionType",h.dicomParameters->mrImageModule->mrAcquisitionType);
+ append_optional_node(n2,"echoTrainLength",h.dicomParameters->mrImageModule->echoTrainLength);
+ append_optional_node(n2,"triggerTime",h.dicomParameters->mrImageModule->triggerTime);
+ append_optional_node(n2,"flipAngle_deg",h.dicomParameters->mrImageModule->flipAngle_deg);
+ append_optional_node(n2,"freqEncodingDirection",h.dicomParameters->mrImageModule->freqEncodingDirection);
+ }
+ }
+
+ if (h.userParameters) {
+ n1 = root.append_child("userParameters");
+ append_user_parameter(n1,"userParameterLong",h.userParameters->userParameterLong);
+ append_user_parameter(n1,"userParameterDouble",h.userParameters->userParameterDouble);
+ append_user_parameter(n1,"userParameterString",h.userParameters->userParameterString);
+ append_user_parameter(n1,"userParameterBase64",h.userParameters->userParameterBase64);
+ }
+
doc.save(o);
}
diff --git a/xml/ismrmrd_xml.h b/xml/ismrmrd_xml.h
index 2459022..6a9f729 100644
--- a/xml/ismrmrd_xml.h
+++ b/xml/ismrmrd_xml.h
@@ -79,7 +79,7 @@ namespace ISMRMRD
};
- struct EXPORTISMRMRDXML SubjectInformation
+ struct SubjectInformation
{
Optional<std::string> patientName;
Optional<float> patientWeight_kg;
@@ -101,7 +101,7 @@ namespace ISMRMRD
struct MeasurementDependency
{
std::string dependencyType;
- std::string dependencyID;
+ std::string measurementID;
};
struct MeasurementInformation
@@ -113,7 +113,7 @@ namespace ISMRMRD
Optional<long int> initialSeriesNumber;
Optional<std::string> protocolName;
Optional<std::string> seriesDescription;
- std::vector<MeasurementDependency> measurementDepencency;
+ std::vector<MeasurementDependency> measurementDependency;
};
@@ -253,7 +253,7 @@ namespace ISMRMRD
{
Optional<std::string> imageType;
Optional<std::string> scanningSequence;
- Optional<std::string> sequenceVartiant;
+ Optional<std::string> sequenceVariant;
Optional<std::string> scanOptions;
Optional<std::string> mrAcquisitionType;
Optional<long> echoTrainLength;
@@ -266,7 +266,7 @@ namespace ISMRMRD
{
std::string studyInstanceUID;
Optional<std::string> seriesInstanceUIDRoot;
- Optional<std::string> frameOfReference;
+ Optional<std::string> frameOfReferenceUID;
std::vector<ReferencedImageSequence> referencedImageSequence;
Optional<MRImageModule> mrImageModule;
};
@@ -292,7 +292,7 @@ namespace ISMRMRD
Optional<StudyInformation> studyInformation;
Optional<MeasurementInformation> measurementInformation;
Optional<AcquisitionSystemInformation> acquisitionSystemInformation;
- Optional<ExperimentalConditions> experimentalConditions;
+ ExperimentalConditions experimentalConditions;
std::vector<Encoding> encoding;
Optional<ParallelImaging> parallelImaging;
Optional<SequenceParameters> sequenceParameters;
@@ -302,8 +302,9 @@ namespace ISMRMRD
- void deserialize(const char* xml, IsmrmrdHeader& h);
- void serialize(const IsmrmrdHeader& h, std::ostream& o);
+ EXPORTISMRMRDXML void deserialize(const char* xml, IsmrmrdHeader& h);
+ EXPORTISMRMRDXML void serialize(const IsmrmrdHeader& h, std::ostream& o);
+
/*
class IsmrmrdHeaderProxy
diff --git a/xml/dump_ismrmrd_header.cpp b/xml/test_ismrmrd_xml.cpp
similarity index 54%
rename from xml/dump_ismrmrd_header.cpp
rename to xml/test_ismrmrd_xml.cpp
index a22dc50..db9abfe 100644
--- a/xml/dump_ismrmrd_header.cpp
+++ b/xml/test_ismrmrd_xml.cpp
@@ -1,29 +1,42 @@
#include <iostream>
-#include "ismrmrd.h"
-#include "ismrmrd_hdf5.h"
+#include <fstream>
+#include <streambuf>
#include "ismrmrd_xml.h"
+#include "pugixml.hpp"
int main(int argc, char** argv)
{
if (argc < 2) {
- std::cout << "Usage:\n\tdump_ismrmrd_header <ISMRMRD_FILE_NAME>\n" << std::endl;
+ std::cout << "Usage:\n\ttest_ismrmrd_xml <ismrmrd_xml_header.xml>\n" << std::endl;
return -1;
}
std::string filename(argv[1]);
- std::cout << "ISMRMRD Header Dump: " << filename << std::endl;
+ std::cout << "ISMRMRD Header: " << filename << std::endl;
- ISMRMRD::IsmrmrdDataset d(filename.c_str(),"/dataset");
-
- boost::shared_ptr<std::string> xml = d.readHeader();
- //std::cout << "XML: \n" << *xml << std::endl;
+ std::ifstream t(filename.c_str());
+ std::string xml((std::istreambuf_iterator<char>(t)),
+ std::istreambuf_iterator<char>());
ISMRMRD::IsmrmrdHeader h;
+ deserialize(xml.c_str(),h);
+
+ pugi::xml_document doc;
+ pugi::xml_parse_result result = doc.load(xml.c_str());
+
+ std::ofstream raw("raw.xml");
+ std::ofstream proc("processed.xml");
+
+
+ doc.save(raw);
+ serialize(h,proc);
+
+ /*
deserialize(xml->c_str(),h);
- std::cout << "Resonance frequency: " << h.experimentalConditions.get().H1resonanceFrequency_Hz << std::endl;
+ std::cout << "Resonance frequency: " << h.experimentalConditions.H1resonanceFrequency_Hz << std::endl;
std::cout << "TR: " << h.sequenceParameters.get().TR[0] << std::endl;
if (h.userParameters) {
std::cout << "User parameters found" << std::endl;
@@ -34,5 +47,6 @@ int main(int argc, char** argv)
}
serialize(h,std::cout);
+ */
return 0;
}
--
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