CustusX  16.12
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 "cxCustomMetric.h"
49 #include "cxAngleMetric.h"
50 #include "cxSphereMetric.h"
52 #include "cxDataFactory.h"
53 #include "cxLegacySingletons.h"
54 #include "cxSpaceProvider.h"
55 #include "cxTypeConversions.h"
56 #include "cxPatientModelService.h"
57 #include "cxViewService.h"
58 #include "cxLogger.h"
59 
60 namespace cx
61 {
62 
64 {
66  connect(patientService().get(), SIGNAL(dataAddedOrRemoved()), this, SIGNAL(metricsChanged()));
67 }
68 
70 {
71  DataPtr data = patientService()->getData(uid);
72  DataMetricPtr metric = boost::dynamic_pointer_cast<DataMetric>(data);
73  return metric;
74 }
75 
76 std::vector<DataMetricPtr> MetricManager::getAllMetrics()
77 {
78  std::vector<DataMetricPtr> retval;
79  std::map<QString, DataPtr> all = patientService()->getDatas();
80  for (std::map<QString, DataPtr>::iterator iter=all.begin(); iter!=all.end(); ++iter)
81  {
82  DataMetricPtr metric = boost::dynamic_pointer_cast<DataMetric>(iter->second);
83  if (metric)
84  retval.push_back(metric);
85  }
86  return retval;
87 }
88 
89 void MetricManager::setSelection(std::set<QString> selection)
90 {
91  mSelection = selection;
92 }
93 
94 void MetricManager::setActiveUid(QString uid)
95 {
96  mActiveLandmark = uid;
97  emit activeMetricChanged();
98 // this->setModified();
99 }
100 
102 {
103  DataMetricPtr metric = this->getMetric(uid);
104  if (!metric)
105  return;
106  Vector3D p_r = metric->getRefCoord();;
107  this->setManualToolPosition(p_r);
108 }
109 
110 void MetricManager::setManualToolPosition(Vector3D p_r)
111 {
112  Transform3D rMpr = patientService()->get_rMpr();
113  Vector3D p_pr = rMpr.inv().coord(p_r);
114 
115  // set the picked point as offset tip
116  ToolPtr tool = trackingService()->getManualTool();
117  Vector3D offset = tool->get_prMt().vector(Vector3D(0, 0, tool->getTooltipOffset()));
118  p_pr -= offset;
119  p_r = rMpr.coord(p_pr);
120 
121  // TODO set center here will not do: must handle
122  patientService()->setCenter(p_r);
123  Vector3D p0_pr = tool->get_prMt().coord(Vector3D(0, 0, 0));
124  tool->set_prMt(createTransformTranslate(p_pr - p0_pr) * tool->get_prMt());
125 }
126 
127 PointMetricPtr MetricManager::addPoint(Vector3D point, CoordinateSystem space, QString uid, QColor color)
128 {
129  PointMetricPtr p1 = patientService()->createSpecificData<PointMetric>(uid);
130  p1->get_rMd_History()->setParentSpace("reference");
131  p1->setSpace(space);
132  p1->setCoordinate(point);
133  p1->setColor(color);
134  patientService()->insertData(p1);
135 
136  viewService()->getGroup(0)->addData(p1->getUid());
137  this->setActiveUid(p1->getUid());
138 
139  return p1;
140 }
141 
142 
144 {
145  this->addPointInDefaultPosition();
146 }
147 
148 PointMetricPtr MetricManager::addPointInDefaultPosition()
149 {
151  QColor color = QColor(240, 170, 255, 255);
152  Vector3D p_ref = spaceProvider()->getActiveToolTipPoint(ref, true);
153 
154  DataPtr data = patientService()->getData(mActiveLandmark);
155  if(!data)
156 
157  return this->addPoint(p_ref, ref,"point%1", color);
158 
159  PointMetricPtr pointMetric = boost::dynamic_pointer_cast<PointMetric>(data);
160  if(pointMetric)
161  {
162  ref = pointMetric->getSpace();
163  p_ref = spaceProvider()->getActiveToolTipPoint(ref, true);
164  }
165 
166  DataMetricPtr metric = boost::dynamic_pointer_cast<DataMetric>(data);
167  if(metric)
168  color = metric->getColor();
169 
170 
171 
172  return this->addPoint(p_ref, ref,"point%1", color);
173 }
174 
176 {
177  FrameMetricPtr frame = patientService()->createSpecificData<FrameMetric>("frame%1");
178 // FrameMetricPtr frame(new FrameMetric("frame%1", "frame%1"));
179  frame->get_rMd_History()->setParentSpace("reference");
180 
182  Transform3D rMt = spaceProvider()->getActiveToolTipTransform(ref, true);
183 
184  frame->setSpace(ref);
185  frame->setFrame(rMt);
186 
187  this->installNewMetric(frame);
188 }
189 
191 {
192  ToolMetricPtr frame = patientService()->createSpecificData<ToolMetric>("tool%1");
193  frame->get_rMd_History()->setParentSpace("reference");
194 
196  Transform3D rMt = spaceProvider()->getActiveToolTipTransform(ref, true);
197 
198  frame->setSpace(ref);
199  frame->setFrame(rMt);
200  frame->setToolName(trackingService()->getActiveTool()->getName());
201  frame->setToolOffset(trackingService()->getActiveTool()->getTooltipOffset());
202 
203  this->installNewMetric(frame);
204 }
205 
207 {
208  PlaneMetricPtr p1 = patientService()->createSpecificData<PlaneMetric>("plane%1");
209  p1->get_rMd_History()->setParentSpace("reference");
210 
211  std::vector<DataPtr> args = this->getSpecifiedNumberOfValidArguments(p1->getArguments());
212  for (unsigned i=0; i<args.size(); ++i)
213  p1->getArguments()->set(i, args[i]);
214 
215  this->installNewMetric(p1);
216 }
217 
222 std::vector<DataPtr> MetricManager::refinePointArguments(std::vector<DataPtr> args, unsigned argNo)
223 {
224  // erase non-selected arguments if we have more than enough
225  //std::set<QString> selectedUids = this->getSelectedUids();
226  for (unsigned i=0; i<args.size();)
227  {
228  if (args.size() <= argNo)
229  break;
230  if (!mSelection.count(args[i]->getUid()))
231  args.erase(args.begin()+i);
232  else
233  ++i;
234  }
235 
236  while (args.size() > argNo)
237  args.erase(args.begin());
238 
239  while (args.size() < argNo)
240  {
241  PointMetricPtr p0 = this->addPointInDefaultPosition();
242  args.push_back(p0);
243  }
244 
245  return args;
246 }
247 
249 {
250  RegionOfInterestMetricPtr d0 = patientService()->createSpecificData<RegionOfInterestMetric>("roi%1");
251  d0->get_rMd_History()->setParentSpace("reference");
252  this->installNewMetric(d0);
253 }
254 
256 {
257  DistanceMetricPtr d0 = patientService()->createSpecificData<DistanceMetric>("distance%1");
258 // DistanceMetricPtr d0(new DistanceMetric("distance%1","distance%1"));
259  d0->get_rMd_History()->setParentSpace("reference");
260 
261  std::vector<DataPtr> args = this->getSpecifiedNumberOfValidArguments(d0->getArguments());
262  for (unsigned i=0; i<args.size(); ++i)
263  d0->getArguments()->set(i, args[i]);
264 
265  this->installNewMetric(d0);
266 }
267 
269 {
270  AngleMetricPtr d0 = patientService()->createSpecificData<AngleMetric>("angle%1");
271 // AngleMetricPtr d0(new AngleMetric("angle%1","angle%1"));
272  d0->get_rMd_History()->setParentSpace("reference");
273 
274  std::vector<DataPtr> args = this->getSpecifiedNumberOfValidArguments(d0->getArguments(), 3);
275  d0->getArguments()->set(0, args[0]);
276  d0->getArguments()->set(1, args[1]);
277  d0->getArguments()->set(2, args[1]);
278  d0->getArguments()->set(3, args[2]);
279 
280  this->installNewMetric(d0);
281 }
282 
283 std::vector<DataPtr> MetricManager::getSpecifiedNumberOfValidArguments(MetricReferenceArgumentListPtr arguments, int numberOfRequiredArguments)
284 {
285  // first try to reuse existing points as distance arguments, otherwise create new ones.
286 
287  std::vector<DataMetricPtr> metrics = this->getAllMetrics();
288 
289  std::vector<DataPtr> args;
290  for (unsigned i=0; i<metrics.size(); ++i)
291  {
292  if (arguments->validArgument(metrics[i]))
293  args.push_back(metrics[i]);
294  }
295 
296  if (numberOfRequiredArguments<0)
297  numberOfRequiredArguments = arguments->getCount();
298  args = this->refinePointArguments(args, numberOfRequiredArguments);
299 
300  return args;
301 }
302 
304 {
305  SphereMetricPtr d0 = patientService()->createSpecificData<SphereMetric>("sphere%1");
306  d0->get_rMd_History()->setParentSpace("reference");
307  std::vector<DataPtr> args = this->getSpecifiedNumberOfValidArguments(d0->getArguments());
308  d0->getArguments()->set(0, args[0]);
309 
310  this->installNewMetric(d0);
311 }
312 
314 {
315  DonutMetricPtr d0 = patientService()->createSpecificData<DonutMetric>("donut%1");
316  d0->get_rMd_History()->setParentSpace("reference");
317  std::vector<DataPtr> args = this->getSpecifiedNumberOfValidArguments(d0->getArguments());
318  d0->getArguments()->set(0, args[0]);
319  d0->getArguments()->set(1, args[1]);
320 
321  this->installNewMetric(d0);
322 }
323 
325 {
326  CustomMetricPtr d0 = patientService()->createSpecificData<CustomMetric>("Custom%1");
327  d0->get_rMd_History()->setParentSpace("reference");
328  std::vector<DataPtr> args = this->getSpecifiedNumberOfValidArguments(d0->getArguments());
329  d0->getArguments()->set(0, args[0]);
330  d0->getArguments()->set(1, args[1]);
331 
332  this->installNewMetric(d0);
333 }
334 
335 void MetricManager::installNewMetric(DataMetricPtr metric)
336 {
337  DataMetricPtr prevMetric = this->getMetric(mActiveLandmark);
338  if(prevMetric)
339  {
340  metric->setColor(prevMetric->getColor());
341  }
342 
343  patientService()->insertData(metric);
344  this->setActiveUid(metric->getUid());
345  viewService()->getGroup(0)->addData(metric->getUid());
346 }
347 
349 {
350  ToolPtr refTool = trackingService()->getReferenceTool();
351  if(!refTool) // we only load reference points from reference tools
352  {
353  reportDebug("No reference tool, cannot load reference points into the pointsampler");
354  return;
355  }
356 
357  std::map<int, Vector3D> referencePoints_s = refTool->getReferencePoints();
358  if(referencePoints_s.empty())
359  {
360  reportWarning("No referenceppoints in reference tool "+refTool->getName());
361  return;
362  }
363 
365  CoordinateSystem sensor = spaceProvider()->getS(refTool);
366 
367  std::map<int, Vector3D>::iterator it = referencePoints_s.begin();
368  for(; it != referencePoints_s.end(); ++it)
369  {
370  Vector3D P_ref = spaceProvider()->get_toMfrom(sensor, ref).coord(it->second);
371  this->addPoint(P_ref, CoordinateSystem(csREF), "ref%1");
372  }
373 }
374 
375 
377 {
378  QFile file(filename);
379  if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
380  return;
381 
382  std::map<QString, DataPtr> dataMap = patientService()->getDatas();
383  std::map<QString, DataPtr>::iterator iter;
384  for (iter = dataMap.begin(); iter != dataMap.end(); ++iter)
385  {
386  DataMetricPtr metric = boost::dynamic_pointer_cast<DataMetric>(iter->second);
387  if(metric)
388  {
389  file.write(metric->getAsSingleLineString().toLatin1());
390  file.write("\n");
391  }
392  }
393  file.close();
394 }
395 
396 
397 } // namespace cx
398 
399 
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:96
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
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:112
void exportMetricsToFile(QString filename)
void reportWarning(QString msg)
Definition: cxLogger.cpp:91
Data class that represents a custom.
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. ...
boost::shared_ptr< class RegionOfInterestMetric > RegionOfInterestMetricPtr
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()
PointMetricPtr addPoint(Vector3D point, CoordinateSystem space=CoordinateSystem(csREF), QString uid="point%1", QColor color=QColor(240, 170, 255, 255))
cxLogicManager_EXPORT TrackingServicePtr trackingService()
void activeMetricChanged()
void addDistanceButtonClickedSlot()
Base class for all Data Metrics.
Definition: cxDataMetric.h:64
boost::shared_ptr< class CustomMetric > CustomMetricPtr
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