Fraxinus  18.10
An IGT application
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) 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 
12 #include "cxMetricManager.h"
13 #include "cxManualTool.h"
14 #include "cxViewGroupData.h"
15 #include "cxTrackingService.h"
16 #include <QFile>
17 #include <QTextStream>
18 #include <QDialog>
19 #include <QInputDialog>
20 #include <QVBoxLayout>
21 #include <QPushButton>
22 #include <QCheckBox>
23 #include <QGroupBox>
24 #include <QLabel>
25 #include <QButtonGroup>
26 #include <vtkMNITagPointReader.h>
27 #include <vtkStringArray.h>
28 #include "vtkForwardDeclarations.h"
29 #include "cxDataReaderWriter.h"
30 #include "cxLogger.h"
32 #include "cxPointMetric.h"
33 #include "cxDistanceMetric.h"
34 #include "cxFrameMetric.h"
35 #include "cxToolMetric.h"
36 #include "cxPlaneMetric.h"
37 #include "cxShapedMetric.h"
38 #include "cxCustomMetric.h"
39 #include "cxAngleMetric.h"
40 #include "cxSphereMetric.h"
42 #include "cxDataFactory.h"
43 #include "cxSpaceProvider.h"
44 #include "cxTypeConversions.h"
45 #include "cxPatientModelService.h"
46 #include "cxViewService.h"
47 #include "cxOrderedQDomDocument.h"
48 #include "cxXmlFileHandler.h"
49 #include "cxTime.h"
50 #include "cxErrorObserver.h"
51 #include "cxHelperWidgets.h"
52 #include "cxFileHelpers.h"
53 #include "cxSpaceProperty.h"
54 #include "cxSpaceEditWidget.h"
55 
56 namespace cx
57 {
58 
59 MetricManager::MetricManager(ViewServicePtr viewService, PatientModelServicePtr patientModelService, TrackingServicePtr trackingService, SpaceProviderPtr spaceProvider) :
60  QObject(NULL),
61  mViewService(viewService),
62  mPatientModelService(patientModelService),
63  mTrackingService(trackingService),
64  mSpaceProvider(spaceProvider)
65 {
66  connect(trackingService.get(), &TrackingService::stateChanged, this, &MetricManager::metricsChanged);
67  connect(patientModelService.get(), SIGNAL(dataAddedOrRemoved()), this, SIGNAL(metricsChanged()));
68 
70  mUserSettings.imageRefs.push_back("");
71  mUserSettings.imageRefs.push_back("");
72 }
73 
75 {
76  DataPtr data = mPatientModelService->getData(uid);
77  DataMetricPtr metric = boost::dynamic_pointer_cast<DataMetric>(data);
78  return metric;
79 }
80 
82 {
83  return this->getAllMetrics().size();
84 }
85 
86 std::vector<DataMetricPtr> MetricManager::getAllMetrics() const
87 {
88  std::vector<DataMetricPtr> retval;
89  std::map<QString, DataPtr> all = mPatientModelService->getDatas();
90  for (std::map<QString, DataPtr>::iterator iter=all.begin(); iter!=all.end(); ++iter)
91  {
92  DataMetricPtr metric = boost::dynamic_pointer_cast<DataMetric>(iter->second);
93  if (metric)
94  retval.push_back(metric);
95  }
96  return retval;
97 }
98 
99 void MetricManager::setSelection(std::set<QString> selection)
100 {
101  mSelection = selection;
102 }
103 
105 {
106  mActiveLandmark = uid;
107  emit activeMetricChanged();
108 }
109 
111 {
112  DataMetricPtr metric = this->getMetric(uid);
113  if (!metric)
114  return;
115  Vector3D p_r = metric->getRefCoord();;
116  this->setManualToolPosition(p_r);
117 }
118 
119 void MetricManager::setManualToolPosition(Vector3D p_r)
120 {
121  Transform3D rMpr = mPatientModelService->get_rMpr();
122  Vector3D p_pr = rMpr.inv().coord(p_r);
123 
124  // set the picked point as offset tip
125  ToolPtr tool = mTrackingService->getManualTool();
126  Vector3D offset = tool->get_prMt().vector(Vector3D(0, 0, tool->getTooltipOffset()));
127  p_pr -= offset;
128  p_r = rMpr.coord(p_pr);
129 
130  // TODO set center here will not do: must handle
131  mPatientModelService->setCenter(p_r);
132  Vector3D p0_pr = tool->get_prMt().coord(Vector3D(0, 0, 0));
133  tool->set_prMt(createTransformTranslate(p_pr - p0_pr) * tool->get_prMt());
134 }
135 
136 PointMetricPtr MetricManager::addPoint(Vector3D point, CoordinateSystem space, QString uid, QColor color)
137 {
138  PointMetricPtr p1 = mPatientModelService->createSpecificData<PointMetric>(uid);
139  p1->get_rMd_History()->setParentSpace("reference");
140  p1->setSpace(space);
141  p1->setCoordinate(point);
142  p1->setColor(color);
143  mPatientModelService->insertData(p1);
144 
145  mViewService->getGroup(0)->addData(p1->getUid());
146  this->setActiveUid(p1->getUid());
147 
148  return p1;
149 }
150 
152 {
153  DistanceMetricPtr d0 = mPatientModelService->createSpecificData<DistanceMetric>(uid);
154  d0->get_rMd_History()->setParentSpace("reference");
155 
156  std::vector<DataPtr> args = this->getSpecifiedNumberOfValidArguments(d0->getArguments());
157  for (unsigned i=0; i<args.size(); ++i)
158  d0->getArguments()->set(i, args[i]);
159 
160  this->installNewMetric(d0);
161 
162  return d0;
163 }
164 
166 {
167  this->addPointInDefaultPosition();
168 }
169 
170 PointMetricPtr MetricManager::addPointInDefaultPosition()
171 {
173  QColor color = QColor(240, 170, 255, 255);
174  Vector3D p_ref = mSpaceProvider->getActiveToolTipPoint(ref, true);
175 
176  DataPtr data = mPatientModelService->getData(mActiveLandmark);
177  if(!data)
178 
179  return this->addPoint(p_ref, ref,"point%1", color);
180 
181  PointMetricPtr pointMetric = boost::dynamic_pointer_cast<PointMetric>(data);
182  if(pointMetric)
183  {
184  ref = pointMetric->getSpace();
185  p_ref = mSpaceProvider->getActiveToolTipPoint(ref, true);
186  }
187 
188  DataMetricPtr metric = boost::dynamic_pointer_cast<DataMetric>(data);
189  if(metric)
190  color = metric->getColor();
191 
192 
193 
194  return this->addPoint(p_ref, ref,"point%1", color);
195 }
196 
198 {
199  FrameMetricPtr frame = mPatientModelService->createSpecificData<FrameMetric>("frame%1");
200  frame->get_rMd_History()->setParentSpace("reference");
201 
203  Transform3D rMt = mSpaceProvider->getActiveToolTipTransform(ref, true);
204 
205  frame->setSpace(ref);
206  frame->setFrame(rMt);
207 
208  this->installNewMetric(frame);
209 }
210 
212 {
213  ToolMetricPtr frame = mPatientModelService->createSpecificData<ToolMetric>("tool%1");
214  frame->get_rMd_History()->setParentSpace("reference");
215 
217  Transform3D rMt = mSpaceProvider->getActiveToolTipTransform(ref, true);
218 
219  frame->setSpace(ref);
220  frame->setFrame(rMt);
221  frame->setToolName(mTrackingService->getActiveTool()->getName());
222  frame->setToolOffset(mTrackingService->getActiveTool()->getTooltipOffset());
223 
224  this->installNewMetric(frame);
225 }
226 
228 {
229  PlaneMetricPtr p1 = mPatientModelService->createSpecificData<PlaneMetric>("plane%1");
230  p1->get_rMd_History()->setParentSpace("reference");
231 
232  std::vector<DataPtr> args = this->getSpecifiedNumberOfValidArguments(p1->getArguments());
233  for (unsigned i=0; i<args.size(); ++i)
234  p1->getArguments()->set(i, args[i]);
235 
236  this->installNewMetric(p1);
237 }
238 
243 std::vector<DataPtr> MetricManager::refinePointArguments(std::vector<DataPtr> args, unsigned argNo)
244 {
245  // erase non-selected arguments if we have more than enough
246  //std::set<QString> selectedUids = this->getSelectedUids();
247  for (unsigned i=0; i<args.size();)
248  {
249  if (args.size() <= argNo)
250  break;
251  if (!mSelection.count(args[i]->getUid()))
252  args.erase(args.begin()+i);
253  else
254  ++i;
255  }
256 
257  while (args.size() > argNo)
258  args.erase(args.begin());
259 
260  while (args.size() < argNo)
261  {
262  PointMetricPtr p0 = this->addPointInDefaultPosition();
263  args.push_back(p0);
264  }
265 
266  return args;
267 }
268 
270 {
271  RegionOfInterestMetricPtr d0 = mPatientModelService->createSpecificData<RegionOfInterestMetric>("roi%1");
272  d0->get_rMd_History()->setParentSpace("reference");
273  this->installNewMetric(d0);
274 }
275 
277 {
278  this->addDistance();
279 }
280 
282 {
283  AngleMetricPtr d0 = mPatientModelService->createSpecificData<AngleMetric>("angle%1");
284  d0->get_rMd_History()->setParentSpace("reference");
285 
286  std::vector<DataPtr> args = this->getSpecifiedNumberOfValidArguments(d0->getArguments(), 3);
287  d0->getArguments()->set(0, args[0]);
288  d0->getArguments()->set(1, args[1]);
289  d0->getArguments()->set(2, args[1]);
290  d0->getArguments()->set(3, args[2]);
291 
292  this->installNewMetric(d0);
293 }
294 
295 std::vector<DataPtr> MetricManager::getSpecifiedNumberOfValidArguments(MetricReferenceArgumentListPtr arguments, int numberOfRequiredArguments)
296 {
297  // first try to reuse existing points as distance arguments, otherwise create new ones.
298 
299  std::vector<DataMetricPtr> metrics = this->getAllMetrics();
300 
301  std::vector<DataPtr> args;
302  for (unsigned i=0; i<metrics.size(); ++i)
303  {
304  if (arguments->validArgument(metrics[i]))
305  args.push_back(metrics[i]);
306  }
307 
308  if (numberOfRequiredArguments<0)
309  numberOfRequiredArguments = arguments->getCount();
310  args = this->refinePointArguments(args, numberOfRequiredArguments);
311 
312  return args;
313 }
314 
316 {
317  SphereMetricPtr d0 = mPatientModelService->createSpecificData<SphereMetric>("sphere%1");
318  d0->get_rMd_History()->setParentSpace("reference");
319  std::vector<DataPtr> args = this->getSpecifiedNumberOfValidArguments(d0->getArguments());
320  d0->getArguments()->set(0, args[0]);
321 
322  this->installNewMetric(d0);
323 }
324 
326 {
327  DonutMetricPtr d0 = mPatientModelService->createSpecificData<DonutMetric>("donut%1");
328  d0->get_rMd_History()->setParentSpace("reference");
329  std::vector<DataPtr> args = this->getSpecifiedNumberOfValidArguments(d0->getArguments());
330  d0->getArguments()->set(0, args[0]);
331  d0->getArguments()->set(1, args[1]);
332 
333  this->installNewMetric(d0);
334 }
335 
337 {
338  CustomMetricPtr d0 = mPatientModelService->createSpecificData<CustomMetric>("Custom%1");
339  d0->get_rMd_History()->setParentSpace("reference");
340  std::vector<DataPtr> args = this->getSpecifiedNumberOfValidArguments(d0->getArguments());
341  d0->getArguments()->set(0, args[0]);
342  d0->getArguments()->set(1, args[1]);
343 
344  this->installNewMetric(d0);
345 }
346 
347 void MetricManager::installNewMetric(DataMetricPtr metric)
348 {
349  DataMetricPtr prevMetric = this->getMetric(mActiveLandmark);
350  if(prevMetric)
351  {
352  metric->setColor(prevMetric->getColor());
353  }
354 
355  mPatientModelService->insertData(metric);
356  this->setActiveUid(metric->getUid());
357  mViewService->getGroup(0)->addData(metric->getUid());
358 }
359 
361 {
362  ToolPtr refTool = mTrackingService->getReferenceTool();
363  if(!refTool) // we only load reference points from reference tools
364  {
365  reportDebug("No reference tool, cannot load reference points into the pointsampler");
366  return;
367  }
368 
369  std::map<int, Vector3D> referencePoints_s = refTool->getReferencePoints();
370  if(referencePoints_s.empty())
371  {
372  reportWarning("No referenceppoints in reference tool "+refTool->getName());
373  return;
374  }
375 
377  CoordinateSystem sensor = mSpaceProvider->getS(refTool);
378 
379  std::map<int, Vector3D>::iterator it = referencePoints_s.begin();
380  for(; it != referencePoints_s.end(); ++it)
381  {
382  Vector3D P_ref = mSpaceProvider->get_toMfrom(sensor, ref).coord(it->second);
383  this->addPoint(P_ref, CoordinateSystem(csREF), "ref%1");
384  }
385 }
386 
388 {
389  OrderedQDomDocument orderedDoc;
390  QDomDocument& doc = orderedDoc.doc();
391  doc.appendChild(doc.createProcessingInstruction("xml version =", "'1.0'"));
392  QDomElement patientNode = doc.createElement("patient");
393  doc.appendChild(patientNode);
394  QDomElement managersNode = doc.createElement("managers");
395  patientNode.appendChild(managersNode);
396  QDomElement datamanagerNode = doc.createElement("datamanager");
397  managersNode.appendChild(datamanagerNode);
398  std::map<QString, DataPtr> dataMap = mPatientModelService->getDatas();
399 
400  std::map<QString, DataPtr>::iterator iter;
401  for (iter = dataMap.begin(); iter != dataMap.end(); ++iter)
402  {
403  DataMetricPtr metric = boost::dynamic_pointer_cast<DataMetric>(iter->second);
404  if(metric)
405  {
406  QDomElement dataNode = doc.createElement("data");
407  metric->addXml(dataNode);
408  datamanagerNode.appendChild(dataNode);
409  }
410  }
411 
412  XmlFileHandler::writeXmlFile(doc, filename);
413 }
414 
415 void MetricManager::resolveUnknownParentSpacesForPointMetrics(QDomNode dataNode, std::map<QString, QString> mapping_of_unknown_to_known_spaces, DataPtr data)
416 {
417  QString uid = data->getUid();
418  PointMetricPtr point_metric = boost::static_pointer_cast<PointMetric>(data);
419  if(!point_metric)
420  return;
421 
422  QString string_space = dataNode.toElement().attribute("space");
423  CoordinateSystem parentSpace = CoordinateSystem::fromString(string_space);
424  bool need_parent = parentSpace.isValid() && (parentSpace.mId == csDATA);
425  bool parent_found = mPatientModelService->getData(parentSpace.mRefObject) != DataPtr();
426  if(need_parent && !parent_found)
427  {
428  if(mapping_of_unknown_to_known_spaces.find(string_space) == mapping_of_unknown_to_known_spaces.end())
429  {
430  SpacePropertyPtr space_property;
431  space_property = SpaceProperty::initialize("selectSpace",
432  "Space",
433  "Select parent coordinate system of metric with uid: "+uid);
434  space_property->setSpaceProvider(mSpaceProvider);
435  QWidget* widget = new QWidget;
436  widget->setFocusPolicy(Qt::StrongFocus); // needed for help system: focus is used to display help text
437  QVBoxLayout *layout = new QVBoxLayout();
438  layout->addWidget(new QLabel("Select parent space for Point metric: "+uid+"."));
439  layout->addWidget(new SpaceEditWidget(widget, space_property));
440  QDialog dialog;
441  dialog.setWindowTitle("Space "+string_space+" does not exist.");
442  dialog.setLayout(layout);
443  QPushButton *okButton = new QPushButton(tr("Ok"));
444  layout->addWidget(okButton);
445  connect(okButton, &QAbstractButton::clicked, &dialog, &QWidget::close);
446  dialog.exec();
447  CX_LOG_DEBUG() << "New space is now: " << space_property->getValue().mId << " " << space_property->getValue().mRefObject;
448  CoordinateSystem new_parentspace = space_property->getValue();
449  mapping_of_unknown_to_known_spaces[string_space] = new_parentspace.toString();
450  }
451  parentSpace = CoordinateSystem::fromString(mapping_of_unknown_to_known_spaces[string_space]);
452  point_metric->setSpace(parentSpace);
453  point_metric->setCoordinate(Vector3D::fromString(dataNode.toElement().attribute("coord")));
454  dataNode.toElement().setAttribute("space", parentSpace.toString());
455  }
456 }
457 
459 {
460  QDomDocument xml = XmlFileHandler::readXmlFile(filename);
461  QDomElement patientNode = xml.documentElement();
462 
463  std::map<DataPtr, QDomNode> datanodes;
464 
465  QDomNode managersNode = patientNode.firstChildElement("managers");
466  QDomNode datamanagerNode = managersNode.firstChildElement("datamanager");
467  QDomNode dataNode = datamanagerNode.firstChildElement("data");
468 
469 
470  std::map<QString, QString> mapping_of_unknown_to_known_spaces;
471 
472  for (; !dataNode.isNull(); dataNode = dataNode.nextSibling())
473  {
474  QDomNamedNodeMap attributes = dataNode.attributes();
475  QDomNode typeAttribute = attributes.namedItem("type");
476  bool isMetric = false;
477  if(typeAttribute.isAttr())
478  {
479  isMetric = typeAttribute.toAttr().value().contains("Metric");
480  }
481 
482  if (dataNode.nodeName() == "data" && isMetric)
483  {
484 
485  QString uid = dataNode.toElement().attribute("uid");
486  if(mPatientModelService->getData(uid))
487  {
488  QString name = dataNode.toElement().attribute("name");
489  reportWarning("Metric: " + name + ", is already in the model with Uid: " + uid + ". Import skipped.");
490  continue;
491  }
492 
493  DataPtr data = this->loadDataFromXMLNode(dataNode.toElement());
494  if (data)
495  datanodes[data] = dataNode.toElement();
496 
497  //If point metrics space is uknown to the system, user needs to select a new parent -> POPUP DIALOG
498  this->resolveUnknownParentSpacesForPointMetrics(dataNode, mapping_of_unknown_to_known_spaces, data);
499  }
500  }
501 
502  // parse xml data separately: we want to first load all data
503  // because there might be interdependencies (cx::DistanceMetric)
504  for (std::map<DataPtr, QDomNode>::iterator iter = datanodes.begin(); iter != datanodes.end(); ++iter)
505  {
506  iter->first->parseXml(iter->second);
507  }
508 }
509 
510 QColor MetricManager::getRandomColor()
511 {
512  QStringList colorNames = QColor::colorNames();
513  int random_int = rand() % colorNames.size();
514  QColor color(colorNames[random_int]);
515  if(color == QColor("black"))
516  color = getRandomColor();
517 
518  return color;
519 }
520 
522  MetricManager::dialogForSelectingVolumesForImportedMNITagFile( int number_of_volumes,
523  QString description)
524 {
525  ImportMNIuserSettings userSettings;
526 
527  QInputDialog selectCoordinateSystemDialog;
528  QStringList selectableItems;
529  selectableItems << "RAS coordinates (NIfTI/ITKsnap)" << "LPS coordiantes (DICOM/CustusX)";
530  selectCoordinateSystemDialog.setComboBoxItems(selectableItems);
531 
532 
533  QDialog selectVolumeDialog;
534  selectVolumeDialog.setWindowTitle("Select volume(s) related to points in MNI Tag Point file.");
535 
536  QVBoxLayout *layout = new QVBoxLayout();
537  QLabel *description_label = new QLabel(description);
538  layout->addWidget(description_label);
539 
540  QButtonGroup *coordinateSysSelector = new QButtonGroup();
541  QCheckBox *selectorLPS = new QCheckBox(tr("LPS (DICOM/CX)"));
542  QCheckBox *selectorRAS = new QCheckBox(tr("RAS (Neuro)"));
543  enum selectorID {
544  selectorRASid=1,
545  selectorLPSid
546  };
547 
548  selectorRAS->setChecked(true);
549  coordinateSysSelector->addButton(selectorRAS);
550  coordinateSysSelector->addButton(selectorLPS);
551  coordinateSysSelector->setId(selectorRAS, selectorRASid);
552  coordinateSysSelector->setId(selectorLPS, selectorLPSid);
553  QGroupBox *coordinateSysSelectors = new QGroupBox(tr("Coordinate system format"));
554  selectorLPS->setToolTip("LPS (X=Right->Left Y=Anterior->Posterio Z=Inferior->Superior) - DICOM, CustusX");
555  selectorRAS->setToolTip("RAS (X=Left->Right Y=Posterior->Anterior Z=Inferior->Superior) - NIfTI, ITK-snap");
556  QVBoxLayout *coordSelectLayout = new QVBoxLayout;
557  coordSelectLayout->addWidget(selectorLPS);
558  coordSelectLayout->addWidget(selectorRAS);
559  coordSelectLayout->addStretch(1);
560  coordinateSysSelectors->setLayout(coordSelectLayout);
561  layout->addWidget(coordinateSysSelectors);
562 
563  std::map<int, StringPropertySelectImagePtr> selectedImageProperties;
564  for(int i=0; i < number_of_volumes; ++i)
565  {
566  StringPropertySelectImagePtr image_property = StringPropertySelectImage::New(mPatientModelService);
567  QWidget *widget = createDataWidget(mViewService, mPatientModelService, NULL, image_property);
568  layout->addWidget(widget);
569  selectedImageProperties[i] = image_property;
570  }
571 
572  QPushButton *okButton = new QPushButton(tr("Ok"));
573  layout->addWidget(okButton);
574  connect(okButton, &QAbstractButton::clicked, &selectVolumeDialog, &QWidget::close);
575  selectVolumeDialog.setLayout(layout);
576  selectVolumeDialog.exec();
577  for(int i=0; i < number_of_volumes; ++i)
578  {
579  StringPropertySelectImagePtr image_property = selectedImageProperties[i];
580  userSettings.imageRefs.push_back(image_property->getValue());
581  }
582  // Set correct coordinate space
583  if(coordinateSysSelector->checkedId() == selectorRASid)
584  userSettings.coordSys = pcsRAS;
585  else
586  userSettings.coordSys = pcsLPS;
587 
588  return userSettings;
589 }
590 
591 void MetricManager::importMetricsFromMNITagFile(QString &filename, bool testmode)
592 {
593  //--- HACK to be able to read *.tag files with missing newline before eof
594  forceNewlineBeforeEof(filename);
595 
596  //--- Reader for MNI Tag Point files
597  vtkMNITagPointReaderPtr reader = vtkMNITagPointReader::New();
598  reader->SetFileName(filename.toStdString().c_str());
599  reader->Update();
600  if (!ErrorObserver::checkedRead(reader, filename))
601  CX_LOG_ERROR() << "Error reading MNI Tag Point file.";
602 
603 
604  //--- Prompt user to select the volume(s) that is(are) related to the points in the file
605  //--- and specify coordinate system for the coordinates (LPS or RAS)
606  int number_of_volumes = reader->GetNumberOfVolumes();
607  QString description(reader->GetComments());
608 // ImportMNIuserSettings userSettings;
609  if(!testmode)
610  mUserSettings = dialogForSelectingVolumesForImportedMNITagFile(number_of_volumes,
611  description);
612 
613  //--- Create the point metrics
614  QString type = "pointMetric";
615  QString uid = "";
616  QString name = "";
617  vtkStringArray *labels = reader->GetLabelText();
618 
619  for(int i=0; i< number_of_volumes; ++i)
620  {
621  QColor color = getRandomColor();
622 
623  vtkPoints *points = reader->GetPoints(i);
624  if(points != NULL)
625  {
626  unsigned int number_of_points = points->GetNumberOfPoints();
627  //CX_LOG_DEBUG() << "Number of points: " << number_of_points;
628 
629  for(int j=0; j < number_of_points; ++j)
630  {
631  vtkStdString label = labels->GetValue(j);
632  name = QString::fromStdString(label);
633  if(name.isEmpty() || (name == QString(" ")) ) // if no name label is given in .tag file, metric name is set to continous numbering
634  name = QString::number(j+1);
635 
636  uid = QDateTime::currentDateTime().toString(timestampMilliSecondsFormat()) + "_" + QString::number(i)+ QString::number(j);
637 
638  double *point = points->GetPoint(j);
639  DataPtr data = this->createData(type, uid, name);
640  PointMetricPtr point_metric = boost::static_pointer_cast<PointMetric>(data);
641  Vector3D vector_ras;
642  Vector3D vector_lps;
643  CoordinateSystem space;
644 
645  if(mUserSettings.coordSys == pcsRAS) {
646  // The coordinates are given in RAS format
647  space.mId = csDATA;
649  vector_ras[0] = point[0]; vector_ras[1] = point[1]; vector_ras[2] = point[2];
651  vector_lps = sMr.inv() * vector_ras;
652  } else {
653  // The coordinates are given in LPS format
654  space.mId = csREF;
656  vector_lps[0] = point[0]; vector_lps[1] = point[1]; vector_lps[2] = point[2];
657  }
658 
659  point_metric->setCoordinate(vector_lps);
660  point_metric->setSpace(space);
661  point_metric->setColor(color);
662  }
663  }
664 
665  }
666 }
667 
668 DataPtr MetricManager::loadDataFromXMLNode(QDomElement node)
669 {
670  QString uid = node.toElement().attribute("uid");
671  QString name = node.toElement().attribute("name");
672  QString type = node.toElement().attribute("type");
673 
674  return this->createData(type, uid, name);
675 
676 }
677 
678 DataPtr MetricManager::createData(QString type, QString uid, QString name)
679 {
680  DataPtr data = mPatientModelService->createData(type, uid, name);
681  if (!data)
682  {
683  reportError(QString("Not able to create metric with name: %1, uid: %2, type: %3").arg(name).arg(uid).arg(type));
684  return DataPtr();
685  }
686 
687  if (!name.isEmpty())
688  data->setName(name);
689 
690  mPatientModelService->insertData(data);
691 
692  return data;
693 
694 }
695 
696 
697 } // namespace cx
698 
699 
boost::shared_ptr< class SpaceProvider > SpaceProviderPtr
static void writeXmlFile(QDomDocument &doc, QString &filename)
pcsRAS
Right-Anterior-Superior, used by Slicer3D, ITK-Snap, nifti, MINC.
void reportError(QString msg)
Definition: cxLogger.cpp:71
void exportMetricsToXMLFile(QString &filename)
boost::shared_ptr< class DistanceMetric > DistanceMetricPtr
void addXml(QDomNode &dataNode)
adds xml information about the data and its variabels
Composite widget for string selection.
boost::shared_ptr< class FrameMetric > FrameMetricPtr
Definition: cxFrameMetric.h:23
boost::shared_ptr< class ToolMetric > ToolMetricPtr
Definition: cxToolMetric.h:24
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:73
cxResource_EXPORT Transform3D createTransformFromReferenceToExternal(PATIENT_COORDINATE_SYSTEM external)
boost::shared_ptr< class TrackingService > TrackingServicePtr
QString timestampMilliSecondsFormat()
Definition: cxTime.cpp:22
static SpacePropertyPtr initialize(const QString &uid, QString name, QString help, Space value=Space(), std::vector< Space > range=std::vector< Space >(), QDomNode root=QDomNode())
boost::shared_ptr< class SpaceProperty > SpacePropertyPtr
csREF
the data reference space (r) using LPS (left-posterior-superior) coordinates.
Definition: cxDefinitions.h:88
boost::shared_ptr< class SphereMetric > SphereMetricPtr
DistanceMetricPtr addDistance(QString uid="distance%1")
Data class that represents a single frame (transform).
Definition: cxFrameMetric.h:33
boost::shared_ptr< class ViewService > ViewServicePtr
Data class representing a plane.
Definition: cxPlaneMetric.h:48
static CoordinateSystem reference()
MetricManager(ViewServicePtr viewService, PatientModelServicePtr patientModelService, TrackingServicePtr trackingService, SpaceProviderPtr spaceProvider)
boost::shared_ptr< class AngleMetric > AngleMetricPtr
Definition: cxAngleMetric.h:33
csDATA
a datas space (d)
Definition: cxDefinitions.h:88
QWidget * createDataWidget(ViewServicePtr viewService, PatientModelServicePtr patientModelService, QWidget *parent, PropertyPtr data, QGridLayout *gridLayout, int row)
Create a widget capable of displaying the input data.
COORDINATE_SYSTEM mId
the type of coordinate system
Data class that represents a donut.
boost::shared_ptr< class PlaneMetric > PlaneMetricPtr
Definition: cxPlaneMetric.h:34
boost::shared_ptr< class Data > DataPtr
void setSelection(std::set< QString > selection)
virtual RegistrationHistoryPtr get_rMd_History()
Definition: cxData.cpp:91
void importMetricsFromMNITagFile(QString &filename, bool testmode=false)
Note: testmode is available to skip dialog popup for running automatic tests.
void reportWarning(QString msg)
Definition: cxLogger.cpp:70
#define CX_LOG_ERROR
Definition: cxLogger.h:99
Data class that represents a custom.
ImportMNIuserSettings mUserSettings
Data class that represents a donut.
boost::shared_ptr< class PatientModelService > PatientModelServicePtr
boost::shared_ptr< class MetricReferenceArgumentList > MetricReferenceArgumentListPtr
DataMetricPtr getMetric(QString uid)
Transform3D createTransformTranslate(const Vector3D &translation)
Identification of a Coordinate system.
QColor getColor()
Data class that represents a distance between two points, or a point and a plane. ...
boost::shared_ptr< class RegionOfInterestMetric > RegionOfInterestMetricPtr
QString mRefObject
for tool, sensor and data we need a object uid to define the coordinate system
pcsLPS
Left-Posterior-Superior, used internally by CustusX, also DICOM, ITK.
boost::shared_ptr< class StringPropertySelectImage > StringPropertySelectImagePtr
Data class that represents a single point.
Definition: cxPointMetric.h:42
void importMetricsFromXMLFile(QString &filename)
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
Definition: cxVector3D.h:42
void forceNewlineBeforeEof(QString path)
#define CX_LOG_DEBUG
Definition: cxLogger.h:95
static QDomDocument readXmlFile(QString &filename)
static bool checkedRead(vtkSmartPointer< vtkAlgorithm > reader, QString filename)
PointMetricPtr addPoint(Vector3D point, CoordinateSystem space=CoordinateSystem(csREF), QString uid="point%1", QColor color=QColor(240, 170, 255, 255))
static StringPropertySelectImagePtr New(PatientModelServicePtr patientModelService)
void activeMetricChanged()
void addDistanceButtonClickedSlot()
int getNumberOfMetrics() const
Base class for all Data Metrics.
Definition: cxDataMetric.h:43
boost::shared_ptr< class CustomMetric > CustomMetricPtr
vtkSmartPointer< class vtkMNITagPointReader > vtkMNITagPointReaderPtr
Data class that represents an angle between two lines.
Definition: cxAngleMetric.h:46
void moveToMetric(QString uid)
static CoordinateSystem fromString(QString text)
void reportDebug(QString msg)
Definition: cxLogger.cpp:68
void setActiveUid(QString uid)
Namespace for all CustusX production code.
boost::shared_ptr< class PointMetric > PointMetricPtr
boost::shared_ptr< class Tool > ToolPtr