Skip to content

Commit

Permalink
doc: better docstrings for sphere graphs
Browse files Browse the repository at this point in the history
  • Loading branch information
mdeff committed Nov 23, 2020
1 parent 67fd47e commit 2ba2372
Show file tree
Hide file tree
Showing 6 changed files with 233 additions and 107 deletions.
2 changes: 1 addition & 1 deletion pygsp/graphs/nngraphs/bunny.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class Bunny(NNGraph):
>>> ax1 = fig.add_subplot(121)
>>> ax2 = fig.add_subplot(122, projection='3d')
>>> _ = ax1.spy(G.W, markersize=0.1)
>>> _ = _ = G.plot(ax=ax2)
>>> _ = G.plot(ax=ax2)
"""

Expand Down
34 changes: 29 additions & 5 deletions pygsp/graphs/nngraphs/sphere.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,50 @@


class Sphere(NNGraph):
r"""Randomly sampled hypersphere.
r"""Random uniform sampling of an hypersphere.
Parameters
----------
N : int
Number of vertices (default = 300).
dim : int
Dimensionality of the space the hypersphere is embedded in (default = 3).
Dimension of the space the hypersphere is embedded in.
seed : int
Seed for the random number generator (for reproducible graphs).
kwargs : dict
Additional keyword parameters are passed to :class:`NNGraph`.
Attributes
----------
signals : dict
Vertex position as latitude ``'lat'`` in [-π/2,π/2] and longitude
``'lon'`` in [0,2π[.
See Also
--------
SphereEquiangular, SphereGaussLegendre : based on quadrature theorems
SphereIcosahedron, SphereHealpix : based on subdivided polyhedra
CubeRandom : randomly sampled cube
References
----------
.. [1] http://mathworld.wolfram.com/HyperspherePointPicking.html
.. [2] J. S. Hicks and R. F. Wheeling, An Efficient Method for Generating
Uniformly Distributed Points on the Surface of an n-Dimensional Sphere,
1959.
Examples
--------
>>> import matplotlib.pyplot as plt
>>> G = graphs.Sphere(100, seed=42)
>>> fig = plt.figure()
>>> ax1 = fig.add_subplot(121)
>>> ax2 = fig.add_subplot(122, projection='3d')
>>> ax1 = fig.add_subplot(131)
>>> ax2 = fig.add_subplot(132, projection='3d')
>>> ax3 = fig.add_subplot(133)
>>> _ = ax1.spy(G.W, markersize=1.5)
>>> _ = _ = G.plot(ax=ax2)
>>> _ = G.plot(ax=ax2)
>>> G.set_coordinates('sphere', dim=2)
>>> _ = G.plot(ax=ax3, indices=True)
"""

Expand Down
66 changes: 65 additions & 1 deletion pygsp/graphs/nngraphs/spheregausslegendre.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,71 @@


class SphereGaussLegendre(NNGraph):
r"""Sphere sampled with a Gauss-Legendre scheme.
r"""Sphere sampled with a Gauss–Legendre scheme.
Background information is found at :doc:`/background/spherical_samplings`.
Parameters
----------
nlat : int
Number of isolatitude (longitudinal) rings.
reduced : {False, 'ecmwf-octahedral'}
If ``False``, there are ``2*nlat`` pixels per ring.
If ``'ecmwf-octahedral'``, there are ``4*i+16`` pixels per ring, where
``i`` is the ring number from 1 (nearest to the poles) to ``nlat/2``
(nearest to the equator).
kwargs : dict
Additional keyword parameters are passed to :class:`NNGraph`.
Attributes
----------
signals : dict
Vertex position as latitude ``'lat'`` in [-π/2,π/2] and longitude
``'lon'`` in [0,2π[.
See Also
--------
SphereEquiangular : based on quadrature theorems
SphereIcosahedron, SphereHealpix : based on subdivided polyhedra
SphereRandom : random uniform sampling
Notes
-----
Edge weights are computed by :class:`NNGraph`. Gaussian kernel widths have
however not been optimized for convolutions on the resulting graph to be
maximally equivariant to rotation [8]_.
The ECMWF's Integrated Forecast System (IFS) O320 grid is instantiated as
``SphereGaussLegendre(640, reduced='ecmwf-octahedral')`` [6]_ [7]_.
References
----------
.. [1] M. H. Payne, Truncation effects in geopotential modelling, 1971.
.. [2] A. G. Doroshkevich et al., Gauss–Legendre sky pixelization (GLESP)
for CMB maps, 2005.
.. [3] N Schaeffer, Efficient spherical harmonic transforms aimed at
pseudospectral numerical simulations, 2013.
.. [4] J. Keiner and D. Potts, Fast evaluation of quadrature formulae on
the sphere, 2008.
.. [5] M. Hortal and A. J. Simmons, Use of reduced Gaussian grids in
spectral models, 1991.
.. [6] https://confluence.ecmwf.int/display/FCST/Introducing+the+octahedral+reduced+Gaussian+grid
.. [7] https://confluence.ecmwf.int/display/OIFS/4.2+OpenIFS%3A+Octahedral+grid
.. [8] M. Defferrard et al., DeepSphere: a graph-based spherical CNN, 2019.
Examples
--------
>>> import matplotlib.pyplot as plt
>>> G = graphs.SphereGaussLegendre()
>>> fig = plt.figure()
>>> ax1 = fig.add_subplot(131)
>>> ax2 = fig.add_subplot(132, projection='3d')
>>> ax3 = fig.add_subplot(133)
>>> _ = ax1.spy(G.W, markersize=1.5)
>>> _ = G.plot(ax=ax2)
>>> G.set_coordinates('sphere', dim=2)
>>> _ = G.plot(ax=ax3, indices=True)
"""

def __init__(self, nlat=4, reduced=False, **kwargs):
Expand Down
62 changes: 33 additions & 29 deletions pygsp/graphs/nngraphs/spherehealpix.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,15 @@ def _import_hp():


class SphereHealpix(NNGraph):
r"""Sphere sampled with an HEALPix scheme.
r"""Sphere sampled with the HEALPix scheme.
The Hierarchical Equal Area isoLatitude Pixelisation (HEALPix) [1]_ is a
sampling scheme for the sphere whose pixels
(1) have equal area, for white noise to remain white,
(2) are arranged on isolatitude rings, for an FFT to be computed per ring,
(3) is hierarchical, where each pixel is sub-divided into four pixels.
HEALPix is used in cosmology for cosmic microwave background (CMB) maps.
Background information is found at :doc:`/background/spherical_samplings`.
Parameters
----------
nside : int
Controls the resolution of the sampling. It must be a power of 2.
The number of pixels is ``12*npix**2``, and the number of pixels around
the equator is ``4*nside``.
subdivisions : int
Number of recursive subdivisions. Known as ``order`` in HEALPix
terminology, with ``nside=2**order`` and ``npix=12*4**order``.
indexes : array_like of int
Indexes of the pixels from which to build a graph. Useful to build a
graph from a subset of the pixels, e.g., for partial sky observations.
Expand All @@ -40,49 +34,59 @@ class SphereHealpix(NNGraph):
kwargs : dict
Additional keyword parameters are passed to :class:`NNGraph`.
Attributes
----------
signals : dict
Vertex position as latitude ``'lat'`` in [-π/2,π/2] and longitude
``'lon'`` in [0,2π[.
See Also
--------
SphereEquiangular, SphereIcosahedron
SphereEquiangular, SphereGaussLegendre : based on quadrature theorems
SphereIcosahedron : based on subdivided polyhedra
SphereRandom : random uniform sampling
Notes
-----
Edge weights are computed by :class:`NNGraph`. Gaussian kernel widths have
been optimized for some combinations of resolutions `nside` and number of
been optimized for some combinations of resolutions `nlat` and number of
neighbors `k` for the convolutions on the resulting graph to be maximally
equivariant to rotation [2]_.
References
----------
.. [1] Gorski K. M., et al., "HEALPix: a Framework for High Resolution
Discretization and Fast Analysis of Data Distributed on the Sphere", The
Astrophysical Journal, 2005.
.. [2] Defferrard, Michaël, et al., "DeepSphere: a graph-based spherical
CNN", International Conference on Learning Representations (ICLR), 2019.
.. [1] K. M. Gorski et al., HEALPix: a Framework for High Resolution
Discretization and Fast Analysis of Data Distributed on the Sphere,
2005.
.. [2] M. Defferrard et al., DeepSphere: a graph-based spherical CNN, 2019.
Examples
--------
>>> import matplotlib.pyplot as plt
>>> G = graphs.SphereHealpix()
>>> G = graphs.SphereHealpix(1, k=8)
>>> fig = plt.figure()
>>> ax1 = fig.add_subplot(121)
>>> ax2 = fig.add_subplot(122, projection='3d')
>>> ax1 = fig.add_subplot(131)
>>> ax2 = fig.add_subplot(132, projection='3d')
>>> ax3 = fig.add_subplot(133)
>>> _ = ax1.spy(G.W, markersize=1.5)
>>> _ = _ = G.plot(ax=ax2)
>>> _ = G.plot(ax=ax2)
>>> G.set_coordinates('sphere', dim=2)
>>> _ = G.plot(ax=ax3, indices=True)
Vertex orderings:
>>> import matplotlib.pyplot as plt
>>> fig, axes = plt.subplots(1, 2)
>>> graph = graphs.SphereHealpix(nside=2, nest=False, k=8)
>>> graph.coords = np.stack([graph.signals['lon'], graph.signals['lat']]).T
>>> graph.plot(indices=True, ax=axes[0], title='RING ordering')
>>> graph = graphs.SphereHealpix(nside=2, nest=True, k=8)
>>> graph.coords = np.stack([graph.signals['lon'], graph.signals['lat']]).T
>>> graph.plot(indices=True, ax=axes[1], title='NESTED ordering')
>>> graph = graphs.SphereHealpix(1, nest=False, k=8)
>>> graph.set_coordinates('sphere', dim=2)
>>> _ = graph.plot(indices=True, ax=axes[0], title='RING ordering')
>>> graph = graphs.SphereHealpix(1, nest=True, k=8)
>>> graph.set_coordinates('sphere', dim=2)
>>> _ = graph.plot(indices=True, ax=axes[1], title='NESTED ordering')
"""

def __init__(self, subdivisions=2, indexes=None, nest=False, **kwargs):
def __init__(self, subdivisions=1, indexes=None, nest=False, **kwargs):
hp = _import_hp()

nside = hp.order2nside(subdivisions)
Expand Down
65 changes: 49 additions & 16 deletions pygsp/graphs/nngraphs/sphereicosahedron.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,38 +19,71 @@ def _import_trimesh():


class SphereIcosahedron(NNGraph):
r"""Spherical-shaped graph based on the projection of the icosahedron (NN-graph).
Code inspired by Max Jiang [https://github.com/maxjiang93/ugscnn/blob/master/meshcnn/mesh.py]
r"""Sphere sampled as a subdivided icosahedron.
Background information is found at :doc:`/background/spherical_samplings`.
Parameters
----------
level : int
Resolution of the sampling scheme, or how many times the faces are divided (default = 5)
sampling : string
What the pixels represent. Either a vertex or a face (default = 'vertex')
subdivisions : int
Number of recursive subdivisions.
dual : bool
Whether the graph vertices correspond to the vertices (``dual=False``)
or the triangular faces (``dual=True``) of the subdivided icosahedron.
kwargs : dict
Additional keyword parameters are passed to :class:`NNGraph`.
Attributes
----------
signals : dict
Vertex position as latitude ``'lat'`` in [-π/2,π/2] and longitude
``'lon'`` in [0,2π[.
See Also
--------
SphereDodecahedron, SphereHealpix, SphereEquiangular
SphereEquiangular, SphereGaussLegendre : based on quadrature theorems
SphereHealpix : based on subdivided polyhedra
SphereRandom : random uniform sampling
Notes
------
The icosahedron is the dual of the dodecahedron. Thus the pixels in this graph represent either the vertices \
of the icosahedron, or the faces of the dodecahedron.
-----
Edge weights are computed by :class:`NNGraph`. Gaussian kernel widths have
however not been optimized for convolutions on the resulting graph to be
maximally equivariant to rotation [3]_.
References
----------
.. [1] https://sinestesia.co/blog/tutorials/python-icospheres/
.. [2] M. Tegmark, An icosahedron-based method for pixelizing the celestial
sphere, 1996.
.. [3] M. Defferrard et al., DeepSphere: a graph-based spherical CNN, 2019.
Examples
--------
>>> import matplotlib.pyplot as plt
>>> from mpl_toolkits.mplot3d import Axes3D
>>> G = graphs.SphereIcosahedron(level=1)
>>> G = graphs.SphereIcosahedron()
>>> fig = plt.figure()
>>> ax1 = fig.add_subplot(121)
>>> ax2 = fig.add_subplot(122, projection='3d')
>>> ax1 = fig.add_subplot(131)
>>> ax2 = fig.add_subplot(132, projection='3d')
>>> ax3 = fig.add_subplot(133)
>>> _ = ax1.spy(G.W, markersize=1.5)
>>> _ = _ = G.plot(ax=ax2)
>>> _ = G.plot(ax=ax2)
>>> G.set_coordinates('sphere', dim=2)
>>> _ = G.plot(ax=ax3, indices=True)
Primal and dual polyhedrons:
>>> import matplotlib.pyplot as plt
>>> fig, axes = plt.subplots(1, 2)
>>> graph = graphs.SphereIcosahedron(0, dual=False, k=5)
>>> graph.set_coordinates('sphere', dim=2)
>>> _ = graph.plot(indices=True, ax=axes[0], title='Icosahedron')
>>> graph = graphs.SphereIcosahedron(0, dual=True, k=3)
>>> graph.set_coordinates('sphere', dim=2)
>>> _ = graph.plot(indices=True, ax=axes[1], title='Dodecahedron')
"""
def __init__(self, subdivisions=2, dual=False, **kwargs):
def __init__(self, subdivisions=1, dual=False, **kwargs):

self.subdivisions = subdivisions
self.dual = dual
Expand Down
Loading

0 comments on commit 2ba2372

Please sign in to comment.