Skip to content

fix grid_lebedev() due to quadpy API changes #22

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 23 additions & 4 deletions micarray/modal/angular.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from .. import util
from warnings import warn
try:
import quadpy # only for grid_lebedev()
import quadpy.u3._lebedev as _lebedev # only for grid_lebedev()
except ImportError:
pass

Expand Down Expand Up @@ -34,6 +34,8 @@ def sht_matrix(N, azi, colat, weights=None):
(Note: :math:`\mathbf{Y}` is interpreted as the inverse transform (or synthesis)
matrix in examples and documentation.)

cf. eq. (1.9), (3.29) :cite:`Rafaely2019_book`

Parameters
----------
N : int
Expand Down Expand Up @@ -265,13 +267,30 @@ def available_quadrature(d):
return matches[0]

if n > 65:
print(n)
raise ValueError("Maximum available Lebedev grid order is 65. "
"(requested: {})".format(n))

# this needs https://pypi.python.org/pypi/quadpy
q = quadpy.sphere.Lebedev(degree=available_quadrature(2*n))
# currently validated with 0.16.5
degree = _lebedev.lebedev_003a() # tmp call to mute pep8 warning
degree = available_quadrature(2 * n)
# the nice API handling currently returns only up to lebedev_047:
# q = quadpy.u3.get_good_scheme(degree=degree)
# thus we call the appropriate lebedev function directly in low level,
# not nice, but then we are save until the quadpy API will be consistent:
if degree == 3:
fcn = '_lebedev.lebedev_00' + str(degree) + 'a()'
elif degree < 10:
fcn = '_lebedev.lebedev_00'+str(degree) + '()'
elif degree < 100:
fcn = '_lebedev.lebedev_0' + str(degree) + '()'
else:
fcn = '_lebedev.lebedev_' + str(degree) + '()'
q = eval(fcn)
if np.any(q.weights < 0):
warn("Lebedev grid of order {} has negative weights.".format(n))
azi = q.azimuthal_polar[:, 0]
colat = q.azimuthal_polar[:, 1]
azi, colat, r = util.cart2sph(q.points[0, :],
q.points[1, :],
q.points[2, :])
return azi, colat, 4*np.pi*q.weights
76 changes: 76 additions & 0 deletions micarray/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,79 @@ def db(x, power=False):
"""
with np.errstate(divide='ignore'):
return 10 if power else 20 * np.log10(np.abs(x))


def sph2cart(alpha, beta, r):
r"""Spherical to cartesian coordinate transform.

taken from https://github.com/sfstoolbox/sfs-python commit: efdda38

.. math::

x = r \cos \alpha \sin \beta \\
y = r \sin \alpha \sin \beta \\
z = r \cos \beta

with :math:`\alpha \in [0, 2\pi), \beta \in [0, \pi], r \geq 0`

Parameters
----------
alpha : float or array_like
Azimuth angle in radiants
beta : float or array_like
Colatitude angle in radiants (with 0 denoting North pole)
r : float or array_like
Radius

Returns
-------
x : float or `numpy.ndarray`
x-component of Cartesian coordinates
y : float or `numpy.ndarray`
y-component of Cartesian coordinates
z : float or `numpy.ndarray`
z-component of Cartesian coordinates

"""
x = r * np.cos(alpha) * np.sin(beta)
y = r * np.sin(alpha) * np.sin(beta)
z = r * np.cos(beta)
return x, y, z


def cart2sph(x, y, z):
r"""Cartesian to spherical coordinate transform.

taken from https://github.com/sfstoolbox/sfs-python commit: efdda38

.. math::

\alpha = \arctan \left( \frac{y}{x} \right) \\
\beta = \arccos \left( \frac{z}{r} \right) \\
r = \sqrt{x^2 + y^2 + z^2}

with :math:`\alpha \in [-pi, pi], \beta \in [0, \pi], r \geq 0`

Parameters
----------
x : float or array_like
x-component of Cartesian coordinates
y : float or array_like
y-component of Cartesian coordinates
z : float or array_like
z-component of Cartesian coordinates

Returns
-------
alpha : float or `numpy.ndarray`
Azimuth angle in radiants
beta : float or `numpy.ndarray`
Colatitude angle in radiants (with 0 denoting North pole)
r : float or `numpy.ndarray`
Radius

"""
r = np.sqrt(x**2 + y**2 + z**2)
alpha = np.arctan2(y, x)
beta = np.arccos(z / r)
return alpha, beta, r