38 #include <QTextStream> 40 #include <QVBoxLayout> 41 #include <QPushButton> 43 #include <vtkMNITagPointReader.h> 44 #include <vtkStringArray.h> 78 mViewService(viewService),
79 mPatientModelService(patientModelService),
80 mTrackingService(trackingService),
81 mSpaceProvider(spaceProvider)
84 connect(patientModelService.get(), SIGNAL(dataAddedOrRemoved()),
this, SIGNAL(
metricsChanged()));
89 DataPtr data = mPatientModelService->getData(uid);
96 return this->getAllMetrics().size();
99 std::vector<DataMetricPtr> MetricManager::getAllMetrics()
const 101 std::vector<DataMetricPtr> retval;
102 std::map<QString, DataPtr> all = mPatientModelService->getDatas();
103 for (std::map<QString, DataPtr>::iterator iter=all.begin(); iter!=all.end(); ++iter)
107 retval.push_back(metric);
114 mSelection = selection;
119 mActiveLandmark = uid;
128 Vector3D p_r = metric->getRefCoord();;
129 this->setManualToolPosition(p_r);
132 void MetricManager::setManualToolPosition(
Vector3D p_r)
134 Transform3D rMpr = mPatientModelService->get_rMpr();
135 Vector3D p_pr = rMpr.inv().coord(p_r);
138 ToolPtr tool = mTrackingService->getManualTool();
139 Vector3D offset = tool->get_prMt().vector(
Vector3D(0, 0, tool->getTooltipOffset()));
141 p_r = rMpr.coord(p_pr);
144 mPatientModelService->setCenter(p_r);
154 p1->setCoordinate(point);
156 mPatientModelService->insertData(p1);
158 mViewService->getGroup(0)->addData(p1->getUid());
169 std::vector<DataPtr> args = this->getSpecifiedNumberOfValidArguments(d0->getArguments());
170 for (
unsigned i=0; i<args.size(); ++i)
171 d0->getArguments()->set(i, args[i]);
173 this->installNewMetric(d0);
180 this->addPointInDefaultPosition();
186 QColor color = QColor(240, 170, 255, 255);
187 Vector3D p_ref = mSpaceProvider->getActiveToolTipPoint(ref,
true);
189 DataPtr data = mPatientModelService->getData(mActiveLandmark);
192 return this->
addPoint(p_ref, ref,
"point%1", color);
197 ref = pointMetric->getSpace();
198 p_ref = mSpaceProvider->getActiveToolTipPoint(ref,
true);
207 return this->
addPoint(p_ref, ref,
"point%1", color);
216 Transform3D rMt = mSpaceProvider->getActiveToolTipTransform(ref,
true);
218 frame->setSpace(ref);
219 frame->setFrame(rMt);
221 this->installNewMetric(frame);
230 Transform3D rMt = mSpaceProvider->getActiveToolTipTransform(ref,
true);
232 frame->setSpace(ref);
233 frame->setFrame(rMt);
234 frame->setToolName(mTrackingService->getActiveTool()->getName());
235 frame->setToolOffset(mTrackingService->getActiveTool()->getTooltipOffset());
237 this->installNewMetric(frame);
245 std::vector<DataPtr> args = this->getSpecifiedNumberOfValidArguments(p1->getArguments());
246 for (
unsigned i=0; i<args.size(); ++i)
247 p1->getArguments()->set(i, args[i]);
249 this->installNewMetric(p1);
256 std::vector<DataPtr> MetricManager::refinePointArguments(std::vector<DataPtr> args,
unsigned argNo)
260 for (
unsigned i=0; i<args.size();)
262 if (args.size() <= argNo)
264 if (!mSelection.count(args[i]->getUid()))
265 args.erase(args.begin()+i);
270 while (args.size() > argNo)
271 args.erase(args.begin());
273 while (args.size() < argNo)
286 this->installNewMetric(d0);
299 std::vector<DataPtr> args = this->getSpecifiedNumberOfValidArguments(d0->getArguments(), 3);
300 d0->getArguments()->set(0, args[0]);
301 d0->getArguments()->set(1, args[1]);
302 d0->getArguments()->set(2, args[1]);
303 d0->getArguments()->set(3, args[2]);
305 this->installNewMetric(d0);
312 std::vector<DataMetricPtr> metrics = this->getAllMetrics();
314 std::vector<DataPtr> args;
315 for (
unsigned i=0; i<metrics.size(); ++i)
317 if (arguments->validArgument(metrics[i]))
318 args.push_back(metrics[i]);
321 if (numberOfRequiredArguments<0)
322 numberOfRequiredArguments = arguments->getCount();
323 args = this->refinePointArguments(args, numberOfRequiredArguments);
332 std::vector<DataPtr> args = this->getSpecifiedNumberOfValidArguments(d0->getArguments());
333 d0->getArguments()->set(0, args[0]);
335 this->installNewMetric(d0);
342 std::vector<DataPtr> args = this->getSpecifiedNumberOfValidArguments(d0->getArguments());
343 d0->getArguments()->set(0, args[0]);
344 d0->getArguments()->set(1, args[1]);
346 this->installNewMetric(d0);
353 std::vector<DataPtr> args = this->getSpecifiedNumberOfValidArguments(d0->getArguments());
354 d0->getArguments()->set(0, args[0]);
355 d0->getArguments()->set(1, args[1]);
357 this->installNewMetric(d0);
365 metric->setColor(prevMetric->getColor());
368 mPatientModelService->insertData(metric);
370 mViewService->getGroup(0)->addData(metric->getUid());
375 ToolPtr refTool = mTrackingService->getReferenceTool();
378 reportDebug(
"No reference tool, cannot load reference points into the pointsampler");
382 std::map<int, Vector3D> referencePoints_s = refTool->getReferencePoints();
383 if(referencePoints_s.empty())
385 reportWarning(
"No referenceppoints in reference tool "+refTool->getName());
392 std::map<int, Vector3D>::iterator it = referencePoints_s.begin();
393 for(; it != referencePoints_s.end(); ++it)
395 Vector3D P_ref = mSpaceProvider->get_toMfrom(sensor, ref).coord(it->second);
403 QDomDocument& doc = orderedDoc.
doc();
404 doc.appendChild(doc.createProcessingInstruction(
"xml version =",
"'1.0'"));
405 QDomElement patientNode = doc.createElement(
"patient");
406 doc.appendChild(patientNode);
407 QDomElement managersNode = doc.createElement(
"managers");
408 patientNode.appendChild(managersNode);
409 QDomElement datamanagerNode = doc.createElement(
"datamanager");
410 managersNode.appendChild(datamanagerNode);
411 std::map<QString, DataPtr> dataMap = mPatientModelService->getDatas();
413 std::map<QString, DataPtr>::iterator iter;
414 for (iter = dataMap.begin(); iter != dataMap.end(); ++iter)
419 QDomElement dataNode = doc.createElement(
"data");
421 datamanagerNode.appendChild(dataNode);
428 void MetricManager::resolveUnknownParentSpacesForPointMetrics(QDomNode dataNode, std::map<QString, QString> mapping_of_unknown_to_known_spaces,
DataPtr data)
430 QString uid = data->getUid();
435 QString string_space = dataNode.toElement().attribute(
"space");
438 bool parent_found = mPatientModelService->getData(parentSpace.
mRefObject) !=
DataPtr();
439 if(need_parent && !parent_found)
441 if(mapping_of_unknown_to_known_spaces.find(string_space) == mapping_of_unknown_to_known_spaces.end())
446 "Select parent coordinate system of metric with uid: "+uid);
447 space_property->setSpaceProvider(mSpaceProvider);
448 QWidget* widget =
new QWidget;
449 widget->setFocusPolicy(Qt::StrongFocus);
450 QVBoxLayout *layout =
new QVBoxLayout();
451 layout->addWidget(
new QLabel(
"Select parent space for Point metric: "+uid+
"."));
454 dialog.setWindowTitle(
"Space "+string_space+
" does not exist.");
455 dialog.setLayout(layout);
456 QPushButton *okButton =
new QPushButton(tr(
"Ok"));
457 layout->addWidget(okButton);
458 connect(okButton, &QAbstractButton::clicked, &dialog, &QWidget::close);
460 CX_LOG_DEBUG() <<
"New space is now: " << space_property->getValue().mId <<
" " << space_property->getValue().mRefObject;
462 mapping_of_unknown_to_known_spaces[string_space] = new_parentspace.
toString();
465 point_metric->setSpace(parentSpace);
466 point_metric->setCoordinate(Vector3D::fromString(dataNode.toElement().attribute(
"coord")));
467 dataNode.toElement().setAttribute(
"space", parentSpace.
toString());
474 QDomElement patientNode = xml.documentElement();
476 std::map<DataPtr, QDomNode> datanodes;
478 QDomNode managersNode = patientNode.firstChildElement(
"managers");
479 QDomNode datamanagerNode = managersNode.firstChildElement(
"datamanager");
480 QDomNode dataNode = datamanagerNode.firstChildElement(
"data");
483 std::map<QString, QString> mapping_of_unknown_to_known_spaces;
485 for (; !dataNode.isNull(); dataNode = dataNode.nextSibling())
487 QDomNamedNodeMap attributes = dataNode.attributes();
488 QDomNode typeAttribute = attributes.namedItem(
"type");
489 bool isMetric =
false;
490 if(typeAttribute.isAttr())
492 isMetric = typeAttribute.toAttr().value().contains(
"Metric");
495 if (dataNode.nodeName() ==
"data" && isMetric)
498 QString uid = dataNode.toElement().attribute(
"uid");
499 if(mPatientModelService->getData(uid))
501 QString name = dataNode.toElement().attribute(
"name");
502 reportWarning(
"Metric: " + name +
", is already in the model with Uid: " + uid +
". Import skipped.");
506 DataPtr data = this->loadDataFromXMLNode(dataNode.toElement());
508 datanodes[data] = dataNode.toElement();
511 this->resolveUnknownParentSpacesForPointMetrics(dataNode, mapping_of_unknown_to_known_spaces, data);
517 for (std::map<DataPtr, QDomNode>::iterator iter = datanodes.begin(); iter != datanodes.end(); ++iter)
519 iter->first->parseXml(iter->second);
523 QColor MetricManager::getRandomColor()
525 QStringList colorNames = QColor::colorNames();
526 int random_int = rand() % colorNames.size();
527 QColor color(colorNames[random_int]);
528 if(color == QColor(
"black"))
529 color = getRandomColor();
534 std::vector<QString> MetricManager::dialogForSelectingVolumesForImportedMNITagFile(
int number_of_volumes, QString description)
536 std::vector<QString> data_uid;
538 QDialog selectVolumeDialog;
539 selectVolumeDialog.setWindowTitle(
"Select volume(s) related to points in MNI Tag Point file.");
541 QVBoxLayout *layout =
new QVBoxLayout();
542 QLabel *description_label =
new QLabel(description);
543 layout->addWidget(description_label);
545 std::map<int, StringPropertySelectImagePtr> selectedImageProperties;
546 for(
int i=0; i < number_of_volumes; ++i)
549 QWidget *widget =
createDataWidget(mViewService, mPatientModelService, NULL, image_property);
550 layout->addWidget(widget);
551 selectedImageProperties[i] = image_property;
554 QPushButton *okButton =
new QPushButton(tr(
"Ok"));
555 layout->addWidget(okButton);
556 connect(okButton, &QAbstractButton::clicked, &selectVolumeDialog, &QWidget::close);
557 selectVolumeDialog.setLayout(layout);
558 selectVolumeDialog.exec();
559 for(
int i=0; i < number_of_volumes; ++i)
562 data_uid.push_back(image_property->getValue());
574 reader->SetFileName(filename.toStdString().c_str());
581 int number_of_volumes = reader->GetNumberOfVolumes();
582 QString description(reader->GetComments());
583 std::vector<QString> data_uid;
584 data_uid.push_back(
"");
585 data_uid.push_back(
"");
587 data_uid = dialogForSelectingVolumesForImportedMNITagFile(number_of_volumes, description);
590 QString type =
"pointMetric";
593 vtkStringArray *labels = reader->GetLabelText();
595 for(
int i=0; i< number_of_volumes; ++i)
597 QColor color = getRandomColor();
599 vtkPoints *points = reader->GetPoints(i);
602 unsigned int number_of_points = points->GetNumberOfPoints();
605 for(
int j=0; j < number_of_points; ++j)
607 vtkStdString label = labels->GetValue(j);
608 name = QString(*label);
611 double *point = points->GetPoint(j);
612 DataPtr data = this->createData(type, uid, QString::number(j+1));
616 Vector3D vector_ras(point[0], point[1], point[2]);
621 Vector3D vector_lps = sMr.inv() * vector_ras;
623 point_metric->setCoordinate(vector_lps);
624 point_metric->setSpace(space);
625 point_metric->setColor(color);
632 DataPtr MetricManager::loadDataFromXMLNode(QDomElement node)
634 QString uid = node.toElement().attribute(
"uid");
635 QString name = node.toElement().attribute(
"name");
636 QString type = node.toElement().attribute(
"type");
638 return this->createData(type, uid, name);
642 DataPtr MetricManager::createData(QString type, QString uid, QString name)
644 DataPtr data = mPatientModelService->createData(type, uid, name);
647 reportError(QString(
"Not able to create metric with name: %1, uid: %2, type: %3").arg(name).arg(uid).arg(type));
654 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())
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.
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.
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
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