Find overriding plate of closest subducting line
This example finds the overriding plate of the nearest subducting line over time by:
reconstructing regular features,
resolving topological plate boundaries,
finding the nearest subducting line (in the topological plate boundaries) to each regular feature,
determining the overriding plate of that subducting line.
Sample code
import pygplates
# Load one or more rotation files into a rotation model.
rotation_model = pygplates.RotationModel('rotations.rot')
# Load some features to test for closeness to subducting lines.
features = pygplates.FeatureCollection('features.gpml')
# Create a topological model from the topological plate polygon features (can also include deforming networks)
# and the rotation model.
topological_model = pygplates.TopologicalModel('topologies.gpml', rotation_model)
# Our geological times will be from 0Ma to 'num_time_steps' Ma (inclusive) in 1 My intervals.
num_time_steps = 140
# 'time' = 0, 1, 2, ... , 140
for time in range(num_time_steps + 1):
print 'Time %f' % time
# Reconstruct the features to the current 'time'.
reconstructed_features = []
pygplates.reconstruct(features, rotation_model, reconstructed_features, time, group_with_feature=True)
# Get a snapshot of our resolved topologies at the current 'time'.
topological_snapshot = topological_model.topological_snapshot(time)
# Extract the boundary sections between our resolved topological plate polygons (and deforming networks) from the current snapshot.
shared_boundary_sections = topological_snapshot.get_resolved_topological_sections()
# Iterate over all reconstructed features.
for feature, feature_reconstructed_geometries in reconstructed_features:
# Print out the feature name.
print ' Feature: %s' % feature.get_name()
#
# Find the nearest subducting line (in the resolved topologies) to the current feature.
#
# The minimum distance of the current feature (its geometries) to all subducting lines in resolved topologies.
min_distance_to_all_subducting_lines = None
nearest_shared_sub_segment = None
# Iterate over all reconstructed geometries of the current feature.
for feature_reconstructed_geometry in feature_reconstructed_geometries:
# Iterate over the shared boundary sections of all resolved topologies.
for shared_boundary_section in shared_boundary_sections:
# Skip sections that are not subduction zones.
# We're only interesting in closeness to subducting lines.
if shared_boundary_section.get_feature().get_feature_type() != pygplates.FeatureType.gpml_subduction_zone:
continue
# Iterate over the shared sub-segments of the current subducting line.
# These are the parts of the subducting line that actually contribute to topological boundaries.
for shared_sub_segment in shared_boundary_section.get_shared_sub_segments():
# Get the minimum distance from the current reconstructed geometry to
# the current subducting line.
min_distance_to_subducting_line = pygplates.GeometryOnSphere.distance(
feature_reconstructed_geometry.get_reconstructed_geometry(),
shared_sub_segment.get_resolved_geometry(),
min_distance_to_all_subducting_lines)
# If the current subducting line is nearer than all previous ones
# then it's the nearest subducting line so far.
if min_distance_to_subducting_line is not None:
min_distance_to_all_subducting_lines = min_distance_to_subducting_line
nearest_shared_sub_segment = shared_sub_segment
# We should have found the nearest subducting line.
if nearest_shared_sub_segment is None:
print ' Unable to find the nearest subducting line:'
print ' either feature has no geometries or there are no subducting lines in topologies.'
continue
#
# Determine the overriding plate of the subducting line.
#
# Get the subduction polarity of the nearest subducting line.
subduction_polarity = nearest_shared_sub_segment.get_feature().get_enumeration(pygplates.PropertyName.gpml_subduction_polarity)
if (not subduction_polarity or
subduction_polarity == 'Unknown'):
print ' Unable to find the overriding plate of the nearest subducting line "%s"' % nearest_shared_sub_segment.get_feature().get_name()
print ' subduction zone feature is missing subduction polarity property or it is set to "Unknown".'
continue
overriding_plate = None
# Iterate over the topologies that are sharing the part (sub-segment) of the subducting line that is closest to the feature.
sharing_resolved_topologies = nearest_shared_sub_segment.get_sharing_resolved_topologies()
geometry_reversal_flags = nearest_shared_sub_segment.get_sharing_resolved_topology_geometry_reversal_flags()
for index in range(len(sharing_resolved_topologies)):
sharing_resolved_topology = sharing_resolved_topologies[index]
geometry_reversal_flag = geometry_reversal_flags[index]
if sharing_resolved_topology.get_resolved_boundary().get_orientation() == pygplates.PolygonOnSphere.Orientation.clockwise:
# The current topology sharing the subducting line has clockwise orientation (when viewed from above the Earth).
# If the overriding plate is to the 'left' of the subducting line (when following its vertices in order) and
# the subducting line is reversed when contributing to the topology then that topology is the overriding plate.
# A similar test applies to the 'right' but with the subducting line not reversed in the topology.
if ((subduction_polarity == 'Left' and geometry_reversal_flag) or
(subduction_polarity == 'Right' and not geometry_reversal_flag)):
overriding_plate = sharing_resolved_topology
break
else:
# The current topology sharing the subducting line has counter-clockwise orientation (when viewed from above the Earth).
# If the overriding plate is to the 'left' of the subducting line (when following its vertices in order) and
# the subducting line is not reversed when contributing to the topology then that topology is the overriding plate.
# A similar test applies to the 'right' but with the subducting line reversed in the topology.
if ((subduction_polarity == 'Left' and not geometry_reversal_flag) or
(subduction_polarity == 'Right' and geometry_reversal_flag)):
overriding_plate = sharing_resolved_topology
break
if not overriding_plate:
print ' Unable to find the overriding plate of the nearest subducting line "%s"' % nearest_shared_sub_segment.get_feature().get_name()
print ' topology on overriding side of subducting line is missing.'
continue
# Success - we've found the overriding plate of the nearest subduction zone to the current feature.
# So print out the overriding plate ID and the distance to nearest subducting line.
print ' overriding plate ID: %d' % overriding_plate.get_feature().get_reconstruction_plate_id()
print ' distance to subducting line: %fKms' % (min_distance_to_all_subducting_lines * pygplates.Earth.mean_radius_in_kms)
Details
The rotations are loaded from a rotation file into a pygplates.RotationModel
.
rotation_model = pygplates.RotationModel('rotations.rot')
Load the regular features that we want to see which subducting lines (in the topologies) are closest to.
features = pygplates.FeatureCollection('features.gpml')
Create a topological model
from topological features and the rotation model.
topological_model = pygplates.TopologicalModel('topologies.gpml', rotation_model)
time
using pygplates.reconstruct()
.list
for reconstructed_features instead of a filename.True
(it defaults to False
)
so that our reconstructed feature geometries
are grouped with their feature
.reconstructed_features = []
pygplates.reconstruct(features, rotation_model, reconstructed_features, time, group_with_feature=True)
for feature, feature_reconstructed_geometries in reconstructed_features:
...
for feature_reconstructed_geometry in feature_reconstructed_geometries:
time
using pygplates.TopologicalModel.topological_snapshot()
.pygplates.ResolvedTopologicalBoundary
(used for dynamic plate polygons) and
pygplates.ResolvedTopologicalNetwork
(used for deforming regions) are listed in the boundary sections.topological_snapshot = topological_model.topological_snapshot(time)
shared_boundary_sections = topological_snapshot.get_resolved_topological_sections()
boundary sections
are actually what
we’re interested in because their sub-segments have a list of topologies on them.We ignore features that are not subduction zones because we’re only interested in finding the nearest subducting lines.
pygplates.ResolvedTopologicalSection.get_shared_sub_segments()
.for shared_boundary_section in shared_boundary_sections:
if shared_boundary_section.get_feature().get_feature_type() != pygplates.FeatureType.gpml_subduction_zone:
continue
for shared_sub_segment in shared_boundary_section.get_shared_sub_segments():
...
min_distance_to_all_subducting_lines = None
nearest_shared_sub_segment = None
pygplates.GeometryOnSphere.distance()
.min_distance_to_subducting_line = pygplates.GeometryOnSphere.distance(
feature_reconstructed_geometry.get_reconstructed_geometry(),
shared_sub_segment.get_resolved_geometry(),
min_distance_to_all_subducting_lines)
None
was returned then the distance was greater than min_distance_to_subducting_line.if min_distance_to_subducting_line is not None:
min_distance_to_all_subducting_lines = min_distance_to_subducting_line
nearest_shared_sub_segment = shared_sub_segment
subduction_polarity = nearest_shared_sub_segment.get_feature().get_enumeration(pygplates.PropertyName.gpml_subduction_polarity)
pygplates.ResolvedTopologicalSharedSubSegment
.sharing_resolved_topologies = nearest_shared_sub_segment.get_sharing_resolved_topologies()
geometry_reversal_flags = nearest_shared_sub_segment.get_sharing_resolved_topology_geometry_reversal_flags()
We iterate over the two above-mentioned lists and retrieve items from them.
for index in range(len(sharing_resolved_topologies)):
sharing_resolved_topology = sharing_resolved_topologies[index]
geometry_reversal_flag = geometry_reversal_flags[index]
To determine if the current topology in the sharing list is the overriding plate we need to look at:
the polarity of the subducting line,
the topology’s boundary polygon
orientation
andthe geometry reversal flag of the subducting line sub-segment (for that topology).
If the current topology (sharing the subducting line) has clockwise orientation (when viewed from above the Earth) and either:
the overriding plate is left of the subducting line and the subducting line is reversed in the topology, or
the overriding plate is right of the subducting line and the subducting line is not reversed in the topology
…then that topology is the overriding plate.
if sharing_resolved_topology.get_resolved_boundary().get_orientation() == pygplates.PolygonOnSphere.Orientation.clockwise:
if ((subduction_polarity == 'Left' and geometry_reversal_flag) or
(subduction_polarity == 'Right' and not geometry_reversal_flag)):
overriding_plate = sharing_resolved_topology
break
If the current topology (sharing the subducting line) has counter-clockwise orientation (when viewed from above the Earth) and either:
the overriding plate is left of the subducting line and the subducting line is not reversed in the topology, or
the overriding plate is right of the subducting line and the subducting line is reversed in the topology
…then that topology is the overriding plate.
else:
if ((subduction_polarity == 'Left' and not geometry_reversal_flag) or
(subduction_polarity == 'Right' and geometry_reversal_flag)):
overriding_plate = sharing_resolved_topology
break
When we’ve found the overriding plate of the nearest subduction zone to the current feature we print out the overriding plate ID and the distance to nearest subducting line.
print ' overriding plate ID: %d' % overriding_plate.get_feature().get_reconstruction_plate_id()
print ' distance to subducting line: %fKms' % (min_distance_to_all_subducting_lines * pygplates.Earth.mean_radius_in_kms)
Output
When spreading ridges are used as the regular input features then we get output like the following:
Time 0.000000
Feature: IS GRN_EUR, RI Fram Strait
overriding plate ID: 701
distance to subducting line: 3025.617930Kms
Feature: IS GRN_EUR, RI GRN Sea
overriding plate ID: 701
distance to subducting line: 2909.012775Kms
Feature: ISO CANADA BAS XR
overriding plate ID: 101
distance to subducting line: 1158.983648Kms
Feature: IS NAM_EUR, Arctic
overriding plate ID: 701
distance to subducting line: 3316.334722Kms
Feature: Ridge axis (reykanesh?)
overriding plate ID: 301
distance to subducting line: 2543.799959Kms
Feature: Ridge axis-Aegir
overriding plate ID: 301
distance to subducting line: 2121.303051Kms
Feature: Reykjanes/NATL RIDGE AXIS
overriding plate ID: 301
distance to subducting line: 2892.821343Kms
Feature: Reykjanes/NATL RIDGE AXIS
overriding plate ID: 301
distance to subducting line: 2576.504659Kms
Feature: Reykjanes/NATL RIDGE AXIS
overriding plate ID: 301
distance to subducting line: 2740.868166Kms
Feature: Mid-Atlantic Ridge, Klitgord and Schouten 86
overriding plate ID: 301
distance to subducting line: 3083.752943Kms
Feature: Mid-Atlantic Ridge, RDM 6/93 from sat gravity and epicenters
overriding plate ID: 201
distance to subducting line: 2705.900894Kms
Feature: Mid-Atlantic Ridge, Klitgord and Schouten 86
overriding plate ID: 201
distance to subducting line: 2383.736448Kms
Feature: Mid-Atlantic Ridge, Purdy (1990)
overriding plate ID: 201
distance to subducting line: 1830.700938Kms
...