コード例 #1
0
def write_intxt(input_object, output_file, label=None):
    ofile = open(output_file, 'w');
    if label:
        ofile.write(label);
    ofile.write("# General: poissons_ratio friction_coef lon_min lon_max lon_zero lat_min lat_max lat_zero\n");
    ofile.write("# Source_Patch: strike rake dip length_km width_km lon lat depth_km slip_m\n");
    ofile.write("# Receiver: strike rake dip length_km width_km lon lat depth_km\n\n");
    ofile.write("General: %f %f %f %f %f %f %f %f \n" % (input_object.PR1, input_object.FRIC, input_object.minlon,
                                                         input_object.maxlon, input_object.zerolon, input_object.minlat,
                                                         input_object.maxlat, input_object.zerolat) );
    for src in input_object.source_object:
        if not src.potency:  # write a finite source
            L = fault_vector_functions.get_strike_length(src.xstart, src.xfinish, src.ystart, src.yfinish);  # in km
            W = fault_vector_functions.get_downdip_width(src.top, src.bottom, src.dipangle);  # in km
            fault_lon, fault_lat = fault_vector_functions.xy2lonlat(src.xstart, src.ystart, src.zerolon, src.zerolat);
            slip = fault_vector_functions.get_vector_magnitude([src.rtlat, src.reverse]);  # in m
            ofile.write("Source_Patch: %f %f %f %f %f %f %f %f %f\n" % (src.strike, src.rake, src.dipangle, L, W,
                                                                        fault_lon, fault_lat, src.top, slip));
        if src.potency:   # write a focal mechanism source
            continue;   # still working on this.
    for rec in input_object.receiver_object:
        L = fault_vector_functions.get_strike_length(rec.xstart, rec.xfinish, rec.ystart, rec.yfinish);  # in km
        W = fault_vector_functions.get_downdip_width(rec.top, rec.bottom, rec.dipangle);  # in km
        fault_lon, fault_lat = fault_vector_functions.xy2lonlat(rec.xstart, rec.ystart, rec.zerolon, rec.zerolat);
        ofile.write("Receiver: %f %f %f %f %f %f %f %f \n" % (rec.strike, rec.rake, rec.dipangle, L, W, fault_lon,
                                                              fault_lat, rec.top) );
    ofile.close();
    print("Writing file %s " % output_file);
    return;
コード例 #2
0
def write_stress_results_slippy_format(faults_list, shear, normal, coulomb,
                                       outfile):
    """
    :param faults_list: a list of fault dictionaries
    :param outfile: name of output file.
    :param shear: list of shear stress change on each element, kpa
    :param normal: list of normal stress, kpa
    :param coulomb: list of coulomb stress, kpa
    Caveat: This is ALMOST slippy format.
    You will lose the fault segment number, and we add the rake column.
    """
    print("Writing file %s " % outfile)
    ofile = open(outfile, 'w')
    ofile.write(
        "# lon[degrees] lat[degrees] depth[m] strike[degrees] dip[degrees] rake[degrees] length[m] width[m] "
        "shear[KPa] normal[KPa] coulomb[KPa]\n")
    for i, item in enumerate(faults_list):
        x_center, y_center = fault_vector_functions.add_vector_to_point(
            0, 0, item["length"] / 2, item["strike"])
        center_lon, center_lat = fault_vector_functions.xy2lonlat(
            x_center, y_center, item["lon"], item["lat"])
        ofile.write("%f %f %f " %
                    (center_lon, center_lat, item["depth"] * -1000))
        ofile.write(
            "%f %f %f %f %f %f %f %f \n" %
            (item["strike"], item["dip"], item["rake"], item["length"] * 1000,
             item["width"] * 1000, shear[i], normal[i], coulomb[i]))
    ofile.close()
    return
コード例 #3
0
def write_slippy_distribution(faults_list, outfile):
    """
    :param faults_list: a list of fault dictionaries
    :param outfile: name of output file.
    Caveat: can only do one fault segment right now.  That part of the read/write cycle is lossy.
    """
    print("Writing file %s " % outfile)
    ofile = open(outfile, 'w')
    ofile.write(
        "# lon[degrees] lat[degrees] depth[m] strike[degrees] dip[degrees] length[m] width[m] left-lateral[m] "
        "thrust[m] tensile[m] segment_num\n")
    for item in faults_list:
        x_center, y_center = fault_vector_functions.add_vector_to_point(
            0, 0, item["length"] / 2, item["strike"])
        center_lon, center_lat = fault_vector_functions.xy2lonlat(
            x_center, y_center, item["lon"], item["lat"])
        rtlat_slip, dip_slip = fault_vector_functions.get_rtlat_dip_slip(
            item["slip"], item["rake"])
        tensile_slip = 0
        ofile.write("%f %f %f " %
                    (center_lon, center_lat, item["depth"] * -1000))
        ofile.write(
            "%f %f %f %f %f %f %f 0 \n" %
            (item["strike"], item["dip"], item["length"] * 1000,
             item["width"] * 1000, -1 * rtlat_slip, dip_slip, tensile_slip))
    ofile.close()
    return
コード例 #4
0
def get_receiver_profile(line):
    """
    Create a horizontal profile based on the provided params.
    'Receiver_Horizontal_Profile: depth strike dip rake centerlon centerlat length_km width_km inc_km'
    """
    [depth, strike, dip, rake, centerlon, centerlat, length, width, inc] = [float(i) for i in line.split()[1:10]];
    startlon = fault_vector_functions.xy2lonlat(-length, 0, centerlon, centerlat)[0];
    endlon = fault_vector_functions.xy2lonlat(length, 0, centerlon, centerlat)[0];
    startlat = fault_vector_functions.xy2lonlat(0, -width, centerlon, centerlat)[1];
    endlat = fault_vector_functions.xy2lonlat(0, width, centerlon, centerlat)[1];
    lonpts = np.arange(startlon, endlon, inc/111.00);
    latpts = np.arange(startlat, endlat, inc/111.00);
    X, Y = np.meshgrid(lonpts, latpts);
    lon1d = np.reshape(X, (np.size(X),));
    lat1d = np.reshape(Y, (np.size(X),));
    horiz_profile = cc.Receiver_Horiz_Profile(depth_km=depth, strike=strike, dip=dip, rake=rake, centerlon=centerlon,
                                              centerlat=centerlat, lon1d=lon1d, lat1d=lat1d, shape=np.shape(X));
    return horiz_profile;
コード例 #5
0
def get_updip_corners_lon_lat(fault_dict_object):
    """
    Return the lon/lat of 2 shallow corners of a fault_dict_object
    """
    [source] = fault_dict_to_coulomb_fault([fault_dict_object])
    [_, _, x_updip, y_updip] = conversion_math.get_fault_four_corners(source)
    lons, lats = fault_vector_functions.xy2lonlat(x_updip, y_updip,
                                                  source.zerolon,
                                                  source.zerolat)
    return lons, lats
コード例 #6
0
def get_four_corners_lon_lat(fault_dict_object):
    """
    Return the lon/lat of all 4 corners of a fault_dict_object
    """
    [source] = fault_dict_to_coulomb_fault([fault_dict_object])
    [x_total, y_total, _, _] = conversion_math.get_fault_four_corners(source)
    lons, lats = fault_vector_functions.xy2lonlat(x_total, y_total,
                                                  source.zerolon,
                                                  source.zerolat)
    return lons, lats
コード例 #7
0
def annotate_figure_with_sources(fig,
                                 inputs,
                                 params,
                                 fmscale="0.3c",
                                 dotstyle="s0.3c"):
    """
    Draw each source in inputs.source_object, a list of sources
    Inputs and Params provide additional information about the calcuation.
    dotstyle is for source dots
    fmscale is for focal mechanism size
    """
    # Draw dots for EQ sources
    eq_lon, eq_lat = [], []
    for source in inputs.source_object:
        source_lon, source_lat = fault_vector_functions.xy2lonlat(
            source.xstart, source.ystart, inputs.zerolon, inputs.zerolat)
        eq_lon.append(source_lon)
        eq_lat.append(source_lat)
    fig.plot(eq_lon, eq_lat, style=dotstyle, color="purple", pen="thin,black")

    for source in inputs.source_object:
        [x_total, y_total, _,
         _] = conversion_math.get_fault_four_corners(source)
        lons, lats = fault_vector_functions.xy2lonlat(x_total, y_total,
                                                      inputs.zerolon,
                                                      inputs.zerolat)
        if not source.potency:  # in case of area sources, outline the fault patches
            fig.plot(x=lons, y=lats, pen="thick,black")
        else:  # in case of point sources, draw focal mechanisms
            mag = io_intxt.get_mag_from_dc_potency(source.potency, params.mu,
                                                   source.rake)
            focal_mechanism = dict(strike=source.strike,
                                   dip=source.dipangle,
                                   rake=source.rake,
                                   magnitude=mag)
            fig.meca(focal_mechanism,
                     scale=fmscale,
                     longitude=lons[0],
                     latitude=lats[0],
                     depth=source.top)
    return fig
コード例 #8
0
def read_slippy_distribution(infile, desired_segment=-1):
    """
    Read a file from the Slippy inversion outputs (lon[degrees] lat[degrees] depth[m] strike[degrees] dip[degrees]
    length[m] width[m] left-lateral[m] thrust[m] tensile[m] segment_num) into a list of fault dictionaries.
    Lon/lat usually refer to the center top of the fault, so it must convert the lon/lat to the top left corner.

    :param infile: name of input slip distribution file
    :type infile: string
    :param desired_segment: starting at 0, which fault segment do we want to return? default of -1 means all.
    :type desired_segment: int
    :returns: list of fault dictionaries
    :rtype: list
    """
    print("Reading slippy distribution %s " % infile)
    fault_list = []
    [
        lon, lat, depth, strike, dip, length, width, ll_slip, thrust_slip, _,
        num
    ] = np.loadtxt(infile,
                   skiprows=1,
                   unpack=True,
                   dtype={
                       "names":
                       ('lon', 'lat', 'depth', 'strike', 'dip', 'length',
                        'width', 'ss', 'ds', 'tensile', 'num'),
                       "formats": (float, float, float, float, float, float,
                                   float, float, float, float, float)
                   })
    for i in range(len(lon)):
        if desired_segment == -1 or desired_segment == num[i]:
            one_fault = {
                "strike": strike[i],
                "dip": dip[i],
                "length": length[i] / 1000,
                "width": width[i] / 1000,
                "depth": -depth[i] / 1000
            }
            center_lon = lon[i]
            center_lat = lat[i]
            x_start, y_start = fault_vector_functions.add_vector_to_point(
                0, 0, one_fault["length"] / 2, one_fault["strike"] - 180)
            # in km
            corner_lon, corner_lat = fault_vector_functions.xy2lonlat(
                x_start, y_start, center_lon, center_lat)
            one_fault["lon"] = corner_lon
            one_fault["lat"] = corner_lat
            one_fault["rake"] = fault_vector_functions.get_rake(
                rtlat_strike_slip=-ll_slip[i], dip_slip=thrust_slip[i])
            one_fault["slip"] = fault_vector_functions.get_total_slip(
                ll_slip[i], thrust_slip[i])
            one_fault["tensile"] = 0
            fault_list.append(one_fault)
    return fault_list
コード例 #9
0
def write_synthetic_grid_full_results(x, y, x2d, y2d, zerolon, zerolat, u, v,
                                      w, outdir):
    ofile = open(outdir + 'disps_model_grid.txt', 'w')
    ofile.write("# Format: x y lon lat udisp vdisp wdisp (m) \n")
    for i in np.arange(0, len(y)):
        for j in np.arange(0, len(x)):
            loni, lati = fault_vector_functions.xy2lonlat(
                x2d[i][j], y2d[i][j], zerolon, zerolat)
            ofile.write(
                "%f %f %f %f %f %f %f\n" %
                (x2d[i][j], y2d[i][j], loni, lati, u[i][j], v[i][j], w[i][j]))
    ofile.close()
    return
コード例 #10
0
def read_stress_slippy_format(infile):
    """
    Read stress results from CFS calculation
    :param infile: text file in full-stress format
    :returns: fault_list (internal dictionary format). shear, normal, and coulomb are matching lists in KPa
    """
    print("Reading file %s " % infile)
    fault_list = []
    [
        lon, lat, depth, strike, dip, rake, length, width, shear, normal,
        coulomb
    ] = np.loadtxt(infile,
                   skiprows=1,
                   unpack=True,
                   dtype={
                       "names":
                       ('lon', 'lat', 'depth', 'strike', 'dip', 'rake',
                        'length', 'width', 'shear', 'normal', 'coulomb'),
                       "formats": (float, float, float, float, float, float,
                                   float, float, float, float, float, float)
                   })
    for i in range(len(lon)):
        one_fault = {
            "strike": strike[i],
            "dip": dip[i],
            "length": length[i] / 1000,
            "width": width[i] / 1000,
            "depth": -depth[i] / 1000
        }
        center_lon = lon[i]
        center_lat = lat[i]
        x_start, y_start = fault_vector_functions.add_vector_to_point(
            0, 0, one_fault["length"] / 2, one_fault["strike"] - 180)
        # in km
        corner_lon, corner_lat = fault_vector_functions.xy2lonlat(
            x_start, y_start, center_lon, center_lat)
        one_fault["lon"] = corner_lon
        one_fault["lat"] = corner_lat
        one_fault["rake"] = rake[i]
        one_fault["slip"] = 0
        one_fault["tensile"] = 0
        fault_list.append(one_fault)

    return fault_list, shear, normal, coulomb
コード例 #11
0
def write_synthetic_grid_triplets(x, y, x2d, y2d, zerolon, zerolat, u, v, w,
                                  outdir):
    """
    Write lists of lon/lat/def for each component of deformation in synthetic grid
    Used for GMT plots
    """
    ofile_w = open(outdir + 'xyz_model.txt', 'w')
    ofile_u = open(outdir + 'xyu_model.txt', 'w')
    ofile_v = open(outdir + 'xyv_model.txt', 'w')
    for i in np.arange(0, len(y)):
        for j in np.arange(0, len(x)):
            loni, lati = fault_vector_functions.xy2lonlat(
                x2d[i][j], y2d[i][j], zerolon, zerolat)
            ofile_w.write("%f %f %f\n" % (loni, lati, w[i][j]))
            ofile_u.write("%f %f %f\n" % (loni, lati, u[i][j]))
            ofile_v.write("%f %f %f\n" % (loni, lati, v[i][j]))
    ofile_w.close()
    ofile_u.close()
    ofile_v.close()
    return
コード例 #12
0
def write_faults_json(faults_list, outfile):
    """
    Writes faults to json as receivers with zero slip
    position is lon/lat/depth in meters (negative means below surface)

    :param faults_list: list of fault dictionaries
    :type faults_list: list
    :param outfile: name of output json file
    :type outfile: string
    """
    output = {}
    for k, fault in enumerate(faults_list):
        # Convert the fault (which has top left corner) into a fault with top center coordinate
        label = "fault" + str(k)
        newfault = {}

        corner_lon = fault["lon"]
        corner_lat = fault["lat"]
        x_center, y_center = fault_vector_functions.add_vector_to_point(
            0, 0, fault["length"] / 2, fault["strike"])
        center_lon, center_lat = fault_vector_functions.xy2lonlat(
            x_center, y_center, corner_lon, corner_lat)

        newfault["strike"] = fault["strike"]
        newfault["dip"] = fault["dip"]
        newfault["length"] = fault["length"] * 1000
        newfault["width"] = fault["width"] * 1000
        newfault["basis1"] = [1, 0, 0]
        newfault["basis2"] = None
        newfault["Nlength"] = 1
        newfault["Nwidth"] = 1
        newfault["penalty"] = 1
        newfault["position"] = [
            center_lon, center_lat, -fault["depth"] * 1000
        ]
        output[label] = newfault
    with open(outfile, 'w') as ofile:
        json.dump(output, ofile, indent=4)
    return
コード例 #13
0
def read_faults_json(infile):
    """
    Read all faults from a json file (just geometry; no slip or rake) into a list of fault dictionaries.
    It has to convert from fault center to fault corner.
    Faults read from JSON have zero slip.

    :param infile: name of input json file
    :type infile: string
    :returns: list of fault dictionaries
    :rtype: list
    """
    fault_list = []
    config_file = open(infile, 'r')
    config = json.load(config_file)
    for key in config.keys():
        one_fault = {
            "strike": config[key]["strike"],
            "dip": config[key]["dip"],
            "length": config[key]["length"] / 1000.0,
            "width": config[key]["width"] / 1000.0
        }
        center_lon = config[key]["position"][0]
        center_lat = config[key]["position"][1]
        x_start, y_start = fault_vector_functions.add_vector_to_point(
            0, 0, one_fault["length"] / 2, one_fault["strike"] - 180)
        # in km
        corner_lon, corner_lat = fault_vector_functions.xy2lonlat(
            x_start, y_start, center_lon, center_lat)
        #
        one_fault["lon"] = corner_lon
        one_fault["lat"] = corner_lat
        one_fault["depth"] = -config[key]["position"][2] / 1000
        one_fault["rake"] = 0
        one_fault["slip"] = 0
        one_fault["tensile"] = 0
        fault_list.append(one_fault)
    config_file.close()
    return fault_list
コード例 #14
0
def coulomb_fault_to_fault_dict(source_object):
    """Convert a list of fault objects from Elastic_stresses_py into a list of internal dictionary objects"""
    fault_dict_list = []
    for src in source_object:
        if src.potency:
            print(
                "ERROR! Cannot convert a point source into a rectangular source. Skipping..."
            )
            continue
        one_fault = {
            "strike":
            src.strike,
            "dip":
            src.dipangle,
            "depth":
            src.top,
            "rake":
            fault_vector_functions.get_rake(rtlat_strike_slip=src.rtlat,
                                            dip_slip=src.reverse),
            "slip":
            fault_vector_functions.get_total_slip(src.rtlat, src.reverse),
            "tensile":
            src.tensile,
            "length":
            fault_vector_functions.get_strike_length(src.xstart, src.xfinish,
                                                     src.ystart, src.yfinish),
            "width":
            fault_vector_functions.get_downdip_width(src.top, src.bottom,
                                                     src.dipangle)
        }
        lon, lat = fault_vector_functions.xy2lonlat(src.xstart, src.ystart,
                                                    src.zerolon, src.zerolat)
        one_fault["lon"] = lon
        one_fault["lat"] = lat
        fault_dict_list.append(one_fault)
    return fault_dict_list
コード例 #15
0
def read_srcmod_distribution(infile):
    """
    Let's assume that the lon/lat/depth given in the SRCMOD .fsp file is for the top center of the fault patch.
    This function doesn't have a unit test yet.

    :param infile: name of input slip distribution file, defined to be the '.fsp' file
    :type infile: string
    :returns: list of fault dictionaries
    :rtype: list
    """
    print("Reading SRCMOD distribution %s " % infile)
    fault_list = []
    overall_strike, overall_dip, total_len_km, nx, total_width_km, nz = 0, 90, 10, 10, 10, 10
    # defaults.
    ifile = open(infile, 'r')
    for line in ifile:
        temp = line.split()
        if len(temp) > 3:
            if temp[0] == '%' and temp[1] == 'Mech':
                overall_strike = float(temp[5])
                overall_dip = float(temp[8])
            if temp[0] == '%' and temp[1] == 'Size':
                total_len_km = float(temp[5])
                total_width_km = float(temp[9])
            if temp[0] == '%' and temp[3] == 'Nx':
                nx = int(temp[5])
                nz = int(temp[8])
            if temp[0] != '%':
                lon_top_center = float(temp[1])
                lat_top_center = float(temp[0])
                depth_top_center = float(temp[4])
                depth_top, _ = fault_vector_functions.get_top_bottom_from_center(
                    depth_top_center, total_width_km / nz, overall_dip)
                slip_m = float(temp[5])
                rake = float(temp[6])
                one_fault = {
                    "strike": overall_strike,
                    "dip": overall_dip,
                    "length": total_len_km / nx,
                    "width": total_width_km / nz,
                    "depth": depth_top_center,
                    "rake": rake,
                    "slip": slip_m,
                    "tensile": 0
                }
                x_start, y_start = fault_vector_functions.add_vector_to_point(
                    0, 0, one_fault["length"] / 2, one_fault["strike"] - 180)
                # in km
                _downdip_width_proj = one_fault["width"] * np.cos(
                    np.deg2rad(overall_dip))
                # x_start, y_start = fault_vector_functions.add_vector_to_point(x_start, y_start, downdip_width_proj/2,
                #                                                               one_fault["strike"] - 90);
                # ^^ offset the fault location for center. Optional/unknown.
                corner_lon, corner_lat = fault_vector_functions.xy2lonlat(
                    x_start, y_start, lon_top_center, lat_top_center)
                one_fault["lon"] = corner_lon
                one_fault["lat"] = corner_lat
                fault_list.append(one_fault)
    ifile.close()
    print("  -->Returning %d fault segments" % len(fault_list))
    return fault_list
コード例 #16
0
def map_stress_plot(params, inputs, out_object, stress_component):
    """
    Using PyGMT
    Filling in fault patches with colors corresponding to their stress changes
    """
    if stress_component == 'shear':
        plotting_stress = out_object.receiver_shear
        label = 'Shear'
    elif stress_component == 'normal':
        plotting_stress = out_object.receiver_normal
        label = 'Normal'
    else:
        plotting_stress = out_object.receiver_coulomb
        # The default option
        label = 'Coulomb'

    if not out_object.receiver_object:
        return

    # Make stress bounds for color map.
    vmin, vmax = -1, 1
    [cmap_opts, cbar_opts] = utilities.define_colorbar_series(plotting_stress,
                                                              vmin=vmin,
                                                              vmax=vmax)

    # Make cpt
    pygmt.makecpt(cmap="jet",
                  series=str(cmap_opts[0]) + "/" + str(cmap_opts[1]) + "/" +
                  str(cmap_opts[2]),
                  output="mycpt.cpt",
                  background=True)

    # Make Map
    region = [inputs.minlon, inputs.maxlon, inputs.minlat, inputs.maxlat]
    proj = "M7i"
    fig = pygmt.Figure()
    title = "+t\"" + stress_component + " stress\""
    # must put escaped quotations around the title.
    fig.basemap(region=region, projection=proj, frame=title)
    fig.coast(shorelines="1.0p,black",
              region=region,
              borders="1",
              projection=proj,
              frame="1.0")
    # the boundary.
    fig.coast(region=region,
              projection=proj,
              borders='2',
              shorelines='0.5p,black',
              water='white',
              map_scale="g-125.5/39.6+c1.5+w50")

    fig = annotate_figure_with_sources(fig, inputs, params)

    # Draw each receiver, with associated data
    for i in range(len(out_object.receiver_object)):
        rec = out_object.receiver_object[i]
        [x_total, y_total, _, _] = conversion_math.get_fault_four_corners(rec)
        lons, lats = fault_vector_functions.xy2lonlat(x_total, y_total,
                                                      inputs.zerolon,
                                                      inputs.zerolat)
        fig.plot(x=lons,
                 y=lats,
                 zvalue=str(plotting_stress[i]),
                 pen="thick,black",
                 color="+z",
                 cmap="mycpt.cpt")
        # color = stress

    # Colorbar annotation
    fig.coast(shorelines="1.0p,black", region=region, projection=proj)
    # the boundary.
    fig.colorbar(position="jBr+w3.5i/0.2i+o2.5c/1.5c+h",
                 cmap="mycpt.cpt",
                 shading="0.8",
                 truncate=str(cbar_opts[0]) + "/" + str(cbar_opts[1]),
                 frame=["x" + str(0.2), "y+L\"KPa\""])

    # Annotate with aftershock locations
    fig = annotate_figure_with_aftershocks(fig,
                                           aftershocks_file=params.aftershocks,
                                           style='c0.02c')

    fig.savefig(params.outdir + label + '_map.png')
    return