CustusX  15.8
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)
126 {
127  PointMetricPtr p1 = patientService()->createSpecificData<PointMetric>("point%1");
128  p1->get_rMd_History()->setParentSpace("reference");
129  p1->setSpace(space);
130  p1->setCoordinate(point);
131  patientService()->insertData(p1);
132 
133  viewService()->getGroup(0)->addData(p1->getUid());
134  this->setActiveUid(p1->getUid());
135 
136  return p1;
137 }
138 
139 
141 {
142  this->addPointInDefaultPosition();
143 }
144 
145 PointMetricPtr MetricManager::addPointInDefaultPosition()
146 {
148  Vector3D p_ref = spaceProvider()->getActiveToolTipPoint(ref, true);
149  return this->addPoint(p_ref, ref);
150 }
151 
153 {
154  FrameMetricPtr frame = patientService()->createSpecificData<FrameMetric>("frame%1");
155 // FrameMetricPtr frame(new FrameMetric("frame%1", "frame%1"));
156  frame->get_rMd_History()->setParentSpace("reference");
157 
159  Transform3D rMt = spaceProvider()->getActiveToolTipTransform(ref, true);
160 
161  frame->setSpace(ref);
162  frame->setFrame(rMt);
163 
164  this->installNewMetric(frame);
165 }
166 
168 {
169  ToolMetricPtr frame = patientService()->createSpecificData<ToolMetric>("tool%1");
170  frame->get_rMd_History()->setParentSpace("reference");
171 
173  Transform3D rMt = spaceProvider()->getActiveToolTipTransform(ref, true);
174 
175  frame->setSpace(ref);
176  frame->setFrame(rMt);
177  frame->setToolName(trackingService()->getActiveTool()->getName());
178  frame->setToolOffset(trackingService()->getActiveTool()->getTooltipOffset());
179 
180  this->installNewMetric(frame);
181 }
182 
184 {
185  PlaneMetricPtr p1 = patientService()->createSpecificData<PlaneMetric>("plane%1");
186  p1->get_rMd_History()->setParentSpace("reference");
187 
188  std::vector<DataPtr> args = this->getSpecifiedNumberOfValidArguments(p1->getArguments());
189  for (unsigned i=0; i<args.size(); ++i)
190  p1->getArguments()->set(i, args[i]);
191 
192  this->installNewMetric(p1);
193 }
194 
199 std::vector<DataPtr> MetricManager::refinePointArguments(std::vector<DataPtr> args, unsigned argNo)
200 {
201  // erase non-selected arguments if we have more than enough
202  //std::set<QString> selectedUids = this->getSelectedUids();
203  for (unsigned i=0; i<args.size();)
204  {
205  if (args.size() <= argNo)
206  break;
207  if (!mSelection.count(args[i]->getUid()))
208  args.erase(args.begin()+i);
209  else
210  ++i;
211  }
212 
213  while (args.size() > argNo)
214  args.erase(args.begin());
215 
216  while (args.size() < argNo)
217  {
218  PointMetricPtr p0 = this->addPointInDefaultPosition();
219  args.push_back(p0);
220  }
221 
222  return args;
223 }
224 
226 {
227  DistanceMetricPtr d0 = patientService()->createSpecificData<DistanceMetric>("distance%1");
228 // DistanceMetricPtr d0(new DistanceMetric("distance%1","distance%1"));
229  d0->get_rMd_History()->setParentSpace("reference");
230 
231  std::vector<DataPtr> args = this->getSpecifiedNumberOfValidArguments(d0->getArguments());
232  for (unsigned i=0; i<args.size(); ++i)
233  d0->getArguments()->set(i, args[i]);
234 
235  this->installNewMetric(d0);
236 }
237 
239 {
240  AngleMetricPtr d0 = patientService()->createSpecificData<AngleMetric>("angle%1");
241 // AngleMetricPtr d0(new AngleMetric("angle%1","angle%1"));
242  d0->get_rMd_History()->setParentSpace("reference");
243 
244  std::vector<DataPtr> args = this->getSpecifiedNumberOfValidArguments(d0->getArguments(), 3);
245  d0->getArguments()->set(0, args[0]);
246  d0->getArguments()->set(1, args[1]);
247  d0->getArguments()->set(2, args[1]);
248  d0->getArguments()->set(3, args[2]);
249 
250  this->installNewMetric(d0);
251 }
252 
253 std::vector<DataPtr> MetricManager::getSpecifiedNumberOfValidArguments(MetricReferenceArgumentListPtr arguments, int numberOfRequiredArguments)
254 {
255  // first try to reuse existing points as distance arguments, otherwise create new ones.
256 
257  std::vector<DataMetricPtr> metrics = this->getAllMetrics();
258 
259  std::vector<DataPtr> args;
260  for (unsigned i=0; i<metrics.size(); ++i)
261  {
262  if (arguments->validArgument(metrics[i]))
263  args.push_back(metrics[i]);
264  }
265 
266  if (numberOfRequiredArguments<0)
267  numberOfRequiredArguments = arguments->getCount();
268  args = this->refinePointArguments(args, numberOfRequiredArguments);
269 
270  return args;
271 }
272 
274 {
275  SphereMetricPtr d0 = patientService()->createSpecificData<SphereMetric>("sphere%1");
276  d0->get_rMd_History()->setParentSpace("reference");
277  std::vector<DataPtr> args = this->getSpecifiedNumberOfValidArguments(d0->getArguments());
278  d0->getArguments()->set(0, args[0]);
279 
280  this->installNewMetric(d0);
281 }
282 
284 {
285  DonutMetricPtr d0 = patientService()->createSpecificData<DonutMetric>("donut%1");
286  d0->get_rMd_History()->setParentSpace("reference");
287  std::vector<DataPtr> args = this->getSpecifiedNumberOfValidArguments(d0->getArguments());
288  d0->getArguments()->set(0, args[0]);
289  d0->getArguments()->set(1, args[1]);
290 
291  this->installNewMetric(d0);
292 }
293 
294 void MetricManager::installNewMetric(DataMetricPtr metric)
295 {
296  patientService()->insertData(metric);
297  this->setActiveUid(metric->getUid());
298  viewService()->getGroup(0)->addData(metric->getUid());
299 }
300 
302 {
303  ToolPtr refTool = trackingService()->getReferenceTool();
304  if(!refTool) // we only load reference points from reference tools
305  {
306  reportDebug("No reference tool, cannot load reference points into the pointsampler");
307  return;
308  }
309 
310  std::map<int, Vector3D> referencePoints_s = refTool->getReferencePoints();
311  if(referencePoints_s.empty())
312  {
313  reportWarning("No referenceppoints in reference tool "+refTool->getName());
314  return;
315  }
316 
318  CoordinateSystem sensor = spaceProvider()->getS(refTool);
319 
320  std::map<int, Vector3D>::iterator it = referencePoints_s.begin();
321  for(; it != referencePoints_s.end(); ++it)
322  {
323  Vector3D P_ref = spaceProvider()->get_toMfrom(sensor, ref).coord(it->second);
324  this->addPoint(P_ref, CoordinateSystem(csREF), "ref%1");
325  }
326 }
327 
328 
330 {
331  QFile file(filename);
332  if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
333  return;
334 
335  std::map<QString, DataPtr> dataMap = patientService()->getData();
336  std::map<QString, DataPtr>::iterator iter;
337  for (iter = dataMap.begin(); iter != dataMap.end(); ++iter)
338  {
339  DataMetricPtr metric = boost::dynamic_pointer_cast<DataMetric>(iter->second);
340  if(metric)
341  {
342  file.write(metric->getAsSingleLineString().toLatin1());
343  file.write("\n");
344  }
345  }
346  file.close();
347 }
348 
349 
350 } // namespace cx
351 
352 
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:93
csREF
the data reference space (r)
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:105
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()
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