diff --git a/Modules/SegmentationUI/Qmitk/QmitknnUNetToolSlots.cpp b/Modules/SegmentationUI/Qmitk/QmitknnUNetToolSlots.cpp deleted file mode 100644 index dcc64ac223..0000000000 --- a/Modules/SegmentationUI/Qmitk/QmitknnUNetToolSlots.cpp +++ /dev/null @@ -1,534 +0,0 @@ -#include "QmitknnUNetToolGUI.h" -#include -#include -#include -#include -#include - -void QmitknnUNetToolGUI::EnableWidgets(bool enabled) -{ - Superclass::EnableWidgets(enabled); -} - -void QmitknnUNetToolGUI::ClearAllModalities() -{ - m_Controls.multiModalSpinBox->setMinimum(0); - m_Controls.multiModalBox->setChecked(false); - this->ClearAllModalLabels(); -} - -void QmitknnUNetToolGUI::ClearAllModalLabels() -{ - for (auto modalLabel : m_ModalLabels) - { - delete modalLabel; // delete the layout item - m_ModalLabels.pop_back(); - } - m_Controls.advancedSettingsLayout->update(); -} - -void QmitknnUNetToolGUI::DisableEverything() -{ - m_Controls.modeldirectoryBox->setEnabled(false); - m_Controls.refreshdirectoryBox->setEnabled(false); - m_Controls.previewButton->setEnabled(false); - m_Controls.multiModalSpinBox->setVisible(false); - m_Controls.multiModalBox->setEnabled(false); - this->ClearAllComboBoxes(); - this->ClearAllModalities(); -} - -void QmitknnUNetToolGUI::ClearAllComboBoxes() -{ - m_Controls.modelBox->clear(); - m_Controls.taskBox->clear(); - m_Controls.foldBox->clear(); - m_Controls.trainerBox->clear(); - m_Controls.plannerBox->clear(); - for (auto &layout : m_EnsembleParams) - { - layout->modelBox->clear(); - layout->trainerBox->clear(); - layout->plannerBox->clear(); - layout->foldBox->clear(); - } - m_Controls.availableBox->clear(); -} - -void QmitknnUNetToolGUI::OnRefreshPresssed() -{ - const QString resultsFolder = m_Controls.modeldirectoryBox->directory(); - this->OnDirectoryChanged(resultsFolder); -} - -void QmitknnUNetToolGUI::OnDirectoryChanged(const QString &resultsFolder) -{ - m_IsResultsFolderValid = false; - m_Controls.previewButton->setEnabled(false); - this->ClearAllComboBoxes(); - this->ClearAllModalities(); - m_ParentFolder = std::make_shared(resultsFolder); - auto tasks = m_ParentFolder->getAllTasks(); - tasks.removeDuplicates(); - std::for_each(tasks.begin(), tasks.end(), [this](QString task) { m_Controls.taskBox->addItem(task); }); - m_Settings.setValue("nnUNet/LastRESULTS_FOLDERPath", resultsFolder); -} - -void QmitknnUNetToolGUI::OnModelChanged(const QString &model) -{ - if (model.isEmpty()) - { - return; - } - this->ClearAllModalities(); - auto selectedTask = m_Controls.taskBox->currentText(); - ctkComboBox *box = qobject_cast(sender()); - if (box == m_Controls.modelBox) - { - if (model == m_VALID_MODELS.last()) - { - m_Controls.trainerBox->setVisible(false); - m_Controls.trainerLabel->setVisible(false); - m_Controls.plannerBox->setVisible(false); - m_Controls.plannerLabel->setVisible(false); - m_Controls.foldBox->setVisible(false); - m_Controls.foldLabel->setVisible(false); - this->ShowEnsembleLayout(true); - auto models = m_ParentFolder->getModelsForTask(m_Controls.taskBox->currentText()); - models.removeDuplicates(); - models.removeOne(m_VALID_MODELS.last()); - for (auto &layout : m_EnsembleParams) - { - layout->modelBox->clear(); - layout->trainerBox->clear(); - layout->plannerBox->clear(); - std::for_each(models.begin(), - models.end(), - [&layout, this](QString model) - { - if (m_VALID_MODELS.contains(model, Qt::CaseInsensitive)) - layout->modelBox->addItem(model); - }); - } - m_Controls.previewButton->setEnabled(true); - } - else - { - m_Controls.trainerBox->setVisible(true); - m_Controls.trainerLabel->setVisible(true); - m_Controls.plannerBox->setVisible(true); - m_Controls.plannerLabel->setVisible(true); - m_Controls.foldBox->setVisible(true); - m_Controls.foldLabel->setVisible(true); - m_Controls.previewButton->setEnabled(false); - this->ShowEnsembleLayout(false); - auto trainerPlanners = m_ParentFolder->getTrainerPlannersForTask(selectedTask, model); - QStringList trainers, planners; - std::tie(trainers, planners) = ExtractTrainerPlannerFromString(trainerPlanners); - m_Controls.trainerBox->clear(); - m_Controls.plannerBox->clear(); - std::for_each( - trainers.begin(), trainers.end(), [this](QString trainer) { m_Controls.trainerBox->addItem(trainer); }); - std::for_each( - planners.begin(), planners.end(), [this](QString planner) { m_Controls.plannerBox->addItem(planner); }); - } - } - else if (!m_EnsembleParams.empty()) - { - for (auto &layout : m_EnsembleParams) - { - if (box == layout->modelBox) - { - layout->trainerBox->clear(); - layout->plannerBox->clear(); - auto trainerPlanners = m_ParentFolder->getTrainerPlannersForTask(selectedTask, model); - QStringList trainers, planners; - std::tie(trainers, planners) = ExtractTrainerPlannerFromString(trainerPlanners); - std::for_each(trainers.begin(), - trainers.end(), - [&layout](const QString &trainer) { layout->trainerBox->addItem(trainer); }); - std::for_each(planners.begin(), - planners.end(), - [&layout](const QString &planner) { layout->plannerBox->addItem(planner); }); - break; - } - } - } -} - -void QmitknnUNetToolGUI::OnTaskChanged(const QString &task) -{ - if (task.isEmpty()) - { - return; - } - m_Controls.modelBox->clear(); - auto models = m_ParentFolder->getModelsForTask(task); - models.removeDuplicates(); - if (!models.contains(m_VALID_MODELS.last(), Qt::CaseInsensitive)) - { - models << m_VALID_MODELS.last(); // add ensemble even if folder doesn't exist - } - std::for_each(models.begin(), - models.end(), - [this](QString model) - { - if (m_VALID_MODELS.contains(model, Qt::CaseInsensitive)) - m_Controls.modelBox->addItem(model); - }); -} - -void QmitknnUNetToolGUI::OnTrainerChanged(const QString &plannerSelected) -{ - if (plannerSelected.isEmpty()) - { - return; - } - m_IsResultsFolderValid = false; - QString parentPath; - auto *box = qobject_cast(sender()); - if (box == m_Controls.plannerBox) - { - m_Controls.foldBox->clear(); - auto selectedTrainer = m_Controls.trainerBox->currentText(); - auto selectedTask = m_Controls.taskBox->currentText(); - auto selectedModel = m_Controls.modelBox->currentText(); - auto folds = m_ParentFolder->getFoldsForTrainerPlanner( - selectedTrainer, plannerSelected, selectedTask, selectedModel); - std::for_each(folds.begin(), - folds.end(), - [this](QString fold) - { - if (fold.startsWith("fold_", Qt::CaseInsensitive)) // imposed by nnUNet - m_Controls.foldBox->addItem(fold); - }); - if (m_Controls.foldBox->count() != 0) - { - m_IsResultsFolderValid = true; - this->CheckAllInCheckableComboBox(m_Controls.foldBox); - auto tempPath = QStringList() << m_ParentFolder->getResultsFolder() << "nnUNet" << selectedModel << selectedTask - << QString("%1__%2").arg(selectedTrainer, plannerSelected); - parentPath = QDir::cleanPath(tempPath.join(QDir::separator())); - } - } - else if (!m_EnsembleParams.empty()) - { - for (auto &layout : m_EnsembleParams) - { - if (box == layout->plannerBox) - { - layout->foldBox->clear(); - auto selectedTrainer = layout->trainerBox->currentText(); - auto selectedTask = m_Controls.taskBox->currentText(); - auto selectedModel = layout->modelBox->currentText(); - auto folds = m_ParentFolder->getFoldsForTrainerPlanner( - selectedTrainer, plannerSelected, selectedTask, selectedModel); - std::for_each(folds.begin(), - folds.end(), - [&layout](const QString &fold) - { - if (fold.startsWith("fold_", Qt::CaseInsensitive)) // imposed by nnUNet - layout->foldBox->addItem(fold); - }); - if (layout->foldBox->count() != 0) - { - this->CheckAllInCheckableComboBox(layout->foldBox); - m_IsResultsFolderValid = true; - auto tempPath = QStringList() << m_ParentFolder->getResultsFolder() << "nnUNet" << selectedModel << selectedTask - << QString("%1__%2").arg(selectedTrainer, plannerSelected); - parentPath = QDir::cleanPath(tempPath.join(QDir::separator())); - } - break; - } - } - } - if (m_IsResultsFolderValid) - { - m_Controls.previewButton->setEnabled(true); - const QString mitkJsonFile = parentPath + QDir::separator() + m_MITK_EXPORT_JSON_FILENAME; - this->DumpAllJSONs(parentPath); - if (QFile::exists(mitkJsonFile)) - { - this->DisplayMultiModalInfoFromJSON(mitkJsonFile); - } - const QString jsonPath = m_ParentFolder->getResultsFolder() + QDir::separator() + m_AVAILABLE_MODELS_JSON_FILENAME; - if (QFile::exists(mitkJsonFile)) - { - this->FillAvailableModelsInfoFromJSON(jsonPath); - } - } -} - -void QmitknnUNetToolGUI::OnPythonPathChanged(const QString &pyEnv) -{ - if (pyEnv == QString("Select")) - { - QString path = - QFileDialog::getExistingDirectory(m_Controls.pythonEnvComboBox->parentWidget(), "Python Path", "dir"); - if (!path.isEmpty()) - { - this->OnPythonPathChanged(path); // recall same function for new path validation - m_Controls.pythonEnvComboBox->insertItem(0, path); - m_Controls.pythonEnvComboBox->setCurrentIndex(0); - } - } - else if (!this->IsNNUNetInstalled(pyEnv)) - { - std::string warning = - "WARNING: nnUNet is not detected on the Python environment you selected. Please select another " - "environment or create one. For more info refer https://github.com/MIC-DKFZ/nnUNet"; - this->ShowErrorMessage(warning); - this->DisableEverything(); - } - else - { - m_Controls.modeldirectoryBox->setEnabled(true); - m_Controls.previewButton->setEnabled(true); - m_Controls.refreshdirectoryBox->setEnabled(true); - m_Controls.multiModalBox->setEnabled(true); - QString setVal = this->FetchResultsFolderFromEnv(); - if (!setVal.isEmpty()) - { - m_Controls.modeldirectoryBox->setDirectory(setVal); - } - this->OnRefreshPresssed(); - m_PythonPath = pyEnv.mid(pyEnv.indexOf(" ") + 1); - if (!(m_PythonPath.endsWith("bin", Qt::CaseInsensitive) || m_PythonPath.endsWith("bin/", Qt::CaseInsensitive))) - { - m_PythonPath += QDir::separator() + QString("bin"); - } - } -} - -void QmitknnUNetToolGUI::OnCheckBoxChanged(int state) -{ - bool visibility = false; - if (state == Qt::Checked) - { - visibility = true; - } - ctkCheckBox *box = qobject_cast(sender()); - if (box != nullptr) - { - if (box->objectName() == QString("multiModalBox")) - { - m_Controls.multiModalSpinLabel->setVisible(visibility); - m_Controls.multiModalSpinBox->setVisible(visibility); - if (visibility) - { - QmitkDataStorageComboBox *defaultImage = new QmitkDataStorageComboBox(this, true); - defaultImage->setObjectName(QString("multiModal_" + QString::number(0))); - defaultImage->SetPredicate(m_MultiModalPredicate); - mitk::nnUNetTool::Pointer tool = this->GetConnectedToolAs(); - if (tool != nullptr) - { - defaultImage->SetDataStorage(tool->GetDataStorage()); - defaultImage->SetSelectedNode(tool->GetRefNode()); - } - m_Controls.advancedSettingsLayout->addWidget(defaultImage, m_UI_ROWS + m_Modalities.size() + 1, 1, 1, 3); - m_Modalities.push_back(defaultImage); - } - else - { - this->OnModalitiesNumberChanged(0); - m_Controls.multiModalSpinBox->setValue(0); - delete m_Modalities[0]; - m_Modalities.pop_back(); - this->ClearAllModalLabels(); - } - } - } -} - -void QmitknnUNetToolGUI::OnModalitiesNumberChanged(int num) -{ - while (num > static_cast(m_Modalities.size() - 1)) - { - QmitkDataStorageComboBox *multiModalBox = new QmitkDataStorageComboBox(this, true); - mitk::nnUNetTool::Pointer tool = this->GetConnectedToolAs(); - multiModalBox->SetDataStorage(tool->GetDataStorage()); - multiModalBox->SetPredicate(m_MultiModalPredicate); - multiModalBox->setObjectName(QString("multiModal_" + QString::number(m_Modalities.size() + 1))); - m_Controls.advancedSettingsLayout->addWidget(multiModalBox, m_UI_ROWS + m_Modalities.size() + 1, 1, 1, 3); - m_Modalities.push_back(multiModalBox); - } - while (num < static_cast(m_Modalities.size() - 1) && !m_Modalities.empty()) - { - QmitkDataStorageComboBox *child = m_Modalities.back(); - if (child->objectName() == "multiModal_0") - { - std::iter_swap(m_Modalities.end() - 2, m_Modalities.end() - 1); - child = m_Modalities.back(); - } - delete child; // delete the layout item - m_Modalities.pop_back(); - } - m_Controls.advancedSettingsLayout->update(); -} - -void QmitknnUNetToolGUI::AutoParsePythonPaths() -{ - QString homeDir = QDir::homePath(); - std::vector searchDirs; -#ifdef _WIN32 - searchDirs.push_back(QString("C:") + QDir::separator() + QString("ProgramData") + QDir::separator() + - QString("anaconda3")); -#else - // Add search locations for possible standard python paths here - searchDirs.push_back(homeDir + QDir::separator() + "environments"); - searchDirs.push_back(homeDir + QDir::separator() + "anaconda3"); - searchDirs.push_back(homeDir + QDir::separator() + "miniconda3"); - searchDirs.push_back(homeDir + QDir::separator() + "opt" + QDir::separator() + "miniconda3"); - searchDirs.push_back(homeDir + QDir::separator() + "opt" + QDir::separator() + "anaconda3"); -#endif - for (QString searchDir : searchDirs) - { - if (searchDir.endsWith("anaconda3", Qt::CaseInsensitive)) - { - if (QDir(searchDir).exists()) - { - m_Controls.pythonEnvComboBox->insertItem(0, "(base): " + searchDir); - searchDir.append((QDir::separator() + QString("envs"))); - } - } - for (QDirIterator subIt(searchDir, QDir::AllDirs, QDirIterator::NoIteratorFlags); subIt.hasNext();) - { - subIt.next(); - QString envName = subIt.fileName(); - if (!envName.startsWith('.')) // Filter out irrelevent hidden folders, if any. - { - m_Controls.pythonEnvComboBox->insertItem(0, "(" + envName + "): " + subIt.filePath()); - } - } - } - m_Controls.pythonEnvComboBox->setCurrentIndex(-1); -} - -mitk::ModelParams QmitknnUNetToolGUI::MapToRequest(const QString &modelName, - const QString &taskName, - const QString &trainer, - const QString &planId, - const std::vector &folds) -{ - mitk::ModelParams requestObject; - requestObject.model = modelName.toStdString(); - requestObject.trainer = trainer.toStdString(); - requestObject.planId = planId.toStdString(); - requestObject.task = taskName.toStdString(); - requestObject.folds = folds; - mitk::nnUNetTool::Pointer tool = this->GetConnectedToolAs(); - requestObject.inputName = tool->GetRefNode()->GetName(); - requestObject.timeStamp = - std::to_string(mitk::RenderingManager::GetInstance()->GetTimeNavigationController()->GetSelectedTimePoint()); - return requestObject; -} - -void QmitknnUNetToolGUI::SegmentationProcessFailed() -{ - this->WriteErrorMessage( - "STATUS: Error in the segmentation process.
No resulting segmentation can be loaded.
"); - this->setCursor(Qt::ArrowCursor); - std::stringstream stream; - stream << "Error in the segmentation process. No resulting segmentation can be loaded."; - this->ShowErrorMessage(stream.str()); -} - -void QmitknnUNetToolGUI::SegmentationResultHandler(mitk::nnUNetTool *tool, bool forceRender) -{ - if (forceRender) - { - tool->RenderOutputBuffer(); - } - this->SetLabelSetPreview(tool->GetPreviewSegmentation()); - this->WriteStatusMessage("STATUS: Segmentation task finished successfully."); - this->ActualizePreviewLabelVisibility(); -} - -void QmitknnUNetToolGUI::ShowEnsembleLayout(bool visible) -{ - if (m_EnsembleParams.empty()) - { - ctkCollapsibleGroupBox *groupBoxModel1 = new ctkCollapsibleGroupBox(this); - auto lay1 = std::make_unique(groupBoxModel1); - groupBoxModel1->setObjectName(QString::fromUtf8("model_1_Box")); - groupBoxModel1->setTitle(QString::fromUtf8("Model 1")); - groupBoxModel1->setMinimumSize(QSize(0, 0)); - groupBoxModel1->setCollapsedHeight(5); - groupBoxModel1->setCollapsed(false); - groupBoxModel1->setFlat(true); - groupBoxModel1->setAlignment(Qt::AlignRight); - m_Controls.advancedSettingsLayout->addWidget(groupBoxModel1, 5, 0, 1, 2); - - connect(lay1->modelBox, SIGNAL(currentTextChanged(const QString &)), this, SLOT(OnModelChanged(const QString &))); - connect( - lay1->plannerBox, SIGNAL(currentTextChanged(const QString &)), this, SLOT(OnTrainerChanged(const QString &))); - m_EnsembleParams.push_back(std::move(lay1)); - - ctkCollapsibleGroupBox *groupBoxModel2 = new ctkCollapsibleGroupBox(this); - auto lay2 = std::make_unique(groupBoxModel2); - groupBoxModel2->setObjectName(QString::fromUtf8("model_2_Box")); - groupBoxModel2->setTitle(QString::fromUtf8("Model 2")); - groupBoxModel2->setMinimumSize(QSize(0, 0)); - groupBoxModel2->setCollapsedHeight(5); - groupBoxModel2->setCollapsed(false); - groupBoxModel2->setFlat(true); - groupBoxModel2->setAlignment(Qt::AlignLeft); - m_Controls.advancedSettingsLayout->addWidget(groupBoxModel2, 5, 2, 1, 2); - - connect(lay2->modelBox, SIGNAL(currentTextChanged(const QString &)), this, SLOT(OnModelChanged(const QString &))); - connect( - lay2->plannerBox, SIGNAL(currentTextChanged(const QString &)), this, SLOT(OnTrainerChanged(const QString &))); - m_EnsembleParams.push_back(std::move(lay2)); - } - for (auto &layout : m_EnsembleParams) - { - layout->setVisible(visible); - } -} - -void QmitknnUNetToolGUI::OnDownloadModel() -{ - if (m_IsResultsFolderValid) - { - auto selectedTask = m_Controls.availableBox->currentText(); - auto spExec = mitk::ProcessExecutor::New(); - mitk::ProcessExecutor::ArgumentListType args; - args.push_back(selectedTask.toStdString()); - this->WriteStatusMessage("Downloading the requested task in to the selected Results Folder. This might take some time " - "depending on your internet connection..."); - m_Processes["DOWNLOAD"] = spExec; - if (!m_nnUNetThread->isRunning()) - { - MITK_DEBUG << "Starting thread..."; - m_nnUNetThread->start(); - } - QString resultsFolder = m_ParentFolder->getResultsFolder(); - emit Operate(resultsFolder, m_PythonPath, spExec, args); - m_Controls.stopDownloadButton->setVisible(true); - m_Controls.startDownloadButton->setVisible(false); - } -} - -void QmitknnUNetToolGUI::OnDownloadWorkerExit(const bool isSuccess, const QString message) -{ - if (isSuccess) - { - this->WriteStatusMessage(message + QString(" Click Refresh Results Folder to use the new Task.")); - } - else - { - MITK_ERROR << "Download FAILED! " << message.toStdString(); - this->WriteStatusMessage(QString("Download failed. Check your internet connection. " + message)); - } - m_Controls.stopDownloadButton->setVisible(false); - m_Controls.startDownloadButton->setVisible(true); -} - -void QmitknnUNetToolGUI::OnStopDownload() -{ - mitk::ProcessExecutor::Pointer spExec = m_Processes["DOWNLOAD"]; - spExec->KillProcess(); - this->WriteStatusMessage("Download Killed by the user."); - m_Controls.stopDownloadButton->setVisible(false); - m_Controls.startDownloadButton->setVisible(true); -}