def query_raster(raster_name, lons, lats): #construct the grid tree grid_x, grid_y = np.mgrid[-90:91, -180:181] grid_points = [ pygplates.PointOnSphere((float(row[0]), float(row[1]))).to_xyz() for row in zip(grid_x.flatten(), grid_y.flatten()) ] rasterfile = Dataset(raster_name, 'r') z = rasterfile.variables['z'][:] #masked array zz = cv2.resize(z, dsize=(361, 181), interpolation=cv2.INTER_CUBIC) zz = np.roll(zz, 180) z = np.ma.asarray(zz.flatten()) grid_points = np.asarray(grid_points) z_idx = ~np.isnan(z) z = z[z_idx] grid_tree = scipy.spatial.cKDTree(grid_points[z_idx]) points = [ pygplates.PointOnSphere((float(row[1]), float(row[0]))).to_xyz() for row in zip(lons, lats) ] # query the tree dists, indices = grid_tree.query(points, k=1) return z[indices]
def _create_bounding_circle(self): bound_circle_centre = pygplates.PointOnSphere(self._centre_lat, self._centre_lon) left_lon = self._centre_lon - self._half_width_degrees right_lon = self._centre_lon + self._half_width_degrees bottom_lat = self._centre_lat - self._half_width_degrees top_lat = self._centre_lat + self._half_width_degrees # The small circle that bound the four corner points will also bound the associated lat/lon box. # This is because the small circle centre will be inside the box and the small circle curvature # is greater than all four sides of the box (two great circle arcs and two small circle arcs). dist_to_bottom_left = pygplates.GeometryOnSphere.distance( bound_circle_centre, pygplates.PointOnSphere(bottom_lat, left_lon)) dist_to_bottom_right = pygplates.GeometryOnSphere.distance( bound_circle_centre, pygplates.PointOnSphere(bottom_lat, right_lon)) dist_to_top_left = pygplates.GeometryOnSphere.distance( bound_circle_centre, pygplates.PointOnSphere(top_lat, left_lon)) dist_to_top_right = pygplates.GeometryOnSphere.distance( bound_circle_centre, pygplates.PointOnSphere(top_lat, right_lon)) bounding_circle_radius_radians = max(dist_to_bottom_left, dist_to_bottom_right, dist_to_top_left, dist_to_top_right) self._bounding_circle = (bound_circle_centre, bounding_circle_radius_radians)
def write_vgp_feature(vgp, mapping, half_time_range = 10.): ''' Create a vgp feature from one row of a dataframe TODO handle cases where some fields (e.g. description) are not present ''' other_properties = [(pygplates.PropertyName.create_gpml('poleA95'), pygplates.XsDouble(vgp[mapping['PoleA95']])), (pygplates.PropertyName.create_gpml('averageAge'), pygplates.XsDouble(vgp[mapping['AverageAge']]))] if 'geometry' in vgp: other_properties.append( (pygplates.PropertyName.create_gpml('averageSampleSitePosition'), pygplates.GmlPoint(pygplates.PointOnSphere([float(float(vgp.geometry.y)), float(float(vgp.geometry.x))]))) ) vgpFeature = pygplates.Feature.create_reconstructable_feature( pygplates.FeatureType.create_gpml('VirtualGeomagneticPole'), pygplates.PointOnSphere([vgp[mapping['PoleLatitude']], vgp[mapping['PoleLongitude']]]), name = str(vgp[mapping['Name']]), description = str(vgp[mapping['Description']]), valid_time=(float(vgp[mapping['AverageAge']])+half_time_range, float(vgp[mapping['AverageAge']])-half_time_range), other_properties = other_properties) if 'ReconstructionPlateID' in mapping: vgpFeature.set_reconstruction_plate_id(int(vgp[mapping['ReconstructionPlateID']])) return vgpFeature
def query_vector(sample_points, vector_file, region): #prepare the list for result data and insert indices for input points ret=[] indices_bak = [] fn0=vector_file.format(time=start_time, conv_dir=Utils.get_convergence_dir()) with open(fn0, 'r') as f: column_num = len(f.readline().split(',')) for i in range(len(sample_points)): ret.append([np.nan, np.nan]) indices_bak.append(sample_points[i][0]) #keep a copy of the original indices sample_points[i][0] = i #sort and group by time to improve performance sorted_points = sorted(sample_points, key = lambda x: int(x[3])) #sort by time from itertools import groupby for t, group in groupby(sorted_points, lambda x: int(x[3])): #group by time if t>end_time or t<start_time: continue #print('querying '+vector_file.format(time=t)) # build the points tree at time t fn=vector_file.format(time=t, conv_dir=Utils.get_convergence_dir()) data=np.genfromtxt(fn, skip_header=1, delimiter=',') #assume first column is lon and second column is lat points_3d = [pygplates.PointOnSphere((row[1],row[0])).to_xyz() for row in data] points_tree = scipy.spatial.cKDTree(points_3d) # reconstruct the points rotated_points = [] grouped_points = list(group)#must make a copy, the items in "group" will be gone after first iteration for point in grouped_points: point_to_rotate = pygplates.PointOnSphere((point[2], point[1])) finite_rotation = rotation_model.get_rotation(point[3], int(point[4]))#time, plate_id geom = finite_rotation * point_to_rotate rotated_points.append(geom.to_xyz()) idx = point[0] ret[idx][1], ret[idx][0] = geom.to_lat_lon() # query the tree of points dists, indices = points_tree.query( rotated_points, k=1, distance_upper_bound=Utils.degree_to_straight_distance(region)) for point, dist, idx in zip(grouped_points, dists, indices): if idx < len(data): ret[point[0]] = ret[point[0]] + [dist, idx] + list(data[idx]) for i in range(len(ret)): if len(ret[i]) == 2: ret[i] = ret[i] + [np.nan]*(2+column_num) #restore original indices for i in range(len(indices_bak)): sample_points[i][0] = indices_bak[i] return ret
def select_points_in_region(candidate_lons, candidate_lats, trench_lons, trech_lats, region=5): #build the tree points_3d = [pygplates.PointOnSphere((lat,lon)).to_xyz() for lon, lat in zip(trench_lons, trech_lats)] points_tree = scipy.spatial.cKDTree(points_3d) candidates = [pygplates.PointOnSphere((lat,lon)).to_xyz() for lon, lat in zip(candidate_lons, candidate_lats)] dists, indices = points_tree.query( candidates, k=1, distance_upper_bound=degree_to_straight_distance(region)) return indices<len(points_3d)
def get_distance_to_mountain_edge(point_array, reconstruction_basedir, rotation_model, reconstruction_time, area_threshold): distance_threshold_radians = None env_list = ['m'] if reconstruction_time == 0: pg_dir = './present_day_paleogeography.gmt' pg_features = pg.load_paleogeography(pg_dir, env_list, single_file=True, env_field='Layer') else: pg_dir = '%s/PresentDay_Paleogeog_Matthews2016_%dMa/' % ( reconstruction_basedir, reconstruction_time) pg_features = pg.load_paleogeography(pg_dir, env_list) cf = merge_polygons(pg_features, rotation_model, reconstruction_time=reconstruction_time, sampling=0.25) sieve_polygons_t1 = polygon_area_threshold(cf, area_threshold) polygons_as_list = [] for feature in sieve_polygons_t1: polygons_as_list.append(feature.get_geometry()) res1 = find_closest_geometries_to_points( [ pygplates.PointOnSphere(point) for point in zip(point_array[:, 0], point_array[:, 1]) ], polygons_as_list, distance_threshold_radians=distance_threshold_radians) distance_to_polygon_boundary = np.degrees(np.array(list(zip(*res1))[0])) # Make a copy of list of distances. distance_to_polygon = list(distance_to_polygon_boundary) # Set distance to zero for any points inside a polygon (leave other points unchanged). res2 = points_in_polygons.find_polygons([ pygplates.PointOnSphere(point) for point in zip(point_array[:, 0], point_array[:, 1]) ], polygons_as_list) for point_index, rpolygon in enumerate(res2): # If not inside any polygons then result will be None. if rpolygon is None: distance_to_polygon[point_index] = 0.0 return distance_to_polygon
def __init__(self, grid_list_filename, static_polygon_filename, rotation_filenames, longitude, latitude, age=None): """ Load dynamic topography grid filenames and associated ages from grid list file 'grid_list_filename'. The present day location ('longitude' / 'latitude' in degrees) is also assigned a plate ID using the static polygons. """ self.location = pygplates.PointOnSphere((latitude, longitude)) self.age = age self.grids = TimeDependentGrid(grid_list_filename) self.rotation_model = pygplates.RotationModel(rotation_filenames) # Find the plate ID of the static polygon containing the location (or zero if not in any plates). plate_partitioner = pygplates.PlatePartitioner(static_polygon_filename, self.rotation_model) partitioning_plate = plate_partitioner.partition_point(self.location) if partitioning_plate: self.reconstruction_plate_id = partitioning_plate.get_feature().get_reconstruction_plate_id() else: self.reconstruction_plate_id = 0 # Use the age of the containing static polygon if location is None (ie, outside age grid). if self.age is None: if partitioning_plate: self.age, _ = partitioning_plate.get_feature().get_valid_time() else: self.age = 0.0
def reconstruct_vector_points(point_tuples, vector_tuples, point_rotation): # given lists of points and vectors, a rotation pole, returns # a list of reconstructed points and vector directions if len(point_tuples) != len(vector_tuples): raise ValueError('expected same number of points and vectors') reconstructed_points = [ point_rotation * pygplates.PointOnSphere(point_tuple) for point_tuple in point_tuples ] reconstructed_vectors = [ point_rotation * pygplates.LocalCartesian. convert_from_magnitude_azimuth_inclination_to_geocentric( point_tuple, vector_tuple) for (point_tuple, vector_tuple) in zip(point_tuples, vector_tuples) ] reconstructed_vector_magnitude_azimuth_inclinations = pygplates.LocalCartesian.convert_from_geocentric_to_magnitude_azimuth_inclination( reconstructed_points, reconstructed_vectors) return ([ reconstructed_point.to_lat_lon() for reconstructed_point in reconstructed_points ], reconstructed_vector_magnitude_azimuth_inclinations)
def __init__(self, grid_list_filename, static_polygon_filename, rotation_filenames, longitude, latitude, age=None): """ Load dynamic topography grid filenames and associated ages from grid list file 'grid_list_filename'. Parameters ---------- grid_list_filename : str The filename of the grid list file. static_polygon_filename : str The filename of the static polygons file. rotation_filenames : list of str The list of rotation filenames. longitude : float Longitude of the ocean point location. latitude : float Latitude of the ocean point location. age : float, optional The age of the crust that the point location is on. If not specified then the appearance age of the static polygon containing the point is used. Notes ----- Each row in the grid list file should contain two columns. First column containing filename (relative to directory of list file) of a dynamic topography grid at a particular time. Second column containing associated time (in Ma). The present day location ('longitude' / 'latitude' in degrees) is also assigned a plate ID using the static polygons, and the rotations are used to reconstruct the location when sampling the grids at a reconstructed time. """ self.latitude = latitude self.longitude = longitude self.location = pygplates.PointOnSphere((latitude, longitude)) self.age = age self.grids = TimeDependentGrid(grid_list_filename) self.rotation_model = pygplates.RotationModel(rotation_filenames) # Find the plate ID of the static polygon containing the location (or zero if not in any plates). plate_partitioner = pygplates.PlatePartitioner(static_polygon_filename, self.rotation_model) partitioning_plate = plate_partitioner.partition_point(self.location) if partitioning_plate: self.reconstruction_plate_id = partitioning_plate.get_feature( ).get_reconstruction_plate_id() else: self.reconstruction_plate_id = 0 # Use the age of the containing static polygon if location is None (ie, outside age grid). if self.age is None: if partitioning_plate: self.age, _ = partitioning_plate.get_feature().get_valid_time() else: self.age = 0.0
def paleobathymetry_from_topologies(resolved_topologies, shared_boundary_sections, deep_ocean_features, model='GDH1', half_spreading_rate=50.): # Approximation of paleobathymetry based on distance to MORs # given some resolved topologies, and some point features (typically in the deep ocean), # calculates the distance of each point to the nearest mid-ocean ridge segment that # forms part of the boundary that the point is located within - then, determines # the implied age assuming a constant spreading rate and given age-depth model pX, pY, pZ = find_distance_to_nearest_ridge(resolved_topologies, shared_boundary_sections, deep_ocean_features) age = np.array(pZ) / half_spreading_rate pdepth = age2depth(age, model=model) pdepth_points = [] for (lon, lat, depth) in zip(pX, pY, pdepth): point_feature = pygplates.Feature() point_feature.set_geometry(pygplates.PointOnSphere(lat, lon)) point_feature.set_shapefile_attribute('depth', np.float(depth)) pdepth_points.append(point_feature) return pdepth_points
def rotate_to_common_reference(vgps, reconstruction_model, reference_plate_id=701): ''' Rotate a collection of vgps to a common reference plate ''' if isinstance(vgps, _gpd.GeoDataFrame): rotated_vgps = [] for i,row in vgps.iterrows(): vgp_geometry = pygplates.PointOnSphere(row.PoleLatitude,row.PoleLongitude) feature_rotation = reconstruction_model.rotation_model.get_rotation(row.AverageAge, row.PlateID, anchor_plate_id=reference_plate_id) reconstructed_geometry = feature_rotation * vgp_geometry rotated_vgps.append(reconstructed_geometry.to_lat_lon()) vgps.PoleLatitude = list(zip(*rotated_vgps))[0] vgps.PoleLongitude = list(zip(*rotated_vgps))[1] return vgps elif isinstance(vgps, pygplates.FeatureCollection): rotated_vgps = [] for vgp in vgps: feature_rotation = reconstruction_model.rotation_model.get_rotation(vgp.get(pygplates.PropertyName.gpml_average_age).get_value().get_double(), vgp.get_reconstruction_plate_id(), anchor_plate_id=reference_plate_id) reconstructed_geometry = feature_rotation * vgp.get_geometry() vgp.set_geometry(reconstructed_geometry) vgp.set_reconstructed_plate_id(reference_plate_id) rotated_vgps.append(vgp) return pygplates.FeatureCollection(rotated_vgps)
def groupby_healpix(gdf, equal_area_points, return_point_indices=True): """ Given a (geo)dataframe with irregularly distributed point in lat,long, and equal area point distribution, this functions will bin the dataframe point based on the equal area pixel extents (using the underlying healpix function). The function returns a groupby object that can be interrogated to get the statistics of points within each bin, and (optionally) a list of point indices """ # TODO force input to be dataframe?? bin_counts, bin_indices = equal_area_points.point_feature_heatmap( [pygplates.PointOnSphere(point) for point in zip(gdf.geometry.y, gdf.geometry.x)], return_indices=True) point_indices = np.unique(bin_indices) gdf['bin_id'] = bin_indices grouped_points = gdf.groupby(by=['bin_id']) #binned_df = pd.DataFrame(columns=df.columns) #for i,group in enumerate(grouped_points.groups): # points_selection = grouped_points.get_group(group) # binned_df.loc[i] = points_selection.median() if return_point_indices: return grouped_points, point_indices else: return grouped_points
def __make_GPML_velocity_feature(self, coords): """ function to make a velocity mesh nodes at an arbitrary set of points defined in coords[# of points, 3] = x, y, z""" # Add points to a multipoint geometry multi_point = pygplates.MultiPointOnSphere([ pygplates.PointOnSphere(x=coords[i, 0], y=coords[i, 1], z=coords[i, 2], normalise=True) for i in range(numpy.shape(coords)[0]) ]) # Create a feature containing the multipoint feature, and defined as MeshNode type meshnode_feature = pygplates.Feature( pygplates.FeatureType.create_from_qualified_string( 'gpml:MeshNode')) meshnode_feature.set_geometry(multi_point) meshnode_feature.set_name('Velocity Mesh Nodes from pygplates') output_feature_collection = pygplates.FeatureCollection( meshnode_feature) # NB: at this point, the feature could be written to a file using # output_feature_collection.write('myfilename.gpmlz') # for use within the notebook, the velocity domain feature is returned from the function return output_feature_collection
def return_conjugate_points(points, point_ages, point_plate_pairs, target_plate_pair, rotation_model): points_and_conjugate_points = [] for point, point_age, plate_ids in zip(points, point_ages, point_plate_pairs): if plate_ids is None: continue elif plate_ids[0] not in target_plate_pair: continue elif plate_ids[1] not in target_plate_pair: continue else: if not np.isnan(point_age): finite_rotation = rotation_model.get_rotation(float(point_age), int(plate_ids[0]), 0, int(plate_ids[1])) reconstructed_point = finite_rotation * pygplates.PointOnSphere(point) points_and_conjugate_points.append([point.to_lat_lon()[1], point.to_lat_lon()[0], reconstructed_point.to_lat_lon()[1], reconstructed_point.to_lat_lon()[0], plate_ids[0], point_age]) return points_and_conjugate_points
def profile_plate_ids(resolved_topologies,rotation_model,GreatCirclePoints): partitioner = pygplates.PlatePartitioner(resolved_topologies,rotation_model) plate_ids = [] for point in GreatCirclePoints: partitioned_point = partitioner.partition_point(pygplates.PointOnSphere(point)) plate_ids.append(partitioned_point.get_feature().get_reconstruction_plate_id()) return plate_ids
def getRidgeEndPoints(topology_features,rotation_model,time): # given files to make topological polygons, returns the features of type 'MidOceanRidge' # and get the first and last point from each one, along with the plate pairs MorEndPointArrays = [] MorEndPointGeometries = [] MorPlatePairs = [] subduction_boundary_sections = [] # Resolve our topological plate polygons (and deforming networks) to the current 'time'. # We generate both the resolved topology boundaries and the boundary sections between them. resolved_topologies = [] shared_boundary_sections = [] pygplates.resolve_topologies(topology_features, rotation_model, resolved_topologies, time, shared_boundary_sections) for shared_boundary_section in shared_boundary_sections: if shared_boundary_section.get_feature().get_feature_type() == pygplates.FeatureType.create_gpml('MidOceanRidge'): for shared_sub_segment in shared_boundary_section.get_shared_sub_segments(): if len(shared_sub_segment.get_sharing_resolved_topologies())==2: plate_pair = [shared_sub_segment.get_sharing_resolved_topologies()[0].get_feature().get_reconstruction_plate_id(), shared_sub_segment.get_sharing_resolved_topologies()[1].get_feature().get_reconstruction_plate_id()] else: plate_pair = np.array((-1,-1)) #print 'skipping bad topological segment....' tmp = shared_sub_segment.get_geometry() MorEndPointArrays.append(tmp.to_lat_lon_array()) MorEndPointGeometries.append(pygplates.PointOnSphere(tmp.get_points()[0])) MorEndPointGeometries.append(pygplates.PointOnSphere(tmp.get_points()[-1])) MorPlatePairs.append(plate_pair) MorPlatePairs.append(plate_pair) elif shared_boundary_section.get_feature().get_feature_type() == pygplates.FeatureType.create_gpml('SubductionZone'): for shared_sub_segment in shared_boundary_section.get_shared_sub_segments(): subduction_boundary_sections.append(shared_sub_segment) return MorEndPointArrays,MorEndPointGeometries,MorPlatePairs,subduction_boundary_sections
def xyzfile_to_spatial_tree_of_points(xyzfile): data = np.loadtxt(xyzfile) points = [ pygplates.PointOnSphere(lat, lon) for lat, lon in zip(data[:, 1], data[:, 0]) ] return points, data
def orientation_polygon_along_meridian(polygon): median_longitude = np.median(polygon.to_lat_lon_array()[:,1]) reorient_major_axis = pygplates.FiniteRotation( pygplates.PointOnSphere(90,0), -np.radians(median_longitude)) oriented_polygon = reorient_major_axis * polygon return oriented_polygon,reorient_major_axis
def get_nearest_subduction_point(subduction_data,seed_point): subduction_stats_at_seed_points = [] min_distance_to_all_features = None nearest_subduction_point = None for index,row in subduction_data.iterrows(): min_distance_to_feature = pygplates.GeometryOnSphere.distance( pygplates.PointOnSphere(row['lat'], row['lon']), pygplates.PointOnSphere(seed_point), min_distance_to_all_features) # If the current geometry is nearer than all previous geometries then # its associated feature is the nearest feature so far. if min_distance_to_feature is not None: min_distance_to_all_features = min_distance_to_feature nearest_subduction_point = row return nearest_subduction_point
def create_seed_point_feature(plat,plon,plate_id,conjugate_plate_id,time): # Create a gpml point feature given some attributes point = pygplates.PointOnSphere(plat,plon) point_feature = pygplates.Feature() point_feature.set_geometry(point) point_feature.set_valid_time(time,0.) point_feature.set_reconstruction_plate_id(plate_id) point_feature.set_conjugate_plate_id(conjugate_plate_id) point_feature.set_name('Slab Edge | plate %d | rel. plate %d' % (plate_id,conjugate_plate_id)) return point_feature
def test_post(request): if not request.method == "POST": return HttpResponseBadRequest('expecting post requests!') else: #print request.POST json_feature_collection = json.loads(request.body) model = request.GET.get('model', settings.MODEL_DEFAULT) features = [] for json_feature in json_feature_collection['features']: feature = pygplates.Feature() point = json_feature['geometry']['coordinates'] feature.set_geometry(pygplates.PointOnSphere(point[1], point[0])) feature.set_valid_time(json_feature['properties']['age'], 0) features.append(feature) model_dict = get_reconstruction_model_dict(model) rotation_model = pygplates.RotationModel([ str('%s/%s/%s' % (settings.MODEL_STORE_DIR, model, rot_file)) for rot_file in model_dict['RotationFile'] ]) static_polygons_filename = str( '%s/%s/%s' % (settings.MODEL_STORE_DIR, model, model_dict['StaticPolygons'])) # assign plate-ids to points using static polygons assigned_point_features = pygplates.partition_into_plates( static_polygons_filename, rotation_model, features, properties_to_copy=[ pygplates.PartitionProperty.reconstruction_plate_id ]) feature_collection = pygplates.FeatureCollection( assigned_point_features) reconstructed_features = reconstruct_to_birth_time( feature_collection, rotation_model) # prepare the response to be returned ret = '{"coordinates":[' for g in reconstructed_features: ret += '[{0:5.2f},{1:5.2f}],'.format( g.get_geometry().to_lat_lon()[1], g.get_geometry().to_lat_lon()[0]) ret = ret[0:-1] ret += ']}' return HttpResponse(ret, content_type='application/json')
def write_trees_to_file(input_features, rotation_model, filename, reconstruction_time_range, time_step=1, polygon_type='static', root_feature_filename=None): reconstruction_times = np.arange(reconstruction_time_range[0], reconstruction_time_range[1]+time_step, time_step) tree_features = None root_centroid_features = [] for reconstruction_time in reconstruction_times: print 'working on time %0.2f Ma' % reconstruction_time reconstructed_polygons = [] if polygon_type is 'topological': pygplates.resolve_topologies(input_features, rotation_model, reconstructed_polygons, reconstruction_time) else: pygplates.reconstruct(input_features, rotation_model, reconstructed_polygons, reconstruction_time) uniq_plates_from_polygons = get_unique_plate_ids_from_reconstructed_features(reconstructed_polygons) reconstruction_tree = rotation_model.get_reconstruction_tree(reconstruction_time) chains = get_plate_chains(uniq_plates_from_polygons, reconstruction_tree) tree_features = create_hierarchy_features(chains, reconstructed_polygons, tree_features, valid_time=(reconstruction_time+time_step/2., reconstruction_time-time_step/2.)) if root_feature_filename is not None: polygon_centroids = get_polygon_centroids(reconstructed_polygons) root_plates = get_root_static_polygon_plate_ids(reconstruction_tree, uniq_plates_from_polygons) for root_plate in root_plates: p0 = polygon_centroids[root_plate] feature = pygplates.Feature() feature.set_geometry(pygplates.PointOnSphere(p0)) feature.set_name(str(root_plate)) feature.set_valid_time(reconstruction_time+time_step/2., reconstruction_time-time_step/2.) root_centroid_features.append(feature) tree_feature_collection = pygplates.FeatureCollection(tree_features) tree_feature_collection.write(filename) if root_feature_filename is not None: tree_feature_collection = pygplates.FeatureCollection(root_centroid_features) tree_feature_collection.write(root_feature_filename)
def random_points_on_sphere(N): # function to call Marsaglia's method and return Long/ # Lat arrays points = marsaglias_method(N) Long=[] Lat=[] for xyz in points.T: LL = pygplates.PointOnSphere((xyz)) Lat.append(LL.to_lat_lon()[0]) Long.append(LL.to_lat_lon()[1]) return np.array(Long), np.array(Lat)
def get_rotation_to_equator(point): """Get rotation from 'point' to nearest position on equator.""" rotate_from_north_to_point = pygplates.FiniteRotation(pygplates.PointOnSphere.north_pole, point) if rotate_from_north_to_point.represents_identity_rotation(): # Point coincides with North Pole, so just choose any rotation pole on the equator to rotate point with. # The point could end up anywhere along equator. rotate_from_north_to_point_pole = pygplates.PointOnSphere(0, 0) rotate_from_north_to_point_angle = 0.5 * math.pi # Rotate 90 degrees from North Pole to equator. else: rotate_from_north_to_point_pole, rotate_from_north_to_point_angle = rotate_from_north_to_point.get_euler_pole_and_angle() return pygplates.FiniteRotation( rotate_from_north_to_point_pole, 0.5 * math.pi - rotate_from_north_to_point_angle)
def subduction(request): if not request.method == "POST": return HttpResponseBadRequest('expecting post requests!') else: #print request.POST json_feature_collection = json.loads(request.body) model = request.GET.get('model', settings.MODEL_DEFAULT) features = [] for json_feature in json_feature_collection['features']: feature = pygplates.Feature() point = json_feature['geometry']['coordinates'] feature.set_geometry(pygplates.PointOnSphere(point[1], point[0])) feature.set_valid_time(json_feature['properties']['age'], 0) features.append(feature) model_dict = get_reconstruction_model_dict(model) rotation_model = pygplates.RotationModel([ str('%s/%s/%s' % (settings.MODEL_STORE_DIR, model, rot_file)) for rot_file in model_dict['RotationFile'] ]) static_polygons_filename = str( '%s/%s/%s' % (settings.MODEL_STORE_DIR, model, model_dict['StaticPolygons'])) # assign plate-ids to points using static polygons assigned_point_features = pygplates.partition_into_plates( static_polygons_filename, rotation_model, features, properties_to_copy=[ pygplates.PartitionProperty.reconstruction_plate_id ]) seed_point_features = pygplates.FeatureCollection( assigned_point_features) df_OreDepositBirthTimeStats = subduction_parameters( seed_point_features, rotation_model) html_table = df_OreDepositBirthTimeStats.to_html(index=False) return render(request, 'list_template.html', {'html_table': html_table})
def query_grid(sample_points, grid_file, region): #prepare the list for result data and insert indices for input points ret=[] indices_bak = [] for i in range(len(sample_points)): ret.append([np.nan, np.nan]) indices_bak.append(sample_points[i][0]) #keep a copy of the original indices sample_points[i][0] = i #sort and group by time to improve performance sorted_points = sorted(sample_points, key = lambda x: int(x[3])) #sort by time from itertools import groupby for t, group in groupby(sorted_points, lambda x: int(x[3])): #group by time if t>end_time or t<start_time: continue #print('querying '+grid_file.format(time=t)) age_grid_fn = grid_file.format(time=t) # reconstruct the points rotated_points_lons = [] rotated_points_lats = [] grouped_points = list(group)#must make a copy, the items in "group" will be gone after first iteration for point in grouped_points: point_to_rotate = pygplates.PointOnSphere((point[2], point[1])) finite_rotation = rotation_model.get_rotation(point[3], int(point[4]))#time, plate_id geom = finite_rotation * point_to_rotate lat, lon = geom.to_lat_lon() rotated_points_lons.append(lon) rotated_points_lats.append(lat) idx = point[0] ret[idx][1], ret[idx][0] = geom.to_lat_lon() # query the grid tree values = Utils.query_raster(age_grid_fn, rotated_points_lons,rotated_points_lats, region, True) for point, value in zip(grouped_points,values): ret[point[0]] = ret[point[0]] + [region, value] for i in range(len(ret)): if len(ret[i]) == 2: ret[i] = ret[i] + [np.nan]*2 #restore original indices for i in range(len(indices_bak)): sample_points[i][0] = indices_bak[i] return ret
def get_plate_id(lons, lats, static_polygons, rotation_model): p_len = len(lons) assert (p_len == len(lats)), 'The lons and lats must have the same length.' point_features = [] for i in range(p_len): point = pygplates.PointOnSphere(float(lats[i]), float(lons[i])) point_feature = pygplates.Feature() point_feature.set_geometry(point) point_feature.set_name(str(i)) point_features.append(point_feature) plate_ids = [np.nan] * p_len # partition features points = pygplates.partition_into_plates(static_polygons, rotation_model, point_features) for p in points: plate_ids[int(p.get_name())] = p.get_reconstruction_plate_id() return plate_ids
def query_raster(raster_name, lons, lats, region=10, ball=False): points = [ pygplates.PointOnSphere((float(row[1]), float(row[0]))).to_xyz() for row in zip(lons, lats) ] rasterfile = Dataset(raster_name, 'r') z = rasterfile.variables['z'][:] #masked array zz = cv2.resize(z, dsize=(361, 181), interpolation=cv2.INTER_CUBIC) lon_actual_range = rasterfile.variables['lon'].actual_range if int(lon_actual_range[0] ) == 0: #roll 180 if the grid ranges from 0 to 360 zz = np.roll(zz, 180) z = np.ma.asarray(zz.flatten()) # query the tree if not ball: global grid_points grid_points = np.asarray(grid_points) z_idx = ~np.isnan(z) z = z[z_idx] grid_tree = scipy.spatial.cKDTree(grid_points[z_idx]) dists, indices = grid_tree.query( points, k=1, distance_upper_bound=degree_to_straight_distance(region)) z = np.append(z, [np.nan]) return z[indices] else: # ball query the grid tree all_neighbors = full_grid_tree.query_ball_point( points, degree_to_straight_distance(region)) ret = [] for neighbors in all_neighbors: if len(neighbors) > 0 and (~np.isnan(z[neighbors])).any(): ret.append(np.nanmean(z[neighbors])) else: ret.append(np.nan) return ret
def points_on_sphere(N, distribution_type='marsaglia'): # function to call one of several methods and return Long/ # Lat arrays of points distributed on sphere if distribution_type in ['marsaglia','random']: points = marsaglias_method(N) elif distribution_type=='fibonacci': points = fibonacci_sphere(N) elif distribution_type=='spiral': points = golden_spiral(N) else: raise ValueError('unrecognised method for point on sphere generation') Long=[] Lat=[] for xyz in points.T: LL = pygplates.PointOnSphere((xyz)) Lat.append(LL.to_lat_lon()[0]) Long.append(LL.to_lat_lon()[1]) return np.array(Long), np.array(Lat)
def reconstruct_raster(raster_class, static_polygons, rotation_model, time_from, time_to, grid_sampling=1., anchor_plate_id=0, sampling_method='scipy'): grid_longitudes, grid_latitudes = np.meshgrid( np.arange(-180., 180.0001, grid_sampling), np.arange(-90., 90.0001, grid_sampling)) grid_longitudes = grid_longitudes.flatten() grid_latitudes = grid_latitudes.flatten() points = [ pygplates.PointOnSphere(point) for point in zip(grid_latitudes, grid_longitudes) ] spatial_tree_of_uniform_recon_points = points_spatial_tree.PointsSpatialTree( points) (time_to_point_lons, time_to_point_lats, time_from_point_lons, time_from_point_lats) = reconstruct_raster_stage( static_polygons, rotation_model, time_from, time_to, points, spatial_tree_of_uniform_recon_points, anchor_plate_id) if sampling_method == 'scipy': point_raster_values = raster_class.sample(time_from_point_lons, time_from_point_lats) elif sampling_method == 'gmt': point_raster_values = raster_class.sample_using_gmt( time_from_point_lons, time_from_point_lats) elif sampling_method == 'stripy': point_raster_values = raster_class.sample_using_stripy( time_from_point_lons, time_from_point_lats) return time_to_point_lons, time_to_point_lats, point_raster_values