NorMIT-nav  16.5
An IGT application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
cxProbeDefinition.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) 2008-2014, SINTEF Department of Medical Technology
5 All rights reserved.
6 
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9 
10 1. Redistributions of source code must retain the above copyright notice,
11  this list of conditions and the following disclaimer.
12 
13 2. Redistributions in binary form must reproduce the above copyright notice,
14  this list of conditions and the following disclaimer in the documentation
15  and/or other materials provided with the distribution.
16 
17 3. Neither the name of the copyright holder nor the names of its contributors
18  may be used to endorse or promote products derived from this software
19  without specific prior written permission.
20 
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 =========================================================================*/
32 
33 
34 #include "cxProbeDefinition.h"
35 #include <QDomNode>
36 #include "cxTypeConversions.h"
37 #include <iostream>
38 #include "cxEnumConverter.h"
39 #include "cxLogger.h"
40 
41 namespace cx
42 {
43 
44 namespace
45 {
46  double loadAttribute(QDomNode dataNode, QString name, double defVal)
47  {
48  QString text = dataNode.toElement().attribute(name);
49  bool ok;
50  double val = text.toDouble(&ok);
51  if (ok)
52  return val;
53  return defVal;
54  }
55 }
56 
57 // --------------------------------------------------------
58 // --------------------------------------------------------
59 // --------------------------------------------------------
60 
61 
63  mType(type), mDepthStart(0), mDepthEnd(0), mWidth(0),
64  mTemporalCalibration(0), mCenterOffset(0), mSoundSpeedCompensationFactor(1.0),
65  mUid("default"),
66  mOrigin_p(0, 0, 0), mSpacing(-1, -1, -1), mClipRect_p(0, 0, 0, 0), mSize(0, 0),
67  mDigital(false)
68 {}
69 
70 void ProbeDefinition::addXml(QDomNode dataNode) const
71 {
72  QDomElement elem = dataNode.toElement();
73  elem.setAttribute("type", qstring_cast(mType));
74  elem.setAttribute("depthStart", qstring_cast(mDepthStart));
75  elem.setAttribute("depthEnd", qstring_cast(mDepthEnd));
76  elem.setAttribute("width", qstring_cast(mWidth));
77 
78  elem.setAttribute("temporalCalibration", qstring_cast(mTemporalCalibration));
79  elem.setAttribute("centerOffset", qstring_cast(mCenterOffset));
80 
81  elem.setAttribute("uid", qstring_cast(mUid));
82 
83  QDomElement imageNode = dataNode.ownerDocument().createElement("image");
84  this->addImageXml(imageNode);
85  dataNode.appendChild(imageNode);
86 }
87 
88 void ProbeDefinition::parseXml(QDomNode dataNode)
89 {
90  QDomElement elem = dataNode.toElement();
91 
92  mType = static_cast<TYPE>(elem.attribute("type").toInt());
93  mDepthStart = loadAttribute(elem, "depthStart", 0);
94  mDepthEnd = loadAttribute(elem, "depthEnd", 0);
95  mWidth = loadAttribute(elem, "width", 0);
96 
97  mTemporalCalibration = loadAttribute(elem, "temporalCalibration", 0);
98  mCenterOffset = loadAttribute(elem, "centerOffset", 0);
99  mUid = elem.attribute("uid");
100 
101  QDomNode imageNode = dataNode.namedItem("image");
102  this->parseImageXml(imageNode);
103 }
104 
105 void ProbeDefinition::addImageXml(QDomNode dataNode) const
106 {
107  QDomElement elem = dataNode.toElement();
108 
109  elem.setAttribute("origin_p", qstring_cast(mOrigin_p));
110  elem.setAttribute("spacing", qstring_cast(mSpacing));
111  elem.setAttribute("clipRect_p", qstring_cast(mClipRect_p));
112  elem.setAttribute("width", qstring_cast(mSize.width()));
113  elem.setAttribute("height", qstring_cast(mSize.height()));
114 }
115 
116 void ProbeDefinition::parseImageXml(QDomNode dataNode)
117 {
118  QDomElement elem = dataNode.toElement();
119 
120  mOrigin_p = Vector3D::fromString(elem.attribute("origin_p"));
121  mSpacing = Vector3D::fromString(elem.attribute("spacing"));
122  mClipRect_p = DoubleBoundingBox3D::fromString(elem.attribute("clipRect_p"));
123  mSize.setWidth(loadAttribute(elem, "width", 0));
124  mSize.setHeight(loadAttribute(elem, "height", 0));
125 }
126 
128 {
129  mTemporalCalibration = value;
130 }
131 
133 {
134  mType = type;
135 }
136 
137 void ProbeDefinition::setSector(double depthStart, double depthEnd, double width, double centerOffset)
138 {
139  mDepthStart=depthStart;
140  mDepthEnd=depthEnd;
141  mWidth=width;
142  mCenterOffset=centerOffset;
143 }
144 
146 {
147  return mType;
148 }
149 
151 {
152  return mDepthStart;
153 }
154 
156 {
157  return mDepthEnd;
158 }
159 
161 {
162  return mWidth;
163 }
164 
166 {
167  return mTemporalCalibration;
168 }
169 
171 {
172  return mCenterOffset;
173 }
174 
175 void ProbeDefinition::resample(QSize newSize)
176 {
177  if (newSize==mSize)
178  return;
179 
180  Vector3D factor(double(newSize.width())/mSize.width(), double(newSize.height())/mSize.height(), 1);
181 
182  mOrigin_p = multiply_elems(mOrigin_p, factor);
183  mSpacing = divide_elems(mSpacing, factor);
184 
185  Vector3D cr0 = multiply_elems(mClipRect_p.corner(0,0,0), factor);
186  Vector3D cr1 = multiply_elems(mClipRect_p.corner(1,1,1), factor);
187  mClipRect_p = DoubleBoundingBox3D(cr0, cr1);
188 
189  mSize = newSize;
190 }
191 
192 QString ProbeDefinition::getUid() const
193 {
194  return mUid;
195 }
196 
197 void ProbeDefinition::setUid(QString uid)
198 {
199  mUid = uid;
200 }
201 
203 {
204  // cliprect and sector data are connected to linear probes:
205  if (mType==tLINEAR)
206  {
207  mClipRect_p[0] = mOrigin_p[0] - mWidth/2/mSpacing[0];
208  mClipRect_p[1] = mOrigin_p[0] + mWidth/2/mSpacing[0];
209 
210  mClipRect_p[2] = mOrigin_p[1] + mDepthStart/mSpacing[1];
211  mClipRect_p[3] = mOrigin_p[1] + mDepthEnd/mSpacing[1];
212  }
213 }
214 
216 {
217  // cliprect and sector data are connected to linear probes:
218  if (mType==tLINEAR)
219  {
220  mWidth = 2*std::max(fabs(mClipRect_p[0] - mOrigin_p[0]), fabs(mClipRect_p[1] - mOrigin_p[0])) * mSpacing[0];
221  mDepthStart = (mClipRect_p[2] - mOrigin_p[1]) * mSpacing[1];
222  mDepthEnd = (mClipRect_p[3] - mOrigin_p[1]) * mSpacing[1];
223  }
224 }
225 
227 {
228  mSpacing[1] = mSpacing[1] * factor / mSoundSpeedCompensationFactor;
229  mSoundSpeedCompensationFactor = factor;
230 
231  if (this->getType() != ProbeDefinition::tLINEAR)
232  reportWarning("Sound speed compensation is applied to spacing[1], i.e. it is correct for linear probes and approxomate for other probes. Factor: " + qstring_cast(factor));
233 }
234 
236 {
237  return mSoundSpeedCompensationFactor;
238 }
239 
240 //Should be transform_uMv(p) (input in pixels, output in mm)
241 Vector3D ProbeDefinition::transform_p_to_u(const Vector3D& q_p) const
242 {
243  Vector3D c(q_p[0], double(mSize.height()) - q_p[1] - 1, -q_p[2]);
244  c = multiply_elems(c, mSpacing);
245  return c;
246 }
247 
249 {
250  return this->transform_p_to_u(mOrigin_p);
251 }
252 
254 {
255  Vector3D p0 = transform_p_to_u(mClipRect_p.corner(0,0,0));
256  Vector3D p1 = transform_p_to_u(mClipRect_p.corner(1,1,1));
257  return DoubleBoundingBox3D(p0,p1);
258 }
259 
261 {
262  return mOrigin_p;
263 }
264 
266 {
267  return mSpacing;
268 }
269 
271 {
272  return mClipRect_p;
273 }
274 
276 {
277  return mSize;
278 }
279 
281 {
282  mOrigin_p = origin_p;
283 }
284 
286 {
287  mSpacing = spacing;
288 }
289 
291 {
292  mClipRect_p = clipRect_p;
293 }
294 
295 void ProbeDefinition::setSize(QSize size)
296 {
297  mSize = size;
298 }
299 
301 {
302  mDigital = val;
303 }
304 
306 {
307  return mDigital;
308 }
309 
310 void ProbeDefinition::setVariable(QString variableName, QVariant value)
311 {
312  mAdditionalVariables[variableName] = value;
313 }
314 
315 QVariant ProbeDefinition::getVariable(QString variableName)
316 {
317  if(!mAdditionalVariables.contains(variableName))
318  CX_LOG_ERROR(QString("Variable %1 don't exist in ProbeDefinition with uid %2").arg(variableName).arg(this->mUid));
319  return mAdditionalVariables[variableName];
320 }
321 
322 } //cx
QString qstring_cast(const T &val)
double getWidth() const
void addXml(QDomNode dataNode) const
Vector3D divide_elems(const Vector3D &a, const Vector3D &b)
perform element-wise division of a and b.
Definition: cxVector3D.cpp:57
void setSpacing(Vector3D spacing)
double getCenterOffset() const
QVariant getVariable(QString variableName)
US beam is emitted straight forward.
static DoubleBoundingBox3D fromString(const QString &text)
construct a bb from a string containing 6 whitespace-separated numbers
void resample(QSize mSize)
Set a new image size. Resample all other parameters to match this new image size, keeping sizes in mi...
double getSoundSpeedCompensationFactor() const
QString getUid() const
void setSector(double depthStart, double depthEnd, double width, double centerOffset=0)
double getDepthStart() const
void parseXml(QDomNode dataNode)
double getDepthEnd() const
Vector3D getOrigin_p() const
void setOrigin_p(Vector3D origin_p)
void reportWarning(QString msg)
Definition: cxLogger.cpp:91
void setTemporalCalibration(double value)
void setUid(QString uid)
#define CX_LOG_ERROR
Definition: cxLogger.h:114
void setUseDigitalVideo(bool val)
RTSource is digital (eg. US sector is set digitally, not read from .xml file)
void setClipRect_p(DoubleBoundingBox3D clipRect_p)
DoubleBoundingBox3D getClipRect_u() const
sector clipping rect in image space u. (lower-left corner origin)
void applySoundSpeedCompensationFactor(double factor)
Compensate for soundspeed for linear probes.
Representation of a floating-point bounding box in 3D. The data are stored as {xmin,xmax,ymin,ymax,zmin,zmax}, in order to simplify communication with vtk.
ProbeDefinition(TYPE type=tNONE)
Vector3D getOrigin_u() const
probe origin in image space u. (lower-left corner origin)
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
Definition: cxVector3D.h:63
Vector3D multiply_elems(const Vector3D &a, const Vector3D &b)
perform element-wise multiplication of a and b.
Definition: cxVector3D.cpp:52
Vector3D getSpacing() const
double getTemporalCalibration() const
void setVariable(QString variableName, QVariant value)
bool getUseDigitalVideo() const
DoubleBoundingBox3D getClipRect_p() const
void setSize(QSize size)