summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorROUVREAU Vincent <vincent.rouvreau@inria.fr>2021-03-15 19:19:58 +0100
committerROUVREAU Vincent <vincent.rouvreau@inria.fr>2021-03-15 19:19:58 +0100
commitd2ae3d4e9f17649813f64bbc3b00d540b23f21dd (patch)
treef336fe75a32d469e50a6a52304a9616680cef498
parenta1674773ce5ed9060e5ecf173e5b75cd22f85b1a (diff)
Add read_weights in reader_utils. Add exceptions for file not found and inconsistency in alpha ctor. Add UT accordingly
-rw-r--r--src/python/gudhi/alpha_complex.pyx41
-rw-r--r--src/python/gudhi/reader_utils.pyx16
-rwxr-xr-xsrc/python/test/test_alpha_complex.py55
-rwxr-xr-xsrc/python/test/test_reader_utils.py49
4 files changed, 139 insertions, 22 deletions
diff --git a/src/python/gudhi/alpha_complex.pyx b/src/python/gudhi/alpha_complex.pyx
index 0fea3f37..b7c20f74 100644
--- a/src/python/gudhi/alpha_complex.pyx
+++ b/src/python/gudhi/alpha_complex.pyx
@@ -16,11 +16,12 @@ from libcpp.utility cimport pair
from libcpp.string cimport string
from libcpp cimport bool
from libc.stdint cimport intptr_t
+import errno
import os
from gudhi.simplex_tree cimport *
from gudhi.simplex_tree import SimplexTree
-from gudhi import read_points_from_off_file
+from gudhi import read_points_from_off_file, read_weights
__author__ = "Vincent Rouvreau"
__copyright__ = "Copyright (C) 2016 Inria"
@@ -55,7 +56,7 @@ cdef class AlphaComplex:
cdef Alpha_complex_interface * this_ptr
# Fake constructor that does nothing but documenting the constructor
- def __init__(self, points=None, off_file='', precision='safe'):
+ def __init__(self, points=[], off_file='', weights=[], weight_file='', precision='safe'):
"""AlphaComplex constructor.
:param points: A list of points in d-Dimension.
@@ -65,12 +66,24 @@ cdef class AlphaComplex:
read and overwritten by the points in the `off_file`.
:type off_file: string
+ :param weights: A list of weights. If set, the number of weights must correspond to the
+ number of points.
+ :type weights: list of double
+
+ :param weight_file: A file containing a list of weights (one per line).
+ `weights` are read and overwritten by the weights in the `weight_file`.
+ If set, the number of weights must correspond to the number of points.
+ :type weight_file: string
+
:param precision: Alpha complex precision can be 'fast', 'safe' or 'exact'. Default is 'safe'.
:type precision: string
+
+ :raises FileNotFoundError: If `off_file` and/or `weight_file` is set but not found.
+ :raises ValueError: In case of inconsistency between the number of points and weights.
"""
# The real cython constructor
- def __cinit__(self, points = [], off_file = '', precision = 'safe'):
+ def __cinit__(self, points = [], off_file = '', weights=[], weight_file='', precision = 'safe'):
assert precision in ['fast', 'safe', 'exact'], "Alpha complex precision can only be 'fast', 'safe' or 'exact'"
cdef bool fast = precision == 'fast'
cdef bool exact = precision == 'exact'
@@ -79,12 +92,28 @@ cdef class AlphaComplex:
if os.path.isfile(off_file):
points = read_points_from_off_file(off_file = off_file)
else:
- print("file " + off_file + " not found.")
+ raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT), off_file)
+
+ if weight_file:
+ if os.path.isfile(weight_file):
+ weights = read_weights(weight_file = weight_file)
+ else:
+ raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT), weight_file)
+
# need to copy the points to use them without the gil
cdef vector[vector[double]] pts
+ cdef vector[double] wgts
pts = points
- with nogil:
- self.this_ptr = new Alpha_complex_interface(pts, fast, exact)
+ if len(weights) == 0:
+ with nogil:
+ self.this_ptr = new Alpha_complex_interface(pts, fast, exact)
+ else:
+ if len(weights) == len(points):
+ wgts = weights
+ with nogil:
+ self.this_ptr = new Alpha_complex_interface(pts, fast, exact)
+ else:
+ raise ValueError("Inconsistency between the number of points and weights")
def __dealloc__(self):
if self.this_ptr != NULL:
diff --git a/src/python/gudhi/reader_utils.pyx b/src/python/gudhi/reader_utils.pyx
index fe1c3a2e..f997ad3e 100644
--- a/src/python/gudhi/reader_utils.pyx
+++ b/src/python/gudhi/reader_utils.pyx
@@ -84,3 +84,19 @@ def read_persistence_intervals_in_dimension(persistence_file='', only_this_dim=-
'utf-8'), only_this_dim))
print("file " + persistence_file + " not set or not found.")
return []
+
+def read_weights(weight_file=''):
+ """Reads a file containing weights. Only one float value per line is read and stored.
+ The return value is a `list(weight)`.
+
+ :param weight_file: A weight file style name (one weight per line).
+ :type weight_file: string
+
+ :returns: A list of weights.
+ :rtype: List[float]
+ """
+ weights=[]
+ with open(weight_file, 'r') as wfile:
+ weights = [float(wline) for wline in wfile if wline.strip()]
+ return weights
+
diff --git a/src/python/test/test_alpha_complex.py b/src/python/test/test_alpha_complex.py
index 8f1424ec..35059339 100755
--- a/src/python/test/test_alpha_complex.py
+++ b/src/python/test/test_alpha_complex.py
@@ -261,3 +261,58 @@ def _3d_tetrahedrons(precision):
def test_3d_tetrahedrons():
for precision in ['fast', 'safe', 'exact']:
_3d_tetrahedrons(precision)
+
+def test_non_existing_off_file():
+ with pytest.raises(FileNotFoundError):
+ alpha = gd.AlphaComplex(off_file="pouetpouettralala.toubiloubabdou")
+
+def test_non_existing_weight_file():
+ off_file = open("alphacomplexdoc.off", "w")
+ off_file.write("OFF \n" \
+ "7 0 0 \n" \
+ "1.0 1.0 0.0\n" \
+ "7.0 0.0 0.0\n" \
+ "4.0 6.0 0.0\n" \
+ "9.0 6.0 0.0\n" \
+ "0.0 14.0 0.0\n" \
+ "2.0 19.0 0.0\n" \
+ "9.0 17.0 0.0\n" )
+ off_file.close()
+
+ with pytest.raises(FileNotFoundError):
+ alpha = gd.AlphaComplex(off_file="alphacomplexdoc.off",
+ weight_file="pouetpouettralala.toubiloubabdou")
+
+
+def test_inconsistency_off_weight_file():
+ off_file = open("alphacomplexdoc.off", "w")
+ off_file.write("OFF \n" \
+ "7 0 0 \n" \
+ "1.0 1.0 0.0\n" \
+ "7.0 0.0 0.0\n" \
+ "4.0 6.0 0.0\n" \
+ "9.0 6.0 0.0\n" \
+ "0.0 14.0 0.0\n" \
+ "2.0 19.0 0.0\n" \
+ "9.0 17.0 0.0\n" )
+ off_file.close()
+ # 7 points, 8 weights, on purpose
+ weight_file = open("alphacomplexdoc.wgt", "w")
+ weight_file.write("5.0\n" \
+ "2.0\n" \
+ "7.0\n" \
+ "4.0\n" \
+ "9.0\n" \
+ "0.0\n" \
+ "2.0\n" \
+ "9.0\n" )
+ weight_file.close()
+
+ with pytest.raises(ValueError):
+ alpha = gd.AlphaComplex(off_file="alphacomplexdoc.off",
+ weight_file="alphacomplexdoc.wgt")
+
+ # 7 points, 6 weights, on purpose
+ with pytest.raises(ValueError):
+ alpha = gd.AlphaComplex(off_file="alphacomplexdoc.off",
+ weights=[1., 2., 3., 4., 5., 6.])
diff --git a/src/python/test/test_reader_utils.py b/src/python/test/test_reader_utils.py
index 90da6651..91de9ba0 100755
--- a/src/python/test/test_reader_utils.py
+++ b/src/python/test/test_reader_utils.py
@@ -8,8 +8,9 @@
- YYYY/MM Author: Description of the modification
"""
-import gudhi
+import gudhi as gd
import numpy as np
+from pytest import raises
__author__ = "Vincent Rouvreau"
__copyright__ = "Copyright (C) 2017 Inria"
@@ -18,7 +19,7 @@ __license__ = "MIT"
def test_non_existing_csv_file():
# Try to open a non existing file
- matrix = gudhi.read_lower_triangular_matrix_from_csv_file(
+ matrix = gd.read_lower_triangular_matrix_from_csv_file(
csv_file="pouetpouettralala.toubiloubabdou"
)
assert matrix == []
@@ -29,7 +30,7 @@ def test_full_square_distance_matrix_csv_file():
test_file = open("full_square_distance_matrix.csv", "w")
test_file.write("0;1;2;3;\n1;0;4;5;\n2;4;0;6;\n3;5;6;0;")
test_file.close()
- matrix = gudhi.read_lower_triangular_matrix_from_csv_file(
+ matrix = gd.read_lower_triangular_matrix_from_csv_file(
csv_file="full_square_distance_matrix.csv"
)
assert matrix == [[], [1.0], [2.0, 4.0], [3.0, 5.0, 6.0]]
@@ -40,7 +41,7 @@ def test_lower_triangular_distance_matrix_csv_file():
test_file = open("lower_triangular_distance_matrix.csv", "w")
test_file.write("\n1,\n2,3,\n4,5,6,\n7,8,9,10,")
test_file.close()
- matrix = gudhi.read_lower_triangular_matrix_from_csv_file(
+ matrix = gd.read_lower_triangular_matrix_from_csv_file(
csv_file="lower_triangular_distance_matrix.csv", separator=","
)
assert matrix == [[], [1.0], [2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0, 10.0]]
@@ -48,11 +49,11 @@ def test_lower_triangular_distance_matrix_csv_file():
def test_non_existing_persistence_file():
# Try to open a non existing file
- persistence = gudhi.read_persistence_intervals_grouped_by_dimension(
+ persistence = gd.read_persistence_intervals_grouped_by_dimension(
persistence_file="pouetpouettralala.toubiloubabdou"
)
assert persistence == []
- persistence = gudhi.read_persistence_intervals_in_dimension(
+ persistence = gd.read_persistence_intervals_in_dimension(
persistence_file="pouetpouettralala.toubiloubabdou", only_this_dim=1
)
np.testing.assert_array_equal(persistence, [])
@@ -65,21 +66,21 @@ def test_read_persistence_intervals_without_dimension():
"# Simple persistence diagram without dimension\n2.7 3.7\n9.6 14.\n34.2 34.974\n3. inf"
)
test_file.close()
- persistence = gudhi.read_persistence_intervals_in_dimension(
+ persistence = gd.read_persistence_intervals_in_dimension(
persistence_file="persistence_intervals_without_dimension.pers"
)
np.testing.assert_array_equal(
persistence, [(2.7, 3.7), (9.6, 14.0), (34.2, 34.974), (3.0, float("Inf"))]
)
- persistence = gudhi.read_persistence_intervals_in_dimension(
+ persistence = gd.read_persistence_intervals_in_dimension(
persistence_file="persistence_intervals_without_dimension.pers", only_this_dim=0
)
np.testing.assert_array_equal(persistence, [])
- persistence = gudhi.read_persistence_intervals_in_dimension(
+ persistence = gd.read_persistence_intervals_in_dimension(
persistence_file="persistence_intervals_without_dimension.pers", only_this_dim=1
)
np.testing.assert_array_equal(persistence, [])
- persistence = gudhi.read_persistence_intervals_grouped_by_dimension(
+ persistence = gd.read_persistence_intervals_grouped_by_dimension(
persistence_file="persistence_intervals_without_dimension.pers"
)
assert persistence == {
@@ -94,29 +95,29 @@ def test_read_persistence_intervals_with_dimension():
"# Simple persistence diagram with dimension\n0 2.7 3.7\n1 9.6 14.\n3 34.2 34.974\n1 3. inf"
)
test_file.close()
- persistence = gudhi.read_persistence_intervals_in_dimension(
+ persistence = gd.read_persistence_intervals_in_dimension(
persistence_file="persistence_intervals_with_dimension.pers"
)
np.testing.assert_array_equal(
persistence, [(2.7, 3.7), (9.6, 14.0), (34.2, 34.974), (3.0, float("Inf"))]
)
- persistence = gudhi.read_persistence_intervals_in_dimension(
+ persistence = gd.read_persistence_intervals_in_dimension(
persistence_file="persistence_intervals_with_dimension.pers", only_this_dim=0
)
np.testing.assert_array_equal(persistence, [(2.7, 3.7)])
- persistence = gudhi.read_persistence_intervals_in_dimension(
+ persistence = gd.read_persistence_intervals_in_dimension(
persistence_file="persistence_intervals_with_dimension.pers", only_this_dim=1
)
np.testing.assert_array_equal(persistence, [(9.6, 14.0), (3.0, float("Inf"))])
- persistence = gudhi.read_persistence_intervals_in_dimension(
+ persistence = gd.read_persistence_intervals_in_dimension(
persistence_file="persistence_intervals_with_dimension.pers", only_this_dim=2
)
np.testing.assert_array_equal(persistence, [])
- persistence = gudhi.read_persistence_intervals_in_dimension(
+ persistence = gd.read_persistence_intervals_in_dimension(
persistence_file="persistence_intervals_with_dimension.pers", only_this_dim=3
)
np.testing.assert_array_equal(persistence, [(34.2, 34.974)])
- persistence = gudhi.read_persistence_intervals_grouped_by_dimension(
+ persistence = gd.read_persistence_intervals_grouped_by_dimension(
persistence_file="persistence_intervals_with_dimension.pers"
)
assert persistence == {
@@ -124,3 +125,19 @@ def test_read_persistence_intervals_with_dimension():
1: [(9.6, 14.0), (3.0, float("Inf"))],
3: [(34.2, 34.974)],
}
+
+
+def test_non_existing_weights_file():
+ with raises(FileNotFoundError):
+ # Try to open a non existing file
+ persistence = gd.read_weights(weight_file="pouetpouettralala.toubiloubabdou")
+
+def test_read_weights():
+ # Create test file
+ test_file = open("test_read_weights.wgt", "w")
+ test_file.write(
+ "2.7\n 9.6 \n\t34.2\n3.\t\n\n"
+ )
+ test_file.close()
+ weights = gd.read_weights(weight_file = "test_read_weights.wgt")
+ assert weights == [2.7, 9.6, 34.2, 3.]