Fraxinus  16.5.0-fx-rc1
An IGT application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
cxMetricManager.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 #include "cxMetricManager.h"
34 #include "cxManualTool.h"
35 #include "cxViewGroupData.h"
36 #include "cxTrackingService.h"
37 #include <QFile>
38 
39 #include "cxDataReaderWriter.h"
40 #include "cxLogger.h"
42 #include "cxPointMetric.h"
43 #include "cxDistanceMetric.h"
44 #include "cxFrameMetric.h"
45 #include "cxToolMetric.h"
46 #include "cxPlaneMetric.h"
47 #include "cxShapedMetric.h"
48 #include "cxAngleMetric.h"
49 #include "cxSphereMetric.h"
50 #include "cxDataFactory.h"
51 #include "cxLegacySingletons.h"
52 #include "cxSpaceProvider.h"
53 #include "cxTypeConversions.h"
54 #include "cxPatientModelService.h"
55 #include "cxViewService.h"
56 #include "cxLogger.h"
57 
58 namespace cx
59 {
60 
62 {
64  connect(patientService().get(), SIGNAL(dataAddedOrRemoved()), this, SIGNAL(metricsChanged()));
65 }
66 
68 {
69  DataPtr data = patientService()->getData(uid);
70  DataMetricPtr metric = boost::dynamic_pointer_cast<DataMetric>(data);
71  return metric;
72 }
73 
74 std::vector<DataMetricPtr> MetricManager::getAllMetrics()
75 {
76  std::vector<DataMetricPtr> retval;
77  std::map<QString, DataPtr> all = patientService()->getData();
78  for (std::map<QString, DataPtr>::iterator iter=all.begin(); iter!=all.end(); ++iter)
79  {
80  DataMetricPtr metric = boost::dynamic_pointer_cast<DataMetric>(iter->second);
81  if (metric)
82  retval.push_back(metric);
83  }
84  return retval;
85 }
86 
87 void MetricManager::setSelection(std::set<QString> selection)
88 {
89  mSelection = selection;
90 }
91 
92 void MetricManager::setActiveUid(QString uid)
93 {
94  mActiveLandmark = uid;
95  emit activeMetricChanged();
96 // this->setModified();
97 }
98 
99 void MetricManager::moveToMetric(QString uid)
100 {
101  DataMetricPtr metric = this->getMetric(uid);
102  if (!metric)
103  return;
104  Vector3D p_r = metric->getRefCoord();;
105  this->setManualToolPosition(p_r);
106 }
107 
108 void MetricManager::setManualToolPosition(Vector3D p_r)
109 {
110  Transform3D rMpr = patientService()->get_rMpr();
111  Vector3D p_pr = rMpr.inv().coord(p_r);
112 
113  // set the picked point as offset tip
114  ToolPtr tool = trackingService()->getManualTool();
115  Vector3D offset = tool->get_prMt().vector(Vector3D(0, 0, tool->getTooltipOffset()));
116  p_pr -= offset;
117  p_r = rMpr.coord(p_pr);
118 
119  // TODO set center here will not do: must handle
120  patientService()->setCenter(p_r);
121  Vector3D p0_pr = tool->get_prMt().coord(Vector3D(0, 0, 0));
122  tool->set_prMt(createTransformTranslate(p_pr - p0_pr) * tool->get_prMt());
123 }
124 
125 PointMetricPtr MetricManager::addPoint(Vector3D point, CoordinateSystem space, QString name, QColor color)
126 {
127  PointMetricPtr p1 = patientService()->createSpecificData<PointMetric>(name);
128  p1->get_rMd_History()->setParentSpace("reference");
129  p1->setSpace(space);
130  p1->setCoordinate(point);
131  p1->setColor(color);
132  patientService()->insertData(p1);
133 
134  viewService()->getGroup(0)->addData(p1->getUid());
135  this->setActiveUid(p1->getUid());
136 
137  return p1;
138 }
139 
140 
142 {
143  this->addPointInDefaultPosition();
144 }
145 
146 PointMetricPtr MetricManager::addPointInDefaultPosition()
147 {
149  QColor color = QColor(240, 170, 255, 255);
150  Vector3D p_ref = spaceProvider()->getActiveToolTipPoint(ref, true);
151 
152  DataPtr data = patientService()->getData(mActiveLandmark);
153  if(!data)
154 
155  return this->addPoint(p_ref, ref,"point%1", color);
156 
157  PointMetricPtr pointMetric = boost::dynamic_pointer_cast<PointMetric>(data);
158  if(pointMetric)
159  {
160  ref = pointMetric->getSpace();
161  p_ref = spaceProvider()->getActiveToolTipPoint(ref, true);
162  }
163 
164  DataMetricPtr metric = boost::dynamic_pointer_cast<DataMetric>(data);
165  if(metric)
166  color = metric->getColor();
167 
168 
169 
170  return this->addPoint(p_ref, ref,"point%1", color);
171 }
172 
174 {
175  FrameMetricPtr frame = patientService()->createSpecificData<FrameMetric>("frame%1");
176 // FrameMetricPtr frame(new FrameMetric("frame%1", "frame%1"));
177  frame->get_rMd_History()->setParentSpace("reference");
178 
180  Transform3D rMt = spaceProvider()->getActiveToolTipTransform(ref, true);
181 
182  frame->setSpace(ref);
183  frame->setFrame(rMt);
184 
185  this->installNewMetric(frame);
186 }
187 
189 {
190  ToolMetricPtr frame = patientService()->createSpecificData<ToolMetric>("tool%1");
191  frame->get_rMd_History()->setParentSpace("reference");
192 
194  Transform3D rMt = spaceProvider()->getActiveToolTipTransform(ref, true);
195 
196  frame->setSpace(ref);
197  frame->setFrame(rMt);
198  frame->setToolName(trackingService()->getActiveTool()->getName());
199  frame->setToolOffset(trackingService()->getActiveTool()->getTooltipOffset());
200 
201  this->installNewMetric(frame);
202 }
203 
205 {
206  PlaneMetricPtr p1 = patientService()->createSpecificData<PlaneMetric>("plane%1");
207  p1->get_rMd_History()->setParentSpace("reference");
208 
209  std::vector<DataPtr> args = this->getSpecifiedNumberOfValidArguments(p1->getArguments());
210  for (unsigned i=0; i<args.size(); ++i)
211  p1->getArguments()->set(i, args[i]);
212 
213  this->installNewMetric(p1);
214 }
215 
220 std::vector<DataPtr> MetricManager::refinePointArguments(std::vector<DataPtr> args, unsigned argNo)
221 {
222  // erase non-selected arguments if we have more than enough
223  //std::set<QString> selectedUids = this->getSelectedUids();
224  for (unsigned i=0; i<args.size();)
225  {
226  if (args.size() <= argNo)
227  break;
228  if (!mSelection.count(args[i]->getUid()))
229  args.erase(args.begin()+i);
230  else
231  ++i;
232  }
233 
234  while (args.size() > argNo)
235  args.erase(args.begin());
236 
237  while (args.size() < argNo)
238  {
239  PointMetricPtr p0 = this->addPointInDefaultPosition();
240  args.push_back(p0);
241  }
242 
243  return args;
244 }
245 
247 {
248  DistanceMetricPtr d0 = patientService()->createSpecificData<DistanceMetric>("distance%1");
249 // DistanceMetricPtr d0(new DistanceMetric("distance%1","distance%1"));
250  d0->get_rMd_History()->setParentSpace("reference");
251 
252  std::vector<DataPtr> args = this->getSpecifiedNumberOfValidArguments(d0->getArguments());
253  for (unsigned i=0; i<args.size(); ++i)
254  d0->getArguments()->set(i, args[i]);
255 
256  this->installNewMetric(d0);
257 }
258 
260 {
261  AngleMetricPtr d0 = patientService()->createSpecificData<AngleMetric>("angle%1");
262 // AngleMetricPtr d0(new AngleMetric("angle%1","angle%1"));
263  d0->get_rMd_History()->setParentSpace("reference");
264 
265  std::vector<DataPtr> args = this->getSpecifiedNumberOfValidArguments(d0->getArguments(), 3);
266  d0->getArguments()->set(0, args[0]);
267  d0->getArguments()->set(1, args[1]);
268  d0->getArguments()->set(2, args[1]);
269  d0->getArguments()->set(3, args[2]);
270 
271  this->installNewMetric(d0);
272 }
273 
274 std::vector<DataPtr> MetricManager::getSpecifiedNumberOfValidArguments(MetricReferenceArgumentListPtr arguments, int numberOfRequiredArguments)
275 {
276  // first try to reuse existing points as distance arguments, otherwise create new ones.
277 
278  std::vector<DataMetricPtr> metrics = this->getAllMetrics();
279 
280  std::vector<DataPtr> args;
281  for (unsigned i=0; i<metrics.size(); ++i)
282  {
283  if (arguments->validArgument(metrics[i]))
284  args.push_back(metrics[i]);
285  }
286 
287  if (numberOfRequiredArguments<0)
288  numberOfRequiredArguments = arguments->getCount();
289  args = this->refinePointArguments(args, numberOfRequiredArguments);
290 
291  return args;
292 }
293 
295 {
296  SphereMetricPtr d0 = patientService()->createSpecificData<SphereMetric>("sphere%1");
297  d0->get_rMd_History()->setParentSpace("reference");
298  std::vector<DataPtr> args = this->getSpecifiedNumberOfValidArguments(d0->getArguments());
299  d0->getArguments()->set(0, args[0]);
300 
301  this->installNewMetric(d0);
302 }
303 
305 {
306  DonutMetricPtr d0 = patientService()->createSpecificData<DonutMetric>("donut%1");
307  d0->get_rMd_History()->setParentSpace("reference");
308  std::vector<DataPtr> args = this->getSpecifiedNumberOfValidArguments(d0->getArguments());
309  d0->getArguments()->set(0, args[0]);
310  d0->getArguments()->set(1, args[1]);
311 
312  this->installNewMetric(d0);
313 }
314 
315 void MetricManager::installNewMetric(DataMetricPtr metric)
316 {
317  DataMetricPtr prevMetric = this->getMetric(mActiveLandmark);
318  if(prevMetric)
319  {
320  metric->setColor(prevMetric->getColor());
321  }
322 
323  patientService()->insertData(metric);
324  this->setActiveUid(metric->getUid());
325  viewService()->getGroup(0)->addData(metric->getUid());
326 }
327 
329 {
330  ToolPtr refTool = trackingService()->getReferenceTool();
331  if(!refTool) // we only load reference points from reference tools
332  {
333  reportDebug("No reference tool, cannot load reference points into the pointsampler");
334  return;
335  }
336 
337  std::map<int, Vector3D> referencePoints_s = refTool->getReferencePoints();
338  if(referencePoints_s.empty())
339  {
340  reportWarning("No referenceppoints in reference tool "+refTool->getName());
341  return;
342  }
343 
345  CoordinateSystem sensor = spaceProvider()->getS(refTool);
346 
347  std::map<int, Vector3D>::iterator it = referencePoints_s.begin();
348  for(; it != referencePoints_s.end(); ++it)
349  {
350  Vector3D P_ref = spaceProvider()->get_toMfrom(sensor, ref).coord(it->second);
351  this->addPoint(P_ref, CoordinateSystem(csREF), "ref%1");
352  }
353 }
354 
355 
357 {
358  QFile file(filename);
359  if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
360  return;
361 
362  std::map<QString, DataPtr> dataMap = patientService()->getData();
363  std::map<QString, DataPtr>::iterator iter;
364  for (iter = dataMap.begin(); iter != dataMap.end(); ++iter)
365  {
366  DataMetricPtr metric = boost::dynamic_pointer_cast<DataMetric>(iter->second);
367  if(metric)
368  {
369  file.write(metric->getAsSingleLineString().toLatin1());
370  file.write("\n");
371  }
372  }
373  file.close();
374 }
375 
376 
377 } // namespace cx
378 
379 
boost::shared_ptr< class FrameMetric > FrameMetricPtr
Definition: cxFrameMetric.h:44
boost::shared_ptr< class ToolMetric > ToolMetricPtr
Definition: cxToolMetric.h:45
boost::shared_ptr< class DonutMetric > DonutMetricPtr
Transform3D Transform3D
Transform3D is a representation of an affine 3D transform.
boost::shared_ptr< DataMetric > DataMetricPtr
Definition: cxDataMetric.h:95
csREF
the data reference space (r) using LPS (left-posterior-superior) coordinates.
boost::shared_ptr< class SphereMetric > SphereMetricPtr
Data class that represents a single frame (transform).
Definition: cxFrameMetric.h:54
Data class representing a plane.
Definition: cxPlaneMetric.h:69
static CoordinateSystem reference()
boost::shared_ptr< class AngleMetric > AngleMetricPtr
Definition: cxAngleMetric.h:54
PointMetricPtr addPoint(Vector3D point, CoordinateSystem space=CoordinateSystem(csREF), QString name="point%1", QColor color=QColor(240, 170, 255, 255))
Data class that represents a donut.
boost::shared_ptr< class PlaneMetric > PlaneMetricPtr
Definition: cxPlaneMetric.h:55
boost::shared_ptr< class Data > DataPtr
void setSelection(std::set< QString > selection)
virtual RegistrationHistoryPtr get_rMd_History()
Definition: cxData.cpp:111
void exportMetricsToFile(QString filename)
void reportWarning(QString msg)
Definition: cxLogger.cpp:91
Data class that represents a donut.
boost::shared_ptr< class MetricReferenceArgumentList > MetricReferenceArgumentListPtr
DataMetricPtr getMetric(QString uid)
Transform3D createTransformTranslate(const Vector3D &translation)
Identification of a Coordinate system.
boost::shared_ptr< class DistanceMetric > DistanceMetricPtr
Data class that represents a distance between two points, or a point and a plane. ...
cxLogicManager_EXPORT SpaceProviderPtr spaceProvider()
Data class that represents a single point.
Definition: cxPointMetric.h:63
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
Definition: cxVector3D.h:63
cxLogicManager_EXPORT ViewServicePtr viewService()
cxLogicManager_EXPORT PatientModelServicePtr patientService()
cxLogicManager_EXPORT TrackingServicePtr trackingService()
void activeMetricChanged()
void addDistanceButtonClickedSlot()
Base class for all Data Metrics.
Definition: cxDataMetric.h:64
Data class that represents an angle between two lines.
Definition: cxAngleMetric.h:67
void moveToMetric(QString uid)
void reportDebug(QString msg)
Definition: cxLogger.cpp:89
void setActiveUid(QString uid)
boost::shared_ptr< class PointMetric > PointMetricPtr
boost::shared_ptr< class Tool > ToolPtr