Exemple #1
0
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]
Exemple #2
0
    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)
Exemple #3
0
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
Exemple #7
0
 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
Exemple #10
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
Exemple #11
0
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
Exemple #13
0
    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
Exemple #14
0
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
Exemple #15
0
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
Exemple #18
0
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
Exemple #21
0
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')
Exemple #22
0
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)
Exemple #23
0
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)
Exemple #24
0
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)
Exemple #25
0
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