14#include "ui_QmitkUSNavigationMarkerPlacement.h"
26#include "mitkIRenderingManager.h"
29#include <mitkIOUtil.h>
35#include <QInputDialog>
37#include <QSignalMapper>
40#include "QmitkRenderWindow.h"
41#include "QmitkStdMultiWidget.h"
42#include "QmitkStdMultiWidgetEditor.h"
43#include "mitkCameraController.h"
44#include "mitkLayoutAnnotationRenderer.h"
45#include <vtkSmartPointer.h>
48#include <mitkConvert2Dto3DImageFilter.h>
49#include <mitkNodePredicateNot.h>
50#include <mitkNodePredicateProperty.h>
51#include <mitkSceneIO.h>
52#include <mitkSurface.h>
65 m_UpdateTimer(new QTimer(this)),
66 m_ImageAndNavigationDataLoggingTimer(new QTimer(this)),
67 m_StdMultiWidget(nullptr),
68 m_CombinedModality(nullptr),
69 m_ReinitAlreadyDone(false),
70 m_IsExperimentRunning(false),
71 m_CurrentApplicationName(),
72 m_NavigationStepTimer(
mitk::USNavigationStepTimer::New()),
73 m_IconRunning(QPixmap(
":/USNavigation/record.png")),
74 m_IconNotRunning(QPixmap(
":/USNavigation/record-gray.png")),
77 m_ExperimentResultsSubDirectory(),
78 m_NavigationStepNames(),
80 m_USImageLoggingFilter(
mitk::USImageLoggingFilter::New()),
81 m_NavigationDataRecorder(
mitk::NavigationDataRecorder::New()),
82 m_TargetNodeDisplacementFilter(nullptr),
83 m_AblationZonesDisplacementFilter(
mitk::NodeDisplacementFilter::New()),
84 m_ToolVisualizationFilter(nullptr),
85 m_AblationZonesVector(),
89 m_WarnOverlay(
mitk::TextAnnotation2D::New()),
90 m_NavigationDataSource(nullptr),
91 m_CurrentStorage(nullptr),
92 m_ImageStreamNode(nullptr),
119 MITK_INFO <<
"Ablation Zone " <<
id <<
" changed, new size: " << newSize;
123 vtkSphere->SetRadius(newSize / 2);
124 vtkSphere->SetCenter(0, 0, 0);
125 vtkSphere->SetPhiResolution(20);
126 vtkSphere->SetThetaResolution(20);
129 mitk::Surface::Pointer zoneSurface =
dynamic_cast<mitk::Surface *
>(
m_AblationZonesVector.at(
id)->GetData());
130 zoneSurface->SetVtkPolyData(vtkSphere->GetOutput());
137 mitk::DataNode::Pointer NewAblationZone = mitk::DataNode::New();
141 MITK_INFO(
"USNavigationLogging") <<
"Ablation Zone Added, initial size: " << size <<
", origin: " << origin;
143 mitk::Surface::Pointer zone = mitk::Surface::New();
147 vtkSphere->SetRadius(size / 2);
148 vtkSphere->SetCenter(0, 0, 0);
149 vtkSphere->SetPhiResolution(20);
150 vtkSphere->SetThetaResolution(20);
152 zone->SetVtkPolyData(vtkSphere->GetOutput());
156 NewAblationZone->SetData(zone);
157 NewAblationZone->GetData()->GetGeometry()->SetOrigin(origin);
158 mitk::Color SphereColor = mitk::Color();
160 SphereColor[0] = 102;
162 SphereColor[2] = 204;
163 NewAblationZone->SetColor(SphereColor);
164 NewAblationZone->SetOpacity(0.3);
167 std::stringstream name;
169 NewAblationZone->SetName(name.str());
174 this->GetDataStorage()->Add(NewAblationZone);
182 connect(ui->startExperimentButton, SIGNAL(clicked()),
this, SLOT(
OnStartExperiment()));
183 connect(ui->finishExperimentButton, SIGNAL(clicked()),
this, SLOT(
OnFinishExperiment()));
186 connect(ui->m_RefreshView, SIGNAL(clicked()),
this, SLOT(
OnRefreshView()));
196 connect(ui->m_CtToUsRegistrationWidget, SIGNAL(GetCursorPosition()),
this, SLOT(
OnGetCursorPosition()));
219 m_CombinedModality = ui->m_CombinedModalityCreationWidget->GetSelectedCombinedModality();
227 auto centroid = this->GetRenderWindowPart(mitk::WorkbenchUtil::OPEN)->GetSelectedPosition();
228 ui->m_CtToUsRegistrationWidget->OnCalculateTRE(centroid);
237 if (ui->m_CombinedModalityCreationWidget->GetSelectedCombinedModality().IsNull())
241 ui->m_CtToUsRegistrationWidget->SetCombinedModality(
242 ui->m_CombinedModalityCreationWidget->GetSelectedCombinedModality());
244 m_CombinedModality = ui->m_CombinedModalityCreationWidget->GetSelectedCombinedModality();
249 mitk::IRenderWindowPart *renderWindowPart = this->GetRenderWindowPart();
251 QmitkStdMultiWidgetEditor *multiWidgetEditor =
dynamic_cast<QmitkStdMultiWidgetEditor *
>(renderWindowPart);
255 if (multiWidgetEditor)
257 m_StdMultiWidget =
dynamic_cast<QmitkStdMultiWidget *
>(multiWidgetEditor->GetMultiWidget());
258 multiWidgetEditor->ShowLevelWindowWidget(
false);
271 ui->m_CtToUsRegistrationWidget->SetDataStorage(this->GetDataStorage());
272 ui->m_CtToUsRegistrationWidget->OnSettingsChanged(
m_SettingsNode);
273 ui->m_CtToUsRegistrationWidget->OnActivateStep();
274 ui->m_CtToUsRegistrationWidget->OnStartStep();
275 ui->m_CtToUsRegistrationWidget->Update();
282 ui->m_TargetMarkingWidget->SetDataStorage(this->GetDataStorage());
284 ui->m_TargetMarkingWidget->OnActivateStep();
285 ui->m_TargetMarkingWidget->OnStartStep();
286 ui->m_TargetMarkingWidget->Update();
293 ui->m_CriticalStructuresWidget->SetDataStorage(this->GetDataStorage());
294 ui->m_CriticalStructuresWidget->OnSettingsChanged(
m_SettingsNode);
295 ui->m_CriticalStructuresWidget->OnActivateStep();
296 ui->m_CriticalStructuresWidget->OnStartStep();
297 ui->m_CriticalStructuresWidget->Update();
304 ui->m_NavigationWidget->SetDataStorage(this->GetDataStorage());
306 ui->m_NavigationWidget->OnActivateStep();
307 ui->m_NavigationWidget->OnStartStep();
308 ui->m_NavigationWidget->Update();
316 m_CombinedModality->GetNavigationDataSource()->GetToolMetaData(0)->GetToolSurface()->Clone());
322 mitk::Surface::Pointer dummyObject = mitk::Surface::New();
347 mitk::LayoutAnnotationRenderer::AddAnnotation(
348 m_WarnOverlay.GetPointer(),
"stdmulti.widget0", mitk::LayoutAnnotationRenderer::TopLeft);
349 MITK_WARN <<
"No calibration available for the selected ultrasound image depth.";
370 ui->m_CtToUsRegistrationWidget->Update();
371 ui->m_TargetMarkingWidget->Update();
372 ui->m_CriticalStructuresWidget->Update();
373 ui->m_NavigationWidget->Update();
377 if (image.IsNotNull() &&
m_ImageStreamNode->GetData() != image.GetPointer() && image->IsInitialized())
385 mitk::IRenderWindowPart *renderWindowPart = this->GetRenderWindowPart();
387 QmitkStdMultiWidgetEditor *multiWidgetEditor =
dynamic_cast<QmitkStdMultiWidgetEditor*
>(renderWindowPart);
391 if (multiWidgetEditor)
393 m_StdMultiWidget =
dynamic_cast<QmitkStdMultiWidget*
>(multiWidgetEditor->GetMultiWidget());
394 multiWidgetEditor->ShowLevelWindowWidget(
false);
406 this->RequestRenderWindowUpdate(mitk::RenderingManager::REQUEST_UPDATE_2DWINDOWS);
415 MITK_INFO <<
"Navigation Layout";
417 mitk::IRenderWindowPart *renderWindowPart = this->GetRenderWindowPart();
419 QmitkStdMultiWidgetEditor *multiWidgetEditor =
dynamic_cast<QmitkStdMultiWidgetEditor*
>(renderWindowPart);
423 if (multiWidgetEditor)
425 m_StdMultiWidget =
dynamic_cast<QmitkStdMultiWidget*
>(multiWidgetEditor->GetMultiWidget());
426 multiWidgetEditor->ShowLevelWindowWidget(
false);
438 if (!ui->m_enableNavigationLayout->isChecked())
445 mitk::RenderingManager::GetInstance()->InitializeViews(
448 ->GetNamedNode(
"US Viewing Stream - Image 0")
450 ->GetTimeGeometry());
454 MITK_DEBUG <<
"No reinit possible";
465 switch (this->ui->m_RenderWindowSelection->value())
468 mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName(
"stdmulti.widget3"))->GetCameraController()->SetViewToCaudal();
474 mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName(
"stdmulti.widget3"))->GetCameraController()->SetViewToSinister();
480 mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName(
"stdmulti.widget3"))->GetCameraController()->SetViewToAnterior();
492 m_StdMultiWidget->GetMultiWidgetLayoutManager()->SetCurrentRenderWindowWidget(renderWindowWidget.get());
496 this->GetDataStorage()->GetNamedNode(
"stdmulti.widget" + std::to_string(i) +
".plane")
497 ->SetBoolProperty(
"visible",
false, mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName(
"stdmulti.widget4")));
498 this->GetDataStorage()->GetNamedNode(
"stdmulti.widget" + std::to_string(j) +
".plane")
499 ->SetBoolProperty(
"visible",
false, mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName(
"stdmulti.widget4")));
500 this->GetDataStorage()->GetNamedNode(
"stdmulti.widget" + std::to_string(k) +
".plane")
501 ->SetBoolProperty(
"visible",
true, mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName(
"stdmulti.widget4")));
502 this->GetDataStorage()->GetNamedNode(
"stdmulti.widget" + std::to_string(i) +
".plane")
503 ->SetIntProperty(
"Crosshair.Gap Size", 0);
504 this->GetDataStorage()->GetNamedNode(
"stdmulti.widget" + std::to_string(j) +
".plane")
505 ->SetIntProperty(
"Crosshair.Gap Size", 0);
521 if (ui->m_enableNavigationLayout->isChecked())
535 std::string composedMessage =
"";
536 for (std::size_t i = 0; i < messages.size(); i++)
538 composedMessage += messages.at(i);
553 m_ExperimentName = QString::number(QDateTime::currentDateTime().date().year()) +
"_" +
554 QString::number(QDateTime::currentDateTime().date().month()) +
"_" +
555 QString::number(QDateTime::currentDateTime().date().day()) +
"_experiment_" +
556 QString::number(QDateTime::currentDateTime().time().hour()) +
"." +
557 QString::number(QDateTime::currentDateTime().time().minute());
561 MITK_INFO(
"USNavigationLogging") <<
"Experiment started: " <<
m_ExperimentName.toStdString();
567 if (experimentResultsDir.exists())
569 QMessageBox::critical(
570 m_Parent,
"Results Directory Exists",
"The result directory already exists.\nPlease choose an other name.");
587 ui->finishExperimentButton->setEnabled(
true);
588 ui->startExperimentButton->setDisabled(
true);
607 this->WaitCursorOn();
609 MITK_INFO(
"USNavigationLogging") <<
"Experiment finished!";
610 MITK_INFO(
"USNavigationLogging") <<
"Position/Orientation of needle tip: "
614 MITK_INFO(
"USNavigationLogging")
624 ui->finishExperimentButton->setDisabled(
true);
625 ui->startExperimentButton->setEnabled(
true);
647 std::stringstream csvNavigationMessagesFilename;
649 <<
"CSVNavigationMessagesLogFile.csv";
650 MITK_INFO(
"USNavigationLogging") <<
"Writing logged navigation messages to separate csv file: "
651 << csvNavigationMessagesFilename.str();
664 this->WaitCursorOff();
665 MITK_INFO(
"USNavigationLogging") <<
"Finished!";
671 bool experimentMode =
false;
672 settings->GetBoolProperty(
"settings.experiment-mode", experimentMode);
673 ui->startExperimentButton->setVisible(experimentMode);
674 ui->finishExperimentButton->setVisible(experimentMode);
675 ui->runningLabel->setVisible(experimentMode);
680 else if (!experimentMode)
690 std::string resultsDirectory;
691 if (settings->GetStringProperty(
"settings.experiment-results-directory", resultsDirectory))
702 if (!resultsDirectoryQDir.exists())
707 MITK_INFO(
"USNavigation") <<
"Results Directory: " <<
m_ResultsDirectory.toStdString();
720 if (image.IsNotNull() && image->IsInitialized())
723 mitk::IRenderWindowPart *renderWindowPart = this->GetRenderWindowPart();
724 if (renderWindowPart !=
nullptr && image->GetTimeGeometry()->IsValid())
726 renderWindowPart->GetRenderingManager()->InitializeViews(image->GetTimeGeometry());
729 this->RequestRenderWindowUpdate();
738 for (mitk::DataStorage::SetOfObjects::ConstIterator it = nodes->Begin(); it != nodes->End(); ++it)
740 if (it->Value()->GetData() &&
strcmp(it->Value()->GetData()->GetNameOfClass(),
"Image") == 0)
743 mitk::Image::Pointer image =
dynamic_cast<mitk::Image *
>(it->Value()->GetData());
744 if (image.IsNotNull() && image->GetDimension() == 2 && !image->GetGeometry()->Is2DConvertable())
746 mitk::Convert2Dto3DImageFilter::Pointer convert2DTo3DImageFilter = mitk::Convert2Dto3DImageFilter::New();
747 convert2DTo3DImageFilter->SetInput(image);
748 convert2DTo3DImageFilter->Update();
749 it->Value()->SetData(convert2DTo3DImageFilter->GetOutput());
758 m_WarnOverlay->SetText(
"Warning: No calibration available for current depth.");
763 mitk::Point2D overlayPosition;
764 overlayPosition.SetElement(0, -50.0f);
765 overlayPosition.SetElement(1, -50.0f);
779 MITK_WARN <<
"Found an invalid navigation data source object!";
781 us::ModuleContext *context = us::GetModuleContext();
785 std::vector<us::ServiceReference<mitk::NavigationToolStorage>> refs =
791 MITK_WARN <<
"Found an invalid storage object!";
796 MITK_WARN <<
"Found a tool storage, but it has not the same number of tools like the NavigationDataSource. This "
797 "storage won't be used because it isn't the right one.";
static const char * DATANAME_BASENODE
View for navigated marker placement using the combined modality. This view utilizes the QmitkUSNaviga...
mitk::NavigationDataRecorder::Pointer m_NavigationDataRecorder
void ReinitOnImage()
Helper function which performs a reinit on the ultrasound image.
mitk::NodeDisplacementFilter::Pointer m_TargetNodeDisplacementFilter
void OnSettingsChanged(itk::SmartPointer< mitk::DataNode >)
Switches the navigation step widgets if the navigation application was changed.
void CreateQtPartControl(QWidget *parent) override
mitk::NodeDisplacementFilter::Pointer m_AblationZonesDisplacementFilter
QTimer * m_ImageAndNavigationDataLoggingTimer
static const std::string VIEW_ID
void OnCombinedModalityPropertyChanged(const std::string &, const std::string &)
void OnActualizeCtToUsRegistrationWidget()
itk::SmartPointer< mitk::DataNode > m_SettingsNode
mitk::USImageLoggingFilter::Pointer m_USImageLoggingFilter
itk::SmartPointer< mitk::AbstractUltrasoundTrackerDevice > m_CombinedModality
itk::SmartPointer< mitk::DataNode > m_ImageStreamNode
QString m_ExperimentResultsSubDirectory
void OnInitializeNavigation()
itk::SmartPointer< mitk::DataNode > m_BaseNode
mitk::DataNode::Pointer m_InstrumentNode
QmitkStdMultiWidget * m_StdMultiWidget
void OnInitializeTargetMarking()
void OnInitializeCriticalStructureMarking()
mitk::NavigationToolStorage::Pointer m_CurrentStorage
void OnGetCursorPosition()
static const char * DATANAME_TUMOUR
void Convert2DImagesTo3D(mitk::DataStorage::SetOfObjects::ConstPointer nodes)
Helper function for being able to serialize the 2d ultrasound image.
QmitkUSNavigationMarkerPlacement()
itk::SmartPointer< mitk::TextAnnotation2D > m_WarnOverlay
void OnTimeout()
Called periodically to update the rendering. The standard multi widget is changed to fit the navigati...
QString m_ResultsDirectory
void OnChangeLayoutClicked()
void OnInitializeCtToUsRegistration()
void OnStartExperiment()
Initializes anything necessary for an experiment. The user is asked for a directory for storing the r...
mitk::NavigationDataObjectVisualizationFilter::Pointer m_ToolVisualizationFilter
void OnEnableNavigationLayout()
void OnAddAblationZone(int size)
static const char * DATANAME_TARGETSURFACE
void ReInitializeSettingsNodesAndImageStream()
void OnFinishExperiment()
Stops logging and saves everything to the file system.
mitk::NavigationDataSource::Pointer m_NavigationDataSource
virtual void SetTwoWindowView()
Sets the multiwidget to two windows, axial on top and 3D render window on the bottom.
void OnRenderWindowSelection()
static const char * DATANAME_REACHED_TARGETS
void OnImageAndNavigationDataLoggingTimeout()
Called periodically during an experiment for logging the ultrasound images.
std::vector< mitk::DataNode::Pointer > m_AblationZonesVector
static const char * DATANAME_TARGETS_PATHS
static const char * DATANAME_ZONES
itk::SmartPointer< mitk::USNavigationStepTimer > m_NavigationStepTimer
void OnResetStandardLayout()
mitk::USNavigationLoggingBackend m_LoggingBackend
void SetFocus() override
A reinit on the ultrasound image is performed every time the view gets the focus.
static const char * DATANAME_TARGETS
void OnChangeAblationZone(int id, int newSize)
~QmitkUSNavigationMarkerPlacement() override
bool m_IsExperimentRunning
static mitk::USDevice::PropertyKeys GetPropertyKeys()
std::vector< std::string > GetNavigationMessages()
void ClearNavigationMessages()
void WriteCSVFileWithNavigationMessages(std::string filename)
void SetOutputFileName(std::string filename)
Set file path und name for the output file. The file will be opened and all log messages will be dire...
int strcmp(const String &s1, const String &s2)