[ismrmrd] 250/281: changes to XML functionality
Ghislain Vaillant
ghisvail-guest at moszumanska.debian.org
Wed Jan 14 20:01:20 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 74ddb5ae4a41799d2d3172b6b8ab1e553fadba8d
Author: Michael S. Hansen <michael.hansen at nih.gov>
Date: Tue Aug 12 12:37:46 2014 -0400
changes to XML functionality
---
xml/dump_ismrmrd_header.cpp | 35 ++++++
xml/ismrmrd_xml.cpp | 282 +++++++++++++++++++++++++++++++++++++++++++-
xml/ismrmrd_xml.h | 46 ++++----
3 files changed, 336 insertions(+), 27 deletions(-)
diff --git a/xml/dump_ismrmrd_header.cpp b/xml/dump_ismrmrd_header.cpp
new file mode 100644
index 0000000..010906d
--- /dev/null
+++ b/xml/dump_ismrmrd_header.cpp
@@ -0,0 +1,35 @@
+#include <iostream>
+#include "ismrmrd.h"
+#include "ismrmrd_hdf5.h"
+#include "ismrmrd_xml.h"
+
+int main(int argc, char** argv)
+{
+
+ if (argc < 2) {
+ std::cout << "Usage:\n\tdump_ismrmrd_header <ISMRMRD_FILE_NAME>\n" << std::endl;
+ return -1;
+ }
+
+ std::string filename(argv[1]);
+
+ std::cout << "ISMRMRD Header Dump: " << 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;
+
+ ISMRMRD::IsmrmrdHeaderProxy hp(xml->c_str());
+
+ std::cout << "Resonance frequency: " << hp.h().experimentalConditions.get().H1resonanceFrequency_Hz << std::endl;
+ std::cout << "TR: " << hp.h().sequenceParameters.get().TR[0] << std::endl;
+ //for (size_t i = 0; i < hp.h().userParameters.get().userParameterLong.size(); i++) {
+ //std::cout << "UserLong: " << hp.h().userParameters.get().userParameterLong[i].name.size() << std::endl;
+ /*
+ std::cout << "UserLong: " << hp.h().userParameters.get().userParameterLong[i].name.c_str() << ", "
+ << hp.h().userParameters.get().userParameterLong[i].value << std::endl;
+ */
+ //}
+ return 0;
+}
diff --git a/xml/ismrmrd_xml.cpp b/xml/ismrmrd_xml.cpp
index 30511a3..29586af 100644
--- a/xml/ismrmrd_xml.cpp
+++ b/xml/ismrmrd_xml.cpp
@@ -73,6 +73,152 @@ namespace ISMRMRD
return o;
}
+ String parse_string(pugi::xml_node& n, const char* child)
+ {
+ String r(n.child_value(child));
+ if (r.size() == 0) throw std::runtime_error("Null length string");
+ return r;
+ }
+
+ Optional<String> parse_optional_string(pugi::xml_node& n, const char* child)
+ {
+ String s(n.child_value(child));
+ Optional<String> r;
+ if (s.size()) r = s;
+ return r;
+ }
+
+ Optional<float> parse_optional_float(pugi::xml_node& n, const char* child)
+ {
+ Optional<float> r;
+ pugi::xml_node nc = n.child(child);
+ if (nc) {
+ r = std::atof(nc.child_value());
+ }
+ return r;
+ }
+
+ Optional<long> parse_optional_long(pugi::xml_node& n, const char* child) {
+ Optional<long> r;
+ pugi::xml_node nc = n.child(child);
+ if (nc) {
+ r = std::atoi(nc.child_value());
+ }
+ return r;
+ }
+
+ Optional<unsigned short> parse_optional_ushort(pugi::xml_node& n, const char* child) {
+ Optional<unsigned short> r;
+ pugi::xml_node nc = n.child(child);
+ if (nc) {
+ r = static_cast<unsigned short>(std::atoi(nc.child_value()));
+ }
+ return r;
+ }
+
+ Vector<float> parse_vector_float(pugi::xml_node& n, const char* child)
+ {
+ Vector<float> r;
+
+ pugi::xml_node nc = n.child(child);
+
+ while (nc) {
+ float f = std::atof(nc.child_value());
+ r.push_back(f);
+ nc = nc.next_sibling(child);
+ }
+
+ return r;
+ }
+
+ Vector<String> parse_vector_string(pugi::xml_node& n, const char* child)
+ {
+ Vector<String> r;
+ pugi::xml_node nc = n.child(child);
+ while (nc) {
+ String s = nc.child_value();
+ r.push_back(s);
+ nc = nc.next_sibling(child);
+ }
+ return r;
+ }
+
+ Vector<UserParameterLong> parse_user_parameter_long(pugi::xml_node& n, const char* child)
+ {
+ Vector<UserParameterLong> r;
+ pugi::xml_node nc = n.child(child);
+ while (nc) {
+ UserParameterLong v;
+ pugi::xml_node name = nc.child("name");
+ pugi::xml_node value = nc.child("value");
+
+ if (!name || !value) {
+ throw std::runtime_error("Malformed user parameter (long)");
+ }
+
+ v.name = String(name.child_value());
+ v.value = std::atoi(value.child_value());
+
+ r.push_back(v);
+
+ nc = nc.next_sibling(child);
+ }
+ return r;
+ }
+
+ Vector<UserParameterDouble> parse_user_parameter_double(pugi::xml_node& n, const char* child)
+ {
+ Vector<UserParameterDouble> r;
+ pugi::xml_node nc = n.child(child);
+ while (nc) {
+ UserParameterDouble v;
+ pugi::xml_node name = nc.child("name");
+ pugi::xml_node value = nc.child("value");
+
+ if (!name || !value) {
+ throw std::runtime_error("Malformed user parameter (double)");
+ }
+
+ char buffer[10000];
+ memcpy(buffer,name.child_value(),strlen(name.child_value())+1);
+ String tmp("BLAH");
+ v.name = "BLAKKK";//tmp;//String("BLAH");//name.child_value());
+ v.value = std::atof(value.child_value());
+
+ r.push_back(v);
+
+ nc = nc.next_sibling(child);
+ }
+
+ return r;
+ }
+
+ Vector<UserParameterString> parse_user_parameter_string(pugi::xml_node& n, const char* child)
+ {
+ Vector<UserParameterString> r;
+ pugi::xml_node nc = n.child(child);
+ while (nc) {
+ UserParameterString v;
+ pugi::xml_node name = nc.child("name");
+ pugi::xml_node value = nc.child("value");
+
+ if (!name || !value) {
+ throw std::runtime_error("Malformed user parameter (string)");
+ }
+
+ v.name = String(name.child_value());
+ v.value = String(value.child_value());
+
+ r.push_back(v);
+
+ nc = nc.next_sibling(child);
+ }
+
+ return r;
+ }
+
+ //End of utility functions for deserializing header
+
void IsmrmrdHeaderProxy::deserialize(const char* xml)
{
pugi::xml_document doc;
@@ -89,7 +235,7 @@ namespace ISMRMRD
pugi::xml_node encoding = root.child("encoding");
pugi::xml_node parallelImaging = root.child("parallelImaging");
pugi::xml_node sequenceParameters = root.child("sequenceParameters");
- pugi::xml_node dicomeParameters = root.child("dicomParameters");
+ pugi::xml_node dicomParameters = root.child("dicomParameters");
pugi::xml_node userParameters = root.child("userParameters");
//Parsing experimentalConditions
@@ -138,36 +284,162 @@ namespace ISMRMRD
if (!trajectory) {
throw std::runtime_error("trajectory not found in encoding section");
} else {
- e.trajectory = String(trajectory.value());
+ e.trajectory = String(encoding.child_value("trajectory"));
}
pugi::xml_node trajectoryDescription = encoding.child("trajectoryDescription");
if (trajectoryDescription) {
+ TrajectoryDescription traj;
+ try {
+ traj.identifier = parse_string(trajectoryDescription,"identifier");
+ traj.userParameterLong =
+ parse_user_parameter_long(trajectoryDescription, "userParameterLong");
+ traj.userParameterDouble =
+ parse_user_parameter_double(trajectoryDescription, "userParameterDouble");
+ traj.comment = parse_optional_string(trajectoryDescription, "comment");
+ e.trajectoryDescription = traj;
+ } catch (std::runtime_error& e) {
+ std::cout << "Error parsing trajectory description" << std::endl;
+ throw;
+ }
}
+ h_.encoding.push_back(e);
encoding = encoding.next_sibling("encoding");
}
}
if (subjectInformation) {
-
+ SubjectInformation info;
+ info.patientName = parse_optional_string(subjectInformation, "patientName");
+ info.patientWeight_kg = parse_optional_float(subjectInformation, "patientWeight_kg");
+ info.patientID = parse_optional_string(subjectInformation, "patientID");
+ info.patientBirthdate = parse_optional_string(subjectInformation, "patientBirthdate");
+ info.patientGender = parse_optional_string(subjectInformation, "patientGender");
+ h_.subjectInformation = info;
}
if (studyInformation) {
-
+ StudyInformation info;
+ info.studyDate = parse_optional_string(studyInformation,"studyDate");
+ info.studyTime = parse_optional_string(studyInformation,"studyTime");
+ info.studyID = parse_optional_string(studyInformation,"studyID");
+ info.accessionNumber = parse_optional_long(studyInformation,"accessionNumber");
+ info.referringPhysicianName = parse_optional_string(studyInformation,"referringPhysicianName");
+ info.studyDescription = parse_optional_string(studyInformation,"studyDescription");
+ h_.studyInformation = info;
}
if (measurementInformation) {
-
+ MeasurementInformation info;
+ info.measurementID = parse_optional_string(measurementInformation,"measurementID");
+ info.seriesDate = parse_optional_string(measurementInformation, "seriesDate");
+ info.seriesTime = parse_optional_string(measurementInformation, "seriesTime");
+ info.patientPosition = parse_string(measurementInformation, "patientPosition");
+ info.initialSeriesNumber = parse_optional_long(measurementInformation, "initialSeriesNumber");
+ info.protocolName = parse_optional_string(measurementInformation, "protocolName");
+ info.seriesDescription = parse_optional_string(measurementInformation, "seriesDescription");
+
+ pugi::xml_node measurementDependency = measurementInformation.child("measurementDependency");
+ while (measurementDependency) {
+ try {
+ MeasurementDependency d;
+ d.dependencyID = parse_string(measurementDependency,"dependencyID");
+ d.dependencyType = parse_string(measurementDependency,"dependencyType");
+ info.measurementDepencency.push_back(d);
+ } catch (std::runtime_error& e) {
+ std::cout << "Error parsing measurement dependency: " << e.what() << std::endl;
+ throw;
+ }
+ measurementDependency = measurementDependency.next_sibling("measurementDependency");
+ }
+ h_.measurementInformation = info;
}
if (acquisitionSystemInformation) {
+ AcquisitionSystemInformation info;
+ info.systemVendor = parse_optional_string(acquisitionSystemInformation, "systemVendor");
+ info.systemModel = parse_optional_string(acquisitionSystemInformation, "systemModel");
+ info.systemFieldStrength_T = parse_optional_float(acquisitionSystemInformation, "systemFieldStrength_T");
+ info.relativeReceiverNoiseBandwidth = parse_optional_float(acquisitionSystemInformation, "relativeReceiverNoiseBandwidth");
+ info.receiverChannels = parse_optional_ushort(acquisitionSystemInformation, "receiverChannels");
+ info.institutionName = parse_optional_string(acquisitionSystemInformation, "institutionName");
+ info.stationName = parse_optional_string(acquisitionSystemInformation, "stationName");
+
+ h_.acquisitionSystemInformation = info;
+ }
+
+ if (parallelImaging) {
+ ParallelImaging info;
+
+ pugi::xml_node accelerationFactor = parallelImaging.child("accelerationFactor");
+ if (!accelerationFactor) {
+ throw std::runtime_error("Unable to accelerationFactor section in parallelImaging");
+ } else {
+ info.accelerationFactor.kspace_encoding_step_1 = static_cast<unsigned short>(std::atoi(accelerationFactor.child_value("kspace_encoding_step_1")));
+ info.accelerationFactor.kspace_encoding_step_2 = static_cast<unsigned short>(std::atoi(accelerationFactor.child_value("kspace_encoding_step_2")));
+ }
+ info.calibrationMode = parse_optional_string(parallelImaging,"calibrationMode");
+ info.interleavingDimension = parse_optional_string(parallelImaging,"interleavingDimension");
+ h_.parallelImaging = info;
}
+ if (sequenceParameters) {
+ SequenceParameters p;
+ p.TR = parse_vector_float(sequenceParameters,"TR");
+ p.TE = parse_vector_float(sequenceParameters,"TE");
+ p.TI = parse_vector_float(sequenceParameters,"TI");
+ h_.sequenceParameters = p;
+ }
+
+ if (dicomParameters) {
+ DicomParameters p;
+ p.studyInstanceUID = parse_string(dicomParameters,"studyInstanceUID");
+ p.seriesInstanceUIDRoot = parse_optional_string(dicomParameters,"seriesInstanceUIDRoot");
+ p.frameOfReference = 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");
+ if (ri) {
+ pugi::xml_node ric = ri.child("referencedSOPInstanceUID");
+ while (ric) {
+ ReferencedImageSequence r;
+ r.referencedSOPInstanceUID = ric.child_value();
+ p.referencedImageSequence.push_back(r);
+ ric = ric.next_sibling("referenceSOPInstanceIUID");
+ }
+ }
+
+ pugi::xml_node mrimageModule = dicomParameters.child("MRImageModule");
+ if (mrimageModule) {
+ MRImageModule m;
+ m.imageType = parse_optional_string(mrimageModule,"imageType");
+ m.scanningSequence = parse_optional_string(mrimageModule, "scanningSequence");
+ m.sequenceVartiant = 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");
+ m.triggerTime = parse_optional_float(mrimageModule, "triggerTime");
+ m.flipAngle_deg = parse_optional_float(mrimageModule, "flipAngle_deg");
+ m.freqEncodingDirection = parse_optional_string(mrimageModule, "freqEncodingDirection");
+ p.mrImageModule = m;
+ }
+ h_.dicomParameters = p;
+ }
+
+
+ if (userParameters) {
+ UserParameters p;
+ //p.userParameterLong = parse_user_parameter_long(userParameters,"userParameterLong");
+ p.userParameterDouble = parse_user_parameter_double(userParameters,"userParameterDouble");
+ p.userParameterString = parse_user_parameter_string(userParameters,"userParameterString");
+ p.userParameterBase64 = parse_user_parameter_string(userParameters,"userParameterBase64");
+ h_.userParameters = p;
+ }
} else {
throw std::runtime_error("Root node 'ismrmrdHeader' not found");
diff --git a/xml/ismrmrd_xml.h b/xml/ismrmrd_xml.h
index febc072..9584aa4 100644
--- a/xml/ismrmrd_xml.h
+++ b/xml/ismrmrd_xml.h
@@ -32,7 +32,11 @@ namespace ISMRMRD
, siz_(0)
{}
- Vector(const T* v, size_t len) {
+ Vector(const T* v, size_t len)
+ : v_(0)
+ , len_(0)
+ , siz_(0)
+ {
allocate(len);
copy(v,len);
siz_ = len;
@@ -99,12 +103,16 @@ namespace ISMRMRD
void allocate(size_t len) {
T* tmp_v = v_;
if (len != len_) {
- //Allocate new array
- try {
- v_ = new T[len];
- } catch (std::bad_alloc&) {
- std::cout << "Error allocating memory in IsmrmrdXmlString" << std::endl;
- throw;
+ if (len) {
+ //Allocate new array
+ try {
+ v_ = new T[len];
+ } catch (std::bad_alloc&) {
+ std::cout << "Error allocating memory in ISMRMRD::Vector" << std::endl;
+ throw;
+ }
+ } else {
+ v_ = 0;
}
//Copy old content if applicable
@@ -134,26 +142,26 @@ namespace ISMRMRD
*/
class String : public Vector<char>
{
- typedef Vector<char> inherited;
public:
///Default constructor
String()
+ : Vector()
{
- inherited();
}
///Construct taking null terminated string
- String(const char* s)
+ String(const char* s)
+ : Vector(s,strlen(s)+1)
{
- inherited(s,strlen(s)+1);
+ std::cout << "Constructing string: " << s << std::endl;
}
///Construct taking length of string as input
String(const char* s, size_t length)
+ : Vector(length+1)
{
- inherited(length+1);
copy(s,length);
v_[length-1] = '\0';
}
@@ -183,7 +191,7 @@ namespace ISMRMRD
///Get the length of the string
size_t size() {
- return inherited::size()-1;
+ return siz_-1;
}
};
@@ -238,7 +246,7 @@ namespace ISMRMRD
Optional<String> patientName;
Optional<float> patientWeight_kg;
Optional<String> patientID;
- Optional<String> patientBirthDate;
+ Optional<String> patientBirthdate;
Optional<String> patientGender;
};
@@ -247,7 +255,7 @@ namespace ISMRMRD
Optional<String> studyDate;
Optional<String> studyTime;
Optional<String> studyID;
- Optional<long int> accessionNumber;
+ Optional<long> accessionNumber;
Optional<String> referringPhysicianName;
Optional<String> studyDescription;
};
@@ -364,18 +372,12 @@ namespace ISMRMRD
String value;
};
- struct UserParameterBase64
- {
- String name;
- String value;
- };
-
struct UserParameters
{
Vector<UserParameterLong> userParameterLong;
Vector<UserParameterDouble> userParameterDouble;
Vector<UserParameterString> userParameterString;
- Vector<UserParameterBase64> userParameterBase64;
+ Vector<UserParameterString> userParameterBase64;
};
struct TrajectoryDescription
--
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