17 #include <QTextStream> 19 #include <QInputDialog> 20 #include <QVBoxLayout> 21 #include <QPushButton> 25 #include <QButtonGroup> 26 #include <vtkMNITagPointReader.h> 27 #include <vtkStringArray.h> 61 mViewService(viewService),
62 mPatientModelService(patientModelService),
63 mTrackingService(trackingService),
64 mSpaceProvider(spaceProvider)
67 connect(patientModelService.get(), SIGNAL(dataAddedOrRemoved()),
this, SIGNAL(
metricsChanged()));
76 DataPtr data = mPatientModelService->getData(uid);
83 return this->getAllMetrics().size();
86 std::vector<DataMetricPtr> MetricManager::getAllMetrics()
const 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)
94 retval.push_back(metric);
101 mSelection = selection;
106 mActiveLandmark = uid;
115 Vector3D p_r = metric->getRefCoord();;
116 this->setManualToolPosition(p_r);
119 void MetricManager::setManualToolPosition(
Vector3D p_r)
121 Transform3D rMpr = mPatientModelService->get_rMpr();
122 Vector3D p_pr = rMpr.inv().coord(p_r);
125 ToolPtr tool = mTrackingService->getManualTool();
126 Vector3D offset = tool->get_prMt().vector(
Vector3D(0, 0, tool->getTooltipOffset()));
128 p_r = rMpr.coord(p_pr);
131 mPatientModelService->setCenter(p_r);
141 p1->setCoordinate(point);
143 mPatientModelService->insertData(p1);
145 mViewService->getGroup(0)->addData(p1->getUid());
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]);
160 this->installNewMetric(d0);
167 this->addPointInDefaultPosition();
173 QColor color = QColor(240, 170, 255, 255);
174 Vector3D p_ref = mSpaceProvider->getActiveToolTipPoint(ref,
true);
176 DataPtr data = mPatientModelService->getData(mActiveLandmark);
179 return this->
addPoint(p_ref, ref,
"point%1", color);
184 ref = pointMetric->getSpace();
185 p_ref = mSpaceProvider->getActiveToolTipPoint(ref,
true);
194 return this->
addPoint(p_ref, ref,
"point%1", color);
203 Transform3D rMt = mSpaceProvider->getActiveToolTipTransform(ref,
true);
205 frame->setSpace(ref);
206 frame->setFrame(rMt);
208 this->installNewMetric(frame);
217 Transform3D rMt = mSpaceProvider->getActiveToolTipTransform(ref,
true);
219 frame->setSpace(ref);
220 frame->setFrame(rMt);
221 frame->setToolName(mTrackingService->getActiveTool()->getName());
222 frame->setToolOffset(mTrackingService->getActiveTool()->getTooltipOffset());
224 this->installNewMetric(frame);
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]);
236 this->installNewMetric(p1);
243 std::vector<DataPtr> MetricManager::refinePointArguments(std::vector<DataPtr> args,
unsigned argNo)
247 for (
unsigned i=0; i<args.size();)
249 if (args.size() <= argNo)
251 if (!mSelection.count(args[i]->getUid()))
252 args.erase(args.begin()+i);
257 while (args.size() > argNo)
258 args.erase(args.begin());
260 while (args.size() < argNo)
273 this->installNewMetric(d0);
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]);
292 this->installNewMetric(d0);
299 std::vector<DataMetricPtr> metrics = this->getAllMetrics();
301 std::vector<DataPtr> args;
302 for (
unsigned i=0; i<metrics.size(); ++i)
304 if (arguments->validArgument(metrics[i]))
305 args.push_back(metrics[i]);
308 if (numberOfRequiredArguments<0)
309 numberOfRequiredArguments = arguments->getCount();
310 args = this->refinePointArguments(args, numberOfRequiredArguments);
319 std::vector<DataPtr> args = this->getSpecifiedNumberOfValidArguments(d0->getArguments());
320 d0->getArguments()->set(0, args[0]);
322 this->installNewMetric(d0);
329 std::vector<DataPtr> args = this->getSpecifiedNumberOfValidArguments(d0->getArguments());
330 d0->getArguments()->set(0, args[0]);
331 d0->getArguments()->set(1, args[1]);
333 this->installNewMetric(d0);
340 std::vector<DataPtr> args = this->getSpecifiedNumberOfValidArguments(d0->getArguments());
341 d0->getArguments()->set(0, args[0]);
342 d0->getArguments()->set(1, args[1]);
344 this->installNewMetric(d0);
352 metric->setColor(prevMetric->getColor());
355 mPatientModelService->insertData(metric);
357 mViewService->getGroup(0)->addData(metric->getUid());
362 ToolPtr refTool = mTrackingService->getReferenceTool();
365 reportDebug(
"No reference tool, cannot load reference points into the pointsampler");
369 std::map<int, Vector3D> referencePoints_s = refTool->getReferencePoints();
370 if(referencePoints_s.empty())
372 reportWarning(
"No referenceppoints in reference tool "+refTool->getName());
379 std::map<int, Vector3D>::iterator it = referencePoints_s.begin();
380 for(; it != referencePoints_s.end(); ++it)
382 Vector3D P_ref = mSpaceProvider->get_toMfrom(sensor, ref).coord(it->second);
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();
400 std::map<QString, DataPtr>::iterator iter;
401 for (iter = dataMap.begin(); iter != dataMap.end(); ++iter)
406 QDomElement dataNode = doc.createElement(
"data");
408 datamanagerNode.appendChild(dataNode);
415 void MetricManager::resolveUnknownParentSpacesForPointMetrics(QDomNode dataNode, std::map<QString, QString> mapping_of_unknown_to_known_spaces,
DataPtr data)
417 QString uid = data->getUid();
422 QString string_space = dataNode.toElement().attribute(
"space");
425 bool parent_found = mPatientModelService->getData(parentSpace.
mRefObject) !=
DataPtr();
426 if(need_parent && !parent_found)
428 if(mapping_of_unknown_to_known_spaces.find(string_space) == mapping_of_unknown_to_known_spaces.end())
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);
437 QVBoxLayout *layout =
new QVBoxLayout();
438 layout->addWidget(
new QLabel(
"Select parent space for Point metric: "+uid+
"."));
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);
447 CX_LOG_DEBUG() <<
"New space is now: " << space_property->getValue().mId <<
" " << space_property->getValue().mRefObject;
449 mapping_of_unknown_to_known_spaces[string_space] = new_parentspace.
toString();
452 point_metric->setSpace(parentSpace);
453 point_metric->setCoordinate(Vector3D::fromString(dataNode.toElement().attribute(
"coord")));
454 dataNode.toElement().setAttribute(
"space", parentSpace.
toString());
461 QDomElement patientNode = xml.documentElement();
463 std::map<DataPtr, QDomNode> datanodes;
465 QDomNode managersNode = patientNode.firstChildElement(
"managers");
466 QDomNode datamanagerNode = managersNode.firstChildElement(
"datamanager");
467 QDomNode dataNode = datamanagerNode.firstChildElement(
"data");
470 std::map<QString, QString> mapping_of_unknown_to_known_spaces;
472 for (; !dataNode.isNull(); dataNode = dataNode.nextSibling())
474 QDomNamedNodeMap attributes = dataNode.attributes();
475 QDomNode typeAttribute = attributes.namedItem(
"type");
476 bool isMetric =
false;
477 if(typeAttribute.isAttr())
479 isMetric = typeAttribute.toAttr().value().contains(
"Metric");
482 if (dataNode.nodeName() ==
"data" && isMetric)
485 QString uid = dataNode.toElement().attribute(
"uid");
486 if(mPatientModelService->getData(uid))
488 QString name = dataNode.toElement().attribute(
"name");
489 reportWarning(
"Metric: " + name +
", is already in the model with Uid: " + uid +
". Import skipped.");
493 DataPtr data = this->loadDataFromXMLNode(dataNode.toElement());
495 datanodes[data] = dataNode.toElement();
498 this->resolveUnknownParentSpacesForPointMetrics(dataNode, mapping_of_unknown_to_known_spaces, data);
504 for (std::map<DataPtr, QDomNode>::iterator iter = datanodes.begin(); iter != datanodes.end(); ++iter)
506 iter->first->parseXml(iter->second);
510 QColor MetricManager::getRandomColor()
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();
522 MetricManager::dialogForSelectingVolumesForImportedMNITagFile(
int number_of_volumes,
527 QInputDialog selectCoordinateSystemDialog;
528 QStringList selectableItems;
529 selectableItems <<
"RAS coordinates (NIfTI/ITKsnap)" <<
"LPS coordiantes (DICOM/CustusX)";
530 selectCoordinateSystemDialog.setComboBoxItems(selectableItems);
533 QDialog selectVolumeDialog;
534 selectVolumeDialog.setWindowTitle(
"Select volume(s) related to points in MNI Tag Point file.");
536 QVBoxLayout *layout =
new QVBoxLayout();
537 QLabel *description_label =
new QLabel(description);
538 layout->addWidget(description_label);
540 QButtonGroup *coordinateSysSelector =
new QButtonGroup();
541 QCheckBox *selectorLPS =
new QCheckBox(tr(
"LPS (DICOM/CX)"));
542 QCheckBox *selectorRAS =
new QCheckBox(tr(
"RAS (Neuro)"));
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);
563 std::map<int, StringPropertySelectImagePtr> selectedImageProperties;
564 for(
int i=0; i < number_of_volumes; ++i)
567 QWidget *widget =
createDataWidget(mViewService, mPatientModelService, NULL, image_property);
568 layout->addWidget(widget);
569 selectedImageProperties[i] = image_property;
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)
580 userSettings.
imageRefs.push_back(image_property->getValue());
583 if(coordinateSysSelector->checkedId() == selectorRASid)
598 reader->SetFileName(filename.toStdString().c_str());
606 int number_of_volumes = reader->GetNumberOfVolumes();
607 QString description(reader->GetComments());
610 mUserSettings = dialogForSelectingVolumesForImportedMNITagFile(number_of_volumes,
614 QString type =
"pointMetric";
617 vtkStringArray *labels = reader->GetLabelText();
619 for(
int i=0; i< number_of_volumes; ++i)
621 QColor color = getRandomColor();
623 vtkPoints *points = reader->GetPoints(i);
626 unsigned int number_of_points = points->GetNumberOfPoints();
629 for(
int j=0; j < number_of_points; ++j)
631 vtkStdString label = labels->GetValue(j);
632 name = QString::fromStdString(label);
633 if(name.isEmpty() || (name == QString(
" ")) )
634 name = QString::number(j+1);
638 double *point = points->GetPoint(j);
639 DataPtr data = this->createData(type, uid, name);
649 vector_ras[0] = point[0]; vector_ras[1] = point[1]; vector_ras[2] = point[2];
651 vector_lps = sMr.inv() * vector_ras;
656 vector_lps[0] = point[0]; vector_lps[1] = point[1]; vector_lps[2] = point[2];
659 point_metric->setCoordinate(vector_lps);
660 point_metric->setSpace(space);
661 point_metric->setColor(color);
668 DataPtr MetricManager::loadDataFromXMLNode(QDomElement node)
670 QString uid = node.toElement().attribute(
"uid");
671 QString name = node.toElement().attribute(
"name");
672 QString type = node.toElement().attribute(
"type");
674 return this->createData(type, uid, name);
678 DataPtr MetricManager::createData(QString type, QString uid, QString name)
680 DataPtr data = mPatientModelService->createData(type, uid, name);
683 reportError(QString(
"Not able to create metric with name: %1, uid: %2, type: %3").arg(name).arg(uid).arg(type));
690 mPatientModelService->insertData(data);
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)
void exportMetricsToXMLFile(QString &filename)
boost::shared_ptr< class DistanceMetric > DistanceMetricPtr
void addFrameButtonClickedSlot()
void addXml(QDomNode &dataNode)
adds xml information about the data and its variabels
boost::shared_ptr< class FrameMetric > FrameMetricPtr
boost::shared_ptr< class ToolMetric > ToolMetricPtr
void addSphereButtonClickedSlot()
boost::shared_ptr< class DonutMetric > DonutMetricPtr
Transform3D Transform3D
Transform3D is a representation of an affine 3D transform.
boost::shared_ptr< DataMetric > DataMetricPtr
cxResource_EXPORT Transform3D createTransformFromReferenceToExternal(PATIENT_COORDINATE_SYSTEM external)
boost::shared_ptr< class TrackingService > TrackingServicePtr
void addCustomButtonClickedSlot()
void addAngleButtonClickedSlot()
QString timestampMilliSecondsFormat()
static SpacePropertyPtr initialize(const QString &uid, QString name, QString help, Space value=Space(), std::vector< Space > range=std::vector< Space >(), QDomNode root=QDomNode())
std::vector< QString > imageRefs
boost::shared_ptr< class SpaceProperty > SpacePropertyPtr
void addToolButtonClickedSlot()
csREF
the data reference space (r) using LPS (left-posterior-superior) coordinates.
boost::shared_ptr< class SphereMetric > SphereMetricPtr
DistanceMetricPtr addDistance(QString uid="distance%1")
Data class that represents a single frame (transform).
Data class representing a plane.
static CoordinateSystem reference()
MetricManager(ViewServicePtr viewService, PatientModelServicePtr patientModelService, TrackingServicePtr trackingService, SpaceProviderPtr spaceProvider)
boost::shared_ptr< class AngleMetric > AngleMetricPtr
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.
PATIENT_COORDINATE_SYSTEM coordSys
boost::shared_ptr< class PlaneMetric > PlaneMetricPtr
void loadReferencePointsSlot()
boost::shared_ptr< class Data > DataPtr
void setSelection(std::set< QString > selection)
virtual RegistrationHistoryPtr get_rMd_History()
void importMetricsFromMNITagFile(QString &filename, bool testmode=false)
Note: testmode is available to skip dialog popup for running automatic tests.
void reportWarning(QString msg)
void addPlaneButtonClickedSlot()
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.
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.
void addPointButtonClickedSlot()
boost::shared_ptr< class StringPropertySelectImage > StringPropertySelectImagePtr
Data class that represents a single point.
void importMetricsFromXMLFile(QString &filename)
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
void forceNewlineBeforeEof(QString path)
static QDomDocument readXmlFile(QString &filename)
void addDonutButtonClickedSlot()
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 addROIButtonClickedSlot()
void activeMetricChanged()
void addDistanceButtonClickedSlot()
int getNumberOfMetrics() const
Base class for all Data Metrics.
boost::shared_ptr< class CustomMetric > CustomMetricPtr
vtkSmartPointer< class vtkMNITagPointReader > vtkMNITagPointReaderPtr
Data class that represents an angle between two lines.
void moveToMetric(QString uid)
static CoordinateSystem fromString(QString text)
void reportDebug(QString msg)
void setActiveUid(QString uid)
Namespace for all CustusX production code.
boost::shared_ptr< class PointMetric > PointMetricPtr
boost::shared_ptr< class Tool > ToolPtr