Source code for pyfar.samplings.spatial

"""This module provides functions to calculate spherical Voronoi diagrams."""
import deepdiff
import numpy as np
from scipy import spatial as spat
from pyfar import Coordinates
from copy import deepcopy
import warnings
from pyfar.classes.warnings import PyfarDeprecationWarning


[docs] class SphericalVoronoi(spat.SphericalVoronoi): """ Voronoi diagrams on the surface of a sphere. Note that :py:func:`calculate_sph_voronoi_weights` can be used directly, if only the sampling weights are needed. """
[docs] def __init__(self, sampling, round_decimals=12, center=0.0): """ Calculate a Voronoi diagram on the sphere for the given samplings points. This function will be deprecated in pyfar 0.8.0 in favor of :py:func:`spharpy.samplings.spherical_voronoi`. Parameters ---------- sampling : Coordinates Spherical sampling. round_decimals : int Number of decimals to be rounded for checking for equal radius. The default is ``12``. center : double Center point of the voronoi diagram. The default is ``0``. Returns ------- voronoi : SphericalVoronoi Spherical voronoi diagram as implemented in :py:mod:`scipy.spatial`. See Also -------- :py:func:`calculate_sph_voronoi_weights` """ warnings.warn(( "This function will be deprecated in pyfar 0.8.0 in favor " "of spharpy.samplings.spherical_voronoi."), PyfarDeprecationWarning, stacklevel=2) points = sampling.cartesian radius = sampling.radius radius_round = np.unique(np.round(radius, decimals=round_decimals)) if len(radius_round) > 1: raise ValueError("All sampling points need to be on the \ same radius.") super().__init__(points, radius_round[0], center)
[docs] def copy(self): """Return a copy of the Voronoi object.""" return deepcopy(self)
def _encode(self): """Return object in a proper encoding format.""" # Use public interface of the scipy super-class to prevent # error in case of chaning super-class implementations return {'points': self.points, 'center': self.center} @classmethod def _decode(cls, obj_dict): """Decode object based on its respective `_encode` counterpart.""" sampling = Coordinates( obj_dict['points'][:, 0], obj_dict['points'][:, 1], obj_dict['points'][:, 2], domain='cart') return cls(sampling, center=obj_dict['center']) def __eq__(self, other): """Check for equality of two objects.""" return not deepdiff.DeepDiff(self, other)
[docs] def calculate_sph_voronoi_weights( sampling, normalize=True, center=[0, 0, 0], round_decimals=12): r""" Calculate sampling weights for numeric integration. This function will be deprecated in pyfar 0.8.0 in favor of :py:func:`spharpy.samplings.calculate_sampling_weights`. Uses the class method :py:meth:`~scipy.spatial.SphericalVoronoi.calculate_areas` from :py:class:`SphericalVoronoi` to calculate the weights. It requires a spherical sampling grid with a single radius and uses :py:class:`scipy.spatial.SphericalVoronoi` in the background. Parameters ---------- sampling : Coordinates Sampling points on a sphere, i.e., all points must have the same radius. normalize : boolean, optional Normalize the samplings weights to ``sum(weights)=1``. Otherwise the weights sum to :math:`4 \pi r^2`. The default is ``True``. center : list Center of the spherical sampling grid. The default is ``[0, 0, 0]``. round_decimals : int, optional Round to `round_decimals` digits to check for equal radius. The default is ``12``. Returns ------- weigths : ndarray, double Sampling weights of size `samplings.csize`. """ warnings.warn(( "This function will be deprecated in pyfar 0.8.0 in favor " "of spharpy.samplings.calculate_sampling_weights."), PyfarDeprecationWarning, stacklevel=2) # get Voronoi diagram if sampling.csize <= 3: raise ValueError( 'The number of points needs to be at least 4', 'to generate a valid SphericalVoronoi diagram.') sv = SphericalVoronoi(sampling, round_decimals, center) # get the area weights = sv.calculate_areas() if normalize: weights /= np.sum(weights) return weights