コード例 #1
0
def compute_prem_load(station_array, load_array, disk_radius, greensfunc, max_distance):
    # For a given station and a given set of loads,
    # Compute the loading on a PREM earth structure
    # Max distance is in degrees
    total_disp_x, total_disp_y, total_disp_v = [], [], [];
    for i in range(len(station_array.lon)):  # for each station...

        # Take a set of rectangular loads and tile them into disk loads.
        CircleLoads = get_disks(load_array, disk_radius, max_distance, station_array.lon[i], station_array.lat[i]);
        print("Number of circles: %d" % len(CircleLoads.lon));

        disk_sum_v, disk_sum_x, disk_sum_y = 0, 0, 0;
        for j in range(np.size(CircleLoads.lon)):
            dist_from_center = haversine.distance([CircleLoads.lat[j], CircleLoads.lon[j]],
                                                  [station_array.lat[i], station_array.lon[i]]);  # reported in km
            myindex = find_closest_greens(greensfunc.km,
                                          dist_from_center);  # find the nearest answer in the Green's functions
            vdisp = greensfunc.vload[myindex];  # in m
            hdisp = greensfunc.hload[myindex];  # in m
            [xdisp, ydisp] = az_decompose(hdisp, (station_array.lat[i], station_array.lon[i]), (
                CircleLoads.lat[j], CircleLoads.lon[j]));  # Decompose radial into x and y components

            disk_sum_v = disk_sum_v + vdisp * CircleLoads.pressure[
                j] * 1000 / 9.81;  # THIS SHOULD BE DIVIDED BY 9.81! the PREM code already has it. Result in mm
            disk_sum_x = disk_sum_x + xdisp * CircleLoads.pressure[
                j] * 1000 / 9.81;  # THIS SHOULD BE DIVIDED BY 9.81! the PREM code already has it. Result in mm
            disk_sum_y = disk_sum_y + ydisp * CircleLoads.pressure[
                j] * 1000 / 9.81;  # THIS SHOULD BE DIVIDED BY 9.81! the PREM code already has it. Result in mm

        total_disp_x.append(disk_sum_x);
        total_disp_y.append(disk_sum_y);
        total_disp_v.append(disk_sum_v);
    return total_disp_x, total_disp_y, total_disp_v;  # should exactly match length of input station_array fields.
コード例 #2
0
def evaluate_gradients(point1, point2, ascending1, ascending2, descending1,
                       descending2):
    mydistance = haversine.distance([point1[1], point1[0]],
                                    [point2[1], point2[0]])
    print(
        "Gradient in ASCENDING track from point1 to point2: %f mm/yr in %f km "
        % (np.abs(ascending1 - ascending2), mydistance))
    print("Equal to: %f mm/yr per 100 km \n" %
          (100 * np.abs(ascending1 - ascending2) / mydistance))
    print(
        "Gradient in DESCENDING track from point1 to point2: %f mm/yr in %f km "
        % (np.abs(descending1 - descending2), mydistance))
    print("Equal to: %f mm/yr per 100 km \n" %
          (100 * np.abs(descending1 - descending2) / mydistance))
    return
コード例 #3
0
def compute_circle(myVelfield, center, radius):
    close_stations = []
    rad_distance = []
    lon, lat = [], []
    for station_vel in myVelfield:
        mydist = haversine.distance([center[1], center[0]],
                                    [station_vel.nlat, station_vel.elon])
        if mydist <= radius:
            rad_distance.append(mydist)
            lon.append(station_vel.elon)
            lat.append(station_vel.nlat)
            close_stations.append(station_vel.name)
    print("Returning %d stations within %.3f km of %.4f, %.4f" %
          (len(close_stations), radius, center[0], center[1]))
    return close_stations, lon, lat, rad_distance
コード例 #4
0
def get_disks(load_array, disk_radius, threshold_distance, sta_lon, sta_lat):
    # threshold_distance is in degrees
    circle_lons, circle_lats, circle_radius, circle_pressure = [], [], [], [];
    threshold_distance = threshold_distance * (np.pi / 180) * 6370;  # converting to km  (6370km = 1 radian).
    circle_area = np.pi * disk_radius * disk_radius;  # Area = pi * r^2
    square_side_length = np.sqrt(circle_area);  # in same units as disk_radius

    for i in range(len(load_array.lon)):  # for each rectangular load cell
        if abs(load_array.lat[i]) > 85:  # ignoring the arctic and antarctic
            continue;
        dist_from_center = haversine.distance([load_array.lat[i], load_array.lon[i]],
                                              [sta_lat, sta_lon]);  # reported in km
        if dist_from_center < threshold_distance:
            # if the load cell is less than a certain distance from the station, discretize it.

            center = [load_array.lon[i], load_array.lat[i]];
            load_akm = load_array.east_width[i] * 111.0 * np.cos(center[1] * np.pi / 180);
            load_bkm = load_array.north_width[i] * 111.0;

            # The placement of each disk-shaped tile within the load
            n_tiles_x = int(np.floor(load_akm * 2 / square_side_length));
            n_tiles_y = int(np.floor(load_bkm * 2 / square_side_length));  # n tiles fitting in x and y dim of rectangle
            x_array, y_array = [], [];
            x_nodes = np.linspace(center[0] - load_array.east_width[i], center[0] + load_array.east_width[i],
                                  n_tiles_x + 1, endpoint=True);
            y_nodes = np.linspace(center[1] - load_array.north_width[i], center[1] + load_array.north_width[i],
                                  n_tiles_y + 1, endpoint=True);

            for j in range(len(x_nodes) - 1):
                x_array.append((x_nodes[j] + x_nodes[j + 1]) * 0.5);  # average of two nodes
            for j in range(len(y_nodes) - 1):
                y_array.append((y_nodes[j] + y_nodes[j + 1]) * 0.5);  # average of two nodes

            [centerx, centery] = np.meshgrid(x_array, y_array);
            centerx = np.reshape(centerx, (np.size(centerx), 1))
            centery = np.reshape(centery, (np.size(centery), 1))

            # HERE WE RE-PACKAGE INTO CIRCULAR LOADS
            for j in range(np.size(centerx)):
                circle_lons.append(centerx[j]);
                circle_lats.append(centery[j]);
                circle_radius.append(disk_radius);
                circle_pressure.append(load_array.pressure[i]);

    CircleLoads = helper_functions.Load_Array(lon=circle_lons, lat=circle_lats, east_width=circle_radius,
                                              north_width=[], pressure=circle_pressure);
    return CircleLoads;
コード例 #5
0
def create_los_rdr_geo_from_ground_ann_file(ann_file, x_axis, y_axis):
    # Make los.rdr.geo given .ann file from JPL website's UAVSAR interferograms and the ground-range sample points.
    # x-axis and y-axis are the x and y arrays where los vectors will be extracted on a corresponding grid.
    near_angle, far_angle, heading = jpl_uav_read_write.get_nearrange_farrange_heading_angles(
        ann_file)
    heading_cartesian = insar_vector_functions.bearing_to_cartesian(heading)
    # CCW from east
    print("Heading is %f degrees CW from north" % heading)
    print("Cartesian Heading is %f" % heading_cartesian)
    # Get the upper and lower left corners, so we can compute the length of the across-track extent in km
    ul_lon, ul_lat, ll_lon, ll_lat = jpl_uav_read_write.get_ground_range_left_corners(
        ann_file)

    cross_track_max = haversine.distance((ll_lat, ll_lon), (ul_lat, ul_lon))
    # in km

    # Get the azimuth angle for the pixels looking up to the airplane
    # My own documentation says CCW from north, even though that's really strange.
    azimuth = heading_cartesian - 90
    # 90 degrees to the right of the airplane heading
    # (for the look vector from ground to plane)
    azimuth = insar_vector_functions.cartesian_to_ccw_from_north(azimuth)
    # degrees CCW from North
    print("azimuth from ground to plane is:", azimuth)

    [X, Y] = np.meshgrid(x_axis, y_axis)
    (ny, nx) = np.shape(X)
    grid_az = azimuth * np.ones(np.shape(X))
    grid_inc = np.zeros(np.shape(X))

    print("Computing incidence angles for all pixels")
    for i in range(ny):
        for j in range(nx):
            xtp = cross_track_pos(X[i, j], Y[i, j], ll_lon, ll_lat,
                                  heading_cartesian)
            # THIS WILL HAVE TO CHANGE FOR ASCENDING AND DESCENDING
            inc = incidence_angle_trig(xtp, cross_track_max, near_angle,
                                       far_angle)
            grid_inc[i, j] = inc

    # Finally, write the 2 bands for los.rdr.geo
    isce_read_write.write_isce_unw(grid_inc, grid_az, nx, ny, "FLOAT",
                                   'los.rdr.geo')

    return
コード例 #6
0
def vert_adjust_by_reference_stations(names, coords, slope_obj):
    # How do we adjust the verticals for large-scale drought signatures?

    reference_station = 'P208'
    coord_box = [-123, -121, 39, 42]
    eq_coords = [-124.81, 40.53]
    radius = 250
    max_radius = 350
    reference_type = 'radius'  # options = 'radius','box','station'

    new_slope_obj = []
    background_slopes_before = []
    background_slopes_after = []

    for i in range(len(names)):
        if reference_type == 'station':
            if names[i] == reference_station:
                background_slopes_before.append(slope_obj[i][0])
                background_slopes_after.append(slope_obj[i][1])
        elif reference_type == 'box':
            if coord_box[0] < coords[i][0] < coord_box[1]:
                if coord_box[2] < coords[i][1] < coord_box[3]:
                    background_slopes_before.append(slope_obj[i][0])
                    background_slopes_after.append(slope_obj[i][1])
        elif reference_type == 'radius':
            mydistance = haversine.distance([coords[i][1], coords[i][0]],
                                            [eq_coords[1], eq_coords[0]])
            if radius < mydistance < max_radius:
                background_slopes_before.append(slope_obj[i][0])
                background_slopes_after.append(slope_obj[i][1])

    vert_reference_before = np.nanmean(background_slopes_before)
    vert_reference_after = np.nanmean(background_slopes_after)
    print("Vert slope before: %f " % vert_reference_before)
    print("Vert slope after: %f " % vert_reference_after)

    for i in range(len(slope_obj)):
        new_slope_obj.append([
            slope_obj[i][0] - vert_reference_before,
            slope_obj[i][1] - vert_reference_after, slope_obj[i][2]
        ])

    return new_slope_obj
コード例 #7
0
def cross_track_pos(target_lon, target_lat, nearrange_lon, nearrange_lat,
                    heading_cartesian):
    # Given the heading of a plane and the coordinates of one near-range point
    # Get the cross-track position of point in a coordinate system centered
    # at (nearrange_lon, nearrange_lat) with given heading
    distance = haversine.distance((target_lat, target_lon),
                                  (nearrange_lat, nearrange_lon))
    compass_bearing = haversine.calculate_initial_compass_bearing(
        (nearrange_lat, nearrange_lon), (target_lat, target_lon))
    # this comes CW from north
    theta = insar_vector_functions.bearing_to_cartesian(compass_bearing)
    # angle of position vector, cartesian coords
    # heading_cartesian is the angle between the east unit vector and the flight direction
    x0 = distance * np.cos(np.deg2rad(theta))
    y0 = distance * np.sin(np.deg2rad(theta))
    # in the east-north coordinate systeem
    x_prime, y_prime = insar_vector_functions.rotate_vector_by_angle(
        x0, y0, heading_cartesian)
    return y_prime
コード例 #8
0
def get_nearest_pixel_in_raster(raster_lon, raster_lat, target_lon, target_lat):
    """Take a raster (2d arrays with lat and lon)
    and find the grid location closest to the target location
    This could be optimized with a distance formula or walking algorithm in the future.
    """
    dist = np.zeros(np.shape(raster_lon));
    lon_shape = np.shape(raster_lon);
    for i in range(lon_shape[0]):
        for j in range(lon_shape[1]):
            mypt = [raster_lat[i][j], raster_lon[i][j]];
            dist[i][j] = haversine.distance((target_lat, target_lon), mypt);
    minimum_distance = np.nanmin(dist);
    if minimum_distance < 0.25:  # if we're inside the domain.
        idx = np.where(dist == np.nanmin(dist));
        i_found = idx[0][0];
        j_found = idx[1][0];
        print(raster_lon[i_found][j_found], raster_lat[i_found][j_found]);
    else:
        i_found, j_found = np.nan, np.nan;  # error codes
    return i_found, j_found, minimum_distance;
コード例 #9
0
def latlon2xy_single(loni, lati, lon0, lat0):
    """
    Convert lon/lat coordinate into cartesian x/y coordinate using reference point.

    :param loni: longitude of target point
    :type loni: float
    :param lati: latitude of target point
    :type lati: float
    :param lon0: longitude of reference point
    :type lon0: float
    :param lat0: latitude of reference point
    :type lat0: float
    :returns: x, y of target point, in km
    :rtype: float, float
    """
    radius = haversine.distance([lat0, lon0], [lati, loni])
    bearing = haversine.calculate_initial_compass_bearing((lat0, lon0),
                                                          (lati, loni))
    azimuth = 90 - bearing
    x = radius * np.cos(np.deg2rad(azimuth))
    y = radius * np.sin(np.deg2rad(azimuth))
    return x, y
コード例 #10
0
def get_nearest_pixel_in_raster(raster_lon, raster_lat, target_lon,
                                target_lat):
    """
    A very general function
    Take a 2D raster of lons and lats and find the grid location closest to the target location
    """
    dist = np.zeros(np.shape(raster_lon))
    lon_shape = np.shape(raster_lon)
    for i in range(lon_shape[0]):
        for j in range(lon_shape[1]):
            mypt = [raster_lat[i][j], raster_lon[i][j]]
            dist[i][j] = haversine.distance((target_lat, target_lon), mypt)
    minimum_distance = np.nanmin(dist)
    if minimum_distance < 0.25:  # if we're inside the domain.
        idx = np.where(dist == np.nanmin(dist))
        i_found = idx[0][0]
        j_found = idx[1][0]
        print(raster_lon[i_found][j_found], raster_lat[i_found][j_found])
    else:
        i_found, j_found = -1, -1
        # error codes
    return i_found, j_found
コード例 #11
0
def split_fault_trace(fault_trace, typical_spacing_km):
    """
    Algorithm: Walk up the fault in chunks.  If the chunk is smaller than typical_spacing_km, it becomes one segment.
    Otherwise we split the segment into something similar to typical_spacing_km.
    Returns: (starting lon, starting_lat, strike, length, ending_lon, ending_lat) for each fault trace segment
    """
    all_fault_segments = [];
    for i in range(1, len(fault_trace[0])):
        start_point = (fault_trace[1][i-1], fault_trace[0][i-1]);
        end_point = (fault_trace[1][i], fault_trace[0][i]);
        segment_distance = haversine.distance(start_point, end_point);
        strike = haversine.calculate_initial_compass_bearing(start_point, end_point);

        if segment_distance < typical_spacing_km:    # for the really small segments
            one_fault_segment = (fault_trace[0][i-1], fault_trace[1][i-1], strike, segment_distance,
                                 fault_trace[0][i], fault_trace[1][i]);
            all_fault_segments.append(one_fault_segment);

        else:   # the segments greater than 2x the characteristic spacing
            num_subsegments = int(np.ceil(segment_distance / typical_spacing_km));  # making segments < typical_spacing
            counter = [x for x in range(0, num_subsegments+1)];

            lon_difference = fault_trace[0][i] - fault_trace[0][i-1];
            lon_step = lon_difference / num_subsegments;
            lon_subarray = [fault_trace[0][i-1] + lon_step*x for x in counter];
            # for x subsegments, we have x+1 elements in lon_subarray

            lat_difference = fault_trace[1][i] - fault_trace[1][i-1];
            lat_step = lat_difference / num_subsegments;
            lat_subarray = [fault_trace[1][i-1] + lat_step*x for x in counter];

            for j in range(1, len(lon_subarray)):
                one_fault_segment = (lon_subarray[j-1], lat_subarray[j-1], strike, segment_distance/num_subsegments,
                                     lon_subarray[j], lat_subarray[j]);
                all_fault_segments.append(one_fault_segment);
    print("Meshed fault trace of %d segments into %d segments " % (len(fault_trace[0]), len(all_fault_segments)));
    return all_fault_segments;