Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TVB-2719 lint: Use same convention everywhere #63

Merged
merged 5 commits into from
Aug 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 1 addition & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,6 @@ jobs:
language: shell
- stage: lint
language: python
python: 3.8
install: pip install flake8
script:
# stop the build if there are Python syntax errors or undefined names
- flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings
- flake8 . --exit-zero
- flake8 . --show-source --statistics
80 changes: 40 additions & 40 deletions gdist.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -30,24 +30,24 @@

"""
This module defines a Cython wrapper for the geodesic distance C++ library.
The algorithm (implemented in C++) extends Mitchell, Mount and Papadimitriou
The algorithm (implemented in C++) extends Mitchell, Mount and Papadimitriou
(1987) and was written by Danil Kirsanov
(http://code.google.com/archive/p/geodesic/).
The interface definitions and wrapper functions are written in Cython syntax
(http://cython.org/) and provide an API for some of the classes, functions and
constants useful for calculating the geodesic distance.
The interface definitions and wrapper functions are written in Cython syntax
(http://cython.org/) and provide an API for some of the classes, functions and
constants useful for calculating the geodesic distance.
To compile, and build gdist.so using Cython::
python setup.py build_ext --inplace
.. moduleauthor:: Gaurav Malhotra <Gaurav@tvb.invalid>
.. moduleauthor:: Stuart A. Knock <Stuart@tvb.invalid>
"""

#For compatible datatypes
# For compatible datatypes
import numpy
cimport numpy

Expand Down Expand Up @@ -103,12 +103,12 @@ cdef get_mesh(
cdef vector[double] points
cdef vector[unsigned] faces

# Map numpy array of mesh "vertices" to C++ vector of mesh "points"
# Map numpy array of mesh "vertices" to C++ vector of mesh "points"
cdef numpy.float64_t coord
for coord in vertices.flatten():
points.push_back(coord)

# Map numpy array of mesh "triangles" to C++ vector of mesh "faces"
# Map numpy array of mesh "triangles" to C++ vector of mesh "faces"
cdef numpy.int32_t indx
for indx in triangles.flatten():
faces.push_back(indx)
Expand All @@ -118,10 +118,10 @@ cdef get_mesh(

def compute_gdist(numpy.ndarray[numpy.float64_t, ndim=2] vertices,
numpy.ndarray[numpy.int32_t, ndim=2] triangles,
numpy.ndarray[numpy.int32_t, ndim=1] source_indices = None,
numpy.ndarray[numpy.int32_t, ndim=1] target_indices = None,
double max_distance = GEODESIC_INF,
bool is_one_indexed = False):
numpy.ndarray[numpy.int32_t, ndim=1] source_indices=None,
numpy.ndarray[numpy.int32_t, ndim=1] target_indices=None,
double max_distance=GEODESIC_INF,
bool is_one_indexed=False):
"""This is the wrapper function for computing geodesic distance between a
set of sources and targets on a mesh surface.
Expand All @@ -147,12 +147,12 @@ def compute_gdist(numpy.ndarray[numpy.float64_t, ndim=2] vertices,
specifying max_distance will limit the targets to those vertices
within max_distance of a source. If no source_indices are provided,
it defaults to 0.
NOTE: This is the function to use when specifying localised stimuli and
parameter variations. For efficiently using the whole mesh as sources, such
as is required to represent local connectivity within the cortex, see the
as is required to represent local connectivity within the cortex, see the
local_gdist_matrix() function.
Basic usage then looks like::
>>> import numpy
>>> temp = numpy.loadtxt("data/flat_triangular_mesh.txt", skiprows=1)
Expand All @@ -164,7 +164,7 @@ def compute_gdist(numpy.ndarray[numpy.float64_t, ndim=2] vertices,
>>> gdist.compute_gdist(vertices, triangles, source_indices=src, target_indices=trg)
array([0.2])
"""

cdef bool propagate_on_max_distance = False
cdef vector[double] points
cdef vector[unsigned] faces
Expand All @@ -191,16 +191,16 @@ def compute_gdist(numpy.ndarray[numpy.float64_t, ndim=2] vertices,
)
# TODO: Basically copies, can be improved as memory is contiguous.
distances = numpy.asarray(distances)
distances[distances==max_distance] = numpy.inf
distances[distances == max_distance] = numpy.inf
return distances


def local_gdist_matrix(numpy.ndarray[numpy.float64_t, ndim=2] vertices,
numpy.ndarray[numpy.int32_t, ndim=2] triangles,
double max_distance = GEODESIC_INF,
bool is_one_indexed = False):
"""This is the wrapper function for computing geodesic distance from every
vertex on the surface to all those within a distance ``max_distance`` of
double max_distance=GEODESIC_INF,
bool is_one_indexed=False):
"""This is the wrapper function for computing geodesic distance from every
vertex on the surface to all those within a distance ``max_distance`` of
them.
Args:
Expand All @@ -212,12 +212,12 @@ def local_gdist_matrix(numpy.ndarray[numpy.float64_t, ndim=2] vertices,
certain distance from the source.
is_one_indexed (bool): defines if the index of the triangles data is
one-indexed.
Returns:
scipy.sparse.csc_matrix((N, N), dtype=numpy.float64): where N
is the number of vertices, specifying the shortest distance from all
is the number of vertices, specifying the shortest distance from all
vertices to all the vertices within max_distance.
Basic usage then looks like::
>>> import numpy
>>> temp = numpy.loadtxt("data/flat_triangular_mesh.txt", skiprows=1)
Expand All @@ -230,33 +230,33 @@ def local_gdist_matrix(numpy.ndarray[numpy.float64_t, ndim=2] vertices,
Runtime and guesstimated memory usage as a function of max_distance for the
reg_13 cortical surface mesh, ie containing 2**13 vertices per hemisphere.
::
::
[[10, 20, 30, 40, 50, 60, 70, 80, 90, 100], # mm
[19, 28, 49, 81, 125, 181, 248, 331, 422, 522], # s
[ 3, 13, 30, 56, 89, 129, 177, 232, 292, 358]] # MB]
where memory is a min-guestimate given by: mem_req = nnz * 8 / 1024 / 1024.
"""

"""
NOTE: The best_source loop could be sped up considerably by restricting
NOTE: The best_source loop could be sped up considerably by restricting
targets to those vertices within max_distance of the source, however,
this will first require the efficient extraction of this information
from the propgate step...
"""

cdef Mesh amesh
get_mesh(vertices, triangles, amesh, is_one_indexed)

# Define and create object for exact algorithm on that mesh:
cdef GeodesicAlgorithmExact *algorithm = new GeodesicAlgorithmExact(&amesh)

cdef vector[SurfacePoint] source, targets
cdef Py_ssize_t N = vertices.shape[0]
cdef Py_ssize_t k
cdef Py_ssize_t kk
cdef numpy.float64_t distance = 0

# Add all vertices as targets
for k in range(N):
targets.push_back(SurfacePoint(&amesh.vertices()[k]))
Expand All @@ -268,10 +268,10 @@ def local_gdist_matrix(numpy.ndarray[numpy.float64_t, ndim=2] vertices,
source.push_back(SurfacePoint(&amesh.vertices()[k]))
algorithm.propagate(source, max_distance, NULL)
source.pop_back()
for kk in range(N): #TODO: Reduce to vertices reached during propagate.

for kk in range(N): # TODO: Reduce to vertices reached during propagate.
algorithm.best_source(targets[kk], distance)

if (
distance is not GEODESIC_INF
and distance is not 0
Expand All @@ -280,16 +280,16 @@ def local_gdist_matrix(numpy.ndarray[numpy.float64_t, ndim=2] vertices,
rows.append(k)
columns.append(kk)
data.append(distance)

return scipy.sparse.csc_matrix((data, (rows, columns)), shape=(N, N))


def distance_matrix_of_selected_points(
numpy.ndarray[numpy.float64_t, ndim=2] vertices,
numpy.ndarray[numpy.int32_t, ndim=2] triangles,
numpy.ndarray[numpy.int32_t, ndim=1] points,
double max_distance = GEODESIC_INF,
bool is_one_indexed = False
double max_distance=GEODESIC_INF,
bool is_one_indexed=False
):
"""Function for calculating pairwise geodesic distance for a set of points
within a distance ``max_distance`` of them.
Expand All @@ -310,7 +310,7 @@ def distance_matrix_of_selected_points(
scipy.sparse.csc_matrix((N, N), dtype=numpy.float64): where N
is the number of vertices, specifying the pairwise distances among
the given points.
Basic usage then looks like::
>>> import numpy
>>> temp = numpy.loadtxt("data/flat_triangular_mesh.txt", skiprows=1)
Expand All @@ -329,7 +329,7 @@ def distance_matrix_of_selected_points(
cdef vector[unsigned] columns
cdef vector[double] distance_matrix
for index_point, point in enumerate(points):
target_indices = points[index_point + 1 :]
target_indices = points[index_point + 1:]

source_index = numpy.array([point], dtype=numpy.int32)
target_indices = numpy.array(target_indices, dtype=numpy.int32)
Expand Down
16 changes: 16 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[flake8]
filename = *.py, *.pyx
# E501: Line too long (82 > 79 characters)
# W503: Line break occurred before a binary operator
ignore = E501, W503
# E225: Missing whitespace around operator
# E226: Missing whitespace around arithmetic operator
# E227: Missing whitespace around bitwise or shift operator (flake8 will complain
# for the pointers (treated as multiplication operator in python) and
# address-of (&) operator (bitwise and operator in python))
# E266: Too many leading '#' for block comment
# E402: Module level import not at top of file (flake8 treats the cimports as
# non-import code and thus complains about the subsequent imports as imports not
# being on the top)
# E999: SyntaxError
per_file_ignores = gdist.pyx: E225, E226, E227, E266, E402, E999
29 changes: 15 additions & 14 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
"""

import os
import shutil
import setuptools

import numpy
Expand All @@ -50,14 +49,14 @@


compiler_directives = {
'language_level': 3,
"language_level": 3,
}

# Disable assertions; one is failing geodesic_mesh.h:405
define_macros = [('NDEBUG', 1)]
define_macros = [("NDEBUG", 1)]

if 'COVERAGE' in os.environ:
compiler_directives['linetrace'] = True
if "COVERAGE" in os.environ:
compiler_directives["linetrace"] = True
define_macros.append(("CYTHON_TRACE_NOGIL", "1"))

GEODESIC_NAME = "gdist"
Expand All @@ -68,8 +67,8 @@
sources=["gdist.pyx"], # Filename of Cython source
language="c++", # Cython create C++ source
define_macros=define_macros,
extra_compile_args=['--std=c++14'],
extra_link_args=['--std=c++14'],
extra_compile_args=["--std=c++14"],
extra_link_args=["--std=c++14"],
include_dirs=[numpy.get_include(), "geodesic_library"],
)
]
Expand All @@ -81,11 +80,12 @@

TEAM = "Danil Kirsanov, Gaurav Malhotra and Stuart Knock"

INSTALL_REQUIREMENTS = ['numpy', 'scipy', 'cython']
INSTALL_REQUIREMENTS = ["numpy", "scipy", "cython"]

with open(os.path.join(os.path.dirname(__file__), 'README.rst')) as fd:
with open(os.path.join(os.path.dirname(__file__), "README.rst")) as fd:
DESCRIPTION = fd.read()


class new_build_ext(build_ext):
def finalize_options(self):
self.distribution.ext_modules = cythonize(
Expand All @@ -100,18 +100,19 @@ def finalize_options(self):
self.include_dirs.append(numpy.get_include())
super().finalize_options()


setuptools.setup(
name="tvb-" + GEODESIC_NAME,
version='2.1.0',
version="2.1.0",
ext_modules=GEODESIC_MODULE,
include_dirs=INCLUDE_DIRS,
cmdclass={"build_ext": new_build_ext},
install_requires=INSTALL_REQUIREMENTS,
description="Compute geodesic distances",
long_description=DESCRIPTION,
license='GPL v3',
license="GPL v3",
author=TEAM,
author_email='tvb.admin@thevirtualbrain.org',
url='https://github.com/the-virtual-brain/tvb-gdist',
keywords="gdist geodesic distance geo tvb"
author_email="tvb.admin@thevirtualbrain.org",
url="https://github.com/the-virtual-brain/tvb-gdist",
keywords="gdist geodesic distance geo tvb",
)
14 changes: 6 additions & 8 deletions tests/test_equality_with_stable.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,19 @@


def test_equality_with_stable():
surface_datas = ['inner_skull_642', 'outer_skull_642', 'scalp_1082']
surface_datas = ["inner_skull_642", "outer_skull_642", "scalp_1082"]
for surface_data in surface_datas:
expected = np.loadtxt(
f'data/surface_data/{surface_data}/gdist_matrix.txt')
f"data/surface_data/{surface_data}/gdist_matrix.txt"
)
vertices = np.loadtxt(
f'data/surface_data/{surface_data}/vertices.txt',
dtype=np.float64,
f"data/surface_data/{surface_data}/vertices.txt", dtype=np.float64,
)
triangles = np.loadtxt(
f'data/surface_data/{surface_data}/triangles.txt',
dtype=np.int32,
f"data/surface_data/{surface_data}/triangles.txt", dtype=np.int32,
)
actual = gdist.local_gdist_matrix(
vertices=vertices,
triangles=triangles,
vertices=vertices, triangles=triangles,
)
actual = actual.toarray()
np.testing.assert_array_almost_equal(actual, expected)