diff --git a/CMake/mitkFunctionGetLibrarySearchPaths.cmake b/CMake/mitkFunctionGetLibrarySearchPaths.cmake index b0599e3edd..93d5f2a02b 100644 --- a/CMake/mitkFunctionGetLibrarySearchPaths.cmake +++ b/CMake/mitkFunctionGetLibrarySearchPaths.cmake @@ -1,175 +1,168 @@ -macro(_find_package package_name) - find_package(${package_name} REQUIRED PATHS ${${package_name}_DIR} PATH_SUFFIXES ${package_name} NO_DEFAULT_PATH NO_MODULE QUIET) - if(NOT ${package_name}_FOUND) - find_package(${package_name} REQUIRED) - endif() -endmacro() - function(mitkFunctionGetLibrarySearchPaths search_path intermediate_dir) set(_dir_candidates "${MITK_CMAKE_RUNTIME_OUTPUT_DIRECTORY}" "${MITK_CMAKE_RUNTIME_OUTPUT_DIRECTORY}/plugins" "${MITK_CMAKE_LIBRARY_OUTPUT_DIRECTORY}" "${MITK_CMAKE_LIBRARY_OUTPUT_DIRECTORY}/plugins" ) if(MITK_EXTERNAL_PROJECT_PREFIX) list(APPEND _dir_candidates "${MITK_EXTERNAL_PROJECT_PREFIX}/bin" "${MITK_EXTERNAL_PROJECT_PREFIX}/lib" ) endif() # Determine the Qt5 library installation prefix set(_qmake_location ) if(MITK_USE_QT AND TARGET ${Qt5Core_QMAKE_EXECUTABLE}) get_property(_qmake_location TARGET ${Qt5Core_QMAKE_EXECUTABLE} PROPERTY IMPORT_LOCATION) endif() if(_qmake_location) if(NOT _qt_install_libs) if(WIN32) execute_process(COMMAND ${_qmake_location} -query QT_INSTALL_BINS OUTPUT_VARIABLE _qt_install_libs OUTPUT_STRIP_TRAILING_WHITESPACE) else() execute_process(COMMAND ${_qmake_location} -query QT_INSTALL_LIBS OUTPUT_VARIABLE _qt_install_libs OUTPUT_STRIP_TRAILING_WHITESPACE) endif() file(TO_CMAKE_PATH "${_qt_install_libs}" _qt_install_libs) set(_qt_install_libs ${_qt_install_libs} CACHE INTERNAL "Qt library installation prefix" FORCE) endif() if(_qt_install_libs) list(APPEND _dir_candidates ${_qt_install_libs}) endif() elseif(MITK_USE_QT) message(WARNING "The qmake executable could not be found.") endif() get_property(_additional_paths GLOBAL PROPERTY MITK_ADDITIONAL_LIBRARY_SEARCH_PATHS) if(MITK_USE_HDF5) - _find_package(HDF5) - get_target_property(_location hdf5 LOCATION) + FIND_PACKAGE(HDF5 COMPONENTS C HL NO_MODULE REQUIRED shared) + get_target_property(_location hdf5-shared LOCATION) get_filename_component(_location ${_location} PATH) list(APPEND _additional_paths ${_location}) # This is a work-around. The hdf5-config.cmake file is not robust enough # to be included several times via find_pakcage calls. set(HDF5_LIBRARIES ${HDF5_LIBRARIES} PARENT_SCOPE) endif() if(MITK_USE_Vigra) # we cannot use _find_package(Vigra) here because the vigra-config.cmake file # always includes the target-exports files without using an include guard. This # would lead to errors when another find_package(Vigra) call is processed. The # (bad) assumption here is that for the time being, only the Classification module # is using Vigra. if(UNIX) list(APPEND _additional_paths ${Vigra_DIR}/lib) else() list(APPEND _additional_paths ${Vigra_DIR}/bin) endif() endif() if(_additional_paths) list(APPEND _dir_candidates ${_additional_paths}) endif() # The code below is sub-optimal. It makes assumptions about # the structure of the build directories, pointed to by # the *_DIR variables. Instead, we should rely on package # specific "LIBRARY_DIRS" variables, if they exist. if(WIN32) if(SOFA_DIR) list(APPEND _dir_candidates "${SOFA_DIR}/bin") endif() list(APPEND _dir_candidates "${ITK_DIR}/bin") else() if(SOFA_DIR) list(APPEND _dir_candidates "${SOFA_DIR}/lib") endif() endif() if(MITK_USE_MatchPoint) if(WIN32) list(APPEND _dir_candidates "${MatchPoint_DIR}/bin") else() list(APPEND _dir_candidates "${MatchPoint_DIR}/lib") endif() endif() if(OpenCV_DIR) set(_opencv_link_directories "${OpenCV_LIB_DIR_DBG}" "${OpenCV_LIB_DIR_OPT}" "${OpenCV_3RDPARTY_LIB_DIR_DBG}" "${OpenCV_3RDPARTY_LIB_DIR_OPT}") list(REMOVE_DUPLICATES _opencv_link_directories) if(WIN32) foreach(_opencv_link_directory ${_opencv_link_directories}) list(APPEND _dir_candidates "${_opencv_link_directory}/../bin") endforeach() else() list(APPEND _dir_candidates ${_opencv_link_directories}) endif() endif() if(MITK_USE_Python) list(APPEND _dir_candidates "${CTK_DIR}/CMakeExternals/Install/bin") list(APPEND _dir_candidates "${MITK_EXTERNAL_PROJECT_PREFIX}/lib/python2.7/bin") endif() if(MITK_USE_TOF_PMDO3 OR MITK_USE_TOF_PMDCAMCUBE OR MITK_USE_TOF_PMDCAMBOARD) list(APPEND _dir_candidates "${MITK_PMD_SDK_DIR}/plugins" "${MITK_PMD_SDK_DIR}/bin") endif() if(MITK_USE_CTK) list(APPEND _dir_candidates "${CTK_LIBRARY_DIRS}") foreach(_ctk_library ${CTK_LIBRARIES}) if(${_ctk_library}_LIBRARY_DIRS) list(APPEND _dir_candidates "${${_ctk_library}_LIBRARY_DIRS}") endif() endforeach() endif() if(MITK_USE_BLUEBERRY) if(DEFINED CTK_PLUGIN_RUNTIME_OUTPUT_DIRECTORY) if(IS_ABSOLUTE "${CTK_PLUGIN_RUNTIME_OUTPUT_DIRECTORY}") list(APPEND _dir_candidates "${CTK_PLUGIN_RUNTIME_OUTPUT_DIRECTORY}") else() list(APPEND _dir_candidates "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CTK_PLUGIN_RUNTIME_OUTPUT_DIRECTORY}") endif() endif() endif() if(MITK_LIBRARY_DIRS) list(APPEND _dir_candidates ${MITK_LIBRARY_DIRS}) endif() list(REMOVE_DUPLICATES _dir_candidates) set(_search_dirs ) foreach(_dir ${_dir_candidates}) if(EXISTS "${_dir}/${intermediate_dir}") list(APPEND _search_dirs "${_dir}/${intermediate_dir}") else() list(APPEND _search_dirs "${_dir}") endif() endforeach() # Special handling for "internal" search dirs. The intermediate directory # might not have been created yet, so we can't check for its existence. # Hence we just add it for Windows without checking. set(_internal_search_dirs "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/plugins") if(WIN32) foreach(_dir ${_internal_search_dirs}) set(_search_dirs "${_dir}/${intermediate_dir}" ${_search_dirs}) endforeach() else() set(_search_dirs ${_internal_search_dirs} ${_search_dirs}) endif() list(REMOVE_DUPLICATES _search_dirs) set(${search_path} ${_search_dirs} PARENT_SCOPE) endfunction() diff --git a/CMakeExternals/HDF5.cmake b/CMakeExternals/HDF5.cmake index c44d15b0de..84697ca6d1 100644 --- a/CMakeExternals/HDF5.cmake +++ b/CMakeExternals/HDF5.cmake @@ -1,58 +1,58 @@ #----------------------------------------------------------------------------- # HDF5 #----------------------------------------------------------------------------- if(MITK_USE_HDF5) # Sanity checks if(DEFINED HDF5_DIR AND NOT EXISTS ${HDF5_DIR}) message(FATAL_ERROR "HDF5_DIR variable is defined but corresponds to non-existing directory") endif() set(proj HDF5) set(proj_DEPENDENCIES ) set(HDF5_DEPENDS ${proj}) if(NOT DEFINED HDF5_DIR) set(additional_args ) if(CTEST_USE_LAUNCHERS) list(APPEND additional_args "-DCMAKE_PROJECT_${proj}_INCLUDE:FILEPATH=${CMAKE_ROOT}/Modules/CTestUseLaunchers.cmake" ) endif() # We might build static libs with -DBUILD_SHARED_LIBS=0 but this conflicts with # the in ITK integrated version! So we need to go the way with dynamic libs. Too # bad :( This would be fixed by using an external HDF-Installation with ITK/VTK ExternalProject_Add(${proj} - URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/hdf5_1.8.14.tar.gz - URL_MD5 a482686e733514a51cde12d6fe5c5d95 + URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/hdf5-1.8.17.tar.gz + URL_MD5 7d572f8f3b798a628b8245af0391a0ca CMAKE_GENERATOR ${gen} CMAKE_ARGS ${ep_common_args} ${additional_args} -DHDF5_BUILD_HL_LIB:BOOL=ON -DHDF5_BUILD_CPP_LIB:BOOL=ON -DCMAKE_INSTALL_PREFIX:PATH= CMAKE_CACHE_ARGS ${ep_common_cache_args} CMAKE_CACHE_DEFAULT_ARGS ${ep_common_cache_default_args} DEPENDS ${proj_DEPENDENCIES} ) ExternalProject_Get_Property(${proj} install_dir) if(WIN32) - set(HDF5_DIR ${install_dir}/cmake/hdf5) + set(HDF5_DIR ${install_dir}/cmake/) else() set(HDF5_DIR ${install_dir}/share/cmake/hdf5) endif() else() mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}") endif() endif(MITK_USE_HDF5) diff --git a/CMakeExternals/Vigra.patch b/CMakeExternals/Vigra.patch index e7753c32a8..a0a4b9ace6 100644 --- a/CMakeExternals/Vigra.patch +++ b/CMakeExternals/Vigra.patch @@ -1,379 +1,380 @@ diff -urNb vigra-Version-1-10-0/CMakeLists.txt Vigra/CMakeLists.txt --- vigra-Version-1-10-0/CMakeLists.txt 2013-11-18 17:48:16.000000000 +0100 +++ Vigra/CMakeLists.txt 2015-03-03 10:13:57.693725000 +0100 -@@ -70,8 +70,11 @@ +@@ -70,7 +70,12 @@ IF(WITH_OPENEXR) ENDIF() - + IF(WITH_HDF5) + FIND_PACKAGE(HDF5 PATHS ${HDF5_DIR} PATH_SUFFIXES hdf5 NO_DEFAULT_PATH NO_MODULE) -+IF(NOT HDF5_FOUND) ++ IF(NOT HDF5_FOUND) VIGRA_FIND_PACKAGE(HDF5) ++ ENDIF() ++ # HDF5 changed their config, this ports the new style to the old style ++ set(HDF5_LIBRARIES ${HDF5_EXPORT_LIBRARIES}) ENDIF() -+ENDIF() - + IF(WITH_BOOST_GRAPH) - IF(WITH_VIGRANUMPY) @@ -395,3 +398,4 @@ ENDIF() MESSAGE( STATUS "---------------------------------------------------------" ) + diff -urNb vigra-Version-1-10-0/config/VigraConfig.cmake.in Vigra/config/VigraConfig.cmake.in --- vigra-Version-1-10-0/config/VigraConfig.cmake.in 2013-11-18 17:48:16.000000000 +0100 +++ Vigra/config/VigraConfig.cmake.in 2015-03-03 10:13:57.693725000 +0100 @@ -1,7 +1,9 @@ get_filename_component(SELF_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) get_filename_component(Vigra_TOP_DIR "${SELF_DIR}/../../" ABSOLUTE) -include(${SELF_DIR}/vigra-targets.cmake) +if(NOT TARGET vigraimpex) + include(${SELF_DIR}/vigra-targets.cmake) +endif() get_target_property(VIGRA_TYPE vigraimpex TYPE) if(${VIGRA_TYPE} STREQUAL "STATIC_LIBRARY") SET(VIGRA_STATIC_LIB True) @@ -12,3 +14,4 @@ IF(EXISTS ${SELF_DIR}/../vigranumpy/VigranumpyConfig.cmake) INCLUDE(${SELF_DIR}/../vigranumpy/VigranumpyConfig.cmake) ENDIF() + diff -urNb vigra-Version-1-10-0/include/vigra/random_forest/rf_common.hxx Vigra/include/vigra/random_forest/rf_common.hxx --- vigra-Version-1-10-0/include/vigra/random_forest/rf_common.hxx 2013-11-18 17:48:16.000000000 +0100 +++ Vigra/include/vigra/random_forest/rf_common.hxx 2015-07-08 18:55:16.000000000 +0200 @@ -558,6 +558,7 @@ int is_weighted_; // class_weights_ are used double precision_; // termination criterion for regression loss int response_size_; + int max_tree_depth; template void to_classlabel(int index, T & out) const @@ -583,7 +584,8 @@ EQUALS(class_weights_), EQUALS(is_weighted_), EQUALS(precision_), - EQUALS(response_size_) + EQUALS(response_size_), + EQUALS(max_tree_depth) { std::back_insert_iterator > iter(classes); @@ -604,7 +606,8 @@ EQUALS(class_weights_), EQUALS(is_weighted_), EQUALS(precision_), - EQUALS(response_size_) + EQUALS(response_size_), + EQUALS(max_tree_depth) { std::back_insert_iterator > iter(classes); @@ -624,7 +627,8 @@ EQUALS(used_); EQUALS(is_weighted_); EQUALS(precision_); - EQUALS(response_size_) + EQUALS(response_size_); + EQUALS(max_tree_depth) class_weights_.clear(); std::back_insert_iterator > iter2(class_weights_); @@ -648,7 +652,8 @@ EQUALS(used_); EQUALS(is_weighted_); EQUALS(precision_); - EQUALS(response_size_) + EQUALS(response_size_); + EQUALS(max_tree_depth) class_weights_.clear(); std::back_insert_iterator > iter2(class_weights_); @@ -677,7 +682,8 @@ COMPARE(used_); COMPARE(class_weights_); COMPARE(classes); - COMPARE(response_size_) + COMPARE(response_size_); + COMPARE(max_tree_depth) #undef COMPARE return result; } @@ -715,6 +721,7 @@ PULL(used_, int); PULL(precision_, double); PULL(response_size_, int); + PULL(max_tree_depth, int); if(is_weighted_) { vigra_precondition(end - begin == 10 + 2*class_count_, @@ -747,6 +754,7 @@ PUSH(used_); PUSH(precision_); PUSH(response_size_); + PUSH(max_tree_depth); if(is_weighted_) { std::copy(class_weights_.begin(), @@ -773,6 +781,7 @@ PULL(used_, int); PULL(precision_, double); PULL(response_size_, int); + PULL(max_tree_depth, int); class_weights_ = in["class_weights_"]; #undef PUSH } @@ -789,6 +798,7 @@ PUSH(used_); PUSH(precision_); PUSH(response_size_); + PUSH(max_tree_depth); in["class_weights_"] = class_weights_; #undef PUSH } @@ -805,7 +815,8 @@ used_(false), is_weighted_(false), precision_(0.0), - response_size_(1) + response_size_(1), + max_tree_depth(50) {} @@ -857,7 +868,7 @@ is_weighted_ = false; precision_ = 0.0; response_size_ = 0; - + max_tree_depth = 50; } bool used() const diff -urNb vigra-Version-1-10-0/include/vigra/random_forest/rf_decisionTree.hxx Vigra/include/vigra/random_forest/rf_decisionTree.hxx --- vigra-Version-1-10-0/include/vigra/random_forest/rf_decisionTree.hxx 2013-11-18 17:48:16.000000000 +0100 +++ Vigra/include/vigra/random_forest/rf_decisionTree.hxx 2015-07-08 18:55:16.000000000 +0200 @@ -90,6 +90,8 @@ ProblemSpec<> ext_param_; unsigned int classCount_; + std::map m_Parents; + public: /* \brief Create tree with parameters */ @@ -350,6 +352,22 @@ continueLearn(features,labels,stack_entry,split,stop,visitor,randint); } +template < class TRandomForest> +int GetTreeDepthForNode(int nodeIndex, TRandomForest* rf) +{ + int depth = 0; + while (true) + { + if (nodeIndex < 1) + { + break; + } + ++depth; + nodeIndex = rf->m_Parents[nodeIndex]; + } + return depth; +} + template < class U, class C, class U2, class C2, class StackEntry_t, @@ -374,6 +392,11 @@ size_t last_node_pos = 0; StackEntry_t top=stack.back(); + Split_t* splitPointer = &split; + bool isDepthSplitter = true; + + int maximumTreeDepth = splitPointer->GetMaximumTreeDepth(); + while(!stack.empty()) { @@ -392,7 +415,20 @@ //kind of node to make TreeInt NodeID; - if(stop(top)) + bool depthStop = false; + if (isDepthSplitter) + { + int currentDepthLevel; + if (top.leftParent != StackEntry_t::DecisionTreeNoParent) + currentDepthLevel = GetTreeDepthForNode(top.leftParent, this); + else + currentDepthLevel = GetTreeDepthForNode(top.rightParent, this); + + depthStop = (currentDepthLevel >= maximumTreeDepth); + } + if(stop(top) || (depthStop)) + + //if (stop(top) || currentDepthLevel >= MaximumSplitDepth(split)) NodeID = split.makeTerminalNode(features, labels, top, @@ -421,17 +457,20 @@ // Using InteriorNodeBase because exact parameter form not needed. // look at the Node base before getting scared. last_node_pos = topology_.size(); + m_Parents[last_node_pos] = StackEntry_t::DecisionTreeNoParent; if(top.leftParent != StackEntry_t::DecisionTreeNoParent) { NodeBase(topology_, parameters_, top.leftParent).child(0) = last_node_pos; + m_Parents[last_node_pos] = top.leftParent; } else if(top.rightParent != StackEntry_t::DecisionTreeNoParent) { NodeBase(topology_, parameters_, top.rightParent).child(1) = last_node_pos; + m_Parents[last_node_pos] = top.rightParent; } diff -urNb vigra-Version-1-10-0/include/vigra/random_forest/rf_nodeproxy.hxx Vigra/include/vigra/random_forest/rf_nodeproxy.hxx --- vigra-Version-1-10-0/include/vigra/random_forest/rf_nodeproxy.hxx 2013-11-18 17:48:16.000000000 +0100 +++ Vigra/include/vigra/random_forest/rf_nodeproxy.hxx 2015-07-08 18:55:16.000000000 +0200 @@ -50,7 +50,11 @@ namespace vigra { - +class DepthSplitterBase +{ +public: + virtual int GetMaximumTreeDepth() const = 0; +}; enum NodeTags { diff -urNb vigra-Version-1-10-0/include/vigra/random_forest/rf_split.hxx Vigra/include/vigra/random_forest/rf_split.hxx --- vigra-Version-1-10-0/include/vigra/random_forest/rf_split.hxx 2013-11-18 17:48:16.000000000 +0100 +++ Vigra/include/vigra/random_forest/rf_split.hxx 2015-07-08 18:55:16.000000000 +0200 @@ -108,6 +108,11 @@ \ref SplitBase::findBestSplit() or \ref SplitBase::makeTerminalNode(). **/ + virtual int GetMaximumTreeDepth() const + { + return ext_param_.max_tree_depth; + } + template void set_external_parameters(ProblemSpec const & in) { diff -urNb vigra-Version-1-10-0/include/vigra/random_forest.hxx Vigra/include/vigra/random_forest.hxx --- vigra-Version-1-10-0/include/vigra/random_forest.hxx 2013-11-18 17:48:16.000000000 +0100 +++ Vigra/include/vigra/random_forest.hxx 2015-07-15 14:08:18.548277915 +0200 @@ -165,6 +165,7 @@ ProblemSpec_t ext_param_; /*mutable ArrayVector tree_indices_;*/ rf::visitors::OnlineLearnVisitor online_visitor_; + bool multithreadPrediction; // enable/disable multithreaded predictProbabilities and predictLabels void reset() @@ -584,6 +585,18 @@ { vigra_precondition(features.shape(0) == labels.shape(0), "RandomForest::predictLabels(): Label array has wrong size."); + if (multithreadPrediction) + { +#pragma omp parallel for + for(int k=0; k::cast(predictLabel(rowVector(features, k), rf_default())); + } + } + else + { for(int k=0; k::cast(predictLabel(rowVector(features, k), rf_default())); } } + } /** \brief predict multiple labels with given features * @@ -1261,6 +1275,60 @@ } */ //Classify for each row. + if (multithreadPrediction) + { +#pragma omp parallel for + for(int row=0; row < rowCount(features); ++row) + { + MultiArrayView<2, U, StridedArrayTag> currentRow(rowVector(features, row)); + + // when the features contain an NaN, the instance doesn't belong to any class + // => indicate this by returning a zero probability array. + if(detail::contains_nan(currentRow)) + { + rowVector(prob, row).init(0.0); + continue; + } + + ArrayVector::const_iterator weights; + + //totalWeight == totalVoteCount! + double totalWeight = 0.0; + + //Let each tree classify... + for(int k=0; k::cast(totalWeight); + } + } + } + else + { for(int row=0; row < rowCount(features); ++row) { MultiArrayView<2, U, StridedArrayTag> currentRow(rowVector(features, row)); @@ -1309,6 +1377,7 @@ prob(row, l) /= detail::RequiresExplicitCast::cast(totalWeight); } } + } } diff --git a/Modules/DiffusionImaging/Connectomics/CMakeLists.txt b/Modules/DiffusionImaging/Connectomics/CMakeLists.txt index 4c6f902b5a..08091353cf 100644 --- a/Modules/DiffusionImaging/Connectomics/CMakeLists.txt +++ b/Modules/DiffusionImaging/Connectomics/CMakeLists.txt @@ -1,9 +1,9 @@ MITK_CREATE_MODULE( SUBPROJECTS MITK-DTI INCLUDE_DIRS Algorithms Algorithms/BrainParcellation IODataStructures Rendering ${CMAKE_CURRENT_BINARY_DIR} DEPENDS MitkDiffusionCore MitkFiberTracking PACKAGE_DEPENDS VTK|vtkInfovisLayout - WARNINGS_AS_ERRORS +# WARNINGS_AS_ERRORS ) add_subdirectory(Testing)