コード例 #1
0
ファイル: views.py プロジェクト: GPlates/gplates-web-service
def test_post_files(request):
    if not request.method == "POST":
        return HttpResponseBadRequest('expecting post requests!')
    else:
        with open('%s/tmp.gpmlz' % settings.MEDIA_ROOT, 'wb+') as destination:
            for chunk in request.FILES['file1'].chunks():
                destination.write(chunk)
        with open('%s/tmp.rot' % settings.MEDIA_ROOT, 'wb+') as destination:
            for chunk in request.FILES['file2'].chunks():
                destination.write(chunk)

        filename = 'reconstruct_to_birth_time.gpmlz'
        rotation_model = pygplates.RotationModel('%s/tmp.rot' %
                                                 settings.MEDIA_ROOT)
        features = pygplates.FeatureCollection('%s/tmp.gpmlz' %
                                               settings.MEDIA_ROOT)

        reconstructed_features = reconstruct_to_birth_time(
            features, rotation_model)

        tmp = pygplates.FeatureCollection(reconstructed_features)
        tmp.write('%s/%s' % (settings.MEDIA_ROOT, filename))

        f = StringIO(
            file('%s/%s' % (settings.MEDIA_ROOT, filename), "rb").read())

        response = HttpResponse(f, content_type='application/gpmlz')
        response['Content-Disposition'] = 'attachment; filename=%s' % filename

        return response
コード例 #2
0
def masking_job(reconstruction_time,
                COBterrane_file,
                input_rotation_filenames,
                grdspace,
                grd_output_dir,
                output_gridfile_template='seafloor_age_'):

    rotation_model = pygplates.RotationModel(input_rotation_filenames)
    print('Masking for time {:0.2f} Ma'.format(reconstruction_time))
    #mask = pt.get_merged_cob_terrane_raster(COBterrane_file, rotation_model, reconstruction_time,
    #                                        grdspace)

    maskX, maskY, mask = load_netcdf('{0}/masks/mask_{1}Ma.nc'.format(
        grd_output_dir, reconstruction_time))

    ds = xr.open_dataset('{0}/unmasked/{1}{2}Ma.nc'.format(
        grd_output_dir, output_gridfile_template, reconstruction_time))
    # workaround for a bug in older versions of xarray, where masking array cannot be applied directly to data array
    #ds['z'][mask==1] = np.nan
    z_array = ds['z'].data
    z_array[mask == 1] = np.nan
    ds['z'].data = z_array
    ds.to_netcdf('{0}/masked/{1}mask_{2}Ma.nc'.format(
        grd_output_dir, output_gridfile_template, reconstruction_time),
                 format='NETCDF4_CLASSIC')
    ds.close()

    return
コード例 #3
0
def get_deposit_candidates():
    polygon_points = get_region_of_interest_polygon().values.flatten()
    mesh_points = get_mesh_points(polygon_points)

    #let's find plate id for the mesh points
    static_polygons = pygplates.FeatureCollection(
        parameters['static_polygons_file'])
    rotation_model = pygplates.RotationModel(
        get_files(parameters['rotation_files']))
    mesh_plate_ids = get_plate_id(mesh_points.lon.tolist(),
                                  mesh_points.lat.tolist(), static_polygons,
                                  rotation_model)

    mesh_points['plate_id'] = mesh_plate_ids
    deposit_candidates = []
    start_time = parameters["time"]["start"]
    end_time = parameters["time"]["end"]
    time_step = parameters["time"]["step"]
    for t in range(start_time, end_time + 1, time_step):
        for index, p in mesh_points.iterrows():
            deposit_candidates.append([p['lon'], p['lat'], t, p['plate_id']])
    deposit_candidates = pd.DataFrame(
        deposit_candidates, columns=['lon', 'lat', 'age', 'plate_id'])
    deposit_candidates = deposit_candidates.astype({
        "plate_id": int,
        "age": int
    })
    return deposit_candidates
コード例 #4
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
コード例 #5
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'.
        
        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
コード例 #6
0
def resolve_topologies(
    rotation_features_or_model,
    topology_features,
    time,
    output_filename_prefix,
    output_filename_extension,
    transform_segment_deviation_in_radians=separate_ridge_transform_segments.
    DEFAULT_TRANSFORM_SEGMENT_DEVIATION_RADIANS):
    """
    Resolves topologies at specified time and saves (to separate files) the resolved topologies, and their boundary sections as subduction zones,
    mid-ocean ridges (ridge/transform) and others (not subduction zones or mid-ocean ridges).
    
    rotation_features_or_model: Rotation model or feature collection(s), or list of features, or filename(s).
    
    topology_features: Topology feature collection(s), or list of features, or filename(s) or any combination of those.
    
    time: Reconstruction time to resolved topologies.
    
    transform_segment_deviation_in_radians: How much a mid-ocean ridge segment can deviate from the stage pole before
                                            it's considered a transform segment (in radians).
    
    Writes output files containing the following features...
            - resolved topology features (topological plates and networks)
            - ridge and transform boundary sections (resolved features)
            - ridge boundary sections (resolved features)
            - transform boundary sections (resolved features)
            - subduction boundary sections (resolved features)
            - left subduction boundary sections (resolved features)
            - right subduction boundary sections (resolved features)
            - other boundary sections (resolved features) that are not subduction zones or mid-ocean ridges (ridge/transform)
    """

    # Turn rotation data into a RotationModel (if not already).
    rotation_model = pygplates.RotationModel(rotation_features_or_model)

    # Get topology features (could include filenames).
    topology_features = pygplates.FeaturesFunctionArgument(
        topology_features).get_features()

    # 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_topology_features, ridge_transform_boundary_section_features,
     ridge_boundary_section_features, transform_boundary_section_features,
     subduction_boundary_section_features,
     left_subduction_boundary_section_features,
     right_subduction_boundary_section_features,
     other_boundary_section_features) = resolve_topologies_into_features(
         rotation_model, topology_features, time,
         transform_segment_deviation_in_radians)

    # Write each list of features to a separate file.
    _write_resolved_topologies(
        time, output_filename_prefix, output_filename_extension,
        resolved_topology_features, ridge_transform_boundary_section_features,
        ridge_boundary_section_features, transform_boundary_section_features,
        subduction_boundary_section_features,
        left_subduction_boundary_section_features,
        right_subduction_boundary_section_features,
        other_boundary_section_features)
コード例 #7
0
def paleolithology(request):

    anchor_plate_id = request.GET.get('pid', 0)
    time = request.GET.get('time', 0)
    model = request.GET.get('model', settings.MODEL_DEFAULT)

    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']
    ])

    paleolithology_datafile = '%s/boucot_paleolithology_combined.shp' % settings.PALEO_STORE_DIR

    static_polygons_filename = str(
        '%s/%s/%s' %
        (settings.MODEL_STORE_DIR, model, model_dict['StaticPolygons']))

    #select points based on age before doing plate id assignment - should be quicker??
    paleolithology_points = pygplates.FeatureCollection(
        paleolithology_datafile)

    valid_points = []
    for point in paleolithology_points:
        if point.get_valid_time()[0] > float(
                time) and point.get_valid_time()[1] <= float(time):
            valid_points.append(point)

    print(valid_points)

    assigned_features = pygplates.partition_into_plates(
        static_polygons_filename,
        rotation_model,
        valid_points,
        properties_to_copy=[
            pygplates.PartitionProperty.reconstruction_plate_id
        ],
        partition_method=pygplates.PartitionMethod.most_overlapping_plate)

    reconstructed_paleolithology_points = []
    pygplates.reconstruct(assigned_features,
                          rotation_model,
                          reconstructed_paleolithology_points,
                          float(time),
                          anchor_plate_id=anchor_plate_id)

    ret = write_json_reconstructed_point_features(
        reconstructed_paleolithology_points,
        attributes=[('LithCode', 'string'), ('Period', 'string')])

    #add header for CORS
    #http://www.html5rocks.com/en/tutorials/cors/
    response = HttpResponse(ret, content_type='application/json')

    #TODO:
    #The "*" makes the service wide open to anyone. We should implement access control when time comes.
    response['Access-Control-Allow-Origin'] = '*'
    return response
コード例 #8
0
def get_topological_boundaries(request):
    """
    http GET request to retrieve reconstructed topological plate polygons

    **usage**
    
    <http-address-to-gws>/topology/plate_boundaries/time=\ *reconstruction_time*\&model=\ *reconstruction_model*
    
    **parameters:**

    *time* : time for reconstruction [default=0]

    *model* : name for reconstruction model [defaults to default model from web service settings]

    **returns:**

    json containing reconstructed plate boundary features
    """

    time = request.GET.get('time', 0)
    model = request.GET.get('model', settings.MODEL_DEFAULT)

    model_dict = get_reconstruction_model_dict(model)

    features = []
    rotation_model = pygplates.RotationModel([
        str('%s/%s/%s' % (settings.MODEL_STORE_DIR, model, rot_file))
        for rot_file in model_dict['RotationFile']
    ])

    # need to handle cases where topologies are in one file, and where they are spread across
    # multiple files
    topology_features = pygplates.FeatureCollection()
    if type(model_dict['PlatePolygons']) is list:
        for file in model_dict['PlatePolygons']:
            fullfile = str('%s/%s/%s' %
                           (settings.MODEL_STORE_DIR, model, file))
            topology_feature = pygplates.FeatureCollection(fullfile)
            topology_features.add(topology_feature)
    else:
        topology_features = pygplates.FeatureCollection(
            str('%s/%s/%s' % (settings.MODEL_STORE_DIR, model,
                              model_dict['PlatePolygons'])))

    resolved_polygons = []
    shared_boundary_sections = []
    pygplates.resolve_topologies(topology_features, rotation_model,
                                 resolved_polygons, float(time),
                                 shared_boundary_sections)

    data = wrap_plate_boundaries(shared_boundary_sections, 0.)
    print('here')
    ret = json.dumps(pretty_floats(data))

    response = HttpResponse(ret, content_type='application/json')
    #TODO:
    response['Access-Control-Allow-Origin'] = '*'
    return response
コード例 #9
0
def calculate_velocities_over_time(output_filename_prefix,
                                   output_filename_extension,
                                   rotation_filenames,
                                   reconstructable_filenames,
                                   threshold_sampling_distance_radians,
                                   time_young,
                                   time_old,
                                   time_increment,
                                   velocity_delta_time=1.0,
                                   anchor_plate_id=0):

    if time_increment <= 0:
        print('The time increment "{0}" is not positive and non-zero.'.format(
            time_increment),
              file=sys.stderr)
        return

    if time_young > time_old:
        print('The young time {0} is older (larger) than the old time {1}.'.
              format(time_young, time_old),
              file=sys.stderr)
        return

    rotation_model = pygplates.RotationModel(rotation_filenames)

    # Read/parse the reconstructable features once so we're not doing at each time iteration.
    reconstructable_features = [
        pygplates.FeatureCollection(reconstructable_filename)
        for reconstructable_filename in reconstructable_filenames
    ]

    # Iterate over the time range.
    time = time_young
    while time <= pygplates.GeoTimeInstant(time_old):

        print('Time {0}'.format(time))

        # Returns a list of tesselated subduction zone points and associated convergence parameters
        # to write to the output file for the current 'time'.
        output_data = calculate_velocities(
            rotation_model, reconstructable_features,
            threshold_sampling_distance_radians, time, velocity_delta_time,
            anchor_plate_id)

        if output_data:
            output_filename = '{0}_{1:0.2f}.{2}'.format(
                output_filename_prefix, time, output_filename_extension)
            write_output_file(output_filename, output_data)

        # Increment the time further into the past.
        time += time_increment

    return 0  # Success
コード例 #10
0
ファイル: views.py プロジェクト: GPlates/gplates-web-service
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')
コード例 #11
0
ファイル: libgplates.py プロジェクト: g-adopt/g-adopt
    def __init__(self,
                 rotation_filenames,
                 topology_filenames,
                 geologic_zero,
                 nseeds=1000,
                 nneighbours=3,
                 delta_time=1.):
        """
        A class for importing surface velocities from pygplates.
        Each time surface velocity points are generated for [nseeds] of equidistantial points at the surface.
        With these points a cKDTree obect is generated each time, which will be used to interpolate onto required grid points.
        Interpolation is a weighted average of [nneighbours] closest points, unless the closest points is closer than ~numerical zero.
            input:
                rotation_filenames: list of rotation files
                topology_filenames: list of dynamic polygon files
                geologic_zero:      what is the oldest geologic time available in this model
                nseeds:             number of seed points to generate
                nneighbours:        when interpolating between the seed points and mesh points, how many neighboring points should be used
                delta_time:         how many million years should it take before we read in plate velocities again (is passed on to pygplates for
                                    time averaging too)
        """

        # Rotation model(s)
        self.rotation_model = pygplates.RotationModel(rotation_filenames)

        if nneighbours < 2:
            raise ValueError('nneighbours should be at least 2')
        else:
            self.nneighbours = nneighbours

        # Topological plate polygon feature(s).
        self.topology_features = []
        for fname in topology_filenames:
            for f in pygplates.FeatureCollection(fname):
                self.topology_features.append(f)
        # geologic_zero is the same as model_time=0
        self.geologic_zero = geologic_zero

        # time window for velocity interpolations
        self.delta_time = delta_time

        # NB: Not sure if we really need to keep seeds at this stage
        self.seeds = self.__fibonacci_sphere(samples=int(nseeds))
        #
        self.velocity_domain_features = self.__make_GPML_velocity_feature(
            self.seeds)

        # last reconstruction time
        self.reconstruction_time = None

        # Flag to know when to recalculate surface velocities.
        self.recalculation_flg = False
コード例 #12
0
ファイル: tut.py プロジェクト: tylrhall/pygplates-tutorials
    def plot_velocities(self, m):
        delta_time = 5.
        Xnodes = np.arange(-180, 180, 5)
        Ynodes = np.arange(-90, 90, 5)
        Xg, Yg = np.meshgrid(Xnodes, Ynodes)
        Xg = Xg.flatten()
        Yg = Yg.flatten()
        velocity_domain_features = velocity_utils.make_GPML_velocity_feature(
            Xg, Yg)
        # Load one or more rotation files into a rotation model.
        rotation_model = pygplates.RotationModel(rotation_filenames)

        # Load the topological plate polygon features.
        topology_features = []
        for fname in topology_filenames:
            for f in pygplates.FeatureCollection(fname):
                topology_features.append(f)

        # Call the function we created above to get the velocities
        all_velocities = velocity_utils.Get_Plate_Velocities(
            velocity_domain_features, topology_features, rotation_model,
            self.reconstruction_time, delta_time, 'vector_comp')

        uu = []
        vv = []
        for vel in all_velocities:
            if not hasattr(vel, 'get_y'):
                uu.append(vel[1])
                vv.append(vel[0])
            else:
                uu.append(vel.get_y())
                vv.append(vel.get_x())
        u = np.asarray([uu]).reshape((Ynodes.shape[0], Xnodes.shape[0]))
        v = np.asarray([vv]).reshape((Ynodes.shape[0], Xnodes.shape[0]))

        # compute native x,y coordinates of grid.
        x, y = m(Xg, Yg)

        uproj, vproj, xx, yy = m.transform_vector(u,
                                                  v,
                                                  Xnodes,
                                                  Ynodes,
                                                  15,
                                                  15,
                                                  returnxy=True,
                                                  masked=True)
        # now plot.
        Q = m.quiver(xx, yy, uproj, vproj, scale=1000, color='grey')
        # make quiver key.
        qk = plt.quiverkey(Q, 0.95, 1.05, 50, '50 mm/yr', labelpos='W')
コード例 #13
0
ファイル: views.py プロジェクト: GPlates/gplates-web-service
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})
コード例 #14
0
def get_isochrons_for_ridge_snapshot(topology_features,
                                     rotation_filename,
                                     out_dir,
                                     ridge_time,
                                     time_step,
                                     youngest_seed_time=0,
                                     ridge_sampling=2.):
    print("... Writing seed points along a ridge")
    if not os.path.exists(out_dir):
        os.makedirs(out_dir)

    rotation_model = pygplates.RotationModel(rotation_filename)

    oldest_seed_time = ridge_time

    all_longitudes = []
    all_latitudes = []
    all_ages = []

    # The first step is to generate points along the ridge
    resolved_topologies = []
    shared_boundary_sections = []
    pygplates.resolve_topologies(topology_features, rotation_filename,
                                 resolved_topologies, oldest_seed_time,
                                 shared_boundary_sections)

    # Previous points are on the MOR, current are moved by one time step off MOR.
    curr_points = get_mid_ocean_ridges(shared_boundary_sections,
                                       rotation_model, oldest_seed_time,
                                       time_step, ridge_sampling)

    # Write out the ridge point born at 'ridge_time' but their position at 'ridge_time - time_step'.
    mor_point_features = []
    for curr_point in curr_points:
        feature = pygplates.Feature()
        feature.set_geometry(curr_point)
        feature.set_valid_time(ridge_time, -999)  # delete - time_step
        mor_point_features.append(feature)
    pygplates.FeatureCollection(mor_point_features).write(
        './{:s}/MOR_plus_one_points_{:0.2f}.gmt'.format(out_dir, ridge_time))
    #
    print(
        "... Finished writing seed points along the mid ocean ridge for {:0.2f} Ma"
        .format(ridge_time))
コード例 #15
0
def make_masks_job(reconstruction_time, COBterrane_file,
                   input_rotation_filenames, grdspace, grd_output_dir):

    rotation_model = pygplates.RotationModel(input_rotation_filenames)
    print('Masking for time {:0.2f} Ma'.format(reconstruction_time))
    mask = get_merged_cob_terrane_raster(COBterrane_file, rotation_model,
                                         reconstruction_time, grdspace)

    gridX = np.arange(-180., 180. + grdspace, grdspace)
    gridY = np.arange(-90., 90. + grdspace, grdspace)
    #write_netcdf_grid('{0}/masks/mask_{1}Ma.nc'.format(grd_output_dir, reconstruction_time),
    #                  gridX, gridY, mask.astype(int))

    ds = xr.DataArray(mask, coords=[('y', gridY), ('x', gridX)], name='z')
    ds.to_netcdf('{0}/masks/mask_{1}Ma.nc'.format(grd_output_dir,
                                                  reconstruction_time),
                 format='NETCDF4_CLASSIC',
                 encoding={'z': {
                     'dtype': 'int16'
                 }})
    ds.close()
    return
コード例 #16
0
def reconstruct_points(request):
    points = request.GET.get('points', None)
    plate_id = request.GET.get('pid', None)
    time = request.GET.get('time', None)
    
    rotation_model = pygplates.RotationModel(
        MODEL_DEFAULT+"Seton_etal_ESR2012_2012.1.rot")
    static_polygons_filename = \
        MODEL_DEFAULT+"Seton_etal_ESR2012_StaticPolygons_2012.1.gpmlz"
    
    point_features = []
    if points:
        ps = points.split(',')
        if len(ps)%2==0:
            for lat,lon in zip(ps[1::2], ps[0::2]):
                point_feature = pygplates.Feature()
                point_feature.set_geometry(pygplates.PointOnSphere(float(lat),float(lon)))    
                point_features.append(point_feature)

    #for f in point_features:
    #    f.set_reconstruction_plate_id(int(plate_id))
    assigned_point_features = pygplates.partition_into_plates(
        static_polygons_filename,
        rotation_model,
        point_features,
        properties_to_copy = [
            pygplates.PartitionProperty.reconstruction_plate_id,
            pygplates.PartitionProperty.valid_time_period])
    assigned_point_feature_collection = pygplates.FeatureCollection(assigned_point_features)
    reconstructed_feature_geometries = []
    pygplates.reconstruct(assigned_point_feature_collection, rotation_model, reconstructed_feature_geometries, float(time))
    ret='{"coordinates":['
    for g in reconstructed_feature_geometries:
        ret+='[{0:5.2f},{1:5.2f}],'.format(
            g.get_reconstructed_geometry().to_lat_lon()[1],
            g.get_reconstructed_geometry().to_lat_lon()[0])
    ret=ret[0:-1]
    ret+=']}'
    return HttpResponse(ret, content_type='application/json')
コード例 #17
0
def FeatureCollection(model=default_model,
                      layer='rotations',
                      url=default_url,
                      proxy=''):
    """
    function to access gpml data files directly from the gplates-web-service data store 
    and load them into pygplates feature collections.
    :param model: 
    :param layer: 'rotations', 'coastlines', 'static_polygons', 'plate_polygons'
    :param url:
    :param proxy:
    """

    if layer == 'rotations':
        requested_file = 'request.rot'
    else:
        requested_file = 'request.gpmlz'

    with open(requested_file, 'wb') as handle:
        r = requests.get('%s/model/get_model_layer/?model=%s&layer=%s' %
                         (url, model, layer),
                         proxies={'http': '%s' % proxy},
                         stream=True)

        if r.status_code != 200:
            error_string = 'Remote request returned with message %s' % r.text
            raise Exception(error_string)
        else:
            for block in r.iter_content(1024):
                handle.write(block)

        if layer == 'rotations':
            result = pygplates.RotationModel('request.rot')
        else:
            result = pygplates.FeatureCollection('request.gpmlz')

    return result
コード例 #18
0
def reconstruct_coastlines(time):
    shp_path = settings.MODEL_STORE_DIR+'/'+settings.MODEL_DEFAULT+'/coastlines_low_res/Seton_etal_ESR2012_Coastlines_2012.shp'

    import shapefile
    sf = shapefile.Reader(shp_path)
    features = []
    for record in sf.shapeRecords():
        if record.shape.shapeType != 5:
            continue
        for idx in range(len(record.shape.parts)):
            start_idx = record.shape.parts[idx]
            end_idx = len(record.shape.points)
            if idx < (len(record.shape.parts) -1):
                end_idx = record.shape.parts[idx+1]
            polygon_feature = pygplates.Feature()
            points = record.shape.points[start_idx:end_idx]
            polygon_feature.set_geometry(
                pygplates.PolygonOnSphere([(lat,lon) for lon, lat in points]))
            polygon_feature.set_reconstruction_plate_id(int(record.record[0]))
            features.append(polygon_feature)
            break

    feature_collection = pygplates.FeatureCollection(features)
    reconstructed_polygons = []

    model_dict = get_reconstruction_model_dict(settings.MODEL_DEFAULT)
    rotation_model = pygplates.RotationModel([str('%s/%s/%s' %
        (settings.MODEL_STORE_DIR,settings.MODEL_DEFAULT,rot_file)) for rot_file in model_dict['RotationFile']])


    pygplates.reconstruct(
        feature_collection,
        rotation_model,
        reconstructed_polygons,
        float(time))

    return reconstructed_polygons
コード例 #19
0
def spreading_rates(
        rotation_features_or_model,
        topology_features,
        time,
        threshold_sampling_distance_radians,
        spreading_feature_types=None,
        transform_segment_deviation_in_radians=separate_ridge_transform_segments
    .DEFAULT_TRANSFORM_SEGMENT_DEVIATION_RADIANS,
        velocity_delta_time=1.0,
        anchor_plate_id=0):
    """
    Calculates spreading rate and length of ridge segments of spreading features (mid-ocean ridges) of resolved topologies at specified time.
    
    The transform segments of spreading features are ignored.
    
    Resolves topologies at 'time', tessellates all resolved spreading features to within 'threshold_sampling_distance_radians' radians and
    returns a list of tuples where each tuple represents a tessellated point and contains the following parameters:
    
    - point longitude
    - point latitude
    - spreading velocity magnitude (in cm/yr)
    - length of arc segment (in degrees) that current point is on
    
    
    rotation_features_or_model: Rotation model or feature collection(s), or list of features, or filename(s).
    
    topology_features: Topology feature collection(s), or list of features, or filename(s) or any combination of those.
    
    time: Reconstruction time to resolved topologies.
    
    threshold_sampling_distance_radians: Threshold sampling distance along spreading features (in radians).
    
    spreading_feature_types: Only spreading features with a feature type contained in this list are considered.
                             If None then all spreading features are considered.
    
    transform_segment_deviation_in_radians: How much a segment can deviate from the stage pole before
                                            it's considered a transform segment (in radians).
    
    velocity_delta_time: Delta time interval used to calculate spreading velocity.
    
    Returns: List of the tuples described above.
    """
    time = float(time)

    # Turn rotation data into a RotationModel (if not already).
    rotation_model = pygplates.RotationModel(rotation_features_or_model)

    # Turn topology data into a list of features (if not already).
    topology_features = pygplates.FeaturesFunctionArgument(topology_features)

    # 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.get_features(),
                                 rotation_model, resolved_topologies, time,
                                 shared_boundary_sections, anchor_plate_id)

    # List of tesselated spreading points and associated spreading parameters for the current 'time'.
    output_data = []

    # Iterate over the shared boundary sections of all resolved topologies.
    for shared_boundary_section in shared_boundary_sections:

        spreading_feature = shared_boundary_section.get_feature()

        # Skip sections that are not spreading features (if requested).
        if (spreading_feature_types and spreading_feature.get_feature_type()
                not in spreading_feature_types):
            continue

        # Find the stage rotation of the spreading feature in the frame of reference of its reconstructed geometry at the current 'time'.
        # The stage pole can then be directly geometrically compared to the reconstructed spreading geometry.
        spreading_stage_rotation = separate_ridge_transform_segments.get_stage_rotation_for_reconstructed_geometry(
            spreading_feature, rotation_model, time)
        if not spreading_stage_rotation:
            # Skip current feature - it's not a spreading feature.
            continue

        # Iterate over the shared sub-segments of the current line.
        # These are the parts of the line that actually contribute to topological boundaries.
        for shared_sub_segment in shared_boundary_section.get_shared_sub_segments(
        ):

            # Split into ridge and transform segments.
            ridge_and_transform_segment_geometries = separate_ridge_transform_segments.separate_geometry_into_ridges_and_transforms(
                spreading_stage_rotation,
                shared_sub_segment.get_resolved_geometry(),
                transform_segment_deviation_in_radians)
            if not ridge_and_transform_segment_geometries:
                # Skip shared sub segment - it's not a polyline (or polygon).
                continue

            # Only interested in ridge segments.
            ridge_sub_segment_geometries, _ = ridge_and_transform_segment_geometries

            # Ensure the ridge sub-segments are tessellated to within the threshold sampling distance.
            tessellated_shared_sub_segment_polylines = [
                ridge_sub_segment_geometry.to_tessellated(
                    threshold_sampling_distance_radians)
                for ridge_sub_segment_geometry in ridge_sub_segment_geometries
            ]

            # Iterate over the great circle arcs of the tessellated polylines to get the arc midpoints and lengths.
            # There is an arc between each adjacent pair of points in the polyline.
            arc_midpoints = []
            arc_lengths = []
            for tessellated_shared_sub_segment_polyline in tessellated_shared_sub_segment_polylines:
                for arc in tessellated_shared_sub_segment_polyline.get_segments(
                ):
                    if not arc.is_zero_length():
                        arc_midpoints.append(arc.get_arc_point(0.5))
                        arc_lengths.append(arc.get_arc_length())

            # Shouldn't happen, but just in case ridge sub-segment polylines coincide with points.
            if not arc_midpoints:
                continue

            # Calculate the spreading velocities at the arc midpoints.
            #
            # Note that the stage rotation can be used directly on the reconstructed geometries because
            # it is already in the frame of reference of the reconstructed geometries.
            spreading_velocity_vectors = pygplates.calculate_velocities(
                arc_midpoints, spreading_stage_rotation, velocity_delta_time,
                pygplates.VelocityUnits.cms_per_yr)

            for arc_index in range(len(arc_midpoints)):

                arc_midpoint = arc_midpoints[arc_index]
                arc_length = arc_lengths[arc_index]
                lat, lon = arc_midpoint.to_lat_lon()

                spreading_velocity_magnitude = spreading_velocity_vectors[
                    arc_index].get_magnitude()

                # The data will be output in GMT format (ie, lon first, then lat, etc).
                output_data.append((lon, lat, spreading_velocity_magnitude,
                                    math.degrees(arc_length)))

    return output_data
コード例 #20
0
    #

    # Some testing/example code.

    #

    import time

    print('Loading coastline polygons and rotation model...')

    coastline_features = pygplates.FeatureCollection(
        '../../../../sample_data/2.0/SampleData/FeatureCollections/Coastlines/Matthews_etal_GPC_2016_Coastlines.gpmlz'
    )

    rotation_model = pygplates.RotationModel(
        '../../../../sample_data/2.0/SampleData/FeatureCollections/Rotations/Matthews_etal_GPC_2016_410-0Ma_GK07.rot'
    )

    print('Reconstructing coastline polygons...')

    reconstruction_time = 0

    coastline_reconstructed_feature_geometries = []

    pygplates.reconstruct(coastline_features, rotation_model,
                          coastline_reconstructed_feature_geometries,
                          reconstruction_time)

    polygons = []

    polygon_features = []
        while rfg2_index < len(reconstructed_feature_geometries):
            rfg2 = reconstructed_feature_geometries[rfg2_index]
            rfg2_geom = rfg2.get_reconstructed_geometry()
            
            # Compare the geometries of rfg1 and rfg2.
            # Test for duplicate geometries.
            if rfg1_geom == rfg2_geom:
                del reconstructed_feature_geometries[rfg2_index]
                rfg2_index -= 1
            
            rfg2_index += 1
        
        rfg1_index += 1


rotation_model = pygplates.RotationModel(rotation_file)

proximity_features = list(pygplates.FeatureCollection(proximity_features_file))

print('{:<10} {:<10}'.format('Age(Ma)', 'Length(Kms)'))

# Time range 0-230Ma in 1My intervals.
for time in range(0, 231):
    
    length_in_kms = 0
    
    # Reconstruct the proximity features that exist at the current 'time'.
    proximity_reconstructed_feature_geometries = []
    pygplates.reconstruct(proximity_features, rotation_model, proximity_reconstructed_feature_geometries, time)
    
    # Remove any 'exact' duplicate reconstructed geometries.
コード例 #22
0
def coregLoop(pointlist, ages, plateIDs):
    '''
    coregLoop

    This script reconstructs a shapefile of points to their birth time and 
    coregisters each point with another set of points, or a raster file.

    INPUTS:
    pointlist - list of lat/lon
    ages - list of ages corresponding to lat/lon point
    plateIDs - list of plateIDs corresponding to lat/lon point.

    Hardcoded filenames/variables must be changed below:
    input_rotation_filename - Rotation file 
    rasterfile - Time dependent raster files
    f - Time dependent kinemtic csv outputs from 'convergence.py'

    OUTPUTS:
    Coregistered array: List of lat/lons with properties.
    
    METHOD:
    Takes a set of points 
    Rotates the points back to their birth position
    Determines the point's birth position geophysical properties (coregisters)
    '''

    #Set up a list to store the data
    timeSteps = 1  # +- Myrs around point to store. Default 1 which means just the measured point age.
    noVariables = 18  #The number of variables you save
    Nshp = len(pointlist)

    coregData = numpy.zeros((Nshp, timeSteps, noVariables))

    #Create a rotation model to rotate the points back in time
    input_rotation_filename = "Muller_gplates/Global_EarthByte_230-0Ma_GK07_AREPS.rot"

    file_registry = pygplates.FeatureCollectionFileFormatRegistry()
    rotation_feature_collection = file_registry.read(input_rotation_filename)
    rotation_model = pygplates.RotationModel([rotation_feature_collection])

    #Loop over all the samples, coregistering each one.
    for i, currentPoint in enumerate(pointlist):

        lat = currentPoint[1]
        lon = currentPoint[0]
        age = ages[i]
        plateID = int(plateIDs[i])

        print("Deposit:", i, "of", Nshp, "Lat:", lat, "Lon:", lon, "Age:", age,
              "PlateID:", plateID)

        #Loop through each time step in the plate model
        for time in xrange(0, 230, 1):

            #If the point was formed at the current time (or [timeStepsMyr ] prior/after) then we
            #want to find the surrounding plate properties.
            #if  (time > (age-10)) and (time < (age+10)) or (time > (age+20)) and (time < (age+30)):
            if (time > (age - timeSteps)) and (time < (age + timeSteps)):
                t = int(numpy.floor(time - age))
                #print(t,time,age)

                #A raster file, to coregister with, these points have already been rotated
                rasterfile = "Muller_etal_2016_AREPS_Agegrids_v1.11/netCDF_0-230Ma/EarthByte_AREPS_v1.11_Muller_etal_2016_AgeGrid-" + str(
                    time) + ".nc"
                [x, y, z] = gridRead(rasterfile)

                #A vector file to coregister with, these points have already been rotated
                f = numpy.loadtxt("Muller_convergence/subStats_" + str(time) +
                                  ".csv",
                                  delimiter=',')
                lonlat = f[:, 0:2]

                #-------------------#
                #Reconstruct a point to its birth position
                #-------------------#
                latlonPoint = pygplates.LatLonPoint(lat, lon)
                point_to_rotate = pygplates.convert_lat_lon_point_to_point_on_sphere(
                    latlonPoint)

                finite_rotation = rotation_model.get_rotation(time, plateID)
                birthPosition = finite_rotation * point_to_rotate

                latlonBirth = pygplates.convert_point_on_sphere_to_lat_lon_point(
                    birthPosition)
                #allPoints = finite_rotation * pointSet_to_rotate

                latBirth = latlonBirth.get_latitude()
                lonBirth = latlonBirth.get_longitude()

                #-------------------#
                #Set the points for coregistering
                region = 5.0  #degrees

                #-------------------#
                #Coregisterring raster 1
                #-------------------#
                #Find the region in index units
                r = numpy.round(region / (x[1] - x[0]))

                #Find the index unit of lat and lon
                idxLon = (numpy.abs(x - lonBirth)).argmin()
                idxLat = (numpy.abs(y - latBirth)).argmin()

                #Raster 1
                c2 = coregRaster([idxLon, idxLat], z, r)
                #Hack to search further around the age grid if it can't find a match, note index units (not degrees)
                if numpy.isnan(c2):
                    c2 = coregRaster([idxLon, idxLat], z, r + 150.0)
                    print("Trying raster region: ", r + 150.0)

                #-------------------#
                #Coregisterring vector 1
                #-------------------#
                index = coregPoint([lonBirth, latBirth], lonlat, region)
                if index == 'inf':
                    print("trying index region", region + 15)
                    index = coregPoint([lonBirth, latBirth], lonlat,
                                       region + 15.0)

                if numpy.isnan(c2) or index == 'inf':
                    print("Skipping:", i, age, t, time, c2, index, lonBirth,
                          latBirth)

                else:
                    #Vector 1
                    segmentLength = f[index, 3]
                    slabLength = f[index, 9]
                    distSlabEdge = f[index, 15]

                    SPcoregNor = f[index, 4]
                    SPcoregPar = f[index, 12]
                    OPcoregNor = f[index, 5]
                    OPcoregPar = f[index, 13]
                    CONVcoregNor = f[index, 10]
                    CONVcoregPar = f[index, 11]

                    subPolCoreg = f[index, 8]
                    subOblCoreg = f[index, 7]
                    coregData[i, t, :] = [
                        lon, lat, lonBirth, latBirth, age, t, c2,
                        segmentLength, slabLength, distSlabEdge, SPcoregNor,
                        SPcoregPar, OPcoregNor, OPcoregPar, CONVcoregNor,
                        CONVcoregPar, subPolCoreg, subOblCoreg
                    ]

    #Return the filled coregistered array
    return (coregData)
コード例 #23
0
def coregLoopHistory(pointlist, ts0=0, ts1=230, plateID=201):
    '''
    coregLoopHistory

    This script reconstructs a list of points throughout history and 
    coregisters each point with another set of points, or a raster file.

    INPUTS:
    pointlist - list of lat/lon
    ts0 - time step to rotate points from (probably 0Ma)
    ts1 - time step to rotate points to (probably 230Ma).

    Hardcoded filenames/variables must be changed below:
    input_rotation_filename - Rotation file 
    rasterfile - Time dependent raster files
    f - Time dependent kinemtic csv outputs from 'convergence.py'

    OUTPUTS:
    Coregistered array: List of lat/lons with properties.

    METHOD:
    Takes a set of points 
    Rotates the points back to their birth position
    Determines the point's birth position geophysical properties (coregisters)
    '''

    #Set up an array to store the data
    timeSteps = ts1 - ts0  #The length of time before mineralisation you care about
    noVariables = 18  #The number of variables you save
    Nshp = len(pointlist)
    coregData = numpy.zeros((Nshp, timeSteps, noVariables))

    #Create a rotation model to rotate the points back in time
    input_rotation_filename = "Muller_gplates/Global_EarthByte_230-0Ma_GK07_AREPS.rot"

    file_registry = pygplates.FeatureCollectionFileFormatRegistry()
    rotation_feature_collection = file_registry.read(input_rotation_filename)
    rotation_model = pygplates.RotationModel([rotation_feature_collection])

    #Loop through each time step in the plate model
    for time in xrange(ts0, ts1, 1):

        #A raster file, to coregister with, these points have already been rotated
        rasterfile = "Muller_etal_2016_AREPS_Agegrids_v1.11/netCDF_0-230Ma/EarthByte_AREPS_v1.11_Muller_etal_2016_AgeGrid-" + str(
            time) + ".nc"
        [x, y, z] = gridRead(rasterfile)

        #A vector file to coregister with, these points have already been rotated
        f = numpy.loadtxt("Muller_convergence/subStats_" + str(time) + ".csv",
                          delimiter=',')

        lonlat = f[:, 0:2]

        for i, currentPoint in enumerate(pointlist):

            shapeArray = currentPoint
            age = ts0

            t = time - age
            print(i, age, time, t, plateID)

            #-------------------#
            #Reconstruct a point to its birth position
            #-------------------#
            latlonPoint = pygplates.LatLonPoint(shapeArray[1], shapeArray[0])

            point_to_rotate = pygplates.convert_lat_lon_point_to_point_on_sphere(
                latlonPoint)

            finite_rotation = rotation_model.get_rotation(time, plateID)
            birthPosition = finite_rotation * point_to_rotate

            latlonBirth = pygplates.convert_point_on_sphere_to_lat_lon_point(
                birthPosition)
            #allPoints = finite_rotation * pointSet_to_rotate

            latBirth = latlonBirth.get_latitude()
            lonBirth = latlonBirth.get_longitude()

            #-------------------#
            #Set the points for coregistering
            region = 5.0  #degrees

            #-------------------#
            #Coregisterring raster 1
            #-------------------#
            #Find the region in index units
            r = numpy.round(region / (x[1] - x[0]))

            #Find the index unit of lat and lon
            idxLon = (numpy.abs(x - lonBirth)).argmin()
            idxLat = (numpy.abs(y - latBirth)).argmin()

            #Raster 1
            c2 = coregRaster([idxLon, idxLat], z, r)
            #Hack to search further around the age grid if it can't find a match, \
            #note index units (not degrees)
            if numpy.isnan(c2):
                c2 = coregRaster([idxLon, idxLat], z, r + 150.0)
                print("Trying raster region: ", r + 150.0)

            #-------------------#
            #Coregisterring vector 1
            #-------------------#
            index = coregPoint([lonBirth, latBirth], lonlat, region)
            if index == 'inf':
                print("trying index region", region + 15)
                index = coregPoint([lonBirth, latBirth], lonlat, region + 15.0)

            if numpy.isnan(c2) or index == 'inf':
                #if we have some null data, let's save it anyway, see what happens
                print("Skipping:", i, age, t, time, c2, index, lonBirth,
                      latBirth)

            else:
                #Vector 1
                segmentLength = f[index, 3]
                slabLength = f[index, 9]
                distSlabEdge = f[index, 15]

                SPcoregNor = f[index, 4]
                SPcoregPar = f[index, 12]
                OPcoregNor = f[index, 5]
                OPcoregPar = f[index, 13]
                CONVcoregNor = f[index, 10]
                CONVcoregPar = f[index, 11]

                subPolCoreg = f[index, 8]
                subOblCoreg = f[index, 7]

                coregData[i, t, :] = [
                    shapeArray[0], shapeArray[1], lonBirth, latBirth, age, t,
                    c2, segmentLength, slabLength, distSlabEdge, SPcoregNor,
                    SPcoregPar, OPcoregNor, OPcoregPar, CONVcoregNor,
                    CONVcoregPar, subPolCoreg, subOblCoreg
                ]

    return (coregData)
コード例 #24
0
        '--output_filename_extension',
        type=str,
        default='{0}'.format(DEFAULT_OUTPUT_FILENAME_EXTENSION),
        help=
        "The filename extension of the output files containing the resolved topological boundaries and sections "
        "- the default extension is '{0}' - supported extensions include 'shp', 'gmt' and 'xy'."
        .format(DEFAULT_OUTPUT_FILENAME_EXTENSION))

    parser.add_argument(
        'output_filename_prefix',
        type=str,
        nargs='?',
        default='{0}'.format(DEFAULT_OUTPUT_FILENAME_PREFIX),
        help=
        "The prefix of the output files containing the resolved topological boundaries and sections "
        "- the default prefix is '{0}'".format(DEFAULT_OUTPUT_FILENAME_PREFIX))

    # Parse command-line options.
    args = parser.parse_args()

    rotation_model = pygplates.RotationModel(args.rotation_filenames)

    topological_features = [
        pygplates.FeatureCollection(topology_filename)
        for topology_filename in args.topology_filenames
    ]

    for reconstruction_time in args.reconstruction_times:
        reconstruct_features(rotation_model, topological_features,
                             reconstruction_time, args.output_filename_prefix,
                             args.output_filename_extension)
コード例 #25
0
def calc_subducting_sediment_volume(time):

    rotation_model = pygplates.RotationModel(rotation_filename)
    topology_features = pygplates.FeaturesFunctionArgument(
            (topology_dir + '/Global_EarthByte_230-0Ma_GK07_AREPS_PlateBoundaries.gpml',
            topology_dir + '/Global_EarthByte_230-0Ma_GK07_AREPS_Topology_BuildingBlocks.gpml')).get_features()

    sediment_thickness_grid_filename = sediment_thickness_grid_dir + '/sed_thick_0.2d_{0}.grd'.format(time)
    
    subduction_convergence_data = subduction_convergence.subduction_convergence(
                rotation_model,
                topology_features,
                tessellation_threshold_radians,
                time)
    
    subduction_points = [pygplates.PointOnSphere(data[1], data[0]) for data in subduction_convergence_data]
    
    # Sample the sediment thickness raster at the subduction points.
    sediment_thicknesses = raster_query.query_raster_at_points(
            sediment_thickness_grid_filename,
            subduction_points,
            search_radius_radians,
            smoothing_radius_radians)
    
    subducting_lon_lat_thickness_velocity_volume_list = []
    
    # Iterate over subduction points/thicknesses and calculate statistics (including subducting volume).
    weighted_mean_subducting_sed_thickness = 0.0
    weighted_second_moment_subducting_sed_thickness = 0.0
    total_subducting_length_metres = 0.0
    total_subducting_sediment_volume_metres_3_per_year = 0.0
    for subduction_point_index, sediment_thickness in enumerate(sediment_thicknesses):
        if math.isnan(sediment_thickness):
            continue
        
        subduction_convergence_item = subduction_convergence_data[subduction_point_index]
        
        subducting_lon = subduction_convergence_item[0]
        subducting_lat = subduction_convergence_item[1]
        convergence_velocity_magnitude_cm_per_yr = subduction_convergence_item[2]
        convergence_obliquity_degrees = subduction_convergence_item[3]
        #absolute_velocity_magnitude = subduction_convergence_item[4]
        #absolute_obliquity_degrees = subduction_convergence_item[5]
        subducting_length_degrees = subduction_convergence_item[6]
        #subducting_arc_normal_azimuth = subduction_convergence_item[7]
        #subducting_plate_id = subduction_convergence_item[8]
        #overriding_plate_id = subduction_convergence_item[9]
        
        subducting_length_metres = (
            math.radians(subducting_length_degrees) * 1e3 * pygplates.Earth.mean_radius_in_kms)
        
        weighted_mean_subducting_sed_thickness += subducting_length_metres * sediment_thickness
        weighted_second_moment_subducting_sed_thickness += subducting_length_metres * sediment_thickness * sediment_thickness
        
        total_subducting_length_metres += subducting_length_metres
        convergence_normal_velocity_metres_per_year = (
            # 1e-2 converts cm/y to m/y...
            1e-2 * math.fabs(convergence_velocity_magnitude_cm_per_yr) *
            # Negative convergence handled by cos(obliquity_angle)...
            math.cos(math.radians(convergence_obliquity_degrees)))
        subducting_sediment_volume_metres_3_per_year = (
                sediment_thickness * subducting_length_metres * convergence_normal_velocity_metres_per_year)
        total_subducting_sediment_volume_metres_3_per_year += subducting_sediment_volume_metres_3_per_year
        
        subducting_lon_lat_thickness_velocity_volume_list.append((
                subducting_lon,
                subducting_lat,
                sediment_thickness,
                subducting_sediment_volume_metres_3_per_year / subducting_length_metres,
                # cms/year ...
                1e2 * convergence_normal_velocity_metres_per_year))
    
    # mean = M = sum(Ci * Xi) / sum(Ci)
    # std_dev  = sqrt[sum(Ci * (Xi - M)^2) / sum(Ci)]
    #          = sqrt[(sum(Ci * Xi^2) - 2 * M * sum(Ci * Xi) + M^2 * sum(Ci)) / sum(Ci)]
    #          = sqrt[(sum(Ci * Xi^2) - 2 * M * M * sum(Ci) + M^2 * sum(Ci)) / sum(Ci)]
    #          = sqrt[(sum(Ci * Xi^2) - M^2 * sum(Ci)) / sum(Ci)]
    #          = sqrt[(sum(Ci * Xi^2) / sum(Ci) - M^2]
    mean_sed_thickness = weighted_mean_subducting_sed_thickness / total_subducting_length_metres
    variance_sed_thickness = (
            (weighted_second_moment_subducting_sed_thickness / total_subducting_length_metres) -
            mean_sed_thickness * mean_sed_thickness)
    std_dev_sed_thickness = math.sqrt(variance_sed_thickness) if variance_sed_thickness > 0.0 else 0.0
    
    return (time,
            subducting_lon_lat_thickness_velocity_volume_list,
            mean_sed_thickness,
            std_dev_sed_thickness,
            total_subducting_length_metres,
            total_subducting_sediment_volume_metres_3_per_year)
コード例 #26
0
def kinloop(timeFrom,timeTo,data,input_rotation_filename):
    '''
    Determines the absolute and relative velocities of the plates and trench.

    INPUT (with examples):
        
    timeFrom=2 #integer
    timeTo=1 #integer
    data = [[14.7703, 43.5369, 701, 301, 301], [18.8934, 41.5683, 701, 301, 301], 
            [18.6062, 39.7998, 701, 301, 301], [19.4349, 39.3242, 701, 301, 301]]
            #List of points [[Lon, Lat, SPid, TRENCHid, OPid]]
    input_rotation_filename='Shephard_etal_ESR2013_Global_EarthByte_2013.rot' #String
    
    OUTPUT: (array equivalent to 'data' plus Absoulte XYZ and Convergence XYZ 
        velocity components.)

    [14.7703, 43.5369, 701, 301, 301, -13.02077,10.4195,10.45488,-4.86172,
        -4.62026,6.18716]
        
    WARNING: If this function is used stand-alone, without an idea of left
        or right, then it may be backward. Points should be entered CW.

    '''
    #Set the times of interest
    #timeFrom=3 #from xx Ma
    #timeTo=2 # to xx Ma
    
    #Read the SubdctionZoneAttributes data
    kinematicsArray=data

    #Read the rotation file and build a rotation model    
    #input_rotation_filename = "/Users/nbutter/DataMining/CODE/SubductionZoneAttributes/oldTestdata/Global_EarthByte_TPW_CK95G94_PP_20110412.rot"
    file_registry = pygplates.FeatureCollectionFileFormatRegistry()
    rotation_feature_collection = file_registry.read(input_rotation_filename)
    rotation_model = pygplates.RotationModel([rotation_feature_collection])

    #Build the rotations for the times we want    
    fromTimeRotation=rotation_model.get_reconstruction_tree(timeFrom)
    toTimeRotation=rotation_model.get_reconstruction_tree(timeTo)
    
    #Make an array to store our data in
    speedArray=[]
    reversedSub=0 #Initilise this here in case the data does not have headers
    
    #Loop through all the SubdctionZoneAttributes data and find velocities
    for index, point in enumerate(kinematicsArray[:]): 
        #print point[0]
        #See if the point is not a header, or if the next point is not a header
        if isinstance(point[0],str):
            #Also, if it is a header, get the order of the points
            if point[0].find('Reversed') != -1:
                reversedSub=int(point[-1])
                #print reverse
        if len(point) == 5:
            lon = float(point[0])
            lat = float(point[1])
            OPid = int(point[4])
            TRENCHid = int(point[3])
            SPid = int(point[2])

            #Convert point LatLon to XYZ
            pointXYZ, pointXYZcart = latlon2pygplates(lat,lon)
            
            #Get the Euler poles for each of the relevant rotations
            stageTrench = pygplates.ReconstructionTree.get_equivalent_stage_rotation(fromTimeRotation,toTimeRotation,TRENCHid)
            poletTrench,angleTrench = stageTrench.get_euler_pole_and_angle()
            poleTrench = [poletTrench.get_x(), poletTrench.get_y(), poletTrench.get_z()]

            #Absolut velocity is the motion of the SP
            stageSP = pygplates.ReconstructionTree.get_equivalent_stage_rotation(fromTimeRotation,toTimeRotation,SPid)
            poletSP,angleSP = stageSP.get_euler_pole_and_angle()
            #If you want the latitude and longitude, rather than the cartesian:
            #poleSPLatLon = pygplates.convert_point_on_sphere_to_lat_lon_point(poleSP)
            #SPLatLon = [poleSPLatLon.get_latitude(), poleSPLatLon.get_longitude()] 
            poleSP = [poletSP.get_x(), poletSP.get_y(), poletSP.get_z()]

            #Convergence is the relative rotation between the trench and SP
            #if reversedSub==1:
            #convRotation = pygplates.get_relative_stage_rotation(fromTimeRotation,toTimeRotation,TRENCHid,SPid)
            #else:
            convRotation = pygplates.ReconstructionTree.get_relative_stage_rotation(fromTimeRotation,toTimeRotation,SPid,TRENCHid)
            poletCONV,angleCONV = convRotation.get_euler_pole_and_angle()
            poleCONV = [poletCONV.get_x(), poletCONV.get_y(), poletCONV.get_z()]

            #The OP motion
            stageOP = pygplates.ReconstructionTree.get_equivalent_stage_rotation(fromTimeRotation,toTimeRotation,OPid)
            poletOP,angleOP = stageOP.get_euler_pole_and_angle()
            poleOP = [poletOP.get_x(), poletOP.get_y(), poletOP.get_z()]
            
            #Angular velocity (Degrees / Myr) #but need it in radians.. not used
            omegaCONV = numpy.degrees(angleCONV)/(timeFrom-timeTo)
            omegaSP = numpy.degrees(angleSP)/(timeFrom-timeTo) 

            #Velocity vectors at each point in (Earth Radius Units) / Myr
            absoluteV = numpy.cross(poleSP,pointXYZcart) * angleSP/(timeFrom-timeTo) 
            convergenceV = numpy.cross(poleCONV,pointXYZcart) * angleCONV/(timeFrom-timeTo) 
            opV = numpy.cross(poleOP,pointXYZcart) * angleOP/(timeFrom-timeTo)
            trenchV = numpy.cross(poleTrench,pointXYZcart) * angleTrench/(timeFrom-timeTo)            

            #Velocivites vectors in mm/yr (km/Myr)
            Rearth=6371.0 # m 
            vABS = absoluteV * Rearth
            vCONV = convergenceV * Rearth
            vOP = opV * Rearth
            vTrench = trenchV * Rearth

            speedArray.append([lon,lat,SPid,TRENCHid,OPid,\
                round(vABS[0],5),round(vABS[1],5),round(vABS[2],5),\
                round(vCONV[0],5),round(vCONV[1],5),round(vCONV[2],5),\
                round(vOP[0],5),round(vOP[1],5),round(vOP[2],5),\
                round(vTrench[0],5),round(vTrench[1],5),round(vTrench[2],5),\
                int(SPid), int(TRENCHid), int(OPid)])
            #print [lon,lat,SPid,TRENCHid,OPid,round(vABS[0],5),round(vABS[1],5),round(vABS[2],5),round(vCONV[0],5),round(vCONV[1],5),round(vCONV[2],5)]
        #If it is a header, just print it back out.
        else:
            #pass
            speedArray.append(point)

    return(speedArray)
コード例 #27
0
def reconstruct_seeds(input_rotation_filenames,
                      topology_features,
                      seedpoints_output_dir,
                      mor_seedpoint_filename,
                      initial_ocean_seedpoint_filename,
                      max_time,
                      min_time,
                      time_step,
                      grd_output_dir,
                      subduction_collision_parameters=(5.0, 10.0),
                      continent_mask_file_pattern=None):
    # reconstruct the seed points using the reconstruct_by_topologies function
    # returns the result either as lists or dumps to an ascii file

    rotation_model = pygplates.RotationModel(input_rotation_filenames)

    print('Begin assembling seed points and reconstructing by topologies....')

    # load features to reconstruct
    cp = []  # current_point # TODO more verbose names for cp and at
    at = []  # appearance_time
    birth_lat = []  # latitude_of_crust_formation
    prev_lat = []
    prev_lon = []

    seeds_at_start_time = pygplates.FeatureCollection(
        initial_ocean_seedpoint_filename)
    for feature in seeds_at_start_time:
        cp.append(feature.get_geometry())
        at.append(feature.get_valid_time()[0])
        birth_lat.append(feature.get_geometry().to_lat_lon_list()[0]
                         [0])  # Why use a list here??
        prev_lat.append(feature.get_geometry().to_lat_lon_list()[0][0])
        prev_lon.append(feature.get_geometry().to_lat_lon_list()[0][1])

    #seeds_from_topologies = pygplates.FeatureCollection(mor_seedpoint_filename)
    seeds_from_topologies = []

    for time in np.arange(max_time, min_time - time_step, -time_step):
        filename = './{:s}/MOR_plus_one_points_{:0.2f}.gmt'.format(
            seedpoints_output_dir, time)
        print('merging seeds from file {:s}'.format(filename))
        features = pygplates.FeatureCollection(filename)
        for feature in features:
            seeds_from_topologies.append(feature)

    for feature in seeds_from_topologies:
        if feature.get_valid_time()[0] < max_time:
            cp.append(feature.get_geometry())
            at.append(feature.get_valid_time()[0])
            birth_lat.append(feature.get_geometry().to_lat_lon_list()[0][0])
            prev_lat.append(feature.get_geometry().to_lat_lon_list()[0][0])
            prev_lon.append(feature.get_geometry().to_lat_lon_list()[0][1])

    point_id = range(len(cp))

    # specify the collision detection
    default_collision = rbt.DefaultCollision(
        feature_specific_collision_parameters=[(
            pygplates.FeatureType.gpml_subduction_zone,
            subduction_collision_parameters)])

    # specify the collision depending on whether the continent collision is specified
    if continent_mask_file_pattern:
        collision_spec = rbt.ContinentCollision(continent_mask_file_pattern,
                                                default_collision)
    else:
        collision_spec = default_collision

    print('preparing reconstruction by topologies....')
    topology_reconstruction = rbt.ReconstructByTopologies(
        rotation_model,
        topology_features,
        max_time,
        min_time,
        time_step,
        cp,
        point_begin_times=at,
        detect_collisions=collision_spec)

    # Initialise the reconstruction.
    topology_reconstruction.begin_reconstruction()

    # Loop over the reconstruction times until reached end of the reconstruction time span, or
    # all points have entered their valid time range *and* either exited their time range or
    # have been deactivated (subducted forward in time or consumed by MOR backward in time).
    while True:
        print('reconstruct by topologies: working on time {:0.2f} Ma'.format(
            topology_reconstruction.get_current_time()))

        curr_points = topology_reconstruction.get_active_current_points()

        print(len(cp), len(prev_lat))

        curr_lat_lon_points = [point.to_lat_lon() for point in curr_points]
        if curr_lat_lon_points:
            curr_latitudes, curr_longitudes = zip(*curr_lat_lon_points)

            seafloor_age = []
            birth_lat_snapshot = []
            point_id_snapshot = []
            prev_lat_snapshot = []
            prev_lon_snapshot = []
            for point_index, current_point in enumerate(
                    topology_reconstruction.get_all_current_points()):
                if current_point is not None:
                    #all_birth_ages.append(at[point_index])
                    seafloor_age.append(
                        at[point_index] -
                        topology_reconstruction.get_current_time())
                    birth_lat_snapshot.append(birth_lat[point_index])
                    point_id_snapshot.append(point_id[point_index])
                    prev_lat_snapshot.append(prev_lat[point_index])
                    prev_lon_snapshot.append(prev_lon[point_index])

                    prev_lat[point_index] = current_point.to_lat_lon()[0]
                    prev_lon[point_index] = current_point.to_lat_lon()[1]

            write_xyz_file(
                '{:s}/gridding_input/gridding_input_{:0.1f}Ma.xy'.format(
                    grd_output_dir,
                    topology_reconstruction.get_current_time()),
                zip(curr_longitudes, curr_latitudes, seafloor_age,
                    birth_lat_snapshot, point_id_snapshot))

        if not topology_reconstruction.reconstruct_to_next_time():
            break

    print('done')
    return
コード例 #28
0
def get_initial_ocean_seeds(topology_features,
                            input_rotation_filenames,
                            COBterrane_file,
                            output_directory,
                            time,
                            initial_ocean_mean_spreading_rate,
                            initial_ocean_healpix_sampling,
                            area_threshold,
                            mask_sampling=0.5):
    # Get a set of points at the oldest time for a reconstruction sequence, such that the points
    # populate the ocean basins (defined using the COB Terrane polygons) and are assigned ages assuming
    # a uniform average spreading rate combined with the distance of each point to the nearest
    # MidOceanRidge feature in the resolved plate boundary of the the plate containing the point

    print(
        'Begin creating seed points for initial ocean at reconstruction start time....'
    )

    rotation_model = pygplates.RotationModel(input_rotation_filenames)

    cobter = get_merged_cob_terrane_polygons(COBterrane_file, rotation_model,
                                             time, mask_sampling,
                                             area_threshold)

    ocean_points = pg.rasterise_paleogeography(
        cobter,
        rotation_model,
        time,
        sampling=initial_ocean_healpix_sampling,
        meshtype='healpix',
        masking='Inside')
    #ocean_points = rasterise_polygons(cobter, rotation_model,time,
    #                                  sampling=initial_ocean_healpix_sampling, meshtype='healpix',
    #                                  masking='Inside')

    resolved_topologies = []
    shared_boundary_sections = []
    pygplates.resolve_topologies(topology_features, rotation_model,
                                 resolved_topologies, time,
                                 shared_boundary_sections)

    pX, pY, pZ = pg.find_distance_to_nearest_ridge(resolved_topologies,
                                                   shared_boundary_sections,
                                                   ocean_points)

    # divide spreading rate by 2 to use half spreading rate
    pAge = np.array(pZ) / (initial_ocean_mean_spreading_rate / 2.)

    initial_ocean_point_features = []

    for point in zip(pX, pY, pAge):

        point_feature = pygplates.Feature()
        point_feature.set_geometry(pygplates.PointOnSphere(point[1], point[0]))

        # note that we add 'time' to the age at the time of computation
        # to get the valid time in Ma
        point_feature.set_valid_time(point[2] + time, -1)
        initial_ocean_point_features.append(point_feature)

    pygplates.FeatureCollection(initial_ocean_point_features).write(
        '{:s}/age_from_distance_to_mor_{:0.2f}Ma.gmt'.format(
            output_directory, time))

    print('done')
コード例 #29
0
def reconstruct_feature_collection(request):

    if request.method == 'POST':
        params = request.POST
    elif request.method == 'GET':
        params = request.GET
    else:
        return HttpResponseBadRequest('Unrecognized request type')

    anchor_plate_id = params.get('pid', 0)

    if 'time' in params:
        time = params['time']
    elif 'geologicage' in params:
        time = params['geologicage']
    else:
        time = 140 #default reconstruction age

    output_format = params.get('output', 'geojson')
    fc_str = params.get('feature_collection')
    model = str(params.get('model',settings.MODEL_DEFAULT))
    
    if 'keep_properties' in params:
        keep_properties = True
    else:
        keep_properties = False

    try:
        timef = float(time)
    except:
        return HttpResponseBadRequest('The "time" parameter is invalid ({0}).'.format(time))

    try:
        anchor_plate_id = int(anchor_plate_id)
    except:
        return HttpResponseBadRequest('The "pid" parameter is invalid ({0}).'.format(anchor_plate_id))
 
    # Convert geojson input to gplates feature collection
    features=[]
    try:
        fc = json.loads(fc_str)#load the input feature collection
        for f in fc['features']:
            geom = f['geometry']
            feature = pygplates.Feature()
            if geom['type'] == 'Point':
                feature.set_geometry(pygplates.PointOnSphere(
                    float(geom['coordinates'][1]),
                    float(geom['coordinates'][0])))
            if geom['type'] == 'LineString':
                feature.set_geometry(
                    pygplates.PolylineOnSphere([(point[1],point[0]) for point in geom['coordinates']]))
            if geom['type'] == 'Polygon':
                feature.set_geometry(
                    pygplates.PolygonOnSphere([(point[1],point[0]) for point in geom['coordinates'][0]]))
            if geom['type'] == 'MultiPoint':
                 feature.set_geometry(
                    pygplates.MultiPointOnSphere([(point[1],point[0]) for point in geom['coordinates']]))
            
            if keep_properties and 'properties' in f:
                for pk in f['properties']:           
                    p = f['properties'][pk] 
                    if isinstance(p, str):
                        p=str(p) 
                    feature.set_shapefile_attribute(str(pk),p)
            
            features.append(feature)
    except Exception as e:
        #print e
        return HttpResponseBadRequest('Invalid input feature collection')

    model_dict = get_reconstruction_model_dict(model)
    if not model_dict:
        return HttpResponseBadRequest('The "model" ({0}) cannot be recognized.'.format(model))

    rotation_model = pygplates.RotationModel([str('%s/%s/%s' %
        (settings.MODEL_STORE_DIR,model,rot_file)) for rot_file in model_dict['RotationFile']])

    assigned_features = pygplates.partition_into_plates(
        settings.MODEL_STORE_DIR+model+'/'+model_dict['StaticPolygons'],
        rotation_model,
        features,
        properties_to_copy = [
            pygplates.PartitionProperty.reconstruction_plate_id,
            pygplates.PartitionProperty.valid_time_period],
        partition_method = pygplates.PartitionMethod.most_overlapping_plate
    )

    reconstructed_geometries = []
    pygplates.reconstruct(assigned_features, 
        rotation_model, 
        reconstructed_geometries, 
        timef, 
        anchor_plate_id=anchor_plate_id)

    # convert feature collection back to geojson
    data = {"type": "FeatureCollection"}
    data["features"] = []
    for g in reconstructed_geometries:
        geom =  g.get_reconstructed_geometry()
        feature = {"type": "Feature"}
        feature["geometry"] = {}
        if isinstance(geom, pygplates.PointOnSphere):
            feature["geometry"]["type"] = "Point"
            p = geom.to_lat_lon_list()[0]
            feature["geometry"]["coordinates"] = [p[1], p[0]]
        elif isinstance(geom, pygplates.MultiPointOnSphere):
            feature["geometry"]["type"] = 'MultiPoint'
            feature["geometry"]["coordinates"] = [[lon,lat] for lat, lon in geom.to_lat_lon_list()]
        elif isinstance(geom, pygplates.PolylineOnSphere):
            feature["geometry"]["type"] = 'LineString'
            feature["geometry"]["coordinates"] = [[lon,lat] for lat, lon in geom.to_lat_lon_list()]
        elif isinstance(geom, pygplates.PolygonOnSphere):
            feature["geometry"]["type"] = 'Polygon'
            feature["geometry"]["coordinates"] = [[[lon,lat] for lat, lon in geom.to_lat_lon_list()]]
        else:
            return HttpResponseServerError('Unsupported Geometry Type.')

        feature["properties"] = {}
        if keep_properties:
            for pk in g.get_feature().get_shapefile_attributes():
                feature["properties"][pk] = g.get_feature().get_shapefile_attribute(pk)
        #print feature["properties"]
        data["features"].append(feature)

    ret = json.dumps(pretty_floats(data))
    
    #add header for CORS
    #http://www.html5rocks.com/en/tutorials/cors/
    response = HttpResponse(ret, content_type='application/json')
    #TODO:
    response['Access-Control-Allow-Origin'] = '*'
    return response
コード例 #30
0
def reconstruct_files(request):
    if not request.method == "POST":
        return HttpResponseBadRequest('expecting post requests!')
    try:
        print((request.FILES))
        if not len(list(request.FILES.items())):
            return HttpResponseBadRequest("No File Received")

        if not os.path.isdir(settings.MEDIA_ROOT + "/rftmp"):
            os.makedirs(settings.MEDIA_ROOT + "/rftmp" )

        reconstructable_files = []
        
        for fs in request.FILES.lists():
            for f in fs[1]:
                print((f.name))
                (name,ext) = os.path.splitext(f.name)
                if ext in ['.shp', '.gpml','.gpmlz']:
                    reconstructable_files.append(f.name)
                with open(settings.MEDIA_ROOT + "/rftmp/" + f.name, 'wb+') as fp:
                    for chunk in f.chunks():
                        fp.write(chunk)

        time = request.POST.get('time', None)
        model = request.POST.get('model',settings.MODEL_DEFAULT)
        print(model)

        model_dict = get_reconstruction_model_dict(model)

        if not model_dict:
            return HttpResponseBadRequest('The "model" ({0}) cannot be recognized.'.format(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']))

        for f in reconstructable_files:
            #print(f)
            features = pygplates.partition_into_plates(
                static_polygons_filename,        
                rotation_model,
                (settings.MEDIA_ROOT + "/rftmp/" + f).encode("utf-8"),
                partition_method = pygplates.PartitionMethod.most_overlapping_plate,
                properties_to_copy = [pygplates.PartitionProperty.reconstruction_plate_id, 
                                      pygplates.PartitionProperty.valid_time_period]
            )

            feature_collection = pygplates.FeatureCollection(features)
            feature_collection.write((settings.MEDIA_ROOT + "/rftmp/" + f+'.partitioned.gpml').encode("utf-8"))

            if not os.path.isdir(settings.MEDIA_ROOT + "/rftmp/dst/"):
                os.makedirs(settings.MEDIA_ROOT + "/rftmp/dst/" )

            pygplates.reconstruct((settings.MEDIA_ROOT + "/rftmp/" + f+'.partitioned.gpml').encode("utf-8"), 
                                  rotation_model, 
                                  ((settings.MEDIA_ROOT + "/rftmp/dst/" + f + '_' + model + '_' + str(time) + 'Ma').replace('.','_') + '.shp').encode("utf-8"), 
                                  float(time))

        s = io.StringIO()
        zf = zipfile.ZipFile(s, "w")

        #settings.MEDIA_ROOT + '/rftmp/dst/reconstructed_files.zip', 'w', zipfile.ZIP_DEFLATED)
        for r, d, files in os.walk(settings.MEDIA_ROOT + "/rftmp/dst/"):
            if not files:
                return HttpResponseServerError('No output files have been created!') 
            for f in files:
                zf.write(os.path.join(r, f), 'reconstructed_files/'+f)
        zf.close()
        #f = StringIO(file(settings.MEDIA_ROOT + '/rftmp/dst/reconstructed_files.zip', "rb").read())

        response = HttpResponse(s.getvalue(), content_type = 'application/x-zip-compressed')
        response['Content-Disposition'] = 'attachment; filename=reconstructed_files.zip'
        
        #clear_folder(settings.MEDIA_ROOT + "/rftmp" )
        #clear_folder(settings.MEDIA_ROOT + "/rftmp/dst")
        return response
    except:
        clear_folder(settings.MEDIA_ROOT + "/rftmp" )
        clear_folder(settings.MEDIA_ROOT + "/rftmp/dst")
        traceback.print_stack()
        traceback.print_exc(file=sys.stdout)
        err = traceback.format_exc()
        return HttpResponseBadRequest(err)