diff --git a/Modules/Segmentation/Interactions/mitkTotalSegmentatorTool.cpp b/Modules/Segmentation/Interactions/mitkTotalSegmentatorTool.cpp index 1cc97543a9..e6c5ca2c3c 100644 --- a/Modules/Segmentation/Interactions/mitkTotalSegmentatorTool.cpp +++ b/Modules/Segmentation/Interactions/mitkTotalSegmentatorTool.cpp @@ -1,170 +1,199 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ // MITK #include "mitkTotalSegmentatorTool.h" - #include "mitkIOUtil.h" #include -#include "mitkProcessExecutor.h" // us #include #include #include #include #include namespace mitk { MITK_TOOL_MACRO(MITKSEGMENTATION_EXPORT, TotalSegmentatorTool, "Total Segmentator"); } mitk::TotalSegmentatorTool::TotalSegmentatorTool() { this->SetMitkTempDir(IOUtil::CreateTemporaryDirectory("mitk-XXXXXX")); } mitk::TotalSegmentatorTool::~TotalSegmentatorTool() { itksys::SystemTools::RemoveADirectory(this->GetMitkTempDir()); } void mitk::TotalSegmentatorTool::Activated() { Superclass::Activated(); this->SetLabelTransferMode(LabelTransferMode::AllLabels); } const char **mitk::TotalSegmentatorTool::GetXPM() const { return nullptr; } us::ModuleResource mitk::TotalSegmentatorTool::GetIconResource() const { us::Module *module = us::GetModuleContext()->GetModule(); us::ModuleResource resource = module->GetResource("AI.svg"); return resource; } const char *mitk::TotalSegmentatorTool::GetName() const { return "Total Segmentator"; } namespace { void onPythonProcessEvent(itk::Object * /*pCaller*/, const itk::EventObject &e, void *) { std::string testCOUT; std::string testCERR; const auto *pEvent = dynamic_cast(&e); if (pEvent) { testCOUT = testCOUT + pEvent->GetOutput(); MITK_INFO << testCOUT; } const auto *pErrEvent = dynamic_cast(&e); if (pErrEvent) { testCERR = testCERR + pErrEvent->GetOutput(); MITK_ERROR << testCERR; } } } // namespace - void mitk::TotalSegmentatorTool::DoUpdatePreview(const Image *inputAtTimeStep, - const Image * /*oldSegAtTimeStep*/, - LabelSetImage *previewImage, - TimeStepType timeStep) -{ + const Image * /*oldSegAtTimeStep*/, + LabelSetImage *previewImage, + TimeStepType timeStep) +{ std::string inDir, outDir, inputImagePath, outputImagePath, scriptPath; ProcessExecutor::Pointer spExec = ProcessExecutor::New(); itk::CStyleCommand::Pointer spCommand = itk::CStyleCommand::New(); spCommand->SetCallback(&onPythonProcessEvent); spExec->AddObserver(ExternalProcessOutputEvent(), spCommand); inDir = IOUtil::CreateTemporaryDirectory("totalseg-in-XXXXXX", this->GetMitkTempDir()); std::ofstream tmpStream; inputImagePath = IOUtil::CreateTemporaryFile(tmpStream, m_TEMPLATE_FILENAME, inDir + IOUtil::GetDirectorySeparator()); tmpStream.close(); std::size_t found = inputImagePath.find_last_of(IOUtil::GetDirectorySeparator()); std::string fileName = inputImagePath.substr(found + 1); std::string token = fileName.substr(0, fileName.find("_")); outDir = IOUtil::CreateTemporaryDirectory("totalseg-out-XXXXXX", this->GetMitkTempDir()); outputImagePath = outDir + IOUtil::GetDirectorySeparator() + token + "_000.nii.gz"; ProcessExecutor::ArgumentListType args; - MITK_INFO << inputImagePath; - MITK_INFO << outputImagePath; - IOUtil::Save(inputAtTimeStep, inputImagePath); - - // Code calls external process + + std::string *outArg = &outputImagePath; + bool isSubTask = false; + if (this->GetSubTask() != m_DEFAULT_TOTAL_TASK) + { + isSubTask = true; + outputImagePath = outDir + IOUtil::GetDirectorySeparator() + this->GetSubTask() + ".nii.gz"; + outArg = &outDir; + } + + this->run_totalsegmentator( + spExec, inputImagePath, *outArg, this->GetFast(), !isSubTask, this->GetGpuId(), m_DEFAULT_TOTAL_TASK); + + if (isSubTask) + { + this->run_totalsegmentator( + spExec, inputImagePath, *outArg, !isSubTask, !isSubTask, this->GetGpuId(), this->GetSubTask()); + } + + Image::Pointer outputImage = IOUtil::Load(outputImagePath); + auto outputBuffer = mitk::LabelSetImage::New(); + outputBuffer->InitializeByLabeledImage(outputImage); + outputBuffer->SetGeometry(inputAtTimeStep->GetGeometry()); + + TransferLabelSetImageContent(outputBuffer, previewImage, timeStep); +} + +void mitk::TotalSegmentatorTool::run_totalsegmentator(ProcessExecutor::Pointer spExec, + const std::string &inputImagePath, + const std::string &outputImagePath, + bool isFast, + bool isMultiLabel, + unsigned int gpuId, + const std::string &subTask) +{ + ProcessExecutor::ArgumentListType args; std::string command = "TotalSegmentator"; #ifdef _WIN32 - command = "python"; + command = "python"; #else - command = "TotalSegmentator"; + command = "TotalSegmentator"; #endif - - args.clear(); + + args.clear(); #ifdef _WIN32 - args.push_back("TotalSegmentator"); + args.push_back("TotalSegmentator"); #endif - args.push_back("-i"); - args.push_back(inputImagePath); + args.push_back("-i"); + args.push_back(inputImagePath); - args.push_back("-o"); - args.push_back(outputImagePath); + args.push_back("-o"); + args.push_back(outputImagePath); + if (subTask != m_DEFAULT_TOTAL_TASK) + { + args.push_back("-ta"); + args.push_back(subTask); + } + + if (isMultiLabel) + { args.push_back("--ml"); + } - if (this->GetFast()) - { - args.push_back("--fast"); - } + if (isFast) + { + args.push_back("--fast"); + } - try - { - std::string cudaEnv = "CUDA_VISIBLE_DEVICES=" + std::to_string(this->GetGpuId()); - itksys::SystemTools::PutEnv(cudaEnv.c_str()); + try + { + std::string cudaEnv = "CUDA_VISIBLE_DEVICES=" + std::to_string(gpuId); + itksys::SystemTools::PutEnv(cudaEnv.c_str()); - for (auto &arg : args) + for (auto &arg : args) MITK_INFO << arg; - MITK_INFO << this->GetPythonPath(); - - spExec->Execute(this->GetPythonPath(), command, args); - } - catch (const mitk::Exception &e) - { - MITK_ERROR << e.GetDescription(); - return; - } + MITK_INFO << this->GetPythonPath(); - Image::Pointer outputImage = IOUtil::Load(outputImagePath); - auto outputBuffer = mitk::LabelSetImage::New(); - outputBuffer->InitializeByLabeledImage(outputImage); - outputBuffer->SetGeometry(inputAtTimeStep->GetGeometry()); - - TransferLabelSetImageContent(outputBuffer, previewImage, timeStep); - + spExec->Execute(this->GetPythonPath(), command, args); + } + catch (const mitk::Exception &e) + { + MITK_ERROR << e.GetDescription(); + return; + } } diff --git a/Modules/Segmentation/Interactions/mitkTotalSegmentatorTool.h b/Modules/Segmentation/Interactions/mitkTotalSegmentatorTool.h index 22add9a383..aae1dc304c 100644 --- a/Modules/Segmentation/Interactions/mitkTotalSegmentatorTool.h +++ b/Modules/Segmentation/Interactions/mitkTotalSegmentatorTool.h @@ -1,79 +1,87 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef MITKTOTALSEGMENTATORTOOL_H #define MITKTOTALSEGMENTATORTOOL_H #include "mitkSegWithPreviewTool.h" #include +#include "mitkProcessExecutor.h" namespace us { class ModuleResource; } namespace mitk { class MITKSEGMENTATION_EXPORT TotalSegmentatorTool : public SegWithPreviewTool { public: mitkClassMacro(TotalSegmentatorTool, SegWithPreviewTool); itkFactorylessNewMacro(Self); itkCloneMacro(Self); const char *GetName() const override; const char **GetXPM() const override; us::ModuleResource GetIconResource() const override; void Activated() override; itkSetMacro(MitkTempDir, std::string); - itkGetConstMacro(MitkTempDir, std::string); + itkGetConstMacro(MitkTempDir, std::string); + + itkSetMacro(SubTask, std::string); + itkGetConstMacro(SubTask, std::string); itkSetMacro(PythonPath, std::string); itkGetConstMacro(PythonPath, std::string); itkSetMacro(GpuId, unsigned int); itkGetConstMacro(GpuId, unsigned int); itkSetMacro(Fast, bool); itkGetConstMacro(Fast, bool); itkBooleanMacro(Fast); protected: TotalSegmentatorTool(); ~TotalSegmentatorTool(); /** * @brief Overriden method from the tool manager to execute the segmentation * Implementation: * 1. Saves the inputAtTimeStep in a temporary directory. * 3. Sets CUDA_VISIBLE_DEVICES variables in the environment. * 3. Executes "TotalSegmentator" command with the parameters * 4. Expects an output image to be saved in the temporary directory by the python proces. Loads it as * LabelSetImage and sets to previewImage. * * @param inputAtTimeStep * @param oldSegAtTimeStep * @param previewImage * @param timeStep */ void DoUpdatePreview(const Image* inputAtTimeStep, const Image* oldSegAtTimeStep, LabelSetImage* previewImage, TimeStepType timeStep) override; private: + void run_totalsegmentator(ProcessExecutor::Pointer,const std::string &, const std::string &, bool, bool, unsigned int, const std::string &); + std::string m_MitkTempDir; std::string m_PythonPath; + std::string m_SubTask = "total"; unsigned int m_GpuId; bool m_Fast; const std::string m_TEMPLATE_FILENAME = "XXXXXX_000_0000.nii.gz"; + const std::string m_DEFAULT_TOTAL_TASK = "total"; }; // class } // namespace #endif diff --git a/Modules/SegmentationUI/Qmitk/QmitkTotalSegmentatorGUIControls.ui b/Modules/SegmentationUI/Qmitk/QmitkTotalSegmentatorGUIControls.ui index e4a117f666..eb4fe5d02f 100644 --- a/Modules/SegmentationUI/Qmitk/QmitkTotalSegmentatorGUIControls.ui +++ b/Modules/SegmentationUI/Qmitk/QmitkTotalSegmentatorGUIControls.ui @@ -1,224 +1,240 @@ QmitkTotalSegmentatorToolGUIControls 0 0 699 352 0 0 100 0 100000 100000 QmitkTotalSegmentatorToolWidget 0 0 0 0 0 0 0 - <html><head/><body><p>Welcome to Total Segmentator tool in MITK. [Experimental]</p><p>Please note that this is only an interface to Total Segmentator. MITK does not ship with Total Segmentator. Make sure to have a working Python environment with nnUNet set up beforehand. Choose that environment in the Python Path before inferencing. </p><p>Refer to <a href="https://github.com/wasserth/TotalSegmentator"><span style=" text-decoration: underline; color:#0000ff;">https://github.com/wasserth/TotalSegmentator</span></a> to learn everything about the Total Segmentator.</p><p><br/></p></body></html> + <html><head/><body><p>Welcome to Total Segmentator tool in MITK. [Experimental]</p><p>Please note that this is only an interface to Total Segmentator. MITK does not ship with Total Segmentator. Make sure to have a working Python environment with TotalSegmentator set up beforehand. Choose that environment in the Python Path before inferencing. </p><p>Refer to <a href="https://github.com/wasserth/TotalSegmentator"><span style=" text-decoration: underline; color:#0000ff;">https://github.com/wasserth/TotalSegmentator</span></a> to learn everything about the Total Segmentator.</p><p><br/></p></body></html> Qt::RichText true - - - - - 0 - 0 - - - - Python Path: - - - - - - + + + + + 0 + 0 + + + + Python Path: + + + + + + + + + + + + 0 + 0 + + + + Task: + + + + + + 0 0 Advanced true 5 true 0 0 0 0 6 - - - + + 0 0 - Fast + GPU Id: + + + false - - - + + 0 0 - GPU Id: + Fast - - - 0 0 100000 16777215 Run Total Segmentator 0 0 true - + + ctkComboBox QComboBox
ctkComboBox.h
1
ctkCollapsibleGroupBox QWidget
ctkcollapsiblegroupbox.h
ctkCheckBox QWidget
ctkcheckbox.h
diff --git a/Modules/SegmentationUI/Qmitk/QmitkTotalSegmentatorToolGUI.cpp b/Modules/SegmentationUI/Qmitk/QmitkTotalSegmentatorToolGUI.cpp index f96c2433d4..7b1225892c 100644 --- a/Modules/SegmentationUI/Qmitk/QmitkTotalSegmentatorToolGUI.cpp +++ b/Modules/SegmentationUI/Qmitk/QmitkTotalSegmentatorToolGUI.cpp @@ -1,290 +1,285 @@ #include "QmitkTotalSegmentatorToolGUI.h" -#include "usServiceReference.h" #include #include -#include -#include -#include -#include #include #include #include #include -#include -#include -#include #include #include -#include #include "mitkTotalSegmentatorTool.h" MITK_TOOL_GUI_MACRO(MITKSEGMENTATIONUI_EXPORT, QmitkTotalSegmentatorToolGUI, "") QmitkTotalSegmentatorToolGUI::QmitkTotalSegmentatorToolGUI() : QmitkMultiLabelSegWithPreviewToolGUIBase(), m_SuperclassEnableConfirmSegBtnFnc(m_EnableConfirmSegBtnFnc) { // Nvidia-smi command returning zero doesn't always imply lack of GPUs. // Pytorch uses its own libraries to communicate to the GPUs. Hence, only a warning can be given. if (m_GpuLoader.GetGPUCount() == 0) { std::string warning = "WARNING: No GPUs were detected on your machine. The TotalSegmentator tool can be very slow."; this->ShowErrorMessage(warning); } m_EnableConfirmSegBtnFnc = [this](bool enabled) { return !m_FirstPreviewComputation ? m_SuperclassEnableConfirmSegBtnFnc(enabled) : false; }; } void QmitkTotalSegmentatorToolGUI::ConnectNewTool(mitk::SegWithPreviewTool *newTool) { Superclass::ConnectNewTool(newTool); newTool->IsTimePointChangeAwareOff(); m_FirstPreviewComputation = true; } void QmitkTotalSegmentatorToolGUI::InitializeUI(QBoxLayout *mainLayout) { m_Controls.setupUi(this); m_Controls.pythonEnvComboBox->addItem("Select"); m_Controls.previewButton->setDisabled(true); m_Controls.statusLabel->setTextFormat(Qt::RichText); + m_Controls.subtaskComboBox->addItems(m_VALID_TASKS); AutoParsePythonPaths(); SetGPUInfo(); if (m_GpuLoader.GetGPUCount() != 0) { WriteStatusMessage(QString("STATUS: Welcome to Total Segmentator tool. You're in luck: " + QString::number(m_GpuLoader.GetGPUCount()) + " GPU(s) were detected.")); } else { WriteErrorMessage(QString("STATUS: Welcome to Total Segmentator tool. Sorry, " + QString::number(m_GpuLoader.GetGPUCount()) + " GPUs were detected.")); } mainLayout->addLayout(m_Controls.verticalLayout); connect(m_Controls.previewButton, SIGNAL(clicked()), this, SLOT(OnPreviewBtnClicked())); connect(m_Controls.pythonEnvComboBox, SIGNAL(currentTextChanged(const QString &)), this, SLOT(OnPythonPathChanged(const QString &))); Superclass::InitializeUI(mainLayout); QString lastSelectedPyEnv = m_Settings.value("TotalSeg/LastPythonPath").toString(); - m_Controls.pythonEnvComboBox->setCurrentText(lastSelectedPyEnv); + m_Controls.pythonEnvComboBox->insertItem(0, lastSelectedPyEnv); } void QmitkTotalSegmentatorToolGUI::EnableWidgets(bool enabled) { Superclass::EnableWidgets(enabled); } void QmitkTotalSegmentatorToolGUI::SetGPUInfo() { std::vector specs = m_GpuLoader.GetAllGPUSpecs(); for (const QmitkGPUSpec &gpuSpec : specs) { m_Controls.gpuComboBox->addItem(QString::number(gpuSpec.id) + ": " + gpuSpec.name + " (" + gpuSpec.memory + ")"); } if (specs.empty()) { m_Controls.gpuComboBox->setEditable(true); m_Controls.gpuComboBox->addItem(QString::number(0)); m_Controls.gpuComboBox->setValidator(new QIntValidator(0, 999, this)); } } unsigned int QmitkTotalSegmentatorToolGUI::FetchSelectedGPUFromUI() { QString gpuInfo = m_Controls.gpuComboBox->currentText(); if (m_GpuLoader.GetGPUCount() == 0) { return static_cast(gpuInfo.toInt()); } else { QString gpuId = gpuInfo.split(":", QString::SplitBehavior::SkipEmptyParts).first(); return static_cast(gpuId.toInt()); } } void QmitkTotalSegmentatorToolGUI::OnPreviewBtnClicked() { auto tool = this->GetConnectedToolAs(); if (nullptr == tool) { return; } QString pythonPathTextItem = ""; try { m_Controls.previewButton->setEnabled(false); qApp->processEvents(); - pythonPathTextItem = m_Controls.pythonEnvComboBox->currentText(); - if (!this->IsTotalSegmentatorInstalled(m_PythonPath)) { - throw std::runtime_error("TotalSegmentator is not detected in the selected python environment. Please select a valid " - "python environment or install TotalSegmentator."); + throw std::runtime_error(m_WARNING_TOTALSEG_NOT_FOUND); + } + pythonPathTextItem = m_Controls.pythonEnvComboBox->currentText(); + bool isFast = m_Controls.fastBox->isChecked(); + QString& subTask = m_Controls.subtaskComboBox->currentText(); + if (subTask != m_VALID_TASKS[0]) + { + isFast = true; } tool->SetPythonPath(m_PythonPath.toStdString()); tool->SetGpuId(FetchSelectedGPUFromUI()); - tool->SetFast(m_Controls.fastBox->isChecked()); + tool->SetFast(isFast); + tool->SetSubTask(subTask.toStdString()); this->WriteStatusMessage(QString("STATUS: Starting Segmentation task... This might take a while.")); tool->UpdatePreview(); m_Controls.previewButton->setEnabled(true); } catch (const std::exception &e) { std::stringstream errorMsg; errorMsg << "STATUS: Error while processing parameters for TotalSegmentator segmentation. Reason: " << e.what(); this->ShowErrorMessage(errorMsg.str()); this->WriteErrorMessage(QString::fromStdString(errorMsg.str())); m_Controls.previewButton->setEnabled(true); return; } catch (...) { std::string errorMsg = "Unkown error occured while generation TotalSegmentator segmentation."; this->ShowErrorMessage(errorMsg); m_Controls.previewButton->setEnabled(true); return; } this->SetLabelSetPreview(tool->GetPreviewSegmentation()); tool->IsTimePointChangeAwareOn(); this->ActualizePreviewLabelVisibility(); + this->WriteStatusMessage("STATUS: Segmentation task finished successfully."); if (!pythonPathTextItem.isEmpty()) { // only cache if the prediction ended without errors. m_Settings.setValue("TotalSeg/LastPythonPath", pythonPathTextItem); } } void QmitkTotalSegmentatorToolGUI::ShowErrorMessage(const std::string &message, QMessageBox::Icon icon) { this->setCursor(Qt::ArrowCursor); QMessageBox *messageBox = new QMessageBox(icon, nullptr, message.c_str()); messageBox->exec(); delete messageBox; MITK_WARN << message; } void QmitkTotalSegmentatorToolGUI::WriteStatusMessage(const QString &message) { m_Controls.statusLabel->setText(message); m_Controls.statusLabel->setStyleSheet("font-weight: bold; color: white"); } void QmitkTotalSegmentatorToolGUI::WriteErrorMessage(const QString &message) { m_Controls.statusLabel->setText(message); m_Controls.statusLabel->setStyleSheet("font-weight: bold; color: red"); } bool QmitkTotalSegmentatorToolGUI::IsTotalSegmentatorInstalled(const QString &pythonPath) { QString fullPath = pythonPath; #ifdef _WIN32 if (!(fullPath.endsWith("Scripts", Qt::CaseInsensitive) || fullPath.endsWith("Scripts/", Qt::CaseInsensitive))) { fullPath += QDir::separator() + QString("Scripts"); } #else if (!(fullPath.endsWith("bin", Qt::CaseInsensitive) || fullPath.endsWith("bin/", Qt::CaseInsensitive))) { fullPath += QDir::separator() + QString("bin"); } #endif fullPath = fullPath.mid(fullPath.indexOf(" ") + 1); bool isExists = QFile::exists(fullPath + QDir::separator() + QString("TotalSegmentator")) && #ifdef _WIN32 QFile::exists(fullPath + QDir::separator() + QString("python.exe")); #else QFile::exists(fullPath + QDir::separator() + QString("python3")); #endif return isExists; } void QmitkTotalSegmentatorToolGUI::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); } void QmitkTotalSegmentatorToolGUI::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 bool oldState = m_Controls.pythonEnvComboBox->blockSignals(true); // block signal firing while inserting item m_Controls.pythonEnvComboBox->insertItem(0, path); m_Controls.pythonEnvComboBox->setCurrentIndex(0); m_Controls.pythonEnvComboBox->blockSignals(oldState); // unblock signal firing after inserting item. Remove this after Qt6 migration } } else if (!this->IsTotalSegmentatorInstalled(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->ShowErrorMessage(m_WARNING_TOTALSEG_NOT_FOUND); m_Controls.previewButton->setDisabled(true); } else { // Show positive status meeage m_Controls.previewButton->setDisabled(false); m_PythonPath = pyEnv.mid(pyEnv.indexOf(" ") + 1); #ifdef _WIN32 if (!(m_PythonPath.endsWith("Scripts", Qt::CaseInsensitive) || m_PythonPath.endsWith("Scripts/", Qt::CaseInsensitive))) { m_PythonPath += QDir::separator() + QString("Scripts"); } #else if (!(m_PythonPath.endsWith("bin", Qt::CaseInsensitive) || m_PythonPath.endsWith("bin/", Qt::CaseInsensitive))) { m_PythonPath += QDir::separator() + QString("bin"); } #endif } } diff --git a/Modules/SegmentationUI/Qmitk/QmitkTotalSegmentatorToolGUI.h b/Modules/SegmentationUI/Qmitk/QmitkTotalSegmentatorToolGUI.h index 2522098e88..71e70d52a7 100644 --- a/Modules/SegmentationUI/Qmitk/QmitkTotalSegmentatorToolGUI.h +++ b/Modules/SegmentationUI/Qmitk/QmitkTotalSegmentatorToolGUI.h @@ -1,94 +1,98 @@ #ifndef QmitkTotalSegmentatorToolGUI_h_Included #define QmitkTotalSegmentatorToolGUI_h_Included #include "QmitkMultiLabelSegWithPreviewToolGUIBase.h" #include "ui_QmitkTotalSegmentatorGUIControls.h" #include #include #include "QmitknnUNetGPU.h" #include class MITKSEGMENTATIONUI_EXPORT QmitkTotalSegmentatorToolGUI : public QmitkMultiLabelSegWithPreviewToolGUIBase { Q_OBJECT public: mitkClassMacro(QmitkTotalSegmentatorToolGUI, QmitkMultiLabelSegWithPreviewToolGUIBase); itkFactorylessNewMacro(Self); itkCloneMacro(Self); protected slots : void OnPreviewBtnClicked(); /** * @brief Qt Slot */ void OnPythonPathChanged(const QString &); protected: QmitkTotalSegmentatorToolGUI(); ~QmitkTotalSegmentatorToolGUI() = default; void ConnectNewTool(mitk::SegWithPreviewTool* newTool) override; void InitializeUI(QBoxLayout* mainLayout) override; void EnableWidgets(bool enabled) override; /** * @brief Searches and parses paths of python virtual enviroments * from predefined lookout locations */ void AutoParsePythonPaths(); /** * @brief Checks if TotalSegmentator command is valid in the selected python virtual environment. * * @return bool */ bool IsTotalSegmentatorInstalled(const QString &); /** * @brief Creates a QMessage object and shows on screen. */ void ShowErrorMessage(const std::string &, QMessageBox::Icon = QMessageBox::Critical); /** * @brief Writes any message in white on the tool pane. */ void WriteStatusMessage(const QString &); /** * @brief Writes any message in red on the tool pane. */ void WriteErrorMessage(const QString &); /** * @brief Adds GPU information to the gpu combo box. * In case, there aren't any GPUs avaialble, the combo box will be * rendered editable. */ void SetGPUInfo(); /** * @brief Returns GPU id of the selected GPU from the Combo box. * * @return unsigned int */ unsigned int FetchSelectedGPUFromUI(); /** * @brief For storing values like Python path across sessions. */ QSettings m_Settings; QString m_PythonPath; QmitkGPULoader m_GpuLoader; Ui_QmitkTotalSegmentatorToolGUIControls m_Controls; bool m_FirstPreviewComputation = true; EnableConfirmSegBtnFunctionType m_SuperclassEnableConfirmSegBtnFnc; + + const std::string m_WARNING_TOTALSEG_NOT_FOUND = "TotalSegmentator is not detected in the selected python environment.Please select a valid " + "python environment or install TotalSegmentator."; + const QStringList m_VALID_TASKS = {"total", "cerebral_bleed", "hip_implant", "coronary_arteries"}; }; #endif