Fraxinus  18.10
An IGT application
cxCustomMetaImage.cpp
Go to the documentation of this file.
1 /*=========================================================================
2 This file is part of CustusX, an Image Guided Therapy Application.
3 
4 Copyright (c) SINTEF Department of Medical Technology.
5 All rights reserved.
6 
7 CustusX is released under a BSD 3-Clause license.
8 
9 See Lisence.txt (https://github.com/SINTEFMedtek/CustusX/blob/master/License.txt) for details.
10 =========================================================================*/
11 #include "cxCustomMetaImage.h"
12 
13 #include <QFile>
14 #include <QTextStream>
15 #include <QStringList>
16 #include "cxLogger.h"
17 
18 #include "cxTypeConversions.h"
19 
20 namespace cx
21 {
22 
24  mFilename(filename)
25 {}
26 
27 QString CustomMetaImage::readKey(QString key)
28 {
29  QFile file(mFilename);
30 
31  QString line;
32  if (file.open(QIODevice::ReadOnly))
33  {
34  QTextStream t(&file);
35  while (!t.atEnd())
36  {
37  line.clear();
38  line = t.readLine();
39  // do something with the line
40  if (line.startsWith(key, Qt::CaseInsensitive))
41  {
42  QStringList list = line.split("=", QString::SkipEmptyParts);
43  if (list.size() >= 2)
44  {
45  list = list.mid(1);
46  return list.join("=");
47  }
48  }
49  }
50  file.close();
51  }
52 
53  return "";
54 }
55 
57 {
58  QString mod = this->readKey("Modality");
59 
60  if (mod.contains("CT", Qt::CaseInsensitive))
61  return "CT";
62  if (mod.contains("MR", Qt::CaseInsensitive))
63  return "MR";
64  if (mod.contains("US", Qt::CaseInsensitive))
65  return "US";
66  if (mod.contains("OTHER", Qt::CaseInsensitive))
67  return "OTHER";
68  mod = mod.remove("MET_MOD_");
69  return mod;
70 }
71 
73 {
74  return this->readKey("ImageType3");
75 }
76 
80 void CustomMetaImage::remove(QStringList* data, QStringList keys)
81 {
82  QRegExp regexp(QString("(^%1)").arg(keys.join("|^")));
83  QStringList removeThese = data->filter(regexp);
84  for (int i=0; i<removeThese.size(); ++i)
85  data->removeAll(removeThese[i]);
86 }
87 
93 void CustomMetaImage::append(QStringList* data, QString key, QString value)
94 {
95  // find index of ElementDataFile - this is the last element according to MHD standard (but we might have appended something else after it).
96  int last = data->lastIndexOf(QRegExp("^ElementDataFile.*"));
97  data->insert(last, QString("%1 = %2").arg(key).arg(value));
98 }
99 
100 void CustomMetaImage::setKey(QString key, QString value)
101 {
102  QFile file(mFilename);
103 
104  if (!file.open(QIODevice::ReadWrite))
105  {
106  reportError("Failed to open file " + mFilename + ".");
107  return;
108  }
109 
110  QStringList data = QTextStream(&file).readAll().split("\n");
111 
112  this->remove(&data, QStringList()<<key);
113  this->append(&data, key, value);
114 
115  file.resize(0);
116  file.write(data.join("\n").toLatin1());
117 }
118 
119 void CustomMetaImage::setModality(QString value)
120 {
121  QStringList valid_values;
122  valid_values << "CT" << "MR" << "NM" << "US" << "OTHER" << "UNKNOWN";
123  if(!valid_values.contains(value, Qt::CaseInsensitive))
124  value = "UNKNOWN";
125 
126  this->setKey("Modality", value);
127 }
128 
129 void CustomMetaImage::setImageType(QString value)
130 {
131  if (value.isEmpty())
132  return;
133  this->setKey("ImageType3", value);
134 }
135 
136 
138 {
139  //read the specific TransformMatrix-tag from the header
140  Vector3D p_r(0, 0, 0);
141  Vector3D e_x(1, 0, 0);
142  Vector3D e_y(0, 1, 0);
143  Vector3D e_z(0, 0, 1);
144 
145  QFile file(mFilename);
146 
147  QString line;
148  if (file.open(QIODevice::ReadOnly))
149  {
150  QTextStream t(&file);
151  while (!t.atEnd())
152  {
153  line.clear();
154  line = t.readLine();
155  // do something with the line
156  if (line.startsWith("Position", Qt::CaseInsensitive) || line.startsWith("Offset", Qt::CaseInsensitive))
157  {
158  QStringList list = line.split(" ", QString::SkipEmptyParts);
159  if (list.size()>=5)
160  p_r = Vector3D(list[2].toDouble(), list[3].toDouble(), list[4].toDouble());
161  }
162  else if (line.startsWith("TransformMatrix", Qt::CaseInsensitive) || line.startsWith("Orientation",
163  Qt::CaseInsensitive))
164  {
165  QStringList list = line.split(" ", QString::SkipEmptyParts);
166 
167  if (list.size()>=8)
168  {
169  e_x = Vector3D(list[2].toDouble(), list[3].toDouble(), list[4].toDouble());
170  e_y = Vector3D(list[5].toDouble(), list[6].toDouble(), list[7].toDouble());
171  e_z = cross(e_x, e_y);
172  }
173  }
174  }
175  file.close();
176  }
177 
178  Transform3D rMd = Transform3D::Identity();
179 
180  // add rotational part
181  for (unsigned i = 0; i < 3; ++i)
182  {
183  rMd(i,0) = e_x[i];
184  rMd(i,1) = e_y[i];
185  rMd(i,2) = e_z[i];
186  }
187 
188 
189  // add translational part
190  rMd(0,3) = p_r[0];
191  rMd(1,3) = p_r[1];
192  rMd(2,3) = p_r[2];
193  return rMd;
194 }
195 
197 {
198  QFile file(mFilename);
199 
200  if (!file.open(QIODevice::ReadWrite))
201  {
202  reportWarning("Could not save transform because: Failed to open file " + mFilename);
203  return;
204  }
205 
206  QStringList data = QTextStream(&file).readAll().split("\n");
207 
208  this->remove(&data, QStringList()<<"TransformMatrix"<<"Offset"<<"Position"<<"Orientation");
209 
210  int dim = 3; // hardcoded - will fail for 2d images
211  std::stringstream tmList;
212  for (int c=0; c<dim; ++c)
213  for (int r=0; r<dim; ++r)
214  tmList << " " << M(r,c);
215  this->append(&data, "TransformMatrix", qstring_cast(tmList.str()));
216 
217  std::stringstream posList;
218  for (int r=0; r<dim; ++r)
219  posList << " " << M(r,3);
220  this->append(&data, "Offset", qstring_cast(posList.str()));
221 
222  file.resize(0);
223  file.write(data.join("\n").toLatin1());
224 }
225 
226 }
QString qstring_cast(const T &val)
void reportError(QString msg)
Definition: cxLogger.cpp:71
CustomMetaImage(QString filename)
QString readKey(QString key)
Transform3D Transform3D
Transform3D is a representation of an affine 3D transform.
Vector3D cross(const Vector3D &a, const Vector3D &b)
compute cross product of a and b.
Definition: cxVector3D.cpp:41
void setImageType(QString value)
void setModality(QString value)
void reportWarning(QString msg)
Definition: cxLogger.cpp:70
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
Definition: cxVector3D.h:42
void setKey(QString key, QString value)
void setTransform(const Transform3D M)
Namespace for all CustusX production code.