vectorose.tregenza_sphere#

Sphere plotting with (almost) equal-area rectangles.

This module provides the functions necessary to produce an approximately equal area rectangular-based projection of a sphere, with face colours corresponding to either the face count or a sum of the magnitudes of vectors at each orientation. This projection is based on work by Beckers & Beckers. [1]

References

Classes#

TregenzaSphere

Base class for the Tregenza sphere.

CoarseTregenzaSphere

Coarse representation of the Tregenza sphere.

FineTregenzaSphere

Fine representation of the Tregenza sphere.

UltraFineTregenzaSphere

Ultra-fine representation of the Tregenza sphere.

Module Contents#

class vectorose.tregenza_sphere.TregenzaSphere(patch_count: numpy.ndarray, irregular_phi_values: numpy.ndarray, ring_increment: float, number_of_shells: int = 1, magnitude_range: Tuple[float, float] | None = None)[source]#

Bases: vectorose.sphere_base.SphereBase

Base class for the Tregenza sphere.

The Tregenza sphere provides a discretisation of the sphere based on mostly rectangular patches of almost equal area. This class defines the interface for the Tregenza sphere and includes all the functions necessary to use it for histogram binning and 3D representation.

Notes

This sphere design is based on the tiling presented by Beckers & Beckers. [1]

While this class can be instantiated directly, we strongly recommend that you consider one of the derived classes presented below. By using these, you will avoid the tedious task of computing the optimal number of bins per row, as well as computing the almucantar angles for the rings.

binning_precision: int = 10#

Precision for rounding when computing bin assignments.

_rings: pandas.DataFrame#

Tregenza sphere ring definitions.

_ring_increment: float#

Angular increment for regularly-sized rings.

property number_of_rings: int#

Number of rings in the sphere.

property number_of_irregular_rings: int#

Number of irregular rings in the sphere.

property ring_increment: float#

Angular increment for the regularly-sized rings.

property orientation_cols: List[str]#

Name of the histogram columns to use for orientation.

_construct_tregenza_sphere(irregular_phi_values: numpy.ndarray, patch_count: numpy.ndarray, ring_increment: float) pandas.DataFrame[source]#

Define a Tregenza sphere.

Define a Tregenza sphere with the specified patch count and almucantar angles.

Parameters:
  • irregular_phi_values – The phi values for the first rings, which are manually defined and of irregular increments.

  • patch_count – The number of rectangular patches in each ring.

  • ring_increment – The regular phi spacing between adjacent rings.

Returns:

pandas.DataFrame – The structure of the produced Tregenza sphere, containing as index the ring number, and as columns:

  • bins – the number of bins in each ring;

  • start – the starting phi value for each ring;

  • end – the ending phi angle of each ring;

  • theta_inc – the theta increment within each ring;

  • face_area – the area of the faces in each ring;

  • weight – the correction weight for the faces in each

    ring;

  • regular – an indication of whether the ring has a

    regular almucantar spacing or not.

Warning

This method assumes that the Tregenza sphere is symmetric with respect to the equator, i.e., that the northern and southern hemispheres are reflections of each other.

to_dataframe() pandas.DataFrame[source]#

Get the data frame representation of the sphere.

Returns:

pandas.DataFrame – Representation of the sphere as a table. See Notes for details.

Notes

The pandas.DataFrame contains as index the ring number. For each row, the following columns are present:

  • bins – the number of bins in each ring;

  • start – the starting phi value for each ring;

  • end – the ending phi angle of each ring;

  • theta_inc – the theta increment within each ring;

  • face_area – the area of the faces in each ring;

  • weight – the correction weight for the faces in each ring;

  • regular – an indication of whether the ring has a regular almucantar spacing or not.

get_closest_faces(spherical_coordinates: pandas.DataFrame) pandas.DataFrame[source]#

Get the closest faces for a specified spherical positions.

Parameters:

spherical_coordinates – Coordinates containing phi and theta in degrees.

Returns:

pandas.DataFrame – The phi ring and theta bin for each vector.

Notes

To account for floating point errors, when determining the bin index within a ring, there is a rounding step. This step rounds the quotient of the angle and the bin width to a very small precision. This rounding is controlled by binning_precision.

_initial_vector_component_preparation(vectors: pandas.DataFrame) pandas.DataFrame[source]#

Prepare the vector components for histogram construction.

Override this method to include specific operations that should be performed on the vectors in order to construct the histogram in the specific implementation.

Warning

This function should not perform any tasks related to the vector spatial locations, if those are included in the data. Those are handled separately by _initial_vector_data_preparation() which calls this function.

_compute_orientation_binning(vectors: pandas.DataFrame) pandas.DataFrame[source]#

Bin the provided vectors based on orientation.

Parameters:

vectors – The vectors to place in orientation bins.

Returns:

pandas.Series or pandas.DataFrame – The orientation bin(s) corresponding to each vector. The number of columns will depend on the specific sphere representation used.

_construct_orientation_index() pandas.MultiIndex[source]#

Get the orientation index for the current Tregenza sphere.

Produce the histogram orientation index for the current Tregenza sphere.

Returns:

pandas.MultiIndex – Index containing all possible values of ring and bin in a given shell.

correct_histogram_by_area(histogram: pandas.Series) pandas.Series[source]#

Correct histogram by face area.

Weight histogram values by face areas to compensate for slight deviations from equal area.

Parameters:

histogram – Histogram values to correct.

Returns:

pandas.Series – Corrected histogram values.

create_mesh() pyvista.PolyData[source]#

Create Tregenza sphere mesh.

Warning

This mesh construction relies on an approximation that uses a rectangle (or polygon) for each patch. This causes some issues near the sphere poles. In the original work by Beckers and Beckers, [1] the cap at the pole was a circle and all other patches are sectors of the respective rings. In our implementation, the pole is a polygon with the number of vertices corresponding to the number of patches in the next row. The next row contains a small number of patches, which may appear thin or misshapen, leaving holes in the constructed mesh. These holes are only artifacts of the visualisation. In the conceptual calculation of the histogram binning, the holes do not exist.

_construct_interior_ring(ring: pandas.Series) pyvista.PolyData[source]#

Construct a mesh for a single interior ring.

Parameters:

ring – The parameters associated with the ring to construct, extracted from the TregenzaSphere._rings attribute.

Returns:

pyvista.PolyData – A mesh representing the constructed ring.

Notes

The mesh construction occurs carefully to ensure that the indexes of the vertices and faces are in the same order as the bins in any produced histogram data.

_construct_cap(adjacent_ring: pyvista.PolyData, is_top: bool, index: int) pyvista.PolyData[source]#

Construct a Tregenza sphere cap.

Parameters:
  • adjacent_ring – The ring immediately touching the cap.

  • is_top – Indicate whether the cap is on top of the provided ring.

  • index – The ring index.

Returns:

pyvista.PolyData – A single polygon representing the produced cap

static _compute_face_areas(start_angles: numpy.ndarray, patch_counts: numpy.ndarray) numpy.ndarray[source]#

Compute the face areas for each ring.

Compute the face area for each ring the Tregenza sphere.

Parameters:
  • start_angles – The initial angle for each ring.

  • patch_counts – The number of patches in each ring.

Returns:

numpy.ndarray – Array of shape (r,) where r is the number of rings in the sphere. These weights reflect the deviation from equal area.

Notes

For each ring,the area of the spherical cap up to the bottom of the ring is calculated as

\[A_{\textup{cap}}(r) = 2\pi (1 - \cos(\phi_{r+1}))\]

where \(\phi_{r+1}\) is the almucantar angle at the bottom of the ring with index r in radians.

The area of the ring is obtained by subtracting the areas of the previous rings from the total cap area. For the first and last rings, which correspond to the spherical caps, the ring area is equal to the cap area.

The area of each Tregenza patch is then computed by dividing the total ring area by the number of patches in that ring.

To compute weights based on these values, all face areas must be normalised by the smallest face (typically the cap), and then the reciprocal of these values should be taken. These weights represent the ratio of the smallest patch to each patch, and can thus serve as a scaling factor between 0 and 1 to account for effects caused by the slight differences in face area.

convert_vectors_to_cartesian_array(labelled_vectors: pandas.DataFrame, create_unit_vectors: bool = False, include_spatial_coordinates: bool = False) numpy.ndarray[source]#

Convert a set of labelled vectors into Cartesian coordinates.

Each concrete implementation of a sphere may internally represent the vectors differently. This abstract method converts from that implementation-specific formatting to Cartesian coordinates.

Parameters:
  • labelled_vectors – The set of labelled n labelled vectors in d dimensions, in the same format as produced by SphereBase.assign_histogram_bins().

  • create_unit_vectors – Indicate where the returned vectors should be unit vectors. Depending on the implementation, this may either remove an extraneous normalisation step later, or add an extra normalisation step now.

  • include_spatial_coordinates – Indicate whether to include spatial coordinates in the new array. This option may only be called if the vectors have spatial coordinates.

Returns:

numpy.ndarray – Array of shape (n, d) containing the vector components in Cartesian coordinates.

Warning

The option include_spatial_coordinates is only valid if the labelled_vectors include spatial coordinates.

_get_cell_index(orientation_bin: pandas.Series) int[source]#

Get the cell index for a single orientation bin.

Parameters:

orientation_bin – Series containing index keys ring and bin indicating the desired orientation to be studied.

Returns:

int – The cell index for the desired orientation.

Notes

The cell index is found by adding the number of bins in all prior rings, and then adding the number of bins.

get_cell_indices(bins: pandas.DataFrame) pandas.Series[source]#

Get cell indices for specific bins.

Get the mesh cell index for specified orientation bins.

Parameters:

bins – DataFrame containing the implementation-specific orientation bin information for the desired cells

Returns:

Series – Indices of the mesh cells corresponding to the desired orientation bin.

See also

SphereBase.assign_histogram_bins

assign specific orientations and magnitudes to histogram bins.

class vectorose.tregenza_sphere.CoarseTregenzaSphere(number_of_shells: int = 1, magnitude_range: Tuple[float, float] | None = None)[source]#

Bases: TregenzaSphere

Coarse representation of the Tregenza sphere.

This sphere is constructed with 18 rings (9 in each hemisphere). It contains a total of 520 patches.

Notes

This sphere design is based on the tiling presented by Beckers & Beckers. [1]

The almucantar spacing for the regular rings is 11.25 degrees. The first non-cap ring has a start almucantar angle of 5 degrees and an end angle of 11.25 degrees.

class vectorose.tregenza_sphere.FineTregenzaSphere(number_of_shells: int = 1, magnitude_range: Tuple[float, float] | None = None)[source]#

Bases: TregenzaSphere

Fine representation of the Tregenza sphere.

This sphere is constructed with 54 rings (27 in each hemisphere). It contains a total of 5806 patches.

Notes

This sphere design is based on the tiling presented by Beckers & Beckers. [1]

The almucantar spacing for the regular rings is 3.44 degrees. The first non-cap ring has a starting almucantar angle of 1.50 degrees and an ending angle of 4.00 degrees.

class vectorose.tregenza_sphere.UltraFineTregenzaSphere(number_of_shells: int = 1, magnitude_range: Tuple[float, float] | None = None)[source]#

Bases: TregenzaSphere

Ultra-fine representation of the Tregenza sphere.

This sphere is constructed with 124 rings (62 in each hemisphere). It contains a total of 36956 patches.

Notes

This sphere design is based on the tiling presented by Beckers & Beckers. [1]

The almucantar spacing for the regular rings is 1.47 degrees. The first non-cap ring has a starting almucantar angle of 0.60 degrees and an ending angle of 1.80 degrees.