From ad1123c3c7cfddc1c15e9933b96af08ef3398b3c Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Wed, 9 Nov 2022 17:46:39 +0100 Subject: New write_points_to_off_file --- src/python/gudhi/off_utils.pyx | 57 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 src/python/gudhi/off_utils.pyx (limited to 'src/python/gudhi/off_utils.pyx') diff --git a/src/python/gudhi/off_utils.pyx b/src/python/gudhi/off_utils.pyx new file mode 100644 index 00000000..155575d5 --- /dev/null +++ b/src/python/gudhi/off_utils.pyx @@ -0,0 +1,57 @@ +# This file is part of the Gudhi Library - https://gudhi.inria.fr/ - +# which is released under MIT. +# See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full +# license details. +# Author(s): Vincent Rouvreau +# +# Copyright (C) 2016 Inria +# +# Modification(s): +# - YYYY/MM Author: Description of the modification + +from __future__ import print_function +from cython cimport numeric +from libcpp.vector cimport vector +from libcpp.string cimport string +cimport cython +import errno +import os +import numpy as np + +__author__ = "Vincent Rouvreau" +__copyright__ = "Copyright (C) 2016 Inria" +__license__ = "MIT" + +cdef extern from "Off_reader_interface.h" namespace "Gudhi": + vector[vector[double]] read_points_from_OFF_file(string off_file) + +def read_points_from_off_file(off_file=''): + """Read points from OFF file. + + :param off_file: An OFF file style name. + :type off_file: string + + :returns: The point set. + :rtype: List[List[float]] + """ + if off_file: + if os.path.isfile(off_file): + return read_points_from_OFF_file(off_file.encode('utf-8')) + else: + raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT), + off_file) + +@cython.embedsignature(True) +def write_points_to_off_file(fname, points): + """Write points to an OFF file. + + A simple wrapper for `numpy.savetxt`. + + :param fname: Name of the OFF file. + :type fname: str or file handle + :param points: Point coordinates. + :type points: numpy array of shape (n, dim) + """ + points = np.array(points, copy=False) + assert len(points.shape) == 2 + np.savetxt(fname, points, header='nOFF\n{} {} 0 0'.format(points.shape[1], points.shape[0]), comments='') -- cgit v1.2.3 From 4118bcb622c624130e768d9116a7e147a5e45c68 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Fri, 11 Nov 2022 18:00:42 +0100 Subject: Link to OFF format --- src/python/gudhi/off_utils.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/python/gudhi/off_utils.pyx') diff --git a/src/python/gudhi/off_utils.pyx b/src/python/gudhi/off_utils.pyx index 155575d5..a8142791 100644 --- a/src/python/gudhi/off_utils.pyx +++ b/src/python/gudhi/off_utils.pyx @@ -26,7 +26,7 @@ cdef extern from "Off_reader_interface.h" namespace "Gudhi": vector[vector[double]] read_points_from_OFF_file(string off_file) def read_points_from_off_file(off_file=''): - """Read points from OFF file. + """Read points from an `OFF file `_. :param off_file: An OFF file style name. :type off_file: string @@ -43,7 +43,7 @@ def read_points_from_off_file(off_file=''): @cython.embedsignature(True) def write_points_to_off_file(fname, points): - """Write points to an OFF file. + """Write points to an `OFF file `_. A simple wrapper for `numpy.savetxt`. -- cgit v1.2.3 From 2d5039b7eeb16116ab859076aa0a93f092250d88 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Fri, 11 Nov 2022 18:59:42 +0100 Subject: Special case for writing 3d OFF --- src/python/CMakeLists.txt | 1 + src/python/gudhi/off_utils.pyx | 7 ++++++- src/python/test/test_off.py | 21 +++++++++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 src/python/test/test_off.py (limited to 'src/python/gudhi/off_utils.pyx') diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt index 35ddb778..32ec13bd 100644 --- a/src/python/CMakeLists.txt +++ b/src/python/CMakeLists.txt @@ -546,6 +546,7 @@ if(PYTHONINTERP_FOUND) # Reader utils add_gudhi_py_test(test_reader_utils) + add_gudhi_py_test(test_off) # Wasserstein if(OT_FOUND) diff --git a/src/python/gudhi/off_utils.pyx b/src/python/gudhi/off_utils.pyx index a8142791..9276c7b0 100644 --- a/src/python/gudhi/off_utils.pyx +++ b/src/python/gudhi/off_utils.pyx @@ -54,4 +54,9 @@ def write_points_to_off_file(fname, points): """ points = np.array(points, copy=False) assert len(points.shape) == 2 - np.savetxt(fname, points, header='nOFF\n{} {} 0 0'.format(points.shape[1], points.shape[0]), comments='') + dim = points.shape[1] + if dim == 3: + head = 'OFF\n{} 0 0'.format(points.shape[0]) + else: + head = 'nOFF\n{} {} 0 0'.format(dim, points.shape[0]) + np.savetxt(fname, points, header=head, comments='') diff --git a/src/python/test/test_off.py b/src/python/test/test_off.py new file mode 100644 index 00000000..69bfa1f9 --- /dev/null +++ b/src/python/test/test_off.py @@ -0,0 +1,21 @@ +""" This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. + Author(s): Marc Glisse + + Copyright (C) 2022 Inria + + Modification(s): + - YYYY/MM Author: Description of the modification +""" + +import gudhi as gd +import numpy as np +import pytest + + +def test_off_rw(): + for dim in range(2, 6): + X = np.random.rand(123, dim) + gd.write_points_to_off_file('rand.off', X) + Y = gd.read_points_from_off_file('rand.off') + assert Y == pytest.approx(X) -- cgit v1.2.3