diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/src/internal/QmitkMatchPointBrowser.cpp b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/src/internal/QmitkMatchPointBrowser.cpp index 611ddeec99..0818975928 100644 --- a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/src/internal/QmitkMatchPointBrowser.cpp +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/src/internal/QmitkMatchPointBrowser.cpp @@ -1,268 +1,264 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "org_mitk_gui_qt_matchpoint_algorithm_browser_Activator.h" // Blueberry #include #include #include // Qmitk #include "QmitkMatchPointBrowser.h" // Qt #include #include #include #include //MITK #include #include "MatchPointBrowserConstants.h" #include "mitkAlgorithmInfoSelectionProvider.h" // MatchPoint #include #include #include #include #include const std::string QmitkMatchPointBrowser::VIEW_ID = "org.mitk.views.matchpoint.algorithm.browser"; QmitkMatchPointBrowser::QmitkMatchPointBrowser() : m_Parent(NULL), m_LoadedDLLHandle(NULL), m_LoadedAlgorithm(NULL) { } QmitkMatchPointBrowser::~QmitkMatchPointBrowser() { } void QmitkMatchPointBrowser::OnPreferencesChanged(const berry::IBerryPreferences* /*prefs*/) { this->OnSearchFolderButtonPushed(); } void QmitkMatchPointBrowser::CreateConnections() { connect(m_Controls.m_pbSearchFolder, SIGNAL(clicked()), this, SLOT(OnSearchFolderButtonPushed())); connect(m_Controls.m_algoTreeView, SIGNAL(clicked(const QModelIndex&)), this, SLOT(OnAlgoListSelectionChanged(const QModelIndex&))); connect(m_Controls.pbClearSearch, SIGNAL(clicked()), m_Controls.lineSearch, SLOT(clear())); connect(m_Controls.lineSearch, SIGNAL(textChanged(const QString&)), this, SLOT(OnSearchChanged(const QString&))); } void QmitkMatchPointBrowser::OnSearchFolderButtonPushed() { RetrieveAndStorePreferenceValues(); // test if some folder list non-empty int folderCount = m_currentSearchPaths.count(); if (!folderCount) { Error(QString("No search folder selected for MatchPoint algorithm browser! Please set search paths in the MatchPoint preference page.")); m_DLLInfoList.clear(); } else { map::deployment::DLLDirectoryBrowser::Pointer browser = map::deployment::DLLDirectoryBrowser::New(); foreach(QString path, m_currentSearchPaths) { browser->addDLLSearchLocation(path.toStdString()); } browser->update(); m_DLLInfoList = browser->getLibraryInfos(); } m_Controls.groupWarning->setVisible(m_DLLInfoList.empty()); m_Controls.groupList->setVisible(!m_DLLInfoList.empty()); m_algModel->SetAlgorithms(m_DLLInfoList); m_Controls.lineSearch->clear(); } void QmitkMatchPointBrowser::OnAlgoListSelectionChanged(const QModelIndex& index) { QVariant vIndex = index.data(Qt::UserRole).toInt(); map::deployment::DLLInfo::ConstPointer currentItemInfo = NULL; if (vIndex.isValid()) { int algListIndex = vIndex.toInt(); if (algListIndex < m_DLLInfoList.size()) { currentItemInfo = m_DLLInfoList[algListIndex]; } } m_Controls.m_teAlgorithmDetails->updateInfo(currentItemInfo); if (currentItemInfo) { //update selection provider mitk::MAPAlgorithmInfoSelection::Pointer infoSelection = mitk::MAPAlgorithmInfoSelection::Pointer( new mitk::MAPAlgorithmInfoSelection(currentItemInfo)); this->m_SelectionProvider->SetInfoSelection(infoSelection); } } void QmitkMatchPointBrowser::OnSearchChanged(const QString& text) { m_filterProxy->setFilterRegExp(text); m_filterProxy->setFilterCaseSensitivity(Qt::CaseInsensitive); }; void QmitkMatchPointBrowser::CreateQtPartControl(QWidget* parent) { // create GUI widgets from the Qt Designer's .ui file m_Controls.setupUi(parent); m_Parent = parent; m_algModel = new QmitkAlgorithmListModel(parent); m_filterProxy = new QSortFilterProxyModel(parent); //! [Qt Selection Provider registration] // create new qt selection provider m_SelectionProvider = new mitk::AlgorithmInfoSelectionProvider(); m_filterProxy->setSourceModel(m_algModel); m_filterProxy->setDynamicSortFilter(true); m_filterProxy->setFilterKeyColumn(-1); m_Controls.m_algoTreeView->setModel(m_filterProxy); m_Controls.m_algoTreeView->setSelectionMode(QAbstractItemView::SingleSelection); m_Controls.m_algoTreeView->header()->setStretchLastSection(false); -#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) - m_Controls.m_algoTreeView->header()->setResizeMode(0, QHeaderView::Stretch); -#else m_Controls.m_algoTreeView->header()->setSectionResizeMode(0, QHeaderView::Stretch); -#endif m_Controls.m_algoTreeView->setColumnHidden(3, true); this->CreateConnections(); } void QmitkMatchPointBrowser::SetSelectionProvider() { this->GetSite()->SetSelectionProvider(m_SelectionProvider); } void QmitkMatchPointBrowser::SetFocus() { } void QmitkMatchPointBrowser::Error(QString msg) { mitk::StatusBar::GetInstance()->DisplayErrorText(msg.toLatin1()); MITK_ERROR << msg.toStdString().c_str(); } void QmitkMatchPointBrowser::RetrieveAndStorePreferenceValues() { berry::IBerryPreferences::Pointer prefs = this->RetrievePreferences(); bool loadApplicationDir = prefs->GetBool( - MatchPointBrowserConstants::LOAD_FROM_APPLICATION_DIR.c_str(), false); + MatchPointBrowserConstants::LOAD_FROM_APPLICATION_DIR.c_str(), true); bool loadHomeDir = prefs->GetBool(MatchPointBrowserConstants::LOAD_FROM_HOME_DIR.c_str(), false); bool loadCurrentDir = prefs->GetBool(MatchPointBrowserConstants::LOAD_FROM_CURRENT_DIR.c_str(), false); bool loadAutoLoadDir = prefs->GetBool(MatchPointBrowserConstants::LOAD_FROM_AUTO_LOAD_DIR.c_str(), false); // Get some default application paths. QStringList newPaths; // Here we can use the preferences to set up the builder, if (loadApplicationDir) { newPaths << QCoreApplication::applicationDirPath(); } if (loadHomeDir) { newPaths << QDir::homePath(); } if (loadCurrentDir) { newPaths << QDir::currentPath(); } if (loadAutoLoadDir) { char* deployedAlgorithmLoadPath = getenv("MAP_MDRA_LOAD_PATH"); if (deployedAlgorithmLoadPath != NULL) { // The load path may in fact be a semi-colon or colon separated list of directories, not just one. QString paths(deployedAlgorithmLoadPath); #ifdef Q_OS_WIN32 QString pathSeparator(";"); #else QString pathSeparator(":"); #endif QStringList splitPath = paths.split(pathSeparator, QString::SkipEmptyParts); foreach(QString path, splitPath) { QDir dir = QDir(path); newPaths << dir.absolutePath(); } } } // We get additional directory paths from preferences. QString pathString = prefs->Get(MatchPointBrowserConstants::MDAR_DIRECTORIES_NODE_NAME.c_str(), tr("")); QStringList additionalPaths = pathString.split(";", QString::SkipEmptyParts); newPaths << additionalPaths; QString additionalAlgorirthmsString = prefs->Get( MatchPointBrowserConstants::MDAR_FILES_NODE_NAME.c_str(), tr("")); additionalPaths = additionalAlgorirthmsString.split(";", QString::SkipEmptyParts); newPaths << additionalPaths; m_currentSearchPaths = newPaths; } berry::IBerryPreferences::Pointer QmitkMatchPointBrowser::RetrievePreferences() { berry::IPreferencesService* prefService = berry::Platform::GetPreferencesService(); assert(prefService); QString id = tr("/") + QString::fromStdString(MatchPointBrowserConstants::VIEW_ID); berry::IBerryPreferences::Pointer prefs = (prefService->GetSystemPreferences()->Node(id)) .Cast(); assert(prefs); return prefs; } diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/src/internal/QmitkMatchPoint.cpp b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/src/internal/QmitkMatchPoint.cpp index d59e603b09..4e1deb18ab 100644 --- a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/src/internal/QmitkMatchPoint.cpp +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/src/internal/QmitkMatchPoint.cpp @@ -1,970 +1,980 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "org_mitk_gui_qt_matchpoint_algorithmcontrol_Activator.h" // Blueberry #include #include #include #include // Mitk #include #include #include #include #include #include +#include +#include +#include +#include // Qmitk #include "QmitkMatchPoint.h" #include #include // Qt #include #include #include #include #include // MatchPoint #include #include #include #include #include #include #include #include #include -#include - const std::string QmitkMatchPoint::VIEW_ID = "org.mitk.views.matchpoint.algorithm.control"; QmitkMatchPoint::QmitkMatchPoint() : m_Parent(NULL), m_LoadedDLLHandle(NULL), m_LoadedAlgorithm(NULL) { m_CanLoadAlgorithm = false; m_ValidInputs = false; m_Working = false; m_spSelectedTargetData = NULL; m_spSelectedMovingData = NULL; m_spSelectedTargetMaskData = NULL; m_spSelectedMovingMaskData = NULL; } QmitkMatchPoint::~QmitkMatchPoint() { // remove selection service berry::ISelectionService* s = this->GetSite()->GetWorkbenchWindow()->GetSelectionService(); if (s) { s->RemoveSelectionListener(m_AlgorithmSelectionListener.data()); } } void QmitkMatchPoint::SetFocus() { } void QmitkMatchPoint::CreateConnections() { connect(m_Controls.checkMovingMask, SIGNAL(toggled(bool)), this, SLOT(OnMaskCheckBoxToggeled(bool))); connect(m_Controls.checkTargetMask, SIGNAL(toggled(bool)), this, SLOT(OnMaskCheckBoxToggeled(bool))); // ------ // Tab 1 - Shared library loading interface // ------ connect(m_Controls.m_pbLoadSelected, SIGNAL(clicked()), this, SLOT(OnLoadAlgorithmButtonPushed())); // ----- // Tab 2 - Execution // ----- connect(m_Controls.m_pbStartReg, SIGNAL(clicked()), this, SLOT(OnStartRegBtnPushed())); connect(m_Controls.m_pbStopReg, SIGNAL(clicked()), this, SLOT(OnStopRegBtnPushed())); connect(m_Controls.m_pbSaveLog, SIGNAL(clicked()), this, SLOT(OnSaveLogBtnPushed())); } const map::deployment::DLLInfo* QmitkMatchPoint::GetSelectedAlgorithmDLL() const { return m_SelectedAlgorithmInfo; } void QmitkMatchPoint::OnMaskCheckBoxToggeled(bool checked) { if (!m_Working) { CheckInputs(); ConfigureRegistrationControls(); } }; void QmitkMatchPoint::OnSelectedAlgorithmChanged() { std::stringstream descriptionString; ::map::deployment::DLLInfo::ConstPointer currentItemInfo = GetSelectedAlgorithmDLL(); if (!currentItemInfo) { Error(QString("No valid algorithm is selected. ABORTING.")); return; } m_Controls.m_teAlgorithmDetails->updateInfo(currentItemInfo); m_Controls.m_lbSelectedAlgorithm->setText(QString::fromStdString( currentItemInfo->getAlgorithmUID().getName())); // enable loading m_CanLoadAlgorithm = true; this->AdaptFolderGUIElements(); } void QmitkMatchPoint::OnLoadAlgorithmButtonPushed() { map::deployment::DLLInfo::ConstPointer dllInfo = GetSelectedAlgorithmDLL(); if (!dllInfo) { Error(QString("No valid algorithm is selected. Cannot load algorithm. ABORTING.")); return; } ::map::deployment::DLLHandle::Pointer tempDLLHandle = ::map::deployment::openDeploymentDLL( dllInfo->getLibraryFilePath()); ::map::algorithm::RegistrationAlgorithmBase::Pointer tempAlgorithm = ::map::deployment::getRegistrationAlgorithm(tempDLLHandle); if (tempAlgorithm.IsNull()) { Error(QString("Error. Cannot load selected algorithm.")); return; } this->m_LoadedAlgorithm = tempAlgorithm; this->m_LoadedDLLHandle = tempDLLHandle; this->m_Controls.m_AlgoConfigurator->setAlgorithm(m_LoadedAlgorithm); m_Controls.checkMovingMask->setChecked(false); m_Controls.checkTargetMask->setChecked(false); this->AdaptFolderGUIElements(); this->CheckInputs(); this->ConfigureRegistrationControls(); this->ConfigureProgressInfos(); this->m_Controls.m_tabs->setCurrentIndex(1); } void QmitkMatchPoint::Error(QString msg) { mitk::StatusBar::GetInstance()->DisplayErrorText(msg.toLatin1()); MITK_ERROR << msg.toStdString().c_str(); m_Controls.m_teLog->append(QString("") + msg + QString("")); } void QmitkMatchPoint::AdaptFolderGUIElements() { m_Controls.m_pbLoadSelected->setEnabled(m_CanLoadAlgorithm); } void QmitkMatchPoint::CreateQtPartControl(QWidget* parent) { // create GUI widgets from the Qt Designer's .ui file m_Controls.setupUi(parent); m_Parent = parent; m_Controls.checkMovingMask->setChecked(false); m_Controls.checkTargetMask->setChecked(false); m_Controls.m_tabs->setCurrentIndex(0); m_AlgorithmSelectionListener.reset(new berry::SelectionChangedAdapter(this, &QmitkMatchPoint::OnAlgorithmSelectionChanged)); // register selection listener GetSite()->GetWorkbenchWindow()->GetSelectionService()->AddSelectionListener( m_AlgorithmSelectionListener.data()); this->CreateConnections(); this->AdaptFolderGUIElements(); this->CheckInputs(); this->ConfigureProgressInfos(); this->ConfigureRegistrationControls(); berry::ISelection::ConstPointer selection = GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection("org.mitk.views.matchpoint.algorithm.browser"); this->UpdateAlgorithmSelection(selection); } bool QmitkMatchPoint::CheckInputs() { bool validMoving = false; bool validTarget = false; bool validMovingMask = false; bool validTargetMask = false; + mitk::NodePredicateDataType::Pointer isLabelSet = mitk::NodePredicateDataType::New("LabelSetImage"); + mitk::NodePredicateDataType::Pointer isImage = mitk::NodePredicateDataType::New("Image"); + mitk::NodePredicateProperty::Pointer isBinary = mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true)); + mitk::NodePredicateAnd::Pointer isLegacyMask = mitk::NodePredicateAnd::New(isImage, isBinary); + + mitk::NodePredicateOr::Pointer maskPredicate = mitk::NodePredicateOr::New(isLegacyMask, isLabelSet); + if (m_LoadedAlgorithm.IsNull()) { m_Controls.m_lbMovingName->setText(QString("No algorithm seleted!")); m_spSelectedMovingNode = NULL; m_spSelectedMovingData = NULL; m_Controls.m_lbTargetName->setText(QString("No algorithm seleted!")); m_spSelectedTargetNode = NULL; m_spSelectedTargetData = NULL; m_spSelectedMovingMaskNode = NULL; m_spSelectedMovingMaskData = NULL; m_spSelectedTargetMaskNode = NULL; m_spSelectedTargetMaskData = NULL; } else { QList nodes = this->GetDataManagerSelection(); mitk::Image* movingImage = NULL; mitk::PointSet* movingPointSet = NULL; mitk::Image* targetImage = NULL; mitk::PointSet* targetPointSet = NULL; mitk::Image* movingMaskImage = NULL; mitk::Image* targetMaskImage = NULL; typedef ::map::core::continuous::Elements<3>::InternalPointSetType InternalDefaultPointSetType; typedef ::map::algorithm::facet::PointSetRegistrationAlgorithmInterface PointSetRegInterface; typedef ::map::algorithm::facet::MaskedRegistrationAlgorithmInterface<3, 3> MaskRegInterface; PointSetRegInterface* pPointSetInterface = dynamic_cast (m_LoadedAlgorithm.GetPointer()); MaskRegInterface* pMaskInterface = dynamic_cast(m_LoadedAlgorithm.GetPointer()); if (nodes.count() < 1) { m_Controls.m_lbMovingName->setText(QString("no data selected!")); m_spSelectedMovingNode = NULL; m_spSelectedMovingData = NULL; } else { m_spSelectedMovingNode = nodes.front(); m_spSelectedMovingData = m_spSelectedMovingNode->GetData(); movingImage = dynamic_cast(m_spSelectedMovingNode->GetData()); movingPointSet = dynamic_cast(m_spSelectedMovingNode->GetData()); if (movingPointSet && pPointSetInterface) { validMoving = true; } else if (movingImage && !pPointSetInterface) { if (movingImage->GetDimension() - 1 == m_LoadedAlgorithm->getMovingDimensions() && movingImage->GetTimeSteps() > 1) { //images has multiple time steps and a time step has the correct dimensionality mitk::ImageTimeSelector::Pointer imageTimeSelector = mitk::ImageTimeSelector::New(); imageTimeSelector->SetInput(movingImage); imageTimeSelector->SetTimeNr(0); imageTimeSelector->UpdateLargestPossibleRegion(); m_spSelectedMovingData = imageTimeSelector->GetOutput(); validMoving = true; m_Controls.m_teLog->append( QString("Selected moving image has multiple time steps. First time step is used as moving image.")); } else if (movingImage->GetDimension() != m_LoadedAlgorithm->getMovingDimensions()) { m_Controls.m_lbMovingName->setText(QString("wrong image dimension. ") + QString::number(m_LoadedAlgorithm->getMovingDimensions()) + QString("D needed")); } else { validMoving = true; } } else { m_Controls.m_lbMovingName->setText(QString("no supported data selected!")); } nodes.removeFirst(); } if (nodes.count() < 1) { m_Controls.m_lbTargetName->setText(QString("no data selected!")); m_spSelectedTargetNode = NULL; m_spSelectedTargetData = NULL; } else { m_spSelectedTargetNode = nodes.front(); m_spSelectedTargetData = m_spSelectedTargetNode->GetData(); targetImage = dynamic_cast(m_spSelectedTargetNode->GetData()); targetPointSet = dynamic_cast(m_spSelectedTargetNode->GetData()); if (targetPointSet && pPointSetInterface) { validTarget = true; } else if (targetImage && !pPointSetInterface) { if (targetImage->GetDimension() - 1 == m_LoadedAlgorithm->getTargetDimensions() && targetImage->GetTimeSteps() > 1) { //images has multiple time steps and a time step has the correct dimensionality mitk::ImageTimeSelector::Pointer imageTimeSelector = mitk::ImageTimeSelector::New(); imageTimeSelector->SetInput(targetImage); imageTimeSelector->SetTimeNr(0); imageTimeSelector->UpdateLargestPossibleRegion(); m_spSelectedTargetData = imageTimeSelector->GetOutput(); validTarget = true; m_Controls.m_teLog->append( QString("Selected target image has multiple time steps. First time step is used as target image.")); } else if (targetImage->GetDimension() != m_LoadedAlgorithm->getTargetDimensions()) { m_Controls.m_lbTargetName->setText(QString("wrong image dimension. ") + QString::number(m_LoadedAlgorithm->getTargetDimensions()) + QString("D needed")); } else { validTarget = true; } } else { m_Controls.m_lbTargetName->setText(QString("no supported data selected!")); } nodes.removeFirst(); } if (m_Controls.checkMovingMask->isChecked()) { if (nodes.count() < 1) { m_Controls.m_lbMovingMaskName->setText(QString("no data selected!")); m_spSelectedMovingMaskNode = NULL; m_spSelectedMovingMaskData = NULL; } else { m_spSelectedMovingMaskNode = nodes.front(); m_spSelectedMovingMaskData = NULL; + movingMaskImage = dynamic_cast(m_spSelectedMovingMaskNode->GetData()); - bool isMask = false; - m_spSelectedMovingMaskNode->GetBoolProperty("binary", isMask); + + bool isMask = maskPredicate->CheckNode(m_spSelectedMovingMaskNode); if (!isMask) { m_Controls.m_lbMovingMaskName->setText(QString("no mask selected!")); } else if (movingMaskImage && pMaskInterface) { if (movingMaskImage->GetDimension() - 1 == m_LoadedAlgorithm->getMovingDimensions() && movingMaskImage->GetTimeSteps() > 1) { //images has multiple time steps and a time step has the correct dimensionality mitk::ImageTimeSelector::Pointer imageTimeSelector = mitk::ImageTimeSelector::New(); imageTimeSelector->SetInput(movingMaskImage); imageTimeSelector->SetTimeNr(0); imageTimeSelector->UpdateLargestPossibleRegion(); m_spSelectedMovingMaskData = imageTimeSelector->GetOutput(); validMovingMask = true; m_Controls.m_teLog->append( QString("Selected moving mask has multiple time steps. First time step is used as moving mask.")); } else if (movingMaskImage->GetDimension() != m_LoadedAlgorithm->getMovingDimensions()) { m_Controls.m_lbMovingMaskName->setText(QString("wrong image dimension. ") + QString::number(m_LoadedAlgorithm->getMovingDimensions()) + QString("D needed")); } else { m_spSelectedMovingMaskData = movingMaskImage; validMovingMask = true; } } else { m_Controls.m_lbMovingMaskName->setText( QString("no supported data selected!")); } nodes.removeFirst(); } } else { m_Controls.m_lbMovingMaskName->setText(QString("mask deactivated")); validMovingMask = true; m_spSelectedMovingMaskNode = NULL; m_spSelectedMovingMaskData = NULL; } if (m_Controls.checkTargetMask->isChecked()) { if (nodes.count() < 1) { m_Controls.m_lbTargetMaskName->setText(QString("no data selected!")); m_spSelectedTargetMaskNode = NULL; m_spSelectedTargetMaskData = NULL; } else { m_spSelectedTargetMaskNode = nodes.front(); m_spSelectedTargetMaskData = NULL; targetMaskImage = dynamic_cast(m_spSelectedTargetMaskNode->GetData()); - bool isMask = false; - m_spSelectedTargetMaskNode->GetBoolProperty("binary", isMask); + + bool isMask = maskPredicate->CheckNode(m_spSelectedTargetMaskNode); if (!isMask) { m_Controls.m_lbTargetMaskName->setText(QString("no mask selected!")); } else if (targetMaskImage && pMaskInterface) { if (targetMaskImage->GetDimension() - 1 == m_LoadedAlgorithm->getTargetDimensions() && targetMaskImage->GetTimeSteps() > 1) { //images has multiple time steps and a time step has the correct dimensionality mitk::ImageTimeSelector::Pointer imageTimeSelector = mitk::ImageTimeSelector::New(); imageTimeSelector->SetInput(targetMaskImage); imageTimeSelector->SetTimeNr(0); imageTimeSelector->UpdateLargestPossibleRegion(); m_spSelectedTargetMaskData = imageTimeSelector->GetOutput(); validTargetMask = true; m_Controls.m_teLog->append( QString("Selected target mask has multiple time steps. First time step is used as target mask.")); } else if (targetMaskImage->GetDimension() != m_LoadedAlgorithm->getTargetDimensions()) { m_Controls.m_lbTargetMaskName->setText(QString("wrong image dimension. ") + QString::number(m_LoadedAlgorithm->getTargetDimensions()) + QString("D needed")); } else { m_spSelectedTargetMaskData = targetMaskImage; validTargetMask = true; } } else { m_Controls.m_lbTargetMaskName->setText( QString("no supported data selected!")); } } } else { m_Controls.m_lbTargetMaskName->setText(QString("mask deactivated")); validTargetMask = true; m_spSelectedTargetMaskNode = NULL; m_spSelectedTargetMaskData = NULL; } } if (validMoving) { m_Controls.m_lbMovingName->setText(QString::fromStdString(GetInputNodeDisplayName( m_spSelectedMovingNode))); } if (validTarget) { m_Controls.m_lbTargetName->setText(QString::fromStdString(GetInputNodeDisplayName( m_spSelectedTargetNode))); } if (validMovingMask && m_Controls.checkMovingMask->isChecked()) { m_Controls.m_lbMovingMaskName->setText(QString::fromStdString(GetInputNodeDisplayName( m_spSelectedMovingMaskNode))); } if (validTargetMask && m_Controls.checkTargetMask->isChecked()) { m_Controls.m_lbTargetMaskName->setText(QString::fromStdString(GetInputNodeDisplayName( m_spSelectedTargetMaskNode))); } m_ValidInputs = validMoving && validTarget && validMovingMask && validTargetMask; return m_ValidInputs; } std::string QmitkMatchPoint::GetInputNodeDisplayName(const mitk::DataNode* node) const { std::string result = "UNDEFINED/NULL"; if (node) { result = node->GetName(); const mitk::PointSet* pointSet = dynamic_cast(node->GetData()); if (pointSet) { mitk::DataStorage::SetOfObjects::ConstPointer sources = this->GetDataStorage()->GetSources(node); if (sources.IsNotNull() && sources->Size() > 0) { result = result + " (" + sources->GetElement(0)->GetName() + ")"; } } } return result; } mitk::DataStorage::SetOfObjects::Pointer QmitkMatchPoint::GetRegNodes() const { mitk::DataStorage::SetOfObjects::ConstPointer nodes = this->GetDataStorage()->GetAll(); mitk::DataStorage::SetOfObjects::Pointer result = mitk::DataStorage::SetOfObjects::New(); for (mitk::DataStorage::SetOfObjects::const_iterator pos = nodes->begin(); pos != nodes->end(); ++pos) { if (mitk::MITKRegistrationHelper::IsRegNode(*pos)) { result->push_back(*pos); } } return result; } std::string QmitkMatchPoint::GetDefaultRegJobName() const { mitk::DataStorage::SetOfObjects::ConstPointer nodes = this->GetRegNodes().GetPointer(); mitk::DataStorage::SetOfObjects::ElementIdentifier estimatedIndex = nodes->Size(); bool isUnique = false; std::string result = "Unnamed Reg"; while (!isUnique) { ++estimatedIndex; result = "Reg #" +::map::core::convert::toStr(estimatedIndex); isUnique = this->GetDataStorage()->GetNamedNode(result) == NULL; } return result; } void QmitkMatchPoint::ConfigureRegistrationControls() { m_Controls.m_tabSelection->setEnabled(!m_Working); m_Controls.m_leRegJobName->setEnabled(!m_Working); m_Controls.groupMasks->setEnabled(!m_Working); m_Controls.m_pbStartReg->setEnabled(false); m_Controls.m_pbStopReg->setEnabled(false); m_Controls.m_pbStopReg->setVisible(false); m_Controls.m_lbMovingMaskName->setVisible(m_Controls.checkMovingMask->isChecked()); m_Controls.m_lbTargetMaskName->setVisible(m_Controls.checkTargetMask->isChecked()); if (m_LoadedAlgorithm.IsNotNull()) { m_Controls.m_tabSettings->setEnabled(!m_Working); m_Controls.m_tabExecution->setEnabled(true); m_Controls.m_pbStartReg->setEnabled(m_ValidInputs && !m_Working); m_Controls.m_leRegJobName->setEnabled(!m_Working); m_Controls.m_checkMapEntity->setEnabled(!m_Working); m_Controls.m_checkStoreReg->setEnabled(!m_Working); const IStoppableAlgorithm* pIterativ = dynamic_cast (m_LoadedAlgorithm.GetPointer()); if (pIterativ) { m_Controls.m_pbStopReg->setVisible(pIterativ->isStoppable()); } typedef ::map::algorithm::facet::MaskedRegistrationAlgorithmInterface<3, 3> MaskRegInterface; const MaskRegInterface* pMaskReg = dynamic_cast (m_LoadedAlgorithm.GetPointer()); m_Controls.groupMasks->setVisible(pMaskReg != NULL); //if the stop button is set to visible and the algorithm is working -> //then the algorithm is stoppable, thus enable the button. m_Controls.m_pbStopReg->setEnabled(m_Controls.m_pbStopReg->isVisible() && m_Working); this->m_Controls.m_lbLoadedAlgorithmName->setText( QString::fromStdString(m_LoadedAlgorithm->getUID()->toStr())); } else { m_Controls.m_tabSettings->setEnabled(false); m_Controls.m_tabExecution->setEnabled(false); this->m_Controls.m_lbLoadedAlgorithmName->setText( QString("no algorithm loaded!")); m_Controls.groupMasks->setVisible(false); } if (!m_Working) { this->m_Controls.m_leRegJobName->setText(QString::fromStdString(this->GetDefaultRegJobName())); } } void QmitkMatchPoint::ConfigureProgressInfos() { const IIterativeAlgorithm* pIterative = dynamic_cast (m_LoadedAlgorithm.GetPointer()); const IMultiResAlgorithm* pMultiRes = dynamic_cast (m_LoadedAlgorithm.GetPointer()); m_Controls.m_progBarIteration->setVisible(pIterative); m_Controls.m_lbProgBarIteration->setVisible(pIterative); if (pIterative) { QString format = "%p% (%v/%m)"; if (!pIterative->hasMaxIterationCount()) { format = "%v"; m_Controls.m_progBarIteration->setMaximum(0); } else { m_Controls.m_progBarIteration->setMaximum(pIterative->getMaxIterations()); } m_Controls.m_progBarIteration->setFormat(format); } if (pMultiRes) { m_Controls.m_progBarLevel->setMaximum(pMultiRes->getResolutionLevels()); } else { m_Controls.m_progBarLevel->setMaximum(1); } m_Controls.m_progBarIteration->reset(); m_Controls.m_progBarLevel->reset(); } void QmitkMatchPoint::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*source*/, const QList& nodes) { if (!m_Working) { CheckInputs(); ConfigureRegistrationControls(); } } void QmitkMatchPoint::OnStartRegBtnPushed() { this->m_Working = true; //////////////////////////////// //configure GUI this->ConfigureProgressInfos(); m_Controls.m_progBarIteration->reset(); m_Controls.m_progBarLevel->reset(); this->ConfigureRegistrationControls(); if (m_Controls.m_checkClearLog->checkState() == Qt::Checked) { this->m_Controls.m_teLog->clear(); } ///////////////////////// //create job and put it into the thread pool QmitkRegistrationJob* pJob = new QmitkRegistrationJob(m_LoadedAlgorithm); pJob->setAutoDelete(true); pJob->m_spTargetData = m_spSelectedTargetData; pJob->m_spMovingData = m_spSelectedMovingData; pJob->m_TargetNodeUID = mitk::EnsureUID(this->m_spSelectedTargetNode); pJob->m_MovingNodeUID = mitk::EnsureUID(this->m_spSelectedMovingNode); if (m_spSelectedTargetMaskData.IsNotNull()) { pJob->m_spTargetMask = m_spSelectedTargetMaskData; pJob->m_TargetMaskNodeUID = mitk::EnsureUID(this->m_spSelectedTargetMaskNode); } if (m_spSelectedMovingMaskData.IsNotNull()) { pJob->m_spMovingMask = m_spSelectedMovingMaskData; pJob->m_MovingMaskNodeUID = mitk::EnsureUID(this->m_spSelectedMovingMaskNode); } pJob->m_JobName = m_Controls.m_leRegJobName->text().toStdString(); pJob->m_StoreReg = m_Controls.m_checkStoreReg->checkState() == Qt::Checked; connect(pJob, SIGNAL(Error(QString)), this, SLOT(OnRegJobError(QString))); connect(pJob, SIGNAL(Finished()), this, SLOT(OnRegJobFinished())); connect(pJob, SIGNAL(RegResultIsAvailable(mitk::MAPRegistrationWrapper::Pointer, const QmitkRegistrationJob*)), this, SLOT(OnRegResultIsAvailable(mitk::MAPRegistrationWrapper::Pointer, const QmitkRegistrationJob*)), Qt::BlockingQueuedConnection); connect(pJob, SIGNAL(MapResultNodeIsAvailable(mitk::BaseData::Pointer, const QmitkMappingJob*)), this, SLOT(OnMapResultIsAvailable(mitk::BaseData::Pointer, const QmitkMappingJob*)), Qt::BlockingQueuedConnection); connect(pJob, SIGNAL(AlgorithmInfo(QString)), this, SLOT(OnAlgorithmInfo(QString))); connect(pJob, SIGNAL(AlgorithmStatusChanged(QString)), this, SLOT(OnAlgorithmStatusChanged(QString))); connect(pJob, SIGNAL(AlgorithmIterated(QString, bool, unsigned long)), this, SLOT(OnAlgorithmIterated(QString, bool, unsigned long))); connect(pJob, SIGNAL(LevelChanged(QString, bool, unsigned long)), this, SLOT(OnLevelChanged(QString, bool, unsigned long))); QThreadPool* threadPool = QThreadPool::globalInstance(); threadPool->start(pJob); } void QmitkMatchPoint::OnStopRegBtnPushed() { if (m_LoadedAlgorithm.IsNotNull()) { IStoppableAlgorithm* pIterativ = dynamic_cast(m_LoadedAlgorithm.GetPointer()); if (pIterativ && pIterativ->isStoppable()) { if (pIterativ->stopAlgorithm()) { } else { } m_Controls.m_pbStopReg->setEnabled(false); } else { } } } void QmitkMatchPoint::OnSaveLogBtnPushed() { QDateTime currentTime = QDateTime::currentDateTime(); QString fileName = tr("registration_log_") + currentTime.toString(tr("yyyy-MM-dd_hh-mm-ss")) + tr(".txt"); fileName = QFileDialog::getSaveFileName(NULL, tr("Save registration log"), fileName, tr("Text files (*.txt)")); if (fileName.isEmpty()) { QMessageBox::critical(NULL, tr("No file selected!"), tr("Cannot save registration log file. Please selected a file.")); } else { std::ofstream file; std::ios_base::openmode iOpenFlag = std::ios_base::out | std::ios_base::trunc; file.open(fileName.toStdString().c_str(), iOpenFlag); if (!file.is_open()) { mitkThrow() << "Cannot open or create specified file to save. File path: " << fileName.toStdString(); } file << this->m_Controls.m_teLog->toPlainText().toStdString() << std::endl; file.close(); } } void QmitkMatchPoint::OnRegJobError(QString err) { Error(err); }; void QmitkMatchPoint::OnRegJobFinished() { this->m_Working = false; this->GetRenderWindowPart()->RequestUpdate(); this->CheckInputs(); this->ConfigureRegistrationControls(); this->ConfigureProgressInfos(); }; void QmitkMatchPoint::OnRegResultIsAvailable(mitk::MAPRegistrationWrapper::Pointer spResultRegistration, const QmitkRegistrationJob* pRegJob) { mitk::DataNode::Pointer spResultRegistrationNode = mitk::generateRegistrationResultNode( pRegJob->m_JobName, spResultRegistration, pRegJob->GetLoadedAlgorithm()->getUID()->toStr(), pRegJob->m_MovingNodeUID, pRegJob->m_TargetNodeUID); if (pRegJob->m_StoreReg) { m_Controls.m_teLog->append( QString(" Storing registration object in data manager ... ")); this->GetDataStorage()->Add(spResultRegistrationNode); this->GetRenderWindowPart()->RequestUpdate(); } if (m_Controls.m_checkMapEntity->checkState() == Qt::Checked) { QmitkMappingJob* pMapJob = new QmitkMappingJob(); pMapJob->setAutoDelete(true); pMapJob->m_spInputData = pRegJob->m_spMovingData; pMapJob->m_InputNodeUID = pRegJob->m_MovingNodeUID; pMapJob->m_spRegNode = spResultRegistrationNode; pMapJob->m_doGeometryRefinement = false; pMapJob->m_spRefGeometry = pRegJob->m_spTargetData->GetGeometry()->Clone().GetPointer(); pMapJob->m_MappedName = pRegJob->m_JobName + std::string(" mapped moving data"); pMapJob->m_allowUndefPixels = true; pMapJob->m_paddingValue = 100; pMapJob->m_allowUnregPixels = true; pMapJob->m_errorValue = 200; pMapJob->m_InterpolatorLabel = "Linear Interpolation"; pMapJob->m_InterpolatorType = mitk::ImageMappingInterpolator::Linear; connect(pMapJob, SIGNAL(Error(QString)), this, SLOT(OnMapJobError(QString))); connect(pMapJob, SIGNAL(MapResultIsAvailable(mitk::BaseData::Pointer, const QmitkMappingJob*)), this, SLOT(OnMapResultIsAvailable(mitk::BaseData::Pointer, const QmitkMappingJob*)), Qt::BlockingQueuedConnection); connect(pMapJob, SIGNAL(AlgorithmInfo(QString)), this, SLOT(OnAlgorithmInfo(QString))); m_Controls.m_teLog->append( QString("Started mapping input data...")); QThreadPool* threadPool = QThreadPool::globalInstance(); threadPool->start(pMapJob); } }; void QmitkMatchPoint::OnMapJobError(QString err) { Error(err); }; void QmitkMatchPoint::OnMapResultIsAvailable(mitk::BaseData::Pointer spMappedData, const QmitkMappingJob* job) { m_Controls.m_teLog->append(QString("Mapped entity stored. Name: ") + QString::fromStdString(job->m_MappedName) + QString("")); mitk::DataNode::Pointer spMappedNode = mitk::generateMappedResultNode(job->m_MappedName, spMappedData, job->GetRegistration()->getRegistrationUID(), job->m_InputNodeUID, job->m_doGeometryRefinement, job->m_InterpolatorLabel); this->GetDataStorage()->Add(spMappedNode); this->GetRenderWindowPart()->RequestUpdate(); }; void QmitkMatchPoint::OnAlgorithmIterated(QString info, bool hasIterationCount, unsigned long currentIteration) { if (hasIterationCount) { m_Controls.m_progBarIteration->setValue(currentIteration); } m_Controls.m_teLog->append(info); }; void QmitkMatchPoint::OnLevelChanged(QString info, bool hasLevelCount, unsigned long currentLevel) { if (hasLevelCount) { m_Controls.m_progBarLevel->setValue(currentLevel); } m_Controls.m_teLog->append(QString("") + info + QString("")); }; void QmitkMatchPoint::OnAlgorithmStatusChanged(QString info) { m_Controls.m_teLog->append(QString("") + info + QString(" ")); }; void QmitkMatchPoint::OnAlgorithmInfo(QString info) { m_Controls.m_teLog->append(QString("") + info + QString("")); }; void QmitkMatchPoint::OnAlgorithmSelectionChanged(const berry::IWorkbenchPart::Pointer& sourcepart, const berry::ISelection::ConstPointer& selection) { // check for null selection if (selection.IsNull()) { return; } if (sourcepart != this) { UpdateAlgorithmSelection(selection); } } void QmitkMatchPoint::UpdateAlgorithmSelection(berry::ISelection::ConstPointer selection) { mitk::MAPAlgorithmInfoSelection::ConstPointer currentSelection = selection.Cast(); if (currentSelection) { mitk::MAPAlgorithmInfoSelection::AlgorithmInfoVectorType infoVector = currentSelection->GetSelectedAlgorithmInfo(); if (!infoVector.empty()) { // only the first selection is of interest, the rest will be skipped. this->m_SelectedAlgorithmInfo = infoVector[0]; } } this->OnSelectedAlgorithmChanged(); }; diff --git a/Plugins/org.mitk.gui.qt.matchpoint.framereg/src/internal/QmitkMatchPointFrameCorrection.cpp b/Plugins/org.mitk.gui.qt.matchpoint.framereg/src/internal/QmitkMatchPointFrameCorrection.cpp index 36f9ae9635..680480ae60 100644 --- a/Plugins/org.mitk.gui.qt.matchpoint.framereg/src/internal/QmitkMatchPointFrameCorrection.cpp +++ b/Plugins/org.mitk.gui.qt.matchpoint.framereg/src/internal/QmitkMatchPointFrameCorrection.cpp @@ -1,811 +1,820 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "org_mitk_gui_qt_matchpoint_framereg_Activator.h" // Blueberry #include #include #include #include // Mitk #include #include #include +#include +#include +#include +#include +#include +#include +#include // Qmitk #include "QmitkMatchPointFrameCorrection.h" +#include +#include // Qt #include #include #include #include #include // MatchPoint #include #include #include #include #include #include #include #include #include -// Map4CTK -#include -#include -#include -#include -#include - const std::string QmitkMatchPointFrameCorrection::VIEW_ID = "org.mitk.views.matchpoint.algorithm.framereg"; QmitkMatchPointFrameCorrection::QmitkMatchPointFrameCorrection() : m_Parent(NULL), m_LoadedDLLHandle(NULL), m_LoadedAlgorithm(NULL), m_CanLoadAlgorithm(false), m_ValidInputs(false), m_Working(false) { m_spSelectedTargetData = NULL; m_spSelectedTargetMaskData = NULL; } QmitkMatchPointFrameCorrection::~QmitkMatchPointFrameCorrection() { // remove selection service berry::ISelectionService* s = this->GetSite()->GetWorkbenchWindow()->GetSelectionService(); if (s) { s->RemoveSelectionListener(m_AlgorithmSelectionListener.data()); } } void QmitkMatchPointFrameCorrection::SetFocus() { } void QmitkMatchPointFrameCorrection::CreateConnections() { connect(m_Controls.checkTargetMask, SIGNAL(toggled(bool)), this, SLOT(OnMaskCheckBoxToggeled(bool))); // ------ // Tab 1 - Shared library loading interface // ------ connect(m_Controls.m_pbLoadSelected, SIGNAL(clicked()), this, SLOT(OnLoadAlgorithmButtonPushed())); // ----- // Tab 2 - Execution // ----- connect(m_Controls.m_pbStartReg, SIGNAL(clicked()), this, SLOT(OnStartRegBtnPushed())); connect(m_Controls.m_pbSaveLog, SIGNAL(clicked()), this, SLOT(OnSaveLogBtnPushed())); // ----- // Tab 4 - Frames // ----- connect(m_Controls.m_btnFrameSelAll, SIGNAL(clicked()), this, SLOT(OnFramesSelectAllPushed())); connect(m_Controls.m_btnFrameDeSelAll, SIGNAL(clicked()), this, SLOT(OnFramesDeSelectAllPushed())); connect(m_Controls.m_btnFrameInvert, SIGNAL(clicked()), this, SLOT(OnFramesInvertPushed())); } const map::deployment::DLLInfo* QmitkMatchPointFrameCorrection::GetSelectedAlgorithmDLL() const { return m_SelectedAlgorithmInfo; } void QmitkMatchPointFrameCorrection::OnMaskCheckBoxToggeled(bool checked) { if (!m_Working) { CheckInputs(); ConfigureRegistrationControls(); } }; void QmitkMatchPointFrameCorrection::OnSelectedAlgorithmChanged() { std::stringstream descriptionString; ::map::deployment::DLLInfo::ConstPointer currentItemInfo = GetSelectedAlgorithmDLL(); if (!currentItemInfo) { return; } m_Controls.m_teAlgorithmDetails->updateInfo(currentItemInfo); m_Controls.m_lbSelectedAlgorithm->setText(QString::fromStdString( currentItemInfo->getAlgorithmUID().getName())); // enable loading m_CanLoadAlgorithm = true; this->AdaptFolderGUIElements(); } void QmitkMatchPointFrameCorrection::OnLoadAlgorithmButtonPushed() { map::deployment::DLLInfo::ConstPointer dllInfo = GetSelectedAlgorithmDLL(); if (!dllInfo) { Error(QString("No valid algorithm is selected. Cannot load algorithm. ABORTING.")); return; } ::map::deployment::DLLHandle::Pointer tempDLLHandle = ::map::deployment::openDeploymentDLL( dllInfo->getLibraryFilePath()); ::map::algorithm::RegistrationAlgorithmBase::Pointer tempAlgorithm = ::map::deployment::getRegistrationAlgorithm(tempDLLHandle); if (tempAlgorithm.IsNull()) { Error(QString("Error. Cannot load selected algorithm.")); return; } this->m_LoadedAlgorithm = tempAlgorithm; this->m_LoadedDLLHandle = tempDLLHandle; this->m_Controls.m_AlgoConfigurator->setAlgorithm(m_LoadedAlgorithm); m_Controls.checkTargetMask->setChecked(false); this->AdaptFolderGUIElements(); this->CheckInputs(); this->ConfigureRegistrationControls(); this->ConfigureProgressInfos(); this->m_Controls.m_tabs->setCurrentIndex(1); } void QmitkMatchPointFrameCorrection::Error(QString msg) { mitk::StatusBar::GetInstance()->DisplayErrorText(msg.toLatin1()); MITK_ERROR << msg.toStdString().c_str(); m_Controls.m_teLog->append(QString("") + msg + QString("")); } void QmitkMatchPointFrameCorrection::AdaptFolderGUIElements() { m_Controls.m_pbLoadSelected->setEnabled(m_CanLoadAlgorithm); } void QmitkMatchPointFrameCorrection::CreateQtPartControl(QWidget* parent) { // create GUI widgets from the Qt Designer's .ui file m_Controls.setupUi(parent); m_Parent = parent; m_Controls.checkTargetMask->setChecked(false); m_Controls.m_tabs->setCurrentIndex(0); m_Controls.m_mapperSettings->AllowSampling(false); m_AlgorithmSelectionListener.reset(new berry::SelectionChangedAdapter(this, &QmitkMatchPointFrameCorrection::OnAlgorithmSelectionChanged)); // register selection listener GetSite()->GetWorkbenchWindow()->GetSelectionService()->AddSelectionListener( m_AlgorithmSelectionListener.data()); this->CreateConnections(); this->AdaptFolderGUIElements(); this->CheckInputs(); this->ConfigureProgressInfos(); this->ConfigureRegistrationControls(); berry::ISelection::ConstPointer selection = GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection("org.mitk.views.matchpoint.algorithm.browser"); this->UpdateAlgorithmSelection(selection); } bool QmitkMatchPointFrameCorrection::CheckInputs() { bool validTarget = false; bool validTargetMask = false; mitk::DataNode::Pointer oldTargetNode = m_spSelectedTargetNode; + mitk::NodePredicateDataType::Pointer isLabelSet = mitk::NodePredicateDataType::New("LabelSetImage"); + mitk::NodePredicateDataType::Pointer isImage = mitk::NodePredicateDataType::New("Image"); + mitk::NodePredicateProperty::Pointer isBinary = mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true)); + mitk::NodePredicateAnd::Pointer isLegacyMask = mitk::NodePredicateAnd::New(isImage, isBinary); + + mitk::NodePredicateOr::Pointer maskPredicate = mitk::NodePredicateOr::New(isLegacyMask, isLabelSet); + if (m_LoadedAlgorithm.IsNull()) { m_Controls.m_lbLoadedAlgorithmName->setText( QString("No algorithm seleted!")); m_spSelectedTargetNode = NULL; m_spSelectedTargetData = NULL; m_spSelectedTargetMaskNode = NULL; m_spSelectedTargetMaskData = NULL; } else { QList nodes = this->GetDataManagerSelection(); mitk::Image* targetImage = NULL; mitk::PointSet* targetPointSet = NULL; mitk::Image* targetMaskImage = NULL; typedef ::map::algorithm::facet::MaskedRegistrationAlgorithmInterface<3, 3> MaskRegInterface; MaskRegInterface* pMaskInterface = dynamic_cast(m_LoadedAlgorithm.GetPointer()); if (nodes.count() < 1) { m_Controls.m_lbTargetName->setText(QString("no data selected!")); m_spSelectedTargetNode = NULL; m_spSelectedTargetData = NULL; } else { m_spSelectedTargetNode = nodes.front(); m_spSelectedTargetData = m_spSelectedTargetNode->GetData(); targetImage = dynamic_cast(m_spSelectedTargetNode->GetData()); if (targetImage) { if (targetImage->GetTimeSteps() < 1) { m_Controls.m_lbTargetName->setText(QString("Image has no mulitple time steps")); } else if (targetImage->GetDimension() != m_LoadedAlgorithm->getTargetDimensions() + 1) { m_Controls.m_lbTargetName->setText(QString("wrong image dimension. ") + QString::number(m_LoadedAlgorithm->getTargetDimensions()) + QString("D+t needed")); } else { validTarget = true; } } else { m_Controls.m_lbTargetName->setText(QString("no supported data selected!")); } nodes.removeFirst(); } if (m_Controls.checkTargetMask->isChecked()) { if (nodes.count() < 1) { m_Controls.m_lbTargetMaskName->setText(QString("no data selected!")); m_spSelectedTargetMaskNode = NULL; m_spSelectedTargetMaskData = NULL; } else { m_spSelectedTargetMaskNode = nodes.front(); m_spSelectedTargetMaskData = NULL; targetMaskImage = dynamic_cast(m_spSelectedTargetMaskNode->GetData()); - bool isMask = false; - m_spSelectedTargetMaskNode->GetBoolProperty("binary", isMask); + + bool isMask = maskPredicate->CheckNode(m_spSelectedTargetMaskNode); if (!isMask) { m_Controls.m_lbTargetMaskName->setText(QString("no mask selected!")); } else if (targetMaskImage && pMaskInterface) { m_spSelectedTargetMaskData = targetMaskImage; validTargetMask = true; } else { m_Controls.m_lbTargetMaskName->setText( QString("no supported data selected!")); } } } else { m_Controls.m_lbTargetMaskName->setText(QString("mask deactivated")); validTargetMask = true; m_spSelectedTargetMaskNode = NULL; m_spSelectedTargetMaskData = NULL; } } if (validTarget) { m_Controls.m_lbTargetName->setText(QString::fromStdString(GetInputNodeDisplayName( m_spSelectedTargetNode))); if (oldTargetNode != m_spSelectedTargetNode) { ConfigureFrameList(); } } else { m_Controls.m_listFrames->clear(); } if (validTargetMask && m_Controls.checkTargetMask->isChecked()) { m_Controls.m_lbTargetMaskName->setText(QString::fromStdString(GetInputNodeDisplayName( m_spSelectedTargetMaskNode))); } m_ValidInputs = validTarget && validTargetMask; return m_ValidInputs; } std::string QmitkMatchPointFrameCorrection::GetInputNodeDisplayName(const mitk::DataNode* node) const { std::string result = "UNDEFINED/NULL"; if (node) { result = node->GetName(); const mitk::PointSet* pointSet = dynamic_cast(node->GetData()); if (pointSet) { mitk::DataStorage::SetOfObjects::ConstPointer sources = this->GetDataStorage()->GetSources(node); if (sources.IsNotNull() && sources->Size() > 0) { result = result + " (" + sources->GetElement(0)->GetName() + ")"; } } } return result; } mitk::DataStorage::SetOfObjects::Pointer QmitkMatchPointFrameCorrection::GetRegNodes() const { mitk::DataStorage::SetOfObjects::ConstPointer nodes = this->GetDataStorage()->GetAll(); mitk::DataStorage::SetOfObjects::Pointer result = mitk::DataStorage::SetOfObjects::New(); for (mitk::DataStorage::SetOfObjects::const_iterator pos = nodes->begin(); pos != nodes->end(); ++pos) { if (mitk::MITKRegistrationHelper::IsRegNode(*pos)) { result->push_back(*pos); } } return result; } std::string QmitkMatchPointFrameCorrection::GetDefaultJobName() const { mitk::DataStorage::SetOfObjects::ConstPointer nodes = this->GetRegNodes().GetPointer(); mitk::DataStorage::SetOfObjects::ElementIdentifier newIndex = 0; bool isUnique = false; std::string baseName = "corrected #"; if (m_spSelectedTargetNode.IsNotNull()) { baseName = m_spSelectedTargetNode->GetName() + "corrected #"; } std::string result = baseName; while (!isUnique) { ++newIndex; result = baseName + ::map::core::convert::toStr(newIndex); isUnique = this->GetDataStorage()->GetNamedNode(result) == NULL; } return result; } void QmitkMatchPointFrameCorrection::ConfigureRegistrationControls() { m_Controls.m_tabSelection->setEnabled(!m_Working); m_Controls.m_leRegJobName->setEnabled(!m_Working); m_Controls.groupMasks->setEnabled(!m_Working); m_Controls.m_pbStartReg->setEnabled(false); m_Controls.m_lbTargetMaskName->setVisible(m_Controls.checkTargetMask->isChecked()); if (m_LoadedAlgorithm.IsNotNull()) { m_Controls.m_tabSettings->setEnabled(!m_Working); m_Controls.m_tabExclusion->setEnabled(!m_Working); m_Controls.m_tabExecution->setEnabled(true); m_Controls.m_pbStartReg->setEnabled(m_ValidInputs && !m_Working); m_Controls.m_leRegJobName->setEnabled(!m_Working); typedef ::map::algorithm::facet::MaskedRegistrationAlgorithmInterface<3, 3> MaskRegInterface; const MaskRegInterface* pMaskReg = dynamic_cast (m_LoadedAlgorithm.GetPointer()); m_Controls.groupMasks->setVisible(pMaskReg != NULL); this->m_Controls.m_lbLoadedAlgorithmName->setText( QString::fromStdString(m_LoadedAlgorithm->getUID()->toStr())); } else { m_Controls.m_tabSettings->setEnabled(false); m_Controls.m_tabExclusion->setEnabled(false); m_Controls.m_tabExecution->setEnabled(false); this->m_Controls.m_lbLoadedAlgorithmName->setText( QString("no algorithm loaded!")); m_Controls.groupMasks->setVisible(false); } if (!m_Working) { this->m_Controls.m_leRegJobName->setText(QString::fromStdString(this->GetDefaultJobName())); } } void QmitkMatchPointFrameCorrection::ConfigureProgressInfos() { const IIterativeAlgorithm* pIterative = dynamic_cast (m_LoadedAlgorithm.GetPointer()); const IMultiResAlgorithm* pMultiRes = dynamic_cast (m_LoadedAlgorithm.GetPointer()); m_Controls.m_progBarIteration->setVisible(pIterative); m_Controls.m_lbProgBarIteration->setVisible(pIterative); if (pIterative) { QString format = "%p% (%v/%m)"; if (!pIterative->hasMaxIterationCount()) { format = "%v"; m_Controls.m_progBarIteration->setMaximum(0); } else { m_Controls.m_progBarIteration->setMaximum(pIterative->getMaxIterations()); } m_Controls.m_progBarIteration->setFormat(format); } if (pMultiRes) { m_Controls.m_progBarLevel->setMaximum(pMultiRes->getResolutionLevels()); } else { m_Controls.m_progBarLevel->setMaximum(1); } m_Controls.m_progBarIteration->reset(); m_Controls.m_progBarLevel->reset(); m_Controls.m_progBarFrame->reset(); } void QmitkMatchPointFrameCorrection::ConfigureFrameList() { m_Controls.m_listFrames->clear(); if (m_spSelectedTargetData.IsNotNull()) { mitk::TimeGeometry::ConstPointer tg = m_spSelectedTargetData->GetTimeGeometry(); for (unsigned int i = 1; i < tg->CountTimeSteps(); ++i) { QString lable = "Timepoint #" + QString::number(i) + QString(" (") + QString::number( tg->GetMinimumTimePoint(i)) + QString(" ms - " + QString::number(tg->GetMaximumTimePoint( i)) + QString(" ms)")); QListWidgetItem* item = new QListWidgetItem(lable, m_Controls.m_listFrames); item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); item->setCheckState(Qt::Checked); } } } void QmitkMatchPointFrameCorrection::OnFramesSelectAllPushed() { for (unsigned int row = 0; row < m_Controls.m_listFrames->count(); row++) { QListWidgetItem* item = m_Controls.m_listFrames->item(row); item->setCheckState(Qt::Checked); } }; void QmitkMatchPointFrameCorrection::OnFramesDeSelectAllPushed() { for (unsigned int row = 0; row < m_Controls.m_listFrames->count(); row++) { QListWidgetItem* item = m_Controls.m_listFrames->item(row); item->setCheckState(Qt::Unchecked); } }; void QmitkMatchPointFrameCorrection::OnFramesInvertPushed() { for (unsigned int row = 0; row < m_Controls.m_listFrames->count(); row++) { QListWidgetItem* item = m_Controls.m_listFrames->item(row); if (item->checkState() == Qt::Unchecked) { item->setCheckState(Qt::Checked); } else { item->setCheckState(Qt::Unchecked); } } }; mitk::TimeFramesRegistrationHelper::IgnoreListType QmitkMatchPointFrameCorrection::GenerateIgnoreList() const { mitk::TimeFramesRegistrationHelper::IgnoreListType result; for (unsigned int row = 0; row < m_Controls.m_listFrames->count(); row++) { QListWidgetItem* item = m_Controls.m_listFrames->item(row); if (item->checkState() == Qt::Unchecked) { result.push_back(row + 1); } } return result; } void QmitkMatchPointFrameCorrection::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*source*/, const QList& nodes) { if (!m_Working) { CheckInputs(); ConfigureRegistrationControls(); } } void QmitkMatchPointFrameCorrection::OnStartRegBtnPushed() { this->m_Working = true; //////////////////////////////// //configure GUI this->ConfigureProgressInfos(); m_Controls.m_progBarIteration->reset(); m_Controls.m_progBarLevel->reset(); this->ConfigureRegistrationControls(); if (m_Controls.m_checkClearLog->checkState() == Qt::Checked) { this->m_Controls.m_teLog->clear(); } ///////////////////////// //create job and put it into the thread pool QmitkFramesRegistrationJob* pJob = new QmitkFramesRegistrationJob(m_LoadedAlgorithm); pJob->setAutoDelete(true); pJob->m_spTargetData = m_spSelectedTargetData; pJob->m_TargetNodeUID = mitk::EnsureUID(this->m_spSelectedTargetNode); pJob->m_IgnoreList = this->GenerateIgnoreList(); if (m_spSelectedTargetMaskData.IsNotNull()) { pJob->m_spTargetMask = m_spSelectedTargetMaskData; pJob->m_TargetMaskNodeUID = mitk::EnsureUID(this->m_spSelectedTargetMaskNode); } pJob->m_MappedName = m_Controls.m_leRegJobName->text().toStdString(); m_Controls.m_mapperSettings->ConfigureJobSettings(pJob); connect(pJob, SIGNAL(Error(QString)), this, SLOT(OnRegJobError(QString))); connect(pJob, SIGNAL(Finished()), this, SLOT(OnRegJobFinished())); connect(pJob, SIGNAL(ResultIsAvailable(mitk::Image::Pointer, const QmitkFramesRegistrationJob*)), this, SLOT(OnMapResultIsAvailable(mitk::Image::Pointer, const QmitkFramesRegistrationJob*)), Qt::BlockingQueuedConnection); connect(pJob, SIGNAL(AlgorithmInfo(QString)), this, SLOT(OnAlgorithmInfo(QString))); connect(pJob, SIGNAL(AlgorithmStatusChanged(QString)), this, SLOT(OnAlgorithmStatusChanged(QString))); connect(pJob, SIGNAL(AlgorithmIterated(QString, bool, unsigned long)), this, SLOT(OnAlgorithmIterated(QString, bool, unsigned long))); connect(pJob, SIGNAL(LevelChanged(QString, bool, unsigned long)), this, SLOT(OnLevelChanged(QString, bool, unsigned long))); connect(pJob, SIGNAL(FrameRegistered(double)), this, SLOT(OnFrameRegistered(double))); connect(pJob, SIGNAL(FrameMapped(double)), this, SLOT(OnFrameMapped(double))); connect(pJob, SIGNAL(FrameProcessed(double)), this, SLOT(OnFrameProcessed(double))); QThreadPool* threadPool = QThreadPool::globalInstance(); threadPool->start(pJob); } void QmitkMatchPointFrameCorrection::OnSaveLogBtnPushed() { QDateTime currentTime = QDateTime::currentDateTime(); QString fileName = tr("registration_log_") + currentTime.toString(tr("yyyy-MM-dd_hh-mm-ss")) + tr(".txt"); fileName = QFileDialog::getSaveFileName(NULL, tr("Save registration log"), fileName, tr("Text files (*.txt)")); if (fileName.isEmpty()) { QMessageBox::critical(NULL, tr("No file selected!"), tr("Cannot save registration log file. Please selected a file.")); } else { std::ofstream file; std::ios_base::openmode iOpenFlag = std::ios_base::out | std::ios_base::trunc; file.open(fileName.toStdString().c_str(), iOpenFlag); if (!file.is_open()) { mitkThrow() << "Cannot open or create specified file to save. File path: " << fileName.toStdString(); } file << this->m_Controls.m_teLog->toPlainText().toStdString() << std::endl; file.close(); } } void QmitkMatchPointFrameCorrection::OnRegJobError(QString err) { Error(err); }; void QmitkMatchPointFrameCorrection::OnRegJobFinished() { this->m_Working = false; this->GetRenderWindowPart()->RequestUpdate(); this->CheckInputs(); this->ConfigureRegistrationControls(); this->ConfigureProgressInfos(); }; void QmitkMatchPointFrameCorrection::OnMapResultIsAvailable(mitk::Image::Pointer spMappedData, const QmitkFramesRegistrationJob* job) { m_Controls.m_teLog->append(QString("Corrected image stored. Name: ") + QString::fromStdString(job->m_MappedName) + QString("")); mitk::DataNode::Pointer spResultNode = mitk::generateMappedResultNode(job->m_MappedName, spMappedData.GetPointer(), "", job->m_TargetNodeUID, false, job->m_InterpolatorLabel); this->GetDataStorage()->Add(spResultNode, this->m_spSelectedTargetNode); this->GetRenderWindowPart()->RequestUpdate(); }; void QmitkMatchPointFrameCorrection::OnMapJobError(QString err) { Error(err); }; void QmitkMatchPointFrameCorrection::OnAlgorithmIterated(QString info, bool hasIterationCount, unsigned long currentIteration) { if (hasIterationCount) { m_Controls.m_progBarIteration->setValue(currentIteration); } m_Controls.m_teLog->append(info); }; void QmitkMatchPointFrameCorrection::OnLevelChanged(QString info, bool hasLevelCount, unsigned long currentLevel) { if (hasLevelCount) { m_Controls.m_progBarLevel->setValue(currentLevel); } m_Controls.m_teLog->append(QString("") + info + QString("")); }; void QmitkMatchPointFrameCorrection::OnAlgorithmStatusChanged(QString info) { m_Controls.m_teLog->append(QString("") + info + QString(" ")); }; void QmitkMatchPointFrameCorrection::OnAlgorithmInfo(QString info) { m_Controls.m_teLog->append(QString("") + info + QString("")); }; void QmitkMatchPointFrameCorrection::OnFrameProcessed(double progress) { m_Controls.m_teLog->append(QString("Frame processed...")); m_Controls.m_progBarFrame->setValue(100 * progress); }; void QmitkMatchPointFrameCorrection::OnFrameRegistered(double progress) { m_Controls.m_teLog->append(QString("Frame registered...")); m_Controls.m_progBarFrame->setValue(100 * progress); }; void QmitkMatchPointFrameCorrection::OnFrameMapped(double progress) { m_Controls.m_teLog->append(QString("Frame mapped...")); m_Controls.m_progBarFrame->setValue(100 * progress); }; void QmitkMatchPointFrameCorrection::OnAlgorithmSelectionChanged(const berry::IWorkbenchPart::Pointer& sourcepart, const berry::ISelection::ConstPointer& selection) { // check for null selection if (selection.IsNull()) { return; } if (sourcepart != this) { UpdateAlgorithmSelection(selection); } } void QmitkMatchPointFrameCorrection::UpdateAlgorithmSelection(berry::ISelection::ConstPointer selection) { mitk::MAPAlgorithmInfoSelection::ConstPointer currentSelection = selection.Cast(); if (currentSelection) { mitk::MAPAlgorithmInfoSelection::AlgorithmInfoVectorType infoVector = currentSelection->GetSelectedAlgorithmInfo(); if (!infoVector.empty()) { // only the first selection is of interest, the rest will be skipped. this->m_SelectedAlgorithmInfo = infoVector[0]; } } this->OnSelectedAlgorithmChanged(); }; diff --git a/Plugins/org.mitk.gui.qt.matchpoint.mapper/src/internal/QmitkMatchPointMapper.cpp b/Plugins/org.mitk.gui.qt.matchpoint.mapper/src/internal/QmitkMatchPointMapper.cpp index 31b5779861..34173cde5f 100644 --- a/Plugins/org.mitk.gui.qt.matchpoint.mapper/src/internal/QmitkMatchPointMapper.cpp +++ b/Plugins/org.mitk.gui.qt.matchpoint.mapper/src/internal/QmitkMatchPointMapper.cpp @@ -1,673 +1,676 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "org_mitk_gui_qt_matchpoint_mapper_Activator.h" // Blueberry #include #include // Mitk #include #include #include #include "mitkImageMappingHelper.h" #include "mitkMAPRegistrationWrapper.h" #include "mitkMatchPointPropertyTags.h" #include "mitkRegistrationHelper.h" #include #include #include +#include +#include +#include +#include +#include // Qmitk #include "QmitkMatchPointMapper.h" // Qt #include #include #include #include const std::string QmitkMatchPointMapper::VIEW_ID = "org.mitk.views.matchpoint.mapper"; QmitkMatchPointMapper::QmitkMatchPointMapper() : m_Parent(NULL), m_preparedForBinaryInput(false) { } void QmitkMatchPointMapper::SetFocus() { //m_Controls.buttonPerformImageProcessing->setFocus(); } void QmitkMatchPointMapper::CreateConnections() { // show first page m_Controls.m_tabs->setCurrentIndex(0); connect(m_Controls.m_pbLockReg, SIGNAL(clicked()), this, SLOT(OnLockRegButtonPushed())); connect(m_Controls.m_pbLockInput, SIGNAL(clicked()), this, SLOT(OnLockInputButtonPushed())); connect(m_Controls.m_pbLockRef, SIGNAL(clicked()), this, SLOT(OnLockReferenceButtonPushed())); connect(m_Controls.m_cbManualRef, SIGNAL(clicked()), this, SLOT(OnManualRefChecked())); connect(m_Controls.m_cbLinkFactors, SIGNAL(clicked()), this, SLOT(OnLinkSampleFactorChecked())); connect(m_Controls.m_sbXFactor, SIGNAL(valueChanged(double)), this, SLOT(OnXFactorChanged(double))); connect(m_Controls.m_pbMap, SIGNAL(clicked()), this, SLOT(OnMapBtnPushed())); connect(m_Controls.m_pbRefine, SIGNAL(clicked()), this, SLOT(OnRefineBtnPushed())); } void QmitkMatchPointMapper::Error(QString msg) { mitk::StatusBar::GetInstance()->DisplayErrorText(msg.toLatin1()); MITK_ERROR << msg.toStdString().c_str(); m_Controls.m_teLog->append(QString("") + msg + QString("")); } void QmitkMatchPointMapper::CreateQtPartControl(QWidget* parent) { // create GUI widgets from the Qt Designer's .ui file m_Controls.setupUi(parent); m_Parent = parent; this->CreateConnections(); this->CheckInputs(); this->ConfigureProgressInfos(); this->ConfigureMappingControls(); } /** Method checks if the currently selected reg node has a direct kernel that * can be decomposed in a rotation matrix and a offset. If this is true, true * is returned. In all other cases false is returned.*/ bool QmitkMatchPointMapper::IsAbleToRefineGeometry() const { bool result = false; if (this->m_spSelectedRegNode.IsNotNull()) { const mitk::MAPRegistrationWrapper* wrapper = dynamic_cast (this->m_spSelectedRegNode->GetData()); //if the helper does not return null, we can refine the geometry. result = mitk::MITKRegistrationHelper::getAffineMatrix(wrapper, false).IsNotNull(); } return result; } bool QmitkMatchPointMapper::IsBinaryInput() const { - bool result = false; - bool binary = false; + mitk::NodePredicateDataType::Pointer isLabelSet = mitk::NodePredicateDataType::New("LabelSetImage"); + mitk::NodePredicateDataType::Pointer isImage = mitk::NodePredicateDataType::New("Image"); + mitk::NodePredicateProperty::Pointer isBinary = mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true)); + mitk::NodePredicateAnd::Pointer isLegacyMask = mitk::NodePredicateAnd::New(isImage, isBinary); - if (this->m_spSelectedInputNode.IsNotNull()) - { - if (this->m_spSelectedInputNode->GetBoolProperty("binary", binary)) - { - result = binary; - } - } + mitk::NodePredicateOr::Pointer maskPredicate = mitk::NodePredicateOr::New(isLegacyMask, isLabelSet); + + bool result = maskPredicate->CheckNode(this->m_spSelectedInputNode); return result; } bool QmitkMatchPointMapper::IsPointSetInput() const { bool result = false; if (this->m_spSelectedInputNode.IsNotNull()) { result = dynamic_cast(this->m_spSelectedInputNode->GetData()) != NULL; } return result; } mitk::DataNode::Pointer QmitkMatchPointMapper::GetSelectedRegNode() { mitk::DataNode::Pointer spResult = NULL; typedef QList NodeListType; NodeListType nodes = this->GetDataManagerSelection(); for (NodeListType::iterator pos = nodes.begin(); pos != nodes.end(); ++pos) { if (mitk::MITKRegistrationHelper::IsRegNode(*pos)) { spResult = *pos; break; } } return spResult; } QList QmitkMatchPointMapper::GetSelectedDataNodes() { typedef QList NodeListType; NodeListType nodes = this->GetDataManagerSelection(); NodeListType result; for (NodeListType::iterator pos = nodes.begin(); pos != nodes.end(); ++pos) { if (!mitk::MITKRegistrationHelper::IsRegNode(*pos)) { result.push_back(*pos); } } return result; } mitk::DataNode::Pointer QmitkMatchPointMapper::GetAutoRefNodeByReg() { mitk::DataNode::Pointer spResult = NULL; if (this->m_spSelectedRegNode.IsNotNull()) { std::string nodeName; mitk::BaseProperty* uidProp = m_spSelectedRegNode->GetProperty(mitk::nodeProp_RegAlgTargetData); if (uidProp) { //search for the target node mitk::NodePredicateProperty::Pointer predicate = mitk::NodePredicateProperty::New(mitk::nodeProp_UID, uidProp); spResult = this->GetDataStorage()->GetNode(predicate); } } if (spResult.IsNull() && this->m_spSelectedInputNode.IsNotNull()) { //no really reference is available -> use the input as reference spResult = this->m_spSelectedInputNode; m_Controls.m_teLog->append( QString("Cannot determine reference automatically. Use input image as reference.")); } return spResult; } void QmitkMatchPointMapper::CheckInputs() { mitk::DataNode::Pointer regNode = this->GetSelectedRegNode(); QList dataNodes = this->GetSelectedDataNodes(); //first set the internal nodes according to selection if (!m_Controls.m_pbLockReg->isChecked()) { this->m_spSelectedRegNode = regNode; } if (!m_Controls.m_pbLockInput->isChecked()) { mitk::DataNode::Pointer inputNode = NULL; if (dataNodes.size() > 0) { inputNode = dataNodes[0]; } this->m_spSelectedInputNode = inputNode; } if (!(m_Controls.m_cbManualRef->isChecked())) { this->m_spSelectedRefNode = this->GetAutoRefNodeByReg(); } else { if (!m_Controls.m_pbLockRef->isChecked()) { mitk::DataNode::Pointer refNode = NULL; int relevantIndex = 1; if (m_Controls.m_pbLockInput->isChecked()) { //the input is locked thus use the first selected data node relevantIndex = 0; } if (dataNodes.size() > relevantIndex) { refNode = dataNodes[relevantIndex]; } this->m_spSelectedRefNode = refNode; } } //second, check validity of the selected nodes this->CheckNodesValidity(this->m_ValidReg, this->m_ValidInput, this->m_ValidRef); //third, configure widgets if (this->m_spSelectedRegNode.IsNull()) { m_Controls.m_lbRegistrationName->setText( QString("no registration selected!")); } else { if (this->m_ValidReg) { m_Controls.m_lbRegistrationName->setText(QString::fromStdString( this->m_spSelectedRegNode->GetName())); } else { m_Controls.m_lbRegistrationName->setText(QString("") + QString::fromStdString( this->m_spSelectedRegNode->GetName()) + QString("")); } } if (this->m_spSelectedInputNode.IsNull()) { m_Controls.m_lbInputName->setText(QString("no input selected!")); } else { if (this->m_ValidInput) { m_Controls.m_lbInputName->setText(QString::fromStdString(this->m_spSelectedInputNode->GetName())); } else { m_Controls.m_lbInputName->setText(QString("") + QString::fromStdString( this->m_spSelectedInputNode->GetName()) + QString("")); } } if (this->m_spSelectedRefNode.IsNull()) { if (this->m_ValidRef) { m_Controls.m_lbReferenceName->setText(QString("input needs no reference needed")); } else { m_Controls.m_lbReferenceName->setText(QString("no reference selected!")); } } else { if (this->m_ValidRef) { m_Controls.m_lbReferenceName->setText(QString::fromStdString(this->m_spSelectedRefNode->GetName())); if (this->m_spSelectedRefNode->GetData() && this->m_spSelectedRefNode->GetData()->GetTimeSteps() > 1) { m_Controls.m_teLog->append( QString("Selected reference image has multiple time steps. Only geometry of time step 1 is used as reference.")); } } else { m_Controls.m_lbReferenceName->setText(QString("") + QString::fromStdString( this->m_spSelectedRefNode->GetName()) + QString("")); } } this->m_Controls.m_pbLockInput->setEnabled(this->m_spSelectedInputNode.IsNotNull()); this->m_Controls.m_pbLockReg->setEnabled(this->m_spSelectedRegNode.IsNotNull()); this->m_Controls.m_pbLockRef->setEnabled(this->m_spSelectedRefNode.IsNotNull()); } void QmitkMatchPointMapper::CheckNodesValidity(bool& validReg, bool& validInput, bool& validRef) { validReg = this->m_spSelectedRegNode.IsNotNull(); validInput = this->m_spSelectedInputNode.IsNotNull(); validRef = this->m_spSelectedRefNode.IsNotNull(); if (this->m_spSelectedRegNode.IsNotNull()) { if (this->m_spSelectedInputNode.IsNotNull()) { validInput = false; const mitk::MAPRegistrationWrapper* wrapper = dynamic_cast < const mitk::MAPRegistrationWrapper* > (m_spSelectedRegNode->GetData()); mitk::Image* inputImage = dynamic_cast(m_spSelectedInputNode->GetData()); if (inputImage && wrapper) { if (inputImage->GetDimension() - 1 == wrapper->GetMovingDimensions() && inputImage->GetTimeSteps() > 1) { //images has multiple time steps and a time step has the correct dimensionality validInput = true; } if (inputImage->GetDimension() == wrapper->GetMovingDimensions()) { validInput = true; } } if (this->IsPointSetInput() && wrapper) { if (wrapper->GetMovingDimensions() == 3) { validInput = true; } } } if (this->m_spSelectedRefNode.IsNotNull()) { validRef = false; const mitk::MAPRegistrationWrapper* wrapper = dynamic_cast < const mitk::MAPRegistrationWrapper* > (m_spSelectedRegNode->GetData()); mitk::BaseGeometry* geometry = NULL; if (m_spSelectedRefNode->GetData()) { geometry = m_spSelectedRefNode->GetData()->GetGeometry(); } if (geometry && wrapper) { if (wrapper->GetTargetDimensions() == 3) { validRef = true; } else if (wrapper->GetTargetDimensions() == 2) { mitk::BaseGeometry::BoundsArrayType bounds = geometry->GetBounds(); if (bounds[4] != 0 || bounds[5] != 0) { //array "bounds" is constructed as [min Dim1, max Dim1, min Dim2, max Dim2, min Dim3, max Dim3] //therfore [4] and [5] must be 0 validRef = true; } } } } else if (this->IsPointSetInput()) { validRef = true; } } } void QmitkMatchPointMapper::ConfigureMappingControls() { this->m_Controls.m_pbMap->setEnabled(this->m_ValidInput && this->m_ValidRef && (this->m_ValidReg || this->m_spSelectedRegNode.IsNull())); this->m_Controls.m_pbRefine->setEnabled(this->m_ValidInput && this->m_ValidReg && this->IsAbleToRefineGeometry() && !this->IsPointSetInput()); this->m_Controls.m_pbLockRef->setEnabled(this->m_Controls.m_cbManualRef->isChecked()); this->m_Controls.m_lbReferenceName->setEnabled(this->m_Controls.m_cbManualRef->isChecked()); if (this->m_ValidInput && this->m_ValidReg) { this->m_Controls.m_leMappedName->setText(tr("mapped_by_") + QString::fromStdString( m_spSelectedRegNode->GetName())); } else { this->m_Controls.m_leMappedName->setText(tr("mappedData")); } if (this->IsBinaryInput() != this->m_preparedForBinaryInput) { if (this->IsBinaryInput()) { m_Controls.m_teLog->append( QString("Binary input (mask) detected. Preparing for mask mapping (default interpolation: nearest neigbour; padding value: 0)")); this->m_Controls.m_comboInterpolator->setCurrentIndex(0); this->m_Controls.m_sbErrorValue->setValue(0); this->m_Controls.m_sbPaddingValue->setValue(0); } else { this->m_Controls.m_comboInterpolator->setCurrentIndex(1); } this->m_preparedForBinaryInput = this->IsBinaryInput(); } OnLinkSampleFactorChecked(); } void QmitkMatchPointMapper::ConfigureProgressInfos() { } void QmitkMatchPointMapper::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*source*/, const QList& nodes) { this->CheckInputs(); this->ConfigureMappingControls(); } void QmitkMatchPointMapper::OnLockRegButtonPushed() { if (this->m_Controls.m_pbLockReg->isChecked()) { if (this->m_spSelectedRegNode.IsNotNull()) { this->m_spSelectedRegNode->SetSelected(false); this->GetDataStorage()->Modified(); } } this->CheckInputs(); this->ConfigureMappingControls(); } void QmitkMatchPointMapper::OnLockInputButtonPushed() { if (this->m_Controls.m_pbLockInput->isChecked()) { if (this->m_spSelectedInputNode.IsNotNull()) { this->m_spSelectedInputNode->SetSelected(false); this->GetDataStorage()->Modified(); } } this->CheckInputs(); this->ConfigureMappingControls(); } void QmitkMatchPointMapper::OnLockReferenceButtonPushed() { if (this->m_Controls.m_pbLockRef->isChecked()) { if (this->m_spSelectedRefNode.IsNotNull()) { this->m_spSelectedRefNode->SetSelected(false); this->GetDataStorage()->Modified(); } } this->CheckInputs(); this->ConfigureMappingControls(); } void QmitkMatchPointMapper::OnManualRefChecked() { this->CheckInputs(); this->ConfigureMappingControls(); } void QmitkMatchPointMapper::OnLinkSampleFactorChecked() { this->m_Controls.m_sbYFactor->setEnabled(!(this->m_Controls.m_cbLinkFactors->isChecked())); this->m_Controls.m_sbZFactor->setEnabled(!(this->m_Controls.m_cbLinkFactors->isChecked())); if (m_Controls.m_cbLinkFactors->isChecked()) { this->m_Controls.m_sbYFactor->setValue(this->m_Controls.m_sbXFactor->value()); this->m_Controls.m_sbZFactor->setValue(this->m_Controls.m_sbXFactor->value()); } } void QmitkMatchPointMapper::OnMapBtnPushed() { SpawnMappingJob(); } void QmitkMatchPointMapper::OnRefineBtnPushed() { SpawnMappingJob(true); } void QmitkMatchPointMapper::SpawnMappingJob(bool doGeometryRefinement) { if (m_Controls.m_checkClearLog->checkState() == Qt::Checked) { this->m_Controls.m_teLog->clear(); } ///////////////////////// //create job and put it into the thread pool QmitkMappingJob* pJob = new QmitkMappingJob(); pJob->setAutoDelete(true); pJob->m_spInputData = this->m_spSelectedInputNode->GetData(); pJob->m_InputNodeUID = mitk::EnsureUID(this->m_spSelectedInputNode); pJob->m_doGeometryRefinement = doGeometryRefinement; pJob->m_spRegNode = m_spSelectedRegNode; if (m_spSelectedRegNode.IsNull()) { pJob->m_spRegNode = mitk::DataNode::New(); pJob->m_spRegNode->SetData(mitk::GenerateIdentityRegistration3D().GetPointer()); pJob->m_spRegNode->SetName("Auto_Generated_Identity_Transform"); m_Controls.m_teLog->append( QString("No registration selected. Preforming mapping with identity transform")); } if (!doGeometryRefinement) { pJob->m_spRefGeometry = m_spSelectedRefNode->GetData()->GetGeometry()->Clone().GetPointer(); //check for super/sub sampling if (m_Controls.m_groupActivateSampling->isChecked()) { //change the pixel count and spacing of the geometry mitk::BaseGeometry::BoundsArrayType geoBounds = pJob->m_spRefGeometry->GetBounds(); mitk::Vector3D geoSpacing = pJob->m_spRefGeometry->GetSpacing(); geoSpacing[0] = geoSpacing[0] / m_Controls.m_sbXFactor->value(); geoSpacing[1] = geoSpacing[1] / m_Controls.m_sbYFactor->value(); geoSpacing[2] = geoSpacing[2] / m_Controls.m_sbZFactor->value(); geoBounds[1] = geoBounds[1] * m_Controls.m_sbXFactor->value(); geoBounds[3] = geoBounds[3] * m_Controls.m_sbYFactor->value(); geoBounds[5] = geoBounds[5] * m_Controls.m_sbZFactor->value(); pJob->m_spRefGeometry->SetBounds(geoBounds); pJob->m_spRefGeometry->SetSpacing(geoSpacing); } } pJob->m_MappedName = m_Controls.m_leMappedName->text().toStdString(); pJob->m_allowUndefPixels = m_Controls.m_groupAllowUndefPixels->isChecked(); pJob->m_paddingValue = m_Controls.m_sbPaddingValue->value(); pJob->m_allowUnregPixels = m_Controls.m_groupAllowUnregPixels->isChecked(); pJob->m_errorValue = m_Controls.m_sbErrorValue->value(); pJob->m_InterpolatorLabel = m_Controls.m_comboInterpolator->currentText().toStdString(); switch (m_Controls.m_comboInterpolator->currentIndex()) { case 0: pJob->m_InterpolatorType = mitk::ImageMappingInterpolator::NearestNeighbor; break; case 1: pJob->m_InterpolatorType = mitk::ImageMappingInterpolator::Linear; break; case 2: pJob->m_InterpolatorType = mitk::ImageMappingInterpolator::BSpline_3; break; case 3: pJob->m_InterpolatorType = mitk::ImageMappingInterpolator::WSinc_Hamming; break; case 4: pJob->m_InterpolatorType = mitk::ImageMappingInterpolator::WSinc_Welch; break; } connect(pJob, SIGNAL(Error(QString)), this, SLOT(OnMapJobError(QString))); connect(pJob, SIGNAL(MapResultIsAvailable(mitk::BaseData::Pointer, const QmitkMappingJob*)), this, SLOT(OnMapResultIsAvailable(mitk::BaseData::Pointer, const QmitkMappingJob*)), Qt::BlockingQueuedConnection); connect(pJob, SIGNAL(AlgorithmInfo(QString)), this, SLOT(OnMappingInfo(QString))); m_Controls.m_teLog->append(QString("Started mapping job. Name: ") + m_Controls.m_leMappedName->text() + QString("")); QThreadPool* threadPool = QThreadPool::globalInstance(); threadPool->start(pJob); } void QmitkMatchPointMapper::OnMapJobError(QString err) { Error(err); }; void QmitkMatchPointMapper::OnMapResultIsAvailable(mitk::BaseData::Pointer spMappedData, const QmitkMappingJob* job) { m_Controls.m_teLog->append(QString("Mapped entity stored. Name: ") + QString::fromStdString(job->m_MappedName) + QString("")); mitk::DataNode::Pointer spMappedNode = mitk::generateMappedResultNode(job->m_MappedName, spMappedData, job->GetRegistration()->getRegistrationUID(), job->m_InputNodeUID, job->m_doGeometryRefinement, job->m_InterpolatorLabel); this->GetDataStorage()->Add(spMappedNode); this->GetRenderWindowPart()->RequestUpdate(); this->CheckInputs(); this->ConfigureMappingControls(); }; void QmitkMatchPointMapper::OnMappingInfo(QString info) { m_Controls.m_teLog->append(QString("") + info + QString("")); }; void QmitkMatchPointMapper::OnXFactorChanged(double d) { if (m_Controls.m_cbLinkFactors->isChecked()) { this->m_Controls.m_sbYFactor->setValue(d); this->m_Controls.m_sbZFactor->setValue(d); } } diff --git a/Plugins/org.mitk.matchpoint.core.helper/src/internal/MatchPointBrowserPreferencesPage.cpp b/Plugins/org.mitk.matchpoint.core.helper/src/internal/MatchPointBrowserPreferencesPage.cpp index 6cc80af6d0..56254f8163 100644 --- a/Plugins/org.mitk.matchpoint.core.helper/src/internal/MatchPointBrowserPreferencesPage.cpp +++ b/Plugins/org.mitk.matchpoint.core.helper/src/internal/MatchPointBrowserPreferencesPage.cpp @@ -1,160 +1,160 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "MatchPointBrowserPreferencesPage.h" #include "MatchPointBrowserConstants.h" #include #include #include #include #include #include #include #include #include #include #include "QmitkDirectoryListWidget.h" #include "QmitkFileListWidget.h" //----------------------------------------------------------------------------- MatchPointBrowserPreferencesPage::MatchPointBrowserPreferencesPage() : m_MainControl(0) , m_AlgDirectories(0) , m_AlgFiles(0) , m_LoadFromHomeDir(0) , m_LoadFromCurrentDir(0) , m_LoadFromApplicationDir(0) , m_LoadFromAutoLoadPathDir(0) , m_BrowserPreferencesNode(0) { } //----------------------------------------------------------------------------- MatchPointBrowserPreferencesPage::~MatchPointBrowserPreferencesPage() { } //----------------------------------------------------------------------------- void MatchPointBrowserPreferencesPage::Init(berry::IWorkbench::Pointer ) { } //----------------------------------------------------------------------------- void MatchPointBrowserPreferencesPage::CreateQtControl(QWidget* parent) { berry::IPreferencesService* prefService = berry::Platform::GetPreferencesService(); QString id = tr("/") + tr(MatchPointBrowserConstants::VIEW_ID.c_str()); m_BrowserPreferencesNode = prefService->GetSystemPreferences()->Node(id); m_MainControl = new QWidget(parent); m_AlgDirectories = new QmitkDirectoryListWidget(m_MainControl); m_AlgDirectories->m_Label->setText("Select directories to scan:"); m_AlgFiles = new QmitkFileListWidget(m_MainControl); m_AlgFiles->m_Label->setText("Select additional executables:"); m_DebugOutput = new QCheckBox(m_MainControl); m_LoadFromAutoLoadPathDir = new QCheckBox(m_MainControl); m_LoadFromApplicationDir = new QCheckBox(m_MainControl); m_LoadFromHomeDir = new QCheckBox(m_MainControl); m_LoadFromCurrentDir = new QCheckBox(m_MainControl); QFormLayout *formLayout = new QFormLayout; formLayout->addRow("show debug output:", m_DebugOutput); formLayout->addRow("scan home directory:", m_LoadFromHomeDir); formLayout->addRow("scan current directory:", m_LoadFromCurrentDir); formLayout->addRow("scan installation directory:", m_LoadFromApplicationDir); formLayout->addRow("scan MAP_MDRA_LOAD_PATH:", m_LoadFromAutoLoadPathDir); formLayout->addRow("additional algorithm directories:", m_AlgDirectories); formLayout->addRow("additional algorithms:", m_AlgFiles); m_MainControl->setLayout(formLayout); this->Update(); } //----------------------------------------------------------------------------- QWidget* MatchPointBrowserPreferencesPage::GetQtControl() const { return m_MainControl; } //----------------------------------------------------------------------------- QString MatchPointBrowserPreferencesPage::ConvertToString( const QStringList& list ) { QString output; for (int i = 0; i < list.count(); i++) { QString path = list[i] + ";"; output = output + path; } return output; } //----------------------------------------------------------------------------- bool MatchPointBrowserPreferencesPage::PerformOk() { m_BrowserPreferencesNode->PutBool(MatchPointBrowserConstants::DEBUG_OUTPUT_NODE_NAME.c_str(), m_DebugOutput->isChecked()); m_BrowserPreferencesNode->PutBool(MatchPointBrowserConstants::LOAD_FROM_APPLICATION_DIR.c_str(), m_LoadFromApplicationDir->isChecked()); m_BrowserPreferencesNode->PutBool(MatchPointBrowserConstants::LOAD_FROM_HOME_DIR.c_str(), m_LoadFromHomeDir->isChecked()); m_BrowserPreferencesNode->PutBool(MatchPointBrowserConstants::LOAD_FROM_CURRENT_DIR.c_str(), m_LoadFromCurrentDir->isChecked()); m_BrowserPreferencesNode->PutBool(MatchPointBrowserConstants::LOAD_FROM_AUTO_LOAD_DIR.c_str(), m_LoadFromAutoLoadPathDir->isChecked()); QString paths = this->ConvertToString(m_AlgDirectories->directories()); m_BrowserPreferencesNode->Put(MatchPointBrowserConstants::MDAR_DIRECTORIES_NODE_NAME.c_str(), paths); QString modules = this->ConvertToString(m_AlgFiles->files()); m_BrowserPreferencesNode->Put(MatchPointBrowserConstants::MDAR_FILES_NODE_NAME.c_str(), modules); return true; } //----------------------------------------------------------------------------- void MatchPointBrowserPreferencesPage::PerformCancel() { } //----------------------------------------------------------------------------- void MatchPointBrowserPreferencesPage::Update() { m_DebugOutput->setChecked(m_BrowserPreferencesNode->GetBool(MatchPointBrowserConstants::DEBUG_OUTPUT_NODE_NAME.c_str(), false)); - m_LoadFromApplicationDir->setChecked(m_BrowserPreferencesNode->GetBool(MatchPointBrowserConstants::LOAD_FROM_APPLICATION_DIR.c_str(), false)); + m_LoadFromApplicationDir->setChecked(m_BrowserPreferencesNode->GetBool(MatchPointBrowserConstants::LOAD_FROM_APPLICATION_DIR.c_str(), true)); m_LoadFromHomeDir->setChecked(m_BrowserPreferencesNode->GetBool(MatchPointBrowserConstants::LOAD_FROM_HOME_DIR.c_str(), false)); m_LoadFromCurrentDir->setChecked(m_BrowserPreferencesNode->GetBool(MatchPointBrowserConstants::LOAD_FROM_CURRENT_DIR.c_str(), false)); m_LoadFromAutoLoadPathDir->setChecked(m_BrowserPreferencesNode->GetBool(MatchPointBrowserConstants::LOAD_FROM_AUTO_LOAD_DIR.c_str(), false)); QString paths = m_BrowserPreferencesNode->Get(MatchPointBrowserConstants::MDAR_DIRECTORIES_NODE_NAME.c_str(), tr("")); QStringList directoryList = paths.split(";", QString::SkipEmptyParts); m_AlgDirectories->setDirectories(directoryList); QString files = m_BrowserPreferencesNode->Get(MatchPointBrowserConstants::MDAR_FILES_NODE_NAME.c_str(), tr("")); QStringList fileList = files.split(";", QString::SkipEmptyParts); m_AlgFiles->setFiles(fileList); }