pygplates.NetRotationSnapshot

class pygplates.NetRotationSnapshot

Bases: instance

Net rotation snapshot of topological plates and deforming networks at a particular reconstruction time.

A NetRotationSnapshot can also be pickled.

Added in version 0.43.

__init__(topological_snapshot[, velocity_delta_time=1.0][, velocity_delta_time_type=pygplates.VelocityDeltaTimeType.t_plus_delta_t_to_t][, point_distribution])

Create a net rotation snapshot from the specified topological snapshot, and using the requested parameters.

Parameters:
  • topological_snapshot (TopologicalSnapshot) – The topological snapshot to calculate net rotation with.

  • velocity_delta_time (float) – The time delta used to calculate velocities for net rotation (defaults to 1 Myr).

  • velocity_delta_time_type (VelocityDeltaTimeType.t_plus_delta_t_to_t, VelocityDeltaTimeType.t_to_t_minus_delta_t or VelocityDeltaTimeType.t_plus_minus_half_delta_t) – How the two velocity times are calculated relative to the reconstruction time. This includes [t+dt, t], [t, t-dt] and [t+dt/2, t-dt/2]. Defaults to [t+dt, t].

  • point_distribution (int, or sequence of tuple (point, float) where point is a PointOnSphere or LatLonPoint or tuple (latitude,longitude), in degrees, or tuple (x,y,z)) – Can be an integer N representing the number of uniformly spaced latitude-longitude grid points sampled along each meridian (ie, an N x 2N grid). Or can be a sequence of (point, sample_area) tuples where point is a point that contributes to net rotation and sample_area is the surface area around the point in steradians (square radians). If nothing specified then defaults to a 180 x 360 uniformly spaced latitude-longitude points.

Raises:

ValueError if velocity_delta_time is negative or zero.

The total net rotation of all resolved topologies in this snapshot is:

\[\boldsymbol \omega_{net} = \frac{3}{8\pi} \sum_i \int \boldsymbol r \times (\boldsymbol \omega_i(\boldsymbol r) \times \boldsymbol r) \, dS_i\]

…where \(\sum_i\) is the summation over all resolved topologies, and \(\int ... dS_i\) is integration over the surface area of resolved topology \(i\), and \(\boldsymbol \omega_i(\boldsymbol r)\) is the rotation rate vector for resolved topology \(i\) at location \(\boldsymbol r\). For a rigid plate this is just a constant \(\boldsymbol \omega_i(\boldsymbol r) = \boldsymbol \omega_i\), but for a deforming network this varies spatially across the network (hence the dependency on \(\boldsymbol r\)). Note that if a deforming network overlaps a rigid plate then only the deforming network contributes to the total net rotation (in the overlap region).

The surface integrals are approximated by sampling at points distributed across the surface of the globe. So it’s helpful to think of a single integral over the entire globe (rather than a separate integral for each topology) and then approximate that as a summation over points:

\[\begin{split}\boldsymbol \omega_{net} &= \frac{3}{8\pi} \int \boldsymbol r \times (\boldsymbol \omega(\boldsymbol r) \times \boldsymbol r) \, dS\\ &\approx \frac{3}{8\pi} \sum_p (\boldsymbol r_p \times (\boldsymbol \omega(\boldsymbol r_p) \times \boldsymbol r_p)) \, dS_p\end{split}\]

…where the summation is over all locations \(\boldsymbol r_p\) in the point distribution \(p\), and \(dS_p\) is the surface area contributed at location \(\boldsymbol r_p\) (where \(\sum_p dS_p \approx 4\pi\)), and \(\boldsymbol \omega(\boldsymbol r_p)\) is the rotation rate vector contributed by whichever resolved topology happens to intersect location \(\boldsymbol r_p\) (with preference given to deforming networks when they overlap rigid plates).

The point distribution used to calculate net rotation can be controlled with the point_distribution parameter. If point_distribution is an integer N then a uniform latitude-longitude grid of N x 2N points is used. Otherwise point_distribution can be a sequence of (point, sample area) representing an arbitrary user-specified distribution of points (and their sample areas). For example, if you have a distribution that is uniformly spaced on the surface of the sphere then the sample area will be the same for each point (ie, \(4\pi\) steradians divided by the total number of points). If nothing is specified for point_distribution then a uniform latitude-longitude grid of 180 x 360 points is used.

To create a net rotation snapshot (of a topological snapshot) at 0Ma calculated with a velocity delta from 1Ma (to 0Ma):

net_rotation_snapshot = pygplates.NetRotationSnapshot(
    topological_snapshot, 0, 1.0, pygplates.VelocityDeltaTimeType.t_plus_delta_t_to_t)

…which is equivalent to the following code that explicitly specifies a point distribution:

point_distribution = []
num_samples_along_meridian = 180
delta_in_degrees = 180.0 / num_samples_along_meridian
delta_in_radians = math.radians(delta_in_degrees)
for lat_index in range(num_samples_along_meridian):
    lat = -90.0 + (lat_index + 0.5) * delta_in_degrees
    # The cosine is because points near the North/South poles are closer together (latitude parallel small circle radius).
    sample_area_radians = math.cos(math.radians(lat)) * delta_in_radians * delta_in_radians
    for lon_index in range(2*num_samples_along_meridian):
        lon = -180.0 + (lon_index + 0.5) * delta_in_degrees
        point_distribution.append(((lat, lon), sample_area_radians))

net_rotation_snapshot = pygplates.NetRotationSnapshot(
    topological_snapshot, 0, 1.0, pygplates.VelocityDeltaTimeType.t_plus_delta_t_to_t, point_distribution)

Note

The anchor plate is that of the specified topological snapshot (see TopologicalSnapshot.get_anchor_plate_id()).

Methods

__init__(topological_snapshot, ...)

Create a net rotation snapshot from the specified topological snapshot, and using the requested parameters.

get_net_rotation([resolved_topology])

Return the net rotation of the specified resolved topology (or a net rotation for each topology as a dict).

get_topological_snapshot()

Return the associated topological snapshot.

get_total_net_rotation()

Return the total net rotation over all resolved topologies in this snapshot.

get_net_rotation([resolved_topology])

Return the net rotation of the specified resolved topology (or a net rotation for each topology as a dict).

Parameters:

resolved_topology (ResolvedTopologicalBoundary or ResolvedTopologicalNetwork) – Optional resolved topology to retrieve net rotation for. If not specified then net rotations for all resolved boundaries and networks that contribute net rotation are returned (returned as a dict).

Returns:

If resolved_topology is specified then returns the NetRotation of that resolved topology boundary or network (or None if resolved_topology does not contribute net rotation). Otherwise returns a dict mapping each ResolvedTopologicalBoundary or ResolvedTopologicalNetwork that contributes net rotation to its NetRotation.

Return type:

NetRotation or None, or dict

Raises:

ValueError if resolved_topology is specified but is neither a ResolvedTopologicalBoundary nor a ResolvedTopologicalNetwork.

Note

Any resolved boundary or network that did not intersect any sample points (see point_distribution in __init__()) will not contribute net rotation. And if a contributing resolved boundary does not have a reconstruction plate ID then 0 will be used.

The net rotation of resolved topology \(i\) (rigid plate or deforming network) is:

\[\boldsymbol \omega_{i \, net} = \frac{\int \boldsymbol r \times (\boldsymbol \omega_i(\boldsymbol r) \times \boldsymbol r) \, dS_i}{\frac{2}{3} \int \, dS_i}\]

…where \(\int ... dS_i\) is integration over the surface area of resolved topology \(i\), and \(\int dS_i\) is its surface area, and \(\boldsymbol \omega_i(\boldsymbol r)\) is its rotation rate vector at location \(\boldsymbol r\). For a rigid plate this is just a constant \(\boldsymbol \omega_i(\boldsymbol r) = \boldsymbol \omega_i\), but for a deforming network this varies spatially across the network (hence the dependency on \(\boldsymbol r\)).

Note

The net rotation for individual topologies (rigid plates and deforming networks) can differ from those exported by GPlates 2.4 and older. This is because GPlates <= 2.4 calculated a topology’s normalisation factor as \(\frac{1}{\int \cos(latitude)^2 \, dS_i}\) whereas pyGPlates (and GPlates > 2.4) calculate it as \(\frac{1}{\frac{2}{3} \int \, dS_i}\) to avoid any variation with latitude. Both give the same total normalization of \(\frac{3}{8\pi}\) when integrated over the entire globe and hence result in the same total net rotation over all topologies. However they will give different results for an individual topology (ie, integrated over only the rigid plate or deforming network). Equatorial topologies will now have a higher net rotation (and topologies nearer the poles will have a lower net rotation).

To iterate over the resolved topologies that contribute net rotation in this snapshot and print out their individual net rotations:

net_rotation_dict = net_rotation_snapshot.get_net_rotation()
for resolved_topology, net_rotation in net_rotation_dict.items():
    print('Topology {} has net rotation {}'.format(resolved_topology.get_feature().get_name(), net_rotation.get_finite_rotation()))

…which is equivalent to the following:

for resolved_topology in net_rotation_snapshot.get_topological_snapshot().get_resolved_topologies():
    net_rotation = net_rotation_snapshot.get_net_rotation(resolved_topology)
    # Not all resolved topologies in our topological snapshot will necessarily contribute net rotation.
    if net_rotation:
        print('Topology {} has net rotation {}'.format(resolved_topology.get_feature().get_name(), net_rotation.get_finite_rotation()))
get_topological_snapshot()

Return the associated topological snapshot.

Return type:

TopologicalSnapshot

Note

Parameters such as reconstruction time, anchor plate ID and rotation model can be obtained from the topological snapshot.

get_total_net_rotation()

Return the total net rotation over all resolved topologies in this snapshot.

Return type:

NetRotation

The total net rotation of all resolved topologies in this snapshot is:

\[\boldsymbol \omega_{net} = \frac{3}{8\pi} \sum_i \int \boldsymbol r \times (\boldsymbol \omega_i(\boldsymbol r) \times \boldsymbol r) \, dS_i\]

…where \(\sum_i\) is the summation over all resolved topologies, and \(\int ... dS_i\) is integration over the surface area of resolved topology \(i\), and \(\boldsymbol \omega_i(\boldsymbol r)\) is the rotation rate vector for resolved topology \(i\) at location \(\boldsymbol r\). For a rigid plate this is just a constant \(\boldsymbol \omega_i(\boldsymbol r) = \boldsymbol \omega_i\), but for a deforming network this varies spatially across the network (hence the dependency on \(\boldsymbol r\)). Note that if a deforming network overlaps a rigid plate then only the deforming network contributes to the total net rotation (in the overlap region).

total_net_rotation = net_rotation_snapshot.get_total_net_rotation()

This is equivalent to accumulating the net rotation for each resolved topological boundary and network that contributed to the total net rotation:

total_net_rotation = pygplates.NetRotation()  # zero net rotation
# Get the net rotation of each resolved topology that contributed to the toal net rotation (extract *values* from dict).
for resolved_topology_net_rotation in net_rotation_snapshot.get_net_rotation().values():
    total_net_rotation += resolved_topology_net_rotation

Note

If a resolved topological boundary does not have a reconstruction plate ID then 0 will be used.