summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Alpha_complex/utilities/alpha_complex_3d_persistence.cpp2
-rw-r--r--src/Alpha_complex/utilities/alpha_complex_persistence.cpp2
-rw-r--r--src/Alpha_complex/utilities/exact_alpha_complex_3d_persistence.cpp2
-rw-r--r--src/Alpha_complex/utilities/periodic_alpha_complex_3d_persistence.cpp2
-rw-r--r--src/Alpha_complex/utilities/weighted_alpha_complex_3d_persistence.cpp2
-rw-r--r--src/Bottleneck_distance/example/alpha_rips_persistence_bottleneck_distance.cpp2
-rw-r--r--src/Cech_complex/example/cech_complex_step_by_step.cpp2
-rw-r--r--src/Cech_complex/utilities/cech_persistence.cpp2
-rw-r--r--src/Doxyfile.in (renamed from src/Doxyfile)37
-rw-r--r--src/Persistent_cohomology/example/persistence_from_file.cpp2
-rw-r--r--src/Persistent_cohomology/example/rips_multifield_persistence.cpp2
-rw-r--r--src/Persistent_cohomology/example/rips_persistence_step_by_step.cpp2
-rw-r--r--src/Persistent_cohomology/example/rips_persistence_via_boundary_matrix.cpp2
-rw-r--r--src/Rips_complex/utilities/rips_correlation_matrix_persistence.cpp2
-rw-r--r--src/Rips_complex/utilities/rips_distance_matrix_persistence.cpp2
-rw-r--r--src/Rips_complex/utilities/rips_persistence.cpp2
-rw-r--r--src/Rips_complex/utilities/sparse_rips_persistence.cpp2
-rw-r--r--src/Simplex_tree/example/cech_complex_cgal_mini_sphere_3d.cpp2
-rw-r--r--src/Witness_complex/utilities/strong_witness_persistence.cpp2
-rw-r--r--src/Witness_complex/utilities/weak_witness_persistence.cpp2
-rw-r--r--src/cmake/modules/FindCython.cmake44
-rw-r--r--src/cmake/modules/GUDHI_doxygen_target.cmake7
-rw-r--r--src/cmake/modules/GUDHI_third_party_libraries.cmake32
-rw-r--r--src/cmake/modules/GUDHI_user_version_target.cmake171
-rw-r--r--src/cython/CMakeLists.txt171
-rwxr-xr-xsrc/cython/cython/persistence_graphical_tools.py377
-rw-r--r--src/cython/doc/installation.rst54
-rw-r--r--src/cython/gudhi.pyx.in1
-rw-r--r--src/cython/setup.py.in6
29 files changed, 516 insertions, 422 deletions
diff --git a/src/Alpha_complex/utilities/alpha_complex_3d_persistence.cpp b/src/Alpha_complex/utilities/alpha_complex_3d_persistence.cpp
index 8cda0b70..6e603155 100644
--- a/src/Alpha_complex/utilities/alpha_complex_3d_persistence.cpp
+++ b/src/Alpha_complex/utilities/alpha_complex_3d_persistence.cpp
@@ -266,6 +266,6 @@ void program_options(int argc, char *argv[], std::string &off_file_points, std::
std::cout << "Usage: " << argv[0] << " [options] input-file" << std::endl << std::endl;
std::cout << visible << std::endl;
- std::abort();
+ exit(-1);
}
}
diff --git a/src/Alpha_complex/utilities/alpha_complex_persistence.cpp b/src/Alpha_complex/utilities/alpha_complex_persistence.cpp
index 42390b0e..8e6c40b7 100644
--- a/src/Alpha_complex/utilities/alpha_complex_persistence.cpp
+++ b/src/Alpha_complex/utilities/alpha_complex_persistence.cpp
@@ -133,6 +133,6 @@ void program_options(int argc, char *argv[], std::string &off_file_points, std::
std::cout << "Usage: " << argv[0] << " [options] input-file" << std::endl << std::endl;
std::cout << visible << std::endl;
- std::abort();
+ exit(-1);
}
}
diff --git a/src/Alpha_complex/utilities/exact_alpha_complex_3d_persistence.cpp b/src/Alpha_complex/utilities/exact_alpha_complex_3d_persistence.cpp
index cbe003ff..61f49bb1 100644
--- a/src/Alpha_complex/utilities/exact_alpha_complex_3d_persistence.cpp
+++ b/src/Alpha_complex/utilities/exact_alpha_complex_3d_persistence.cpp
@@ -260,6 +260,6 @@ void program_options(int argc, char *argv[], std::string &off_file_points, std::
std::cout << "Usage: " << argv[0] << " [options] input-file" << std::endl << std::endl;
std::cout << visible << std::endl;
- std::abort();
+ exit(-1);
}
}
diff --git a/src/Alpha_complex/utilities/periodic_alpha_complex_3d_persistence.cpp b/src/Alpha_complex/utilities/periodic_alpha_complex_3d_persistence.cpp
index 11010701..a261c5a3 100644
--- a/src/Alpha_complex/utilities/periodic_alpha_complex_3d_persistence.cpp
+++ b/src/Alpha_complex/utilities/periodic_alpha_complex_3d_persistence.cpp
@@ -297,6 +297,6 @@ void program_options(int argc, char *argv[], std::string &off_file_points, std::
std::cout << "Usage: " << argv[0] << " [options] input-file cuboid-file" << std::endl << std::endl;
std::cout << visible << std::endl;
- std::abort();
+ exit(-1);
}
}
diff --git a/src/Alpha_complex/utilities/weighted_alpha_complex_3d_persistence.cpp b/src/Alpha_complex/utilities/weighted_alpha_complex_3d_persistence.cpp
index cdeeabfc..aa7ddee2 100644
--- a/src/Alpha_complex/utilities/weighted_alpha_complex_3d_persistence.cpp
+++ b/src/Alpha_complex/utilities/weighted_alpha_complex_3d_persistence.cpp
@@ -311,6 +311,6 @@ void program_options(int argc, char *argv[], std::string &off_file_points, std::
std::cout << "Usage: " << argv[0] << " [options] input-file weight-file" << std::endl << std::endl;
std::cout << visible << std::endl;
- std::abort();
+ exit(-1);
}
}
diff --git a/src/Bottleneck_distance/example/alpha_rips_persistence_bottleneck_distance.cpp b/src/Bottleneck_distance/example/alpha_rips_persistence_bottleneck_distance.cpp
index 1e27887c..2db1ef80 100644
--- a/src/Bottleneck_distance/example/alpha_rips_persistence_bottleneck_distance.cpp
+++ b/src/Bottleneck_distance/example/alpha_rips_persistence_bottleneck_distance.cpp
@@ -185,6 +185,6 @@ void program_options(int argc, char * argv[]
std::cout << "Usage: " << argv[0] << " [options] input-file" << std::endl << std::endl;
std::cout << visible << std::endl;
- std::abort();
+ exit(-1);
}
}
diff --git a/src/Cech_complex/example/cech_complex_step_by_step.cpp b/src/Cech_complex/example/cech_complex_step_by_step.cpp
index d2dc8b65..6fbbde5b 100644
--- a/src/Cech_complex/example/cech_complex_step_by_step.cpp
+++ b/src/Cech_complex/example/cech_complex_step_by_step.cpp
@@ -161,6 +161,6 @@ void program_options(int argc, char* argv[], std::string& off_file_points, Filtr
std::cout << "Usage: " << argv[0] << " [options] input-file" << std::endl << std::endl;
std::cout << visible << std::endl;
- std::abort();
+ exit(-1);
}
}
diff --git a/src/Cech_complex/utilities/cech_persistence.cpp b/src/Cech_complex/utilities/cech_persistence.cpp
index abd9dbcd..93e92695 100644
--- a/src/Cech_complex/utilities/cech_persistence.cpp
+++ b/src/Cech_complex/utilities/cech_persistence.cpp
@@ -131,6 +131,6 @@ void program_options(int argc, char* argv[], std::string& off_file_points, std::
std::cout << "Usage: " << argv[0] << " [options] input-file" << std::endl << std::endl;
std::cout << visible << std::endl;
- std::abort();
+ exit(-1);
}
}
diff --git a/src/Doxyfile b/src/Doxyfile.in
index 020667e9..858a9299 100644
--- a/src/Doxyfile
+++ b/src/Doxyfile.in
@@ -38,7 +38,7 @@ PROJECT_NAME = "GUDHI"
# could be handy for archiving the generated documentation or if some version
# control system is used.
-PROJECT_NUMBER = "2.2.0"
+PROJECT_NUMBER = "@GUDHI_VERSION@"
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
@@ -780,12 +780,12 @@ RECURSIVE = YES
# Note that relative paths are relative to the directory from which doxygen is
# run.
-EXCLUDE = data/ \
- example/ \
- GudhUI/ \
- cmake/ \
- src/cython/ \
- include/gudhi_patches/
+EXCLUDE = data/ \
+ example/ \
+ GudhUI/ \
+ cmake/ \
+ src/cython/ \
+ include/gudhi_patches/
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
# directories that are symbolic links (a Unix file system feature) are excluded
@@ -818,9 +818,9 @@ EXCLUDE_SYMBOLS =
# that contain example code fragments that are included (see the \include
# command).
-EXAMPLE_PATH = biblio/ \
- example/ \
- utilities/
+EXAMPLE_PATH = biblio/ \
+ example/ \
+ utilities/
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
@@ -840,22 +840,7 @@ EXAMPLE_RECURSIVE = NO
# that contain images that are to be included in the documentation (see the
# \image command).
-IMAGE_PATH = doc/Skeleton_blocker/ \
- doc/Alpha_complex/ \
- doc/common/ \
- doc/Cech_complex/ \
- doc/Contraction/ \
- doc/Simplex_tree/ \
- doc/Persistent_cohomology/ \
- doc/Witness_complex/ \
- doc/Bitmap_cubical_complex/ \
- doc/Rips_complex/ \
- doc/Subsampling/ \
- doc/Spatial_searching/ \
- doc/Tangential_complex/ \
- doc/Bottleneck_distance/ \
- doc/Nerve_GIC/ \
- doc/Persistence_representations/
+IMAGE_PATH = @GUDHI_DOXYGEN_IMAGE_PATH@
# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
diff --git a/src/Persistent_cohomology/example/persistence_from_file.cpp b/src/Persistent_cohomology/example/persistence_from_file.cpp
index c40434a4..53456919 100644
--- a/src/Persistent_cohomology/example/persistence_from_file.cpp
+++ b/src/Persistent_cohomology/example/persistence_from_file.cpp
@@ -138,6 +138,6 @@ void program_options(int argc, char * argv[]
std::cout << "Usage: " << argv[0] << " [options] input-file" << std::endl << std::endl;
std::cout << visible << std::endl;
- std::abort();
+ exit(-1);
}
}
diff --git a/src/Persistent_cohomology/example/rips_multifield_persistence.cpp b/src/Persistent_cohomology/example/rips_multifield_persistence.cpp
index 626ec2ef..d6a5bdad 100644
--- a/src/Persistent_cohomology/example/rips_multifield_persistence.cpp
+++ b/src/Persistent_cohomology/example/rips_multifield_persistence.cpp
@@ -149,6 +149,6 @@ void program_options(int argc, char * argv[]
std::cout << "Usage: " << argv[0] << " [options] input-file" << std::endl << std::endl;
std::cout << visible << std::endl;
- std::abort();
+ exit(-1);
}
}
diff --git a/src/Persistent_cohomology/example/rips_persistence_step_by_step.cpp b/src/Persistent_cohomology/example/rips_persistence_step_by_step.cpp
index 7c81fcfb..796cfa3a 100644
--- a/src/Persistent_cohomology/example/rips_persistence_step_by_step.cpp
+++ b/src/Persistent_cohomology/example/rips_persistence_step_by_step.cpp
@@ -161,6 +161,6 @@ void program_options(int argc, char * argv[]
std::cout << "Usage: " << argv[0] << " [options] input-file" << std::endl << std::endl;
std::cout << visible << std::endl;
- std::abort();
+ exit(-1);
}
}
diff --git a/src/Persistent_cohomology/example/rips_persistence_via_boundary_matrix.cpp b/src/Persistent_cohomology/example/rips_persistence_via_boundary_matrix.cpp
index c7607dce..71fc0802 100644
--- a/src/Persistent_cohomology/example/rips_persistence_via_boundary_matrix.cpp
+++ b/src/Persistent_cohomology/example/rips_persistence_via_boundary_matrix.cpp
@@ -167,6 +167,6 @@ void program_options(int argc, char * argv[]
std::cout << "Usage: " << argv[0] << " [options] input-file" << std::endl << std::endl;
std::cout << visible << std::endl;
- std::abort();
+ exit(-1);
}
}
diff --git a/src/Rips_complex/utilities/rips_correlation_matrix_persistence.cpp b/src/Rips_complex/utilities/rips_correlation_matrix_persistence.cpp
index c78677d2..287e8915 100644
--- a/src/Rips_complex/utilities/rips_correlation_matrix_persistence.cpp
+++ b/src/Rips_complex/utilities/rips_correlation_matrix_persistence.cpp
@@ -166,6 +166,6 @@ void program_options(int argc, char* argv[], std::string& csv_matrix_file, std::
std::cout << "Usage: " << argv[0] << " [options] input-file" << std::endl << std::endl;
std::cout << visible << std::endl;
- std::abort();
+ exit(-1);
}
}
diff --git a/src/Rips_complex/utilities/rips_distance_matrix_persistence.cpp b/src/Rips_complex/utilities/rips_distance_matrix_persistence.cpp
index 53191ca7..c73152cf 100644
--- a/src/Rips_complex/utilities/rips_distance_matrix_persistence.cpp
+++ b/src/Rips_complex/utilities/rips_distance_matrix_persistence.cpp
@@ -128,6 +128,6 @@ void program_options(int argc, char* argv[], std::string& csv_matrix_file, std::
std::cout << "Usage: " << argv[0] << " [options] input-file" << std::endl << std::endl;
std::cout << visible << std::endl;
- std::abort();
+ exit(-1);
}
}
diff --git a/src/Rips_complex/utilities/rips_persistence.cpp b/src/Rips_complex/utilities/rips_persistence.cpp
index 7cee927e..9410b9c2 100644
--- a/src/Rips_complex/utilities/rips_persistence.cpp
+++ b/src/Rips_complex/utilities/rips_persistence.cpp
@@ -130,6 +130,6 @@ void program_options(int argc, char* argv[], std::string& off_file_points, std::
std::cout << "Usage: " << argv[0] << " [options] input-file" << std::endl << std::endl;
std::cout << visible << std::endl;
- std::abort();
+ exit(-1);
}
}
diff --git a/src/Rips_complex/utilities/sparse_rips_persistence.cpp b/src/Rips_complex/utilities/sparse_rips_persistence.cpp
index bcd5c2c5..6d4d86fd 100644
--- a/src/Rips_complex/utilities/sparse_rips_persistence.cpp
+++ b/src/Rips_complex/utilities/sparse_rips_persistence.cpp
@@ -128,6 +128,6 @@ void program_options(int argc, char* argv[], std::string& off_file_points, std::
std::cout << "Usage: " << argv[0] << " [options] input-file" << std::endl << std::endl;
std::cout << visible << std::endl;
- std::abort();
+ exit(-1);
}
}
diff --git a/src/Simplex_tree/example/cech_complex_cgal_mini_sphere_3d.cpp b/src/Simplex_tree/example/cech_complex_cgal_mini_sphere_3d.cpp
index 08ed74bb..34092ef6 100644
--- a/src/Simplex_tree/example/cech_complex_cgal_mini_sphere_3d.cpp
+++ b/src/Simplex_tree/example/cech_complex_cgal_mini_sphere_3d.cpp
@@ -171,7 +171,7 @@ void program_options(int argc, char* argv[], std::string& off_file_points, Filtr
std::cout << "Usage: " << argv[0] << " [options] input-file" << std::endl << std::endl;
std::cout << visible << std::endl;
- std::abort();
+ exit(-1);
}
}
diff --git a/src/Witness_complex/utilities/strong_witness_persistence.cpp b/src/Witness_complex/utilities/strong_witness_persistence.cpp
index 9d23df74..f386e992 100644
--- a/src/Witness_complex/utilities/strong_witness_persistence.cpp
+++ b/src/Witness_complex/utilities/strong_witness_persistence.cpp
@@ -151,6 +151,6 @@ void program_options(int argc, char* argv[], int& nbL, std::string& file_name, s
std::cout << "Usage: " << argv[0] << " [options] input-file" << std::endl << std::endl;
std::cout << visible << std::endl;
- std::abort();
+ exit(-1);
}
}
diff --git a/src/Witness_complex/utilities/weak_witness_persistence.cpp b/src/Witness_complex/utilities/weak_witness_persistence.cpp
index 1315d2ba..ea00cfe7 100644
--- a/src/Witness_complex/utilities/weak_witness_persistence.cpp
+++ b/src/Witness_complex/utilities/weak_witness_persistence.cpp
@@ -151,6 +151,6 @@ void program_options(int argc, char* argv[], int& nbL, std::string& file_name, s
std::cout << "Usage: " << argv[0] << " [options] input-file" << std::endl << std::endl;
std::cout << visible << std::endl;
- std::abort();
+ exit(-1);
}
}
diff --git a/src/cmake/modules/FindCython.cmake b/src/cmake/modules/FindCython.cmake
deleted file mode 100644
index 04aed1f8..00000000
--- a/src/cmake/modules/FindCython.cmake
+++ /dev/null
@@ -1,44 +0,0 @@
-# Find the Cython compiler.
-#
-# This code sets the following variables:
-#
-# CYTHON_EXECUTABLE
-#
-# See also UseCython.cmake
-
-#=============================================================================
-# Copyright 2011 Kitware, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#=============================================================================
-
-# Use the Cython executable that lives next to the Python executable
-# if it is a local installation.
-find_package( PythonInterp )
-if( PYTHONINTERP_FOUND )
- get_filename_component( _python_path ${PYTHON_EXECUTABLE} PATH )
- find_program( CYTHON_EXECUTABLE
- NAMES cython cython.bat cython3
- HINTS ${_python_path}
- )
-else()
- find_program( CYTHON_EXECUTABLE
- NAMES cython cython.bat cython3
- )
-endif()
-
-
-include( FindPackageHandleStandardArgs )
-FIND_PACKAGE_HANDLE_STANDARD_ARGS( Cython REQUIRED_VARS CYTHON_EXECUTABLE )
-
-mark_as_advanced( CYTHON_EXECUTABLE )
diff --git a/src/cmake/modules/GUDHI_doxygen_target.cmake b/src/cmake/modules/GUDHI_doxygen_target.cmake
index f3e2d9f5..9e10e566 100644
--- a/src/cmake/modules/GUDHI_doxygen_target.cmake
+++ b/src/cmake/modules/GUDHI_doxygen_target.cmake
@@ -3,14 +3,17 @@ find_package(Doxygen)
if(DOXYGEN_FOUND)
# configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY)
- #starting from cmake 3.9 the usage of DOXYGEN_EXECUTABLE is deprecated
+ # starting from cmake 3.9 the usage of DOXYGEN_EXECUTABLE is deprecated
if(TARGET Doxygen::doxygen)
get_property(DOXYGEN_EXECUTABLE TARGET Doxygen::doxygen PROPERTY IMPORTED_LOCATION)
endif()
add_custom_target(doxygen ${DOXYGEN_EXECUTABLE} ${GUDHI_USER_VERSION_DIR}/Doxyfile
WORKING_DIRECTORY ${GUDHI_USER_VERSION_DIR}
- DEPENDS ${GUDHI_USER_VERSION_DIR}/Doxyfile ${GUDHI_DOXYGEN_DEPENDENCY}
COMMENT "Generating API documentation with Doxygen in ${GUDHI_USER_VERSION_DIR}/doc/html/" VERBATIM)
+ if(TARGET user_version)
+ # In dev version, doxygen target depends on user_version target. Not existing in user version
+ add_dependencies(doxygen user_version)
+ endif()
endif(DOXYGEN_FOUND)
diff --git a/src/cmake/modules/GUDHI_third_party_libraries.cmake b/src/cmake/modules/GUDHI_third_party_libraries.cmake
index 7433f2f3..f03c2177 100644
--- a/src/cmake/modules/GUDHI_third_party_libraries.cmake
+++ b/src/cmake/modules/GUDHI_third_party_libraries.cmake
@@ -8,11 +8,9 @@ endif(NOT Boost_FOUND)
find_package(GMP)
if(GMP_FOUND)
- message(STATUS "GMP_LIBRARIES = ${GMP_LIBRARIES}")
INCLUDE_DIRECTORIES(${GMP_INCLUDE_DIR})
find_package(GMPXX)
if(GMPXX_FOUND)
- message(STATUS "GMPXX_LIBRARIES = ${GMPXX_LIBRARIES}")
INCLUDE_DIRECTORIES(${GMPXX_INCLUDE_DIR})
endif()
endif()
@@ -79,7 +77,6 @@ endif(WITH_GUDHI_USE_TBB)
set(CGAL_WITH_EIGEN3_VERSION 0.0.0)
find_package(Eigen3 3.1.0)
if (EIGEN3_FOUND)
- message(STATUS "Eigen3 version: ${EIGEN3_VERSION}.")
include( ${EIGEN3_USE_FILE} )
set(CGAL_WITH_EIGEN3_VERSION ${CGAL_VERSION})
endif (EIGEN3_FOUND)
@@ -119,7 +116,34 @@ message(STATUS "boost library dirs:" ${Boost_LIBRARY_DIRS})
# Find the correct Python interpreter.
# Can be set with -DPYTHON_EXECUTABLE=/usr/bin/python3 or -DPython_ADDITIONAL_VERSIONS=3 for instance.
-find_package(Cython)
+find_package( PythonInterp )
+
+# find_python_module tries to import module in Python interpreter and to retrieve its version number
+# returns ${PYTHON_MODULE_NAME_UP}_VERSION and ${PYTHON_MODULE_NAME_UP}_FOUND
+function( find_python_module PYTHON_MODULE_NAME )
+ string(TOUPPER ${PYTHON_MODULE_NAME} PYTHON_MODULE_NAME_UP)
+ execute_process(
+ COMMAND ${PYTHON_EXECUTABLE} -c "import ${PYTHON_MODULE_NAME}; print(${PYTHON_MODULE_NAME}.__version__)"
+ RESULT_VARIABLE PYTHON_MODULE_RESULT
+ OUTPUT_VARIABLE PYTHON_MODULE_VERSION
+ ERROR_VARIABLE PYTHON_MODULE_ERROR)
+ if(PYTHON_MODULE_RESULT EQUAL 0)
+ # Remove carriage return
+ string(STRIP ${PYTHON_MODULE_VERSION} PYTHON_MODULE_VERSION)
+ set(${PYTHON_MODULE_NAME_UP}_VERSION ${PYTHON_MODULE_VERSION} PARENT_SCOPE)
+ set(${PYTHON_MODULE_NAME_UP}_FOUND TRUE PARENT_SCOPE)
+ else()
+ unset(${PYTHON_MODULE_NAME_UP}_VERSION PARENT_SCOPE)
+ set(${PYTHON_MODULE_NAME_UP}_FOUND FALSE PARENT_SCOPE)
+ endif()
+endfunction( find_python_module )
+
+if( PYTHONINTERP_FOUND )
+ find_python_module("cython")
+ find_python_module("pytest")
+ find_python_module("matplotlib")
+ find_python_module("numpy")
+endif()
if(NOT GUDHI_CYTHON_PATH)
message(FATAL_ERROR "ERROR: GUDHI_CYTHON_PATH is not valid.")
diff --git a/src/cmake/modules/GUDHI_user_version_target.cmake b/src/cmake/modules/GUDHI_user_version_target.cmake
index 1205966a..d43a6fa6 100644
--- a/src/cmake/modules/GUDHI_user_version_target.cmake
+++ b/src/cmake/modules/GUDHI_user_version_target.cmake
@@ -1,94 +1,95 @@
-# Some functionnalities requires CMake 2.8.11 minimum
-if (NOT CMAKE_VERSION VERSION_LESS 2.8.11)
+# Definition of the custom target user_version
+add_custom_target(user_version)
- # Definition of the custom target user_version
- add_custom_target(user_version)
-
- if(DEFINED USER_VERSION_DIR)
- # set the GUDHI_USER_VERSION_DIR with USER_VERSION_DIR defined by the user
- set(GUDHI_USER_VERSION_DIR ${CMAKE_CURRENT_BINARY_DIR}/${USER_VERSION_DIR})
- else()
- # set the GUDHI_USER_VERSION_DIR with timestamp and Gudhi version number
- string(TIMESTAMP DATE_AND_TIME "%Y-%m-%d-%H-%M-%S")
- set(GUDHI_USER_VERSION_DIR ${CMAKE_CURRENT_BINARY_DIR}/${DATE_AND_TIME}_GUDHI_${GUDHI_VERSION})
- endif()
+if(DEFINED USER_VERSION_DIR)
+ # set the GUDHI_USER_VERSION_DIR with USER_VERSION_DIR defined by the user
+ set(GUDHI_USER_VERSION_DIR ${CMAKE_CURRENT_BINARY_DIR}/${USER_VERSION_DIR})
+else()
+ # set the GUDHI_USER_VERSION_DIR with timestamp and Gudhi version number
+ string(TIMESTAMP DATE_AND_TIME "%Y-%m-%d-%H-%M-%S")
+ set(GUDHI_USER_VERSION_DIR ${CMAKE_CURRENT_BINARY_DIR}/${DATE_AND_TIME}_GUDHI_${GUDHI_VERSION})
+endif()
- set(GUDHI_DOXYGEN_DEPENDENCY user_version)
+add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E
+ make_directory ${GUDHI_USER_VERSION_DIR}
+ COMMENT "user_version creation in ${GUDHI_USER_VERSION_DIR}")
- add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E
- make_directory ${GUDHI_USER_VERSION_DIR}
- COMMENT "user_version creation in ${GUDHI_USER_VERSION_DIR}")
-
- add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E
- copy ${CMAKE_SOURCE_DIR}/Conventions.txt ${GUDHI_USER_VERSION_DIR}/Conventions.txt)
- add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E
- copy ${CMAKE_SOURCE_DIR}/README ${GUDHI_USER_VERSION_DIR}/README)
- add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E
- copy ${CMAKE_SOURCE_DIR}/COPYING ${GUDHI_USER_VERSION_DIR}/COPYING)
- add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E
- copy ${CMAKE_SOURCE_DIR}/src/CMakeLists.txt ${GUDHI_USER_VERSION_DIR}/CMakeLists.txt)
- add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E
- copy ${CMAKE_SOURCE_DIR}/src/Doxyfile ${GUDHI_USER_VERSION_DIR}/Doxyfile)
- add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E
- copy ${CMAKE_SOURCE_DIR}/src/GUDHIConfigVersion.cmake.in ${GUDHI_USER_VERSION_DIR}/GUDHIConfigVersion.cmake.in)
- add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E
- copy ${CMAKE_SOURCE_DIR}/src/GUDHIConfig.cmake.in ${GUDHI_USER_VERSION_DIR}/GUDHIConfig.cmake.in)
- add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E
- copy ${CMAKE_SOURCE_DIR}/CMakeGUDHIVersion.txt ${GUDHI_USER_VERSION_DIR}/CMakeGUDHIVersion.txt)
-
- add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E
- copy_directory ${CMAKE_SOURCE_DIR}/biblio ${GUDHI_USER_VERSION_DIR}/biblio)
- add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E
- copy_directory ${CMAKE_SOURCE_DIR}/src/cython ${GUDHI_USER_VERSION_DIR}/cython)
- add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E
- copy_directory ${CMAKE_SOURCE_DIR}/data ${GUDHI_USER_VERSION_DIR}/data)
- add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E
- copy_directory ${CMAKE_SOURCE_DIR}/src/cmake ${GUDHI_USER_VERSION_DIR}/cmake)
- add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E
- copy_directory ${CMAKE_SOURCE_DIR}/src/GudhUI ${GUDHI_USER_VERSION_DIR}/GudhUI)
-
- set(GUDHI_DIRECTORIES "doc;example;concept;utilities")
- if (CGAL_VERSION VERSION_LESS 4.11.0)
- set(GUDHI_INCLUDE_DIRECTORIES "include/gudhi;include/Miniball;include/gudhi_patches")
- else ()
- set(GUDHI_INCLUDE_DIRECTORIES "include/gudhi;include/Miniball")
- endif ()
+foreach(GUDHI_MODULE ${GUDHI_MODULES_FULL_LIST})
+ set(GUDHI_DOXYGEN_IMAGE_PATH "${GUDHI_DOXYGEN_IMAGE_PATH} doc/${GUDHI_MODULE}/ \\ \n")
+endforeach(GUDHI_MODULE ${GUDHI_MODULES_FULL_LIST})
- foreach(GUDHI_MODULE ${GUDHI_MODULES_FULL_LIST})
- foreach(GUDHI_DIRECTORY ${GUDHI_DIRECTORIES})
- # Find files
- file(GLOB GUDHI_FILES ${CMAKE_SOURCE_DIR}/src/${GUDHI_MODULE}/${GUDHI_DIRECTORY}/*)
+# Generate setup.py file to cythonize Gudhi - This file must be named setup.py by convention
+configure_file(${CMAKE_SOURCE_DIR}/src/Doxyfile.in "${CMAKE_CURRENT_BINARY_DIR}/src/Doxyfile" @ONLY)
- foreach(GUDHI_FILE ${GUDHI_FILES})
- get_filename_component(GUDHI_FILE_NAME ${GUDHI_FILE} NAME)
- # GUDHI_FILE can be a file or a directory
- if(IS_DIRECTORY ${GUDHI_FILE})
- add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E
- copy_directory ${GUDHI_FILE} ${GUDHI_USER_VERSION_DIR}/${GUDHI_DIRECTORY}/${GUDHI_MODULE}/${GUDHI_FILE_NAME})
- else()
- add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E
- copy ${GUDHI_FILE} ${GUDHI_USER_VERSION_DIR}/${GUDHI_DIRECTORY}/${GUDHI_MODULE}/${GUDHI_FILE_NAME})
- endif()
- endforeach()
- endforeach(GUDHI_DIRECTORY ${GUDHI_DIRECTORIES})
+add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E
+ copy ${CMAKE_CURRENT_BINARY_DIR}/src/Doxyfile ${GUDHI_USER_VERSION_DIR}/Doxyfile)
- foreach(GUDHI_INCLUDE_DIRECTORY ${GUDHI_INCLUDE_DIRECTORIES})
- # include files
- file(GLOB GUDHI_INCLUDE_FILES ${CMAKE_SOURCE_DIR}/src/${GUDHI_MODULE}/${GUDHI_INCLUDE_DIRECTORY}/*)
+add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E
+ copy ${CMAKE_SOURCE_DIR}/Conventions.txt ${GUDHI_USER_VERSION_DIR}/Conventions.txt)
+add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E
+ copy ${CMAKE_SOURCE_DIR}/README ${GUDHI_USER_VERSION_DIR}/README)
+add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E
+ copy ${CMAKE_SOURCE_DIR}/COPYING ${GUDHI_USER_VERSION_DIR}/COPYING)
+add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E
+ copy ${CMAKE_SOURCE_DIR}/src/CMakeLists.txt ${GUDHI_USER_VERSION_DIR}/CMakeLists.txt)
+add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E
+ copy ${CMAKE_SOURCE_DIR}/src/GUDHIConfigVersion.cmake.in ${GUDHI_USER_VERSION_DIR}/GUDHIConfigVersion.cmake.in)
+add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E
+ copy ${CMAKE_SOURCE_DIR}/src/GUDHIConfig.cmake.in ${GUDHI_USER_VERSION_DIR}/GUDHIConfig.cmake.in)
+add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E
+ copy ${CMAKE_SOURCE_DIR}/CMakeGUDHIVersion.txt ${GUDHI_USER_VERSION_DIR}/CMakeGUDHIVersion.txt)
- foreach(GUDHI_INCLUDE_FILE ${GUDHI_INCLUDE_FILES})
- get_filename_component(GUDHI_INCLUDE_FILE_NAME ${GUDHI_INCLUDE_FILE} NAME)
- # GUDHI_INCLUDE_FILE can be a file or a directory
- if(IS_DIRECTORY ${GUDHI_INCLUDE_FILE})
- add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E
- copy_directory ${GUDHI_INCLUDE_FILE} ${GUDHI_USER_VERSION_DIR}/${GUDHI_INCLUDE_DIRECTORY}/${GUDHI_INCLUDE_FILE_NAME})
- else()
- add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E
- copy ${GUDHI_INCLUDE_FILE} ${GUDHI_USER_VERSION_DIR}/${GUDHI_INCLUDE_DIRECTORY}/${GUDHI_INCLUDE_FILE_NAME})
- endif()
- endforeach()
- endforeach(GUDHI_INCLUDE_DIRECTORY ${GUDHI_INCLUDE_DIRECTORIES})
+add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E
+ copy_directory ${CMAKE_SOURCE_DIR}/biblio ${GUDHI_USER_VERSION_DIR}/biblio)
+add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E
+ copy_directory ${CMAKE_SOURCE_DIR}/src/cython ${GUDHI_USER_VERSION_DIR}/cython)
+add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E
+ copy_directory ${CMAKE_SOURCE_DIR}/data ${GUDHI_USER_VERSION_DIR}/data)
+add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E
+ copy_directory ${CMAKE_SOURCE_DIR}/src/cmake ${GUDHI_USER_VERSION_DIR}/cmake)
+add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E
+ copy_directory ${CMAKE_SOURCE_DIR}/src/GudhUI ${GUDHI_USER_VERSION_DIR}/GudhUI)
- endforeach(GUDHI_MODULE ${GUDHI_MODULES_FULL_LIST})
+set(GUDHI_DIRECTORIES "doc;example;concept;utilities")
+if (CGAL_VERSION VERSION_LESS 4.11.0)
+ set(GUDHI_INCLUDE_DIRECTORIES "include/gudhi;include/gudhi_patches")
+else ()
+ set(GUDHI_INCLUDE_DIRECTORIES "include/gudhi")
+endif ()
-endif()
+foreach(GUDHI_MODULE ${GUDHI_MODULES_FULL_LIST})
+ foreach(GUDHI_DIRECTORY ${GUDHI_DIRECTORIES})
+ # Find files
+ file(GLOB GUDHI_FILES ${CMAKE_SOURCE_DIR}/src/${GUDHI_MODULE}/${GUDHI_DIRECTORY}/*)
+
+ foreach(GUDHI_FILE ${GUDHI_FILES})
+ get_filename_component(GUDHI_FILE_NAME ${GUDHI_FILE} NAME)
+ # GUDHI_FILE can be a file or a directory
+ if(IS_DIRECTORY ${GUDHI_FILE})
+ add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E
+ copy_directory ${GUDHI_FILE} ${GUDHI_USER_VERSION_DIR}/${GUDHI_DIRECTORY}/${GUDHI_MODULE}/${GUDHI_FILE_NAME})
+ else()
+ add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E
+ copy ${GUDHI_FILE} ${GUDHI_USER_VERSION_DIR}/${GUDHI_DIRECTORY}/${GUDHI_MODULE}/${GUDHI_FILE_NAME})
+ endif()
+ endforeach()
+ endforeach(GUDHI_DIRECTORY ${GUDHI_DIRECTORIES})
+
+ foreach(GUDHI_INCLUDE_DIRECTORY ${GUDHI_INCLUDE_DIRECTORIES})
+ # include files
+ file(GLOB GUDHI_INCLUDE_FILES ${CMAKE_SOURCE_DIR}/src/${GUDHI_MODULE}/${GUDHI_INCLUDE_DIRECTORY}/*)
+
+ foreach(GUDHI_INCLUDE_FILE ${GUDHI_INCLUDE_FILES})
+ get_filename_component(GUDHI_INCLUDE_FILE_NAME ${GUDHI_INCLUDE_FILE} NAME)
+ # GUDHI_INCLUDE_FILE can be a file or a directory
+ if(IS_DIRECTORY ${GUDHI_INCLUDE_FILE})
+ add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E
+ copy_directory ${GUDHI_INCLUDE_FILE} ${GUDHI_USER_VERSION_DIR}/${GUDHI_INCLUDE_DIRECTORY}/${GUDHI_INCLUDE_FILE_NAME})
+ else()
+ add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E
+ copy ${GUDHI_INCLUDE_FILE} ${GUDHI_USER_VERSION_DIR}/${GUDHI_INCLUDE_DIRECTORY}/${GUDHI_INCLUDE_FILE_NAME})
+ endif()
+ endforeach()
+ endforeach(GUDHI_INCLUDE_DIRECTORY ${GUDHI_INCLUDE_DIRECTORIES})
+
+endforeach(GUDHI_MODULE ${GUDHI_MODULES_FULL_LIST}) \ No newline at end of file
diff --git a/src/cython/CMakeLists.txt b/src/cython/CMakeLists.txt
index 8f1dec76..1849a6ec 100644
--- a/src/cython/CMakeLists.txt
+++ b/src/cython/CMakeLists.txt
@@ -16,17 +16,51 @@ endfunction( add_gudhi_cython_lib )
# THE_TEST is the python test file name (without .py extension) containing tests functions
function( add_gudhi_py_test THE_TEST )
- # use ${PYTHON_EXECUTABLE} -B, otherwise a __pycache__ directory is created in sources by python
- # use py.test no cache provider, otherwise a .cache file is created in sources by py.test
- add_test(NAME ${THE_TEST}_py_test
- WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
- COMMAND ${PYTHON_EXECUTABLE} -B -m pytest -p no:cacheprovider ${CMAKE_CURRENT_SOURCE_DIR}/test/${THE_TEST}.py)
+ if(PYTEST_FOUND)
+ # use ${PYTHON_EXECUTABLE} -B, otherwise a __pycache__ directory is created in sources by python
+ # use py.test no cache provider, otherwise a .cache file is created in sources by py.test
+ add_test(NAME ${THE_TEST}_py_test
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMAND ${PYTHON_EXECUTABLE} -B -m pytest -p no:cacheprovider ${CMAKE_CURRENT_SOURCE_DIR}/test/${THE_TEST}.py)
+ endif()
endfunction( add_gudhi_py_test )
+# Set gudhi.__debug_info__
+# WARNING : to be done before gudhi.pyx.in configure_file
+function( add_gudhi_debug_info DEBUG_INFO )
+ set(GUDHI_CYTHON_DEBUG_INFO "${GUDHI_CYTHON_DEBUG_INFO} \"${DEBUG_INFO}\\n\" \\\n" PARENT_SCOPE)
+endfunction( add_gudhi_debug_info )
+
if(CYTHON_FOUND)
- message("++ ${PYTHON_EXECUTABLE} v.${PYTHON_VERSION_STRING} - Cython is ${CYTHON_EXECUTABLE} - Sphinx is ${SPHINX_PATH}")
+ set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}off_reader;")
+ set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}simplex_tree;")
+ set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}rips_complex;")
+ set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}cubical_complex;")
+ set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}periodic_cubical_complex;")
+ set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}persistence_graphical_tools;")
+ set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}reader_utils;")
+ set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}witness_complex;")
+ set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}strong_witness_complex;")
+
+ add_gudhi_debug_info("Python version ${PYTHON_VERSION_STRING}")
+ add_gudhi_debug_info("Cython version ${CYTHON_VERSION}")
+ if(PYTEST_FOUND)
+ add_gudhi_debug_info("Pytest version ${PYTEST_VERSION}")
+ endif()
+ if(MATPLOTLIB_FOUND)
+ add_gudhi_debug_info("Matplotlib version ${MATPLOTLIB_VERSION}")
+ endif()
+ if(NUMPY_FOUND)
+ add_gudhi_debug_info("Numpy version ${NUMPY_VERSION}")
+ endif()
+ if(MATPLOTLIB_FOUND AND NUMPY_FOUND)
+ set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}persistence_graphical_tools;")
+ else()
+ set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MODULES}persistence_graphical_tools;")
+ endif()
+ message("++ ${PYTHON_EXECUTABLE} v.${PYTHON_VERSION_STRING} - Cython is ${CYTHON_VERSION} - Sphinx is ${SPHINX_PATH}")
set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DBOOST_RESULT_OF_USE_DECLTYPE', ")
set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DBOOST_ALL_NO_LIB', ")
set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DBOOST_SYSTEM_NO_DEPRECATED', ")
@@ -49,25 +83,49 @@ if(CYTHON_FOUND)
endif()
if (EIGEN3_FOUND)
+ add_gudhi_debug_info("Eigen3 version ${EIGEN3_VERSION}")
# No problem, even if no CGAL found
set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_EIGEN3_ENABLED', ")
endif (EIGEN3_FOUND)
if (NOT CGAL_VERSION VERSION_LESS 4.8.1)
set(GUDHI_CYTHON_BOTTLENECK_DISTANCE "include '${CMAKE_CURRENT_SOURCE_DIR}/cython/bottleneck_distance.pyx'")
+ set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}bottleneck_distance;")
set(GUDHI_CYTHON_NERVE_GIC "include '${CMAKE_CURRENT_SOURCE_DIR}/cython/nerve_gic.pyx'")
- endif (NOT CGAL_VERSION VERSION_LESS 4.8.1)
+ set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}nerve_gic;")
+ else()
+ set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MISSING_MODULES}bottleneck_distance;")
+ set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MISSING_MODULES}nerve_gic;")
+ endif ()
if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1)
set(GUDHI_CYTHON_SUBSAMPLING "include '${CMAKE_CURRENT_SOURCE_DIR}/cython/subsampling.pyx'")
+ set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}subsampling;")
set(GUDHI_CYTHON_TANGENTIAL_COMPLEX "include '${CMAKE_CURRENT_SOURCE_DIR}/cython/tangential_complex.pyx'")
- endif (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1)
+ set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}tangential_complex;")
+ else()
+ set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MISSING_MODULES}subsampling;")
+ set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MISSING_MODULES}tangential_complex;")
+ endif ()
if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.7.0)
set(GUDHI_CYTHON_ALPHA_COMPLEX "include '${CMAKE_CURRENT_SOURCE_DIR}/cython/alpha_complex.pyx'")
- endif (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.7.0)
+ set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}alpha_complex;")
+ else()
+ set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MISSING_MODULES}alpha_complex;")
+ endif ()
if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.6.0)
set(GUDHI_CYTHON_EUCLIDEAN_WITNESS_COMPLEX
"include '${CMAKE_CURRENT_SOURCE_DIR}/cython/euclidean_witness_complex.pyx'\ninclude '${CMAKE_CURRENT_SOURCE_DIR}/cython/euclidean_strong_witness_complex.pyx'\n")
- endif (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.6.0)
+ set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}euclidean_witness_complex;")
+ set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}euclidean_strong_witness_complex;")
+ else()
+ set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MISSING_MODULES}euclidean_witness_complex;")
+ set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MISSING_MODULES}euclidean_strong_witness_complex;")
+ endif ()
+
+ add_gudhi_debug_info("Installed modules are: ${GUDHI_CYTHON_MODULES}")
+ if(GUDHI_CYTHON_MISSING_MODULES)
+ add_gudhi_debug_info("Missing modules are: ${GUDHI_CYTHON_MISSING_MODULES}")
+ endif()
if(CGAL_FOUND)
can_cgal_use_cxx11_thread_local()
@@ -77,8 +135,10 @@ if(CYTHON_FOUND)
endif()
# Add CGAL compilation args
if(CGAL_HEADER_ONLY)
+ add_gudhi_debug_info("CGAL header only version ${CGAL_VERSION}")
set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_HEADER_ONLY', ")
else(CGAL_HEADER_ONLY)
+ add_gudhi_debug_info("CGAL version ${CGAL_VERSION}")
add_gudhi_cython_lib(${CGAL_LIBRARY})
set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${CGAL_LIBRARIES_DIR}', ")
# If CGAL is not header only, CGAL library may link with boost system,
@@ -87,10 +147,12 @@ if(CYTHON_FOUND)
endif(CGAL_HEADER_ONLY)
# GMP and GMPXX are not required, but if present, CGAL will link with them.
if(GMP_FOUND)
+ add_gudhi_debug_info("GMP_LIBRARIES = ${GMP_LIBRARIES}")
set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_USE_GMP', ")
add_gudhi_cython_lib(${GMP_LIBRARIES})
set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${GMP_LIBRARIES_DIR}', ")
if(GMPXX_FOUND)
+ add_gudhi_debug_info("GMPXX_LIBRARIES = ${GMPXX_LIBRARIES}")
set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_USE_GMPXX', ")
add_gudhi_cython_lib(${GMPXX_LIBRARIES})
set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${GMPXX_LIBRARIES_DIR}', ")
@@ -112,6 +174,7 @@ if(CYTHON_FOUND)
set(GUDHI_CYTHON_INCLUDE_DIRS "${GUDHI_CYTHON_INCLUDE_DIRS}'${CMAKE_SOURCE_DIR}/${GUDHI_CYTHON_PATH}/include', ")
if (TBB_FOUND AND WITH_GUDHI_USE_TBB)
+ add_gudhi_debug_info("TBB version ${TBB_INTERFACE_VERSION} found and used")
set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DGUDHI_USE_TBB', ")
add_gudhi_cython_lib(${TBB_RELEASE_LIBRARY})
add_gudhi_cython_lib(${TBB_MALLOC_RELEASE_LIBRARY})
@@ -152,27 +215,29 @@ if(CYTHON_FOUND)
${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/alpha_rips_persistence_bottleneck_distance.py"
-f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -t 0.15 -d 3)
- # Tangential
- add_test(NAME tangential_complex_plain_homology_from_off_file_example_py_test
- WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
- COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}"
- ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/tangential_complex_plain_homology_from_off_file_example.py"
- --no-diagram -i 2 -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off)
-
- add_gudhi_py_test(test_tangential_complex)
-
- # Witness complex AND Subsampling
- add_test(NAME euclidean_strong_witness_complex_diagram_persistence_from_off_file_example_py_test
- WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
- COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}"
- ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py"
- --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -a 1.0 -n 20 -d 2)
-
- add_test(NAME euclidean_witness_complex_diagram_persistence_from_off_file_example_py_test
- WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
- COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}"
- ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/euclidean_witness_complex_diagram_persistence_from_off_file_example.py"
- --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -a 1.0 -n 20 -d 2)
+ if(MATPLOTLIB_FOUND AND NUMPY_FOUND)
+ # Tangential
+ add_test(NAME tangential_complex_plain_homology_from_off_file_example_py_test
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}"
+ ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/tangential_complex_plain_homology_from_off_file_example.py"
+ --no-diagram -i 2 -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off)
+
+ add_gudhi_py_test(test_tangential_complex)
+
+ # Witness complex AND Subsampling
+ add_test(NAME euclidean_strong_witness_complex_diagram_persistence_from_off_file_example_py_test
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}"
+ ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py"
+ --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -a 1.0 -n 20 -d 2)
+
+ add_test(NAME euclidean_witness_complex_diagram_persistence_from_off_file_example_py_test
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}"
+ ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/euclidean_witness_complex_diagram_persistence_from_off_file_example.py"
+ --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -a 1.0 -n 20 -d 2)
+ endif()
# Subsampling
add_gudhi_py_test(test_subsampling)
@@ -226,11 +291,13 @@ if(CYTHON_FOUND)
COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}"
${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/alpha_complex_from_points_example.py")
- add_test(NAME alpha_complex_diagram_persistence_from_off_file_example_py_test
+ if(MATPLOTLIB_FOUND AND NUMPY_FOUND)
+ add_test(NAME alpha_complex_diagram_persistence_from_off_file_example_py_test
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}"
${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/alpha_complex_diagram_persistence_from_off_file_example.py"
--no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -a 0.6)
+ endif()
add_gudhi_py_test(test_alpha_complex)
@@ -249,26 +316,30 @@ if(CYTHON_FOUND)
${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/periodic_cubical_complex_barcode_persistence_from_perseus_file_example.py"
--no-barcode -f ${CMAKE_SOURCE_DIR}/data/bitmap/CubicalTwoSphere.txt)
- add_test(NAME random_cubical_complex_persistence_example_py_test
- WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
- COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}"
- ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/random_cubical_complex_persistence_example.py"
- 10 10 10)
+ if(NUMPY_FOUND)
+ add_test(NAME random_cubical_complex_persistence_example_py_test
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}"
+ ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/random_cubical_complex_persistence_example.py"
+ 10 10 10)
+ endif()
add_gudhi_py_test(test_cubical_complex)
# Rips
- add_test(NAME rips_complex_diagram_persistence_from_distance_matrix_file_example_py_test
- WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
- COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}"
- ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py"
- --no-diagram -f ${CMAKE_SOURCE_DIR}/data/distance_matrix/lower_triangular_distance_matrix.csv -e 12.0 -d 3)
-
- add_test(NAME rips_complex_diagram_persistence_from_off_file_example_py_test
- WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
- COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}"
- ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/example/rips_complex_diagram_persistence_from_off_file_example.py
- --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -e 0.25 -d 3)
+ if(MATPLOTLIB_FOUND AND NUMPY_FOUND)
+ add_test(NAME rips_complex_diagram_persistence_from_distance_matrix_file_example_py_test
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}"
+ ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py"
+ --no-diagram -f ${CMAKE_SOURCE_DIR}/data/distance_matrix/lower_triangular_distance_matrix.csv -e 12.0 -d 3)
+
+ add_test(NAME rips_complex_diagram_persistence_from_off_file_example_py_test
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}"
+ ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/example/rips_complex_diagram_persistence_from_off_file_example.py
+ --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -e 0.25 -d 3)
+ endif()
add_test(NAME rips_complex_from_points_example_py_test
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
@@ -297,7 +368,7 @@ if(CYTHON_FOUND)
add_gudhi_py_test(test_reader_utils)
# Documentation generation is available through sphinx - requires all modules
- if(SPHINX_PATH AND NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1)
+ if(SPHINX_PATH AND MATPLOTLIB_FOUND AND NUMPY_FOUND AND NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1)
set (GUDHI_SPHINX_MESSAGE "Generating API documentation with Sphinx in ${CMAKE_CURRENT_BINARY_DIR}/sphinx/")
# User warning - Sphinx is a static pages generator, and configured to work fine with user_version
# Images and biblio warnings because not found on developper version
@@ -317,5 +388,5 @@ if(CYTHON_FOUND)
COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}"
${SPHINX_PATH} -b doctest ${CMAKE_CURRENT_SOURCE_DIR}/doc ${CMAKE_CURRENT_BINARY_DIR}/doctest)
- endif(SPHINX_PATH AND NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1)
+ endif()
endif(CYTHON_FOUND)
diff --git a/src/cython/cython/persistence_graphical_tools.py b/src/cython/cython/persistence_graphical_tools.py
index 216ab8d6..314bd6db 100755
--- a/src/cython/cython/persistence_graphical_tools.py
+++ b/src/cython/cython/persistence_graphical_tools.py
@@ -1,8 +1,3 @@
-import matplotlib.pyplot as plt
-import matplotlib.patches as mpatches
-import numpy as np
-import os
-
"""This file is part of the Gudhi Library. The Gudhi library
(Geometric Understanding in Higher Dimensions) is a generic C++
library for computational topology.
@@ -29,187 +24,197 @@ __author__ = "Vincent Rouvreau, Bertrand Michel"
__copyright__ = "Copyright (C) 2016 Inria"
__license__ = "GPL v3"
-def __min_birth_max_death(persistence, band=0.):
- """This function returns (min_birth, max_death) from the persistence.
-
- :param persistence: The persistence to plot.
- :type persistence: list of tuples(dimension, tuple(birth, death)).
- :param band: band
- :type band: float.
- :returns: (float, float) -- (min_birth, max_death).
- """
- # Look for minimum birth date and maximum death date for plot optimisation
- max_death = 0
- min_birth = persistence[0][1][0]
- for interval in reversed(persistence):
- if float(interval[1][1]) != float('inf'):
- if float(interval[1][1]) > max_death:
- max_death = float(interval[1][1])
- if float(interval[1][0]) > max_death:
- max_death = float(interval[1][0])
- if float(interval[1][0]) < min_birth:
- min_birth = float(interval[1][0])
- if band > 0.:
- max_death += band
- return (min_birth, max_death)
+try:
+ import matplotlib.pyplot as plt
+ import matplotlib.patches as mpatches
+ import numpy as np
+ import os
+
+ def __min_birth_max_death(persistence, band=0.):
+ """This function returns (min_birth, max_death) from the persistence.
+
+ :param persistence: The persistence to plot.
+ :type persistence: list of tuples(dimension, tuple(birth, death)).
+ :param band: band
+ :type band: float.
+ :returns: (float, float) -- (min_birth, max_death).
+ """
+ # Look for minimum birth date and maximum death date for plot optimisation
+ max_death = 0
+ min_birth = persistence[0][1][0]
+ for interval in reversed(persistence):
+ if float(interval[1][1]) != float('inf'):
+ if float(interval[1][1]) > max_death:
+ max_death = float(interval[1][1])
+ if float(interval[1][0]) > max_death:
+ max_death = float(interval[1][0])
+ if float(interval[1][0]) < min_birth:
+ min_birth = float(interval[1][0])
+ if band > 0.:
+ max_death += band
+ return (min_birth, max_death)
-"""
-Only 13 colors for the palette
-"""
-palette = ['#ff0000', '#00ff00', '#0000ff', '#00ffff', '#ff00ff', '#ffff00',
- '#000000', '#880000', '#008800', '#000088', '#888800', '#880088',
- '#008888']
-
-def plot_persistence_barcode(persistence=[], persistence_file='', alpha=0.6,
- max_barcodes=1000, inf_delta=0.1, legend=False):
- """This function plots the persistence bar code from persistence values list
- or from a :doc:`persistence file <fileformats>`.
-
- :param persistence: Persistence values list.
- :type persistence: list of tuples(dimension, tuple(birth, death)).
- :param persistence_file: A :doc:`persistence file <fileformats>` style name
- (reset persistence if both are set).
- :type persistence_file: string
- :param alpha: barcode transparency value (0.0 transparent through 1.0 opaque - default is 0.6).
- :type alpha: float.
- :param max_barcodes: number of maximal barcodes to be displayed.
- Set it to 0 to see all, Default value is 1000.
- (persistence will be sorted by life time if max_barcodes is set)
- :type max_barcodes: int.
- :param inf_delta: Infinity is placed at ((max_death - min_birth) x inf_delta).
- A reasonable value is between 0.05 and 0.5 - default is 0.1.
- :type inf_delta: float.
- :returns: A matplotlib object containing horizontal bar plot of persistence
- (launch `show()` method on it to display it).
"""
- if persistence_file is not '':
- if os.path.isfile(persistence_file):
- # Reset persistence
- persistence = []
- diag = read_persistence_intervals_grouped_by_dimension(persistence_file=persistence_file)
- for key in diag.keys():
- for persistence_interval in diag[key]:
- persistence.append((key, persistence_interval))
- else:
- print("file " + persistence_file + " not found.")
- return None
-
- if max_barcodes > 0 and max_barcodes < len(persistence):
- # Sort by life time, then takes only the max_plots elements
- persistence = sorted(persistence, key=lambda life_time: life_time[1][1]-life_time[1][0], reverse=True)[:max_barcodes]
-
- persistence = sorted(persistence, key=lambda birth: birth[1][0])
-
- (min_birth, max_death) = __min_birth_max_death(persistence)
- ind = 0
- delta = ((max_death - min_birth) * inf_delta)
- # Replace infinity values with max_death + delta for bar code to be more
- # readable
- infinity = max_death + delta
- axis_start = min_birth - delta
- # Draw horizontal bars in loop
- for interval in reversed(persistence):
- if float(interval[1][1]) != float('inf'):
- # Finite death case
- plt.barh(ind, (interval[1][1] - interval[1][0]), height=0.8,
- left = interval[1][0], alpha=alpha,
- color = palette[interval[0]],
- linewidth=0)
- else:
- # Infinite death case for diagram to be nicer
- plt.barh(ind, (infinity - interval[1][0]), height=0.8,
- left = interval[1][0], alpha=alpha,
- color = palette[interval[0]],
- linewidth=0)
- ind = ind + 1
-
- if legend:
- dimensions = list(set(item[0] for item in persistence))
- plt.legend(handles=[mpatches.Patch(color=palette[dim],
- label=str(dim)) for dim in dimensions],
- loc='lower right')
- plt.title('Persistence barcode')
- # Ends plot on infinity value and starts a little bit before min_birth
- plt.axis([axis_start, infinity, 0, ind])
- return plt
-
-def plot_persistence_diagram(persistence=[], persistence_file='', alpha=0.6,
- band=0., max_plots=1000, inf_delta=0.1, legend=False):
- """This function plots the persistence diagram from persistence values list
- or from a :doc:`persistence file <fileformats>`.
-
- :param persistence: Persistence values list.
- :type persistence: list of tuples(dimension, tuple(birth, death)).
- :param persistence_file: A :doc:`persistence file <fileformats>` style name
- (reset persistence if both are set).
- :type persistence_file: string
- :param alpha: plot transparency value (0.0 transparent through 1.0 opaque - default is 0.6).
- :type alpha: float.
- :param band: band (not displayed if :math:`\leq` 0. - default is 0.)
- :type band: float.
- :param max_plots: number of maximal plots to be displayed
- Set it to 0 to see all, Default value is 1000.
- (persistence will be sorted by life time if max_plots is set)
- :type max_plots: int.
- :param inf_delta: Infinity is placed at ((max_death - min_birth) x inf_delta).
- A reasonable value is between 0.05 and 0.5 - default is 0.1.
- :type inf_delta: float.
- :returns: A matplotlib object containing diagram plot of persistence
- (launch `show()` method on it to display it).
+ Only 13 colors for the palette
"""
- if persistence_file is not '':
- if os.path.isfile(persistence_file):
- # Reset persistence
- persistence = []
- diag = read_persistence_intervals_grouped_by_dimension(persistence_file=persistence_file)
- for key in diag.keys():
- for persistence_interval in diag[key]:
- persistence.append((key, persistence_interval))
- else:
- print("file " + persistence_file + " not found.")
- return None
-
- if max_plots > 0 and max_plots < len(persistence):
- # Sort by life time, then takes only the max_plots elements
- persistence = sorted(persistence, key=lambda life_time: life_time[1][1]-life_time[1][0], reverse=True)[:max_plots]
-
- (min_birth, max_death) = __min_birth_max_death(persistence, band)
- ind = 0
- delta = ((max_death - min_birth) * inf_delta)
- # Replace infinity values with max_death + delta for diagram to be more
- # readable
- infinity = max_death + delta
- axis_start = min_birth - delta
-
- # line display of equation : birth = death
- x = np.linspace(axis_start, infinity, 1000)
- # infinity line and text
- plt.plot(x, x, color='k', linewidth=1.0)
- plt.plot(x, [infinity] * len(x), linewidth=1.0, color='k', alpha=alpha)
- plt.text(axis_start, infinity, r'$\infty$', color='k', alpha=alpha)
- # bootstrap band
- if band > 0.:
- plt.fill_between(x, x, x+band, alpha=alpha, facecolor='red')
-
- # Draw points in loop
- for interval in reversed(persistence):
- if float(interval[1][1]) != float('inf'):
- # Finite death case
- plt.scatter(interval[1][0], interval[1][1], alpha=alpha,
- color = palette[interval[0]])
- else:
- # Infinite death case for diagram to be nicer
- plt.scatter(interval[1][0], infinity, alpha=alpha,
- color = palette[interval[0]])
- ind = ind + 1
-
- if legend:
- dimensions = list(set(item[0] for item in persistence))
- plt.legend(handles=[mpatches.Patch(color=palette[dim], label=str(dim)) for dim in dimensions])
-
- plt.title('Persistence diagram')
- plt.xlabel('Birth')
- plt.ylabel('Death')
- # Ends plot on infinity value and starts a little bit before min_birth
- plt.axis([axis_start, infinity, axis_start, infinity + delta])
- return plt
+ palette = ['#ff0000', '#00ff00', '#0000ff', '#00ffff', '#ff00ff', '#ffff00',
+ '#000000', '#880000', '#008800', '#000088', '#888800', '#880088',
+ '#008888']
+
+ def plot_persistence_barcode(persistence=[], persistence_file='', alpha=0.6,
+ max_barcodes=1000, inf_delta=0.1, legend=False):
+ """This function plots the persistence bar code from persistence values list
+ or from a :doc:`persistence file <fileformats>`.
+
+ :param persistence: Persistence values list.
+ :type persistence: list of tuples(dimension, tuple(birth, death)).
+ :param persistence_file: A :doc:`persistence file <fileformats>` style name
+ (reset persistence if both are set).
+ :type persistence_file: string
+ :param alpha: barcode transparency value (0.0 transparent through 1.0 opaque - default is 0.6).
+ :type alpha: float.
+ :param max_barcodes: number of maximal barcodes to be displayed.
+ Set it to 0 to see all, Default value is 1000.
+ (persistence will be sorted by life time if max_barcodes is set)
+ :type max_barcodes: int.
+ :param inf_delta: Infinity is placed at ((max_death - min_birth) x inf_delta).
+ A reasonable value is between 0.05 and 0.5 - default is 0.1.
+ :type inf_delta: float.
+ :returns: A matplotlib object containing horizontal bar plot of persistence
+ (launch `show()` method on it to display it).
+ """
+ if persistence_file is not '':
+ if os.path.isfile(persistence_file):
+ # Reset persistence
+ persistence = []
+ diag = read_persistence_intervals_grouped_by_dimension(persistence_file=persistence_file)
+ for key in diag.keys():
+ for persistence_interval in diag[key]:
+ persistence.append((key, persistence_interval))
+ else:
+ print("file " + persistence_file + " not found.")
+ return None
+
+ if max_barcodes > 0 and max_barcodes < len(persistence):
+ # Sort by life time, then takes only the max_plots elements
+ persistence = sorted(persistence, key=lambda life_time: life_time[1][1]-life_time[1][0], reverse=True)[:max_barcodes]
+
+ persistence = sorted(persistence, key=lambda birth: birth[1][0])
+
+ (min_birth, max_death) = __min_birth_max_death(persistence)
+ ind = 0
+ delta = ((max_death - min_birth) * inf_delta)
+ # Replace infinity values with max_death + delta for bar code to be more
+ # readable
+ infinity = max_death + delta
+ axis_start = min_birth - delta
+ # Draw horizontal bars in loop
+ for interval in reversed(persistence):
+ if float(interval[1][1]) != float('inf'):
+ # Finite death case
+ plt.barh(ind, (interval[1][1] - interval[1][0]), height=0.8,
+ left = interval[1][0], alpha=alpha,
+ color = palette[interval[0]],
+ linewidth=0)
+ else:
+ # Infinite death case for diagram to be nicer
+ plt.barh(ind, (infinity - interval[1][0]), height=0.8,
+ left = interval[1][0], alpha=alpha,
+ color = palette[interval[0]],
+ linewidth=0)
+ ind = ind + 1
+
+ if legend:
+ dimensions = list(set(item[0] for item in persistence))
+ plt.legend(handles=[mpatches.Patch(color=palette[dim],
+ label=str(dim)) for dim in dimensions],
+ loc='lower right')
+ plt.title('Persistence barcode')
+ # Ends plot on infinity value and starts a little bit before min_birth
+ plt.axis([axis_start, infinity, 0, ind])
+ return plt
+
+ def plot_persistence_diagram(persistence=[], persistence_file='', alpha=0.6,
+ band=0., max_plots=1000, inf_delta=0.1, legend=False):
+ """This function plots the persistence diagram from persistence values list
+ or from a :doc:`persistence file <fileformats>`.
+
+ :param persistence: Persistence values list.
+ :type persistence: list of tuples(dimension, tuple(birth, death)).
+ :param persistence_file: A :doc:`persistence file <fileformats>` style name
+ (reset persistence if both are set).
+ :type persistence_file: string
+ :param alpha: plot transparency value (0.0 transparent through 1.0 opaque - default is 0.6).
+ :type alpha: float.
+ :param band: band (not displayed if :math:`\leq` 0. - default is 0.)
+ :type band: float.
+ :param max_plots: number of maximal plots to be displayed
+ Set it to 0 to see all, Default value is 1000.
+ (persistence will be sorted by life time if max_plots is set)
+ :type max_plots: int.
+ :param inf_delta: Infinity is placed at ((max_death - min_birth) x inf_delta).
+ A reasonable value is between 0.05 and 0.5 - default is 0.1.
+ :type inf_delta: float.
+ :returns: A matplotlib object containing diagram plot of persistence
+ (launch `show()` method on it to display it).
+ """
+ if persistence_file is not '':
+ if os.path.isfile(persistence_file):
+ # Reset persistence
+ persistence = []
+ diag = read_persistence_intervals_grouped_by_dimension(persistence_file=persistence_file)
+ for key in diag.keys():
+ for persistence_interval in diag[key]:
+ persistence.append((key, persistence_interval))
+ else:
+ print("file " + persistence_file + " not found.")
+ return None
+
+ if max_plots > 0 and max_plots < len(persistence):
+ # Sort by life time, then takes only the max_plots elements
+ persistence = sorted(persistence, key=lambda life_time: life_time[1][1]-life_time[1][0], reverse=True)[:max_plots]
+
+ (min_birth, max_death) = __min_birth_max_death(persistence, band)
+ ind = 0
+ delta = ((max_death - min_birth) * inf_delta)
+ # Replace infinity values with max_death + delta for diagram to be more
+ # readable
+ infinity = max_death + delta
+ axis_start = min_birth - delta
+
+ # line display of equation : birth = death
+ x = np.linspace(axis_start, infinity, 1000)
+ # infinity line and text
+ plt.plot(x, x, color='k', linewidth=1.0)
+ plt.plot(x, [infinity] * len(x), linewidth=1.0, color='k', alpha=alpha)
+ plt.text(axis_start, infinity, r'$\infty$', color='k', alpha=alpha)
+ # bootstrap band
+ if band > 0.:
+ plt.fill_between(x, x, x+band, alpha=alpha, facecolor='red')
+
+ # Draw points in loop
+ for interval in reversed(persistence):
+ if float(interval[1][1]) != float('inf'):
+ # Finite death case
+ plt.scatter(interval[1][0], interval[1][1], alpha=alpha,
+ color = palette[interval[0]])
+ else:
+ # Infinite death case for diagram to be nicer
+ plt.scatter(interval[1][0], infinity, alpha=alpha,
+ color = palette[interval[0]])
+ ind = ind + 1
+
+ if legend:
+ dimensions = list(set(item[0] for item in persistence))
+ plt.legend(handles=[mpatches.Patch(color=palette[dim], label=str(dim)) for dim in dimensions])
+
+ plt.title('Persistence diagram')
+ plt.xlabel('Birth')
+ plt.ylabel('Death')
+ # Ends plot on infinity value and starts a little bit before min_birth
+ plt.axis([axis_start, infinity, axis_start, infinity + delta])
+ return plt
+
+except ImportError:
+ # Continue in case of import error, functions won't be available
+ pass
diff --git a/src/cython/doc/installation.rst b/src/cython/doc/installation.rst
index 43ff85c5..43576ec9 100644
--- a/src/cython/doc/installation.rst
+++ b/src/cython/doc/installation.rst
@@ -47,9 +47,61 @@ following command in a terminal:
export PYTHONPATH='$PYTHONPATH:/path-to-gudhi/build/cython'
ctest -R py_test
-If tests fail, please try to :code:`import gudhi` and check the errors.
+Debugging issues
+================
+
+If tests fail, please check your PYTHONPATH and try to :code:`import gudhi`
+and check the errors.
The problem can come from a third-party library bad link or installation.
+If :code:`import gudhi` succeeds, please have a look to debug informations:
+
+.. code-block:: python
+
+ import gudhi
+ print(gudhi.__debug_info__)
+
+You shall have something like:
+
+.. code-block:: none
+
+ Python version 2.7.15
+ Cython version 0.26.1
+ Eigen3 version 3.1.1
+ Installed modules are: off_reader;simplex_tree;rips_complex;cubical_complex;periodic_cubical_complex;
+ persistence_graphical_tools;reader_utils;witness_complex;strong_witness_complex;alpha_complex;
+ euclidean_witness_complex;euclidean_strong_witness_complex;
+ Missing modules are: bottleneck_distance;nerve_gic;subsampling;tangential_complex;persistence_graphical_tools;
+ CGAL version 4.7.1000
+ GMP_LIBRARIES = /usr/lib/x86_64-linux-gnu/libgmp.so
+ GMPXX_LIBRARIES = /usr/lib/x86_64-linux-gnu/libgmpxx.so
+ TBB version 9107 found and used
+
+Here, you can see that bottleneck_distance, nerve_gic, subsampling and
+tangential_complex are missing because of the CGAL version.
+persistence_graphical_tools is not available as numpy and matplotlib are not
+available.
+Unitary tests cannot be run as pytest is missing.
+
+A complete configuration would be :
+
+.. code-block:: none
+
+ Python version 3.6.5
+ Cython version 0.28.2
+ Pytest version 3.3.2
+ Matplotlib version 2.2.2
+ Numpy version 1.14.5
+ Eigen3 version 3.3.4
+ Installed modules are: off_reader;simplex_tree;rips_complex;cubical_complex;periodic_cubical_complex;
+ persistence_graphical_tools;reader_utils;witness_complex;strong_witness_complex;persistence_graphical_tools;
+ bottleneck_distance;nerve_gic;subsampling;tangential_complex;alpha_complex;euclidean_witness_complex;
+ euclidean_strong_witness_complex;
+ CGAL header only version 4.11.0
+ GMP_LIBRARIES = /usr/lib/x86_64-linux-gnu/libgmp.so
+ GMPXX_LIBRARIES = /usr/lib/x86_64-linux-gnu/libgmpxx.so
+ TBB version 9107 found and used
+
Documentation
=============
diff --git a/src/cython/gudhi.pyx.in b/src/cython/gudhi.pyx.in
index 56a72b04..0d4b966b 100644
--- a/src/cython/gudhi.pyx.in
+++ b/src/cython/gudhi.pyx.in
@@ -26,6 +26,7 @@ __license__ = "GPL v3"
__version__ = "@GUDHI_VERSION@"
# This variable is used by doctest to find files
__root_source_dir__ = "@CMAKE_SOURCE_DIR@"
+__debug_info__ = @GUDHI_CYTHON_DEBUG_INFO@
include '@CMAKE_CURRENT_SOURCE_DIR@/cython/off_reader.pyx'
include '@CMAKE_CURRENT_SOURCE_DIR@/cython/simplex_tree.pyx'
diff --git a/src/cython/setup.py.in b/src/cython/setup.py.in
index ee381a1b..4037aab6 100644
--- a/src/cython/setup.py.in
+++ b/src/cython/setup.py.in
@@ -46,9 +46,5 @@ setup(
version='@GUDHI_VERSION@',
url='http://gudhi.gforge.inria.fr/',
ext_modules = cythonize(gudhi),
- install_requires = [
- "matplotlib",
- "numpy",
- "cython",
- ],
+ install_requires = ["cython",],
)