diff --git a/Modules/CMakeLists.txt b/Modules/CMakeLists.txt index e7492ae6aa..fcec967d5d 100644 --- a/Modules/CMakeLists.txt +++ b/Modules/CMakeLists.txt @@ -1,57 +1,58 @@ set(LIBPOSTFIX "Ext") # Modules must be listed according to their dependencies set(module_dirs SceneSerializationBase PlanarFigure ImageExtraction ImageStatistics LegacyAdaptors IpPicSupport MitkExt SceneSerialization Segmentation Qmitk QmitkExt GraphAlgorithms DiffusionImaging GPGPU IGT CameraCalibration IGTUI RigidRegistration RigidRegistrationUI DeformableRegistration DeformableRegistrationUI OpenCL OpenCVVideoSupport Overlays InputDevices ToFHardware ToFProcessing ToFUI US ClippingTools USUI DicomUI + Python ) set(MITK_DEFAULT_SUBPROJECTS MITK-Modules) foreach(module_dir ${module_dirs}) add_subdirectory(${module_dir}) endforeach() if(MITK_PRIVATE_MODULES) file(GLOB all_subdirs RELATIVE ${MITK_PRIVATE_MODULES} ${MITK_PRIVATE_MODULES}/*) foreach(subdir ${all_subdirs}) string(FIND ${subdir} "." _result) if(_result EQUAL -1) if(EXISTS ${MITK_PRIVATE_MODULES}/${subdir}/CMakeLists.txt) message(STATUS "Found private module ${subdir}") add_subdirectory(${MITK_PRIVATE_MODULES}/${subdir} private_modules/${subdir}) endif() endif() endforeach() endif(MITK_PRIVATE_MODULES) diff --git a/Modules/Python/CMakeLists.txt b/Modules/Python/CMakeLists.txt new file mode 100644 index 0000000000..48409dc23e --- /dev/null +++ b/Modules/Python/CMakeLists.txt @@ -0,0 +1,8 @@ +MITK_CREATE_MODULE(mitkPython + DEPENDS Mitk CTK + EXPORT_DEFINE MITK_PYTHON_EXPORT + PACKAGE_DEPENDS QT + QT_MODULE +) +configure_file(PythonPath.h.in + "${CMAKE_CURRENT_BINARY_DIR}/PythonPath.h" @ONLY) diff --git a/Modules/Python/PythonPath.h.in b/Modules/Python/PythonPath.h.in new file mode 100644 index 0000000000..945904a8c3 --- /dev/null +++ b/Modules/Python/PythonPath.h.in @@ -0,0 +1,2 @@ +#define PYTHONPATH_ITK_LIBRARY_DIRS "@ITK_LIBRARY_DIRS@" +#define PYTHONPATH_WRAP_ITK_DIR "@ITK_DIR@/Wrapping/WrapITK/Python" diff --git a/Modules/Python/files.cmake b/Modules/Python/files.cmake new file mode 100644 index 0000000000..dced6d26a9 --- /dev/null +++ b/Modules/Python/files.cmake @@ -0,0 +1,21 @@ +SET(CPP_FILES + mitkPythonActivator.cpp + mitkIPythonService.cpp + mitkPythonService.cpp +) + +#SET(CPP_FILES + #Qmitk/QmitkKinectParameterWidget.cpp +#) +#SET(UI_FILES + #Qmitk/QmitkKinectParameterWidgetControls.ui +#) + +#SET(MOC_H_FILES + #Qmitk/QmitkKinectParameterWidget.h +#) + +# uncomment the following line if you want to use Qt resources +#set(QRC_FILES + #resources/QmitkToFUtilWidget.qrc +#) diff --git a/Modules/Python/mitkIPythonService.cpp b/Modules/Python/mitkIPythonService.cpp new file mode 100644 index 0000000000..3138baee1a --- /dev/null +++ b/Modules/Python/mitkIPythonService.cpp @@ -0,0 +1,21 @@ +/*=================================================================== + +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 "mitkIPythonService.h" + +mitk::IPythonService::~IPythonService() +{ +} diff --git a/Modules/Python/mitkIPythonService.h b/Modules/Python/mitkIPythonService.h new file mode 100644 index 0000000000..fbe5f54666 --- /dev/null +++ b/Modules/Python/mitkIPythonService.h @@ -0,0 +1,78 @@ +/*=================================================================== + +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. + +===================================================================*/ +#ifndef mitkIPythonService_h +#define mitkIPythonService_h + +// mitk +#include "mitkPythonExports.h" +#include "mitkImage.h" +//for microservices +#include +// Qt +#include +#include +#include + +namespace mitk +{ + /// + /// describes a python variable (data container) + /// \see IPythonService::GetVariableStack() + /// + struct PythonVariable + { + QString m_Name; + QString m_Type; + QString m_Value; + }; + + /// + /// a PythonCommandObserver gets informed as soon as a python command was issued + /// \see IPythonService::AddPythonCommandObserver() + /// + class PythonCommandObserver + { + public: + virtual void CommandExecuted(const QString& pythonCommand) = 0; + }; + + /// + /// describes a python variable (data container) + /// \see IPythonService::GetVariableStack() + /// + class MITK_PYTHON_EXPORT IPythonService + { + public: + static const int SINGLE_LINE_COMMAND = 0; + static const int MULTI_LINE_COMMAND = 1; + static const int EVAL_COMMAND = 2; + + virtual ~IPythonService(); // leer in mitkIPythonService.cpp implementieren + virtual QVariant Execute( const QString& pythonCommand, int commandType = SINGLE_LINE_COMMAND ) = 0; + virtual QList GetVariableStack() const = 0; + + virtual void AddPythonCommandObserver( PythonCommandObserver* observer ) = 0; + virtual void RemovePythonCommandObserver( PythonCommandObserver* observer ) = 0; + virtual void NotifyObserver( const QString& command ) = 0; + + virtual bool CopyToPythonAsItkImage( mitk::Image* image, const QString& varName ) = 0; + virtual mitk::Image::Pointer CopyItkImageFromPython( const QString& varName ) = 0; + }; +} + +//US_DECLARE_SERVICE_INTERFACE(mitk::IPythonService, "org.mitk.services.IPythonService") + +#endif diff --git a/Modules/Python/mitkPythonActivator.cpp b/Modules/Python/mitkPythonActivator.cpp new file mode 100644 index 0000000000..123feb1ffb --- /dev/null +++ b/Modules/Python/mitkPythonActivator.cpp @@ -0,0 +1,79 @@ +/*=================================================================== + +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. + +===================================================================*/ +#ifndef mitkPythonActivator_h +#define mitkPythonActivator_h + +// Microservices +#include +#include "mitkModuleContext.h" +#include "mitkPythonService.h" +#include +#include "PythonPath.h" + +namespace mitk +{ + /// + /// installs the PythonService + /// runs all initial commands (setting env paths etc) + /// + class PythonActivator : public mitk::ModuleActivator + { + public: + + void Load(mitk::ModuleContext* context) + { + // Registering PythonService as MicroService + m_PythonService = itk::SmartPointer(new PythonService()); + + ServiceProperties _PythonServiceProps; + _PythonServiceProps["Name"] = std::string("PythonService"); + + context->RegisterService(m_PythonService, _PythonServiceProps); + + MITK_DEBUG << "registering python paths"; + + QString itkLibDirs(PYTHONPATH_ITK_LIBRARY_DIRS); + MITK_DEBUG << "itkLibDirs" << itkLibDirs.toStdString(); + + QString itkWrapItkDir(PYTHONPATH_WRAP_ITK_DIR); + MITK_DEBUG << "itkWrapItkDir" << itkWrapItkDir.toStdString(); + + QString basecommand = "sys.path.append('%1');"; + QString pythonCommand; + pythonCommand = basecommand.arg(itkLibDirs); + MITK_DEBUG << "issuing command " << pythonCommand.toStdString(); + m_PythonService->Execute(pythonCommand, mitk::IPythonService::SINGLE_LINE_COMMAND ); + + pythonCommand = basecommand.arg(itkWrapItkDir); + MITK_DEBUG << "issuing command " << pythonCommand.toStdString(); + m_PythonService->Execute(pythonCommand, mitk::IPythonService::SINGLE_LINE_COMMAND ); + } + + void Unload(mitk::ModuleContext* ) + { + } + + ~PythonActivator() + { + } + + private: + itk::SmartPointer m_PythonService; + }; +} + +//US_EXPORT_MODULE_ACTIVATOR(mitkPython, mitk::PythonActivator) +#endif diff --git a/Modules/Python/mitkPythonService.cpp b/Modules/Python/mitkPythonService.cpp new file mode 100644 index 0000000000..16872491db --- /dev/null +++ b/Modules/Python/mitkPythonService.cpp @@ -0,0 +1,150 @@ +/*=================================================================== + +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 "mitkPythonService.h" +#include +#include +#include +#include + +mitk::PythonService::PythonService() +{ + m_PythonManager.initialize(); +} + +mitk::PythonService::~PythonService() +{ +} + +QVariant mitk::PythonService::Execute(const QString &pythonCommand, int commandType) +{ + QVariant result; + bool commandIssued = true; + + if(commandType == IPythonService::SINGLE_LINE_COMMAND ) + result = m_PythonManager.executeString(pythonCommand, ctkAbstractPythonManager::SingleInput ); + else if(commandType == IPythonService::MULTI_LINE_COMMAND ) + result = m_PythonManager.executeString(pythonCommand, ctkAbstractPythonManager::FileInput ); + else if(commandType == IPythonService::EVAL_COMMAND ) + result = m_PythonManager.executeString(pythonCommand, ctkAbstractPythonManager::EvalInput ); + else + commandIssued = false; + + if(commandIssued) + this->NotifyObserver(pythonCommand); + + return result; +} + +QList mitk::PythonService::GetVariableStack() const +{ + QList list; + + PyObject* dict = PyImport_GetModuleDict(); + PyObject* object = PyDict_GetItemString(dict, "__main__"); + PyObject* dirMain = PyObject_Dir(object); + PyObject* tempObject; + + if(dirMain) + { + QString attr, attrValue, attrType; + + for(int i = 0; iob_type->tp_name; + if(PyUnicode_Check(tempObject) || PyString_Check(tempObject)) + attrValue = PyString_AsString(tempObject); + else + attrValue = ""; + mitk::PythonVariable var; + var.m_Name = attr; + var.m_Value = attrValue; + var.m_Type = attrType; + list.append(var); + } + } + + return list; +} + +void mitk::PythonService::AddPythonCommandObserver(mitk::PythonCommandObserver *observer) +{ + if(m_Observer.contains(observer)) + m_Observer.append(observer); +} + +void mitk::PythonService::RemovePythonCommandObserver(mitk::PythonCommandObserver *observer) +{ + m_Observer.removeOne(observer); +} + +void mitk::PythonService::NotifyObserver(const QString &command) +{ + foreach(mitk::PythonCommandObserver* observer, m_Observer) + { + observer->CommandExecuted(command); + } +} + +bool mitk::PythonService::CopyToPythonAsItkImage(mitk::Image *image, const QString &varName) +{ + // save image + QString tmpFolder = QDir::tempPath(); + QString fileName = tmpFolder + QDir::separator() + varName + ".nrrd"; + + MITK_DEBUG << "Saving temporary file " << fileName.toStdString(); + if( !mitk::IOUtil::SaveImage(image, fileName.toStdString()) ) + { + MITK_ERROR << "Temporary file could not be created."; + } + else + { + // TODO CORRECT TYPE SETUP, MAKE MITK_DEBUG MITK_DEBUG + int dim = 3; + QString type = "US"; + QString command; + command.append( "import itk\n" ); + command.append( "try:\n" ); + command.append( " mitkImages" ); + command.append( "except NameError:\n" ); + command.append( " mitkImages = {}\n" ); + //command.append( QString("mitkImages['%1_dim''] = %2\n").arg( varName ).arg(dim) ); + //command.append( QString("mitkImages['%1_pixelType'] = itk.%2\n").arg( varName ).argtype( type ) ); + command.append( QString("mitkImages['%1_imageType'] = itk.Image[%2, %3]\n").arg( varName ).arg( type ).arg( dim ) ); + command.append( QString("readerType = itk.ImageFileReader[mitkImages['%1_imageType']]\n").arg( varName ) ); + command.append( "reader = readerType.New()\n" ); + command.append( QString("reader.SetFileName( \"%1\" )\n").arg(fileName) ); + command.append( "reader.Update()\n" ); + command.append( QString("mitkImages['%1'] = reader.GetOutput()\n").arg( varName )); + MITK_DEBUG << "Issuing python command " << command.toStdString(); + this->Execute(command, IPythonService::SINGLE_LINE_COMMAND ); + + QFile file(fileName); + MITK_DEBUG << "Removing file " << fileName.toStdString(); + file.remove(); + return true; + } + + return false; +} + +mitk::Image::Pointer mitk::PythonService::CopyItkImageFromPython(const QString &varName) +{ + return 0; +} diff --git a/Modules/Python/mitkPythonService.h b/Modules/Python/mitkPythonService.h new file mode 100644 index 0000000000..d0c2c4215f --- /dev/null +++ b/Modules/Python/mitkPythonService.h @@ -0,0 +1,45 @@ +/*=================================================================== + +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. + +===================================================================*/ +#ifndef mitkPythonService_h +#define mitkPythonService_h + +#include "mitkIPythonService.h" +#include +#include + +namespace mitk +{ + class PythonService: public itk::LightObject, public mitk::IPythonService + { + public: + PythonService(); + ~PythonService(); // leer in mitkIPythonService.cpp implementieren + QVariant Execute( const QString& pythonCommand, int commandType = SINGLE_LINE_COMMAND ); + QList GetVariableStack() const; + + void AddPythonCommandObserver( PythonCommandObserver* observer ); + void RemovePythonCommandObserver( PythonCommandObserver* observer ); + void NotifyObserver( const QString& command ); + + bool CopyToPythonAsItkImage( mitk::Image* image, const QString& varName ); + mitk::Image::Pointer CopyItkImageFromPython( const QString& varName ); + private: + QList m_Observer; + ctkAbstractPythonManager m_PythonManager; + + }; +} +#endif