def compute_params_for_WC_source(strike, dip, rake, depth, magnitude, faulting_type, fault_lon, fault_lat, zerolon, zerolat): [xcenter, ycenter] = conversion_math.latlon2xy(fault_lon, fault_lat, zerolon, zerolat) L = wells_and_coppersmith.RLD_from_M(magnitude, faulting_type) # rupture length W = wells_and_coppersmith.RW_from_M(magnitude, faulting_type) # rupture width slip = wells_and_coppersmith.rectangular_slip(L * 1000, W * 1000, magnitude) # must input in meters # xstart,ystart=conversion_math.add_vector_to_point(xcenter,ycenter,-L/2,strike[i]); # if the hypocenter is really the center of the rupture # xfinish,yfinish=conversion_math.add_vector_to_point(xcenter,ycenter,L/2,strike[i]); xstart, ystart = conversion_math.add_vector_to_point( xcenter, ycenter, 0, strike) # if the hypocenter is on one side of the rupture xfinish, yfinish = conversion_math.add_vector_to_point( xcenter, ycenter, L, strike) rtlat, reverse = conversion_math.get_rtlat_dip_slip(slip, rake) top, bottom = conversion_math.get_top_bottom(depth, W, dip) Kode = 100 comment = '' return [ xstart, xfinish, ystart, yfinish, Kode, rtlat, reverse, top, bottom, comment ]
def compute_params_for_source(strike, dip, rake, mag, eq_type, eqlon, eqlat, eqdep, zerolon, zerolat): xstart=[]; xfinish=[]; ystart=[]; yfinish=[]; Kode=[]; rtlat=[]; reverse=[]; top=[]; bottom=[]; comment=[]; # Useful when you have earthquake catalog information, and you want the source information. # The depth/eqlon/eqlat parameters refer to the center of the fault plane by assumption. # Takes lists of parameters. for i in range(len(strike)): [xcenter,ycenter]=conversion_math.latlon2xy(eqlon[i],eqlat[i],zerolon,zerolat); # print("EQ location: %f %f " % (eqlon[i],eqlat[i]) ); # print("Ref location: %f %f " % (zerolon, zerolat) ); # print("Coordinates: %f %f " % (x,y) ); L=wells_and_coppersmith.RLD_from_M(mag[i],eq_type[i]); # rupture length W=wells_and_coppersmith.RW_from_M(mag[i],eq_type[i]); # rupture width slip = wells_and_coppersmith.rectangular_slip(L*1000,W*1000,mag[i]); # must input in meters print("Fault slip: %f" % slip); # xistart,yistart=conversion_math.add_vector_to_point(xcenter,ycenter,-L/2,strike[i]); # if the hypocenter is really the center of the rupture xistart,yistart=conversion_math.add_vector_to_point(xcenter,ycenter,0,strike[i]); # if the hypocenter is on one side of the rupture xifinish,yifinish=conversion_math.add_vector_to_point(xcenter,ycenter,L,strike[i]); rtlati,reversei=conversion_math.get_rtlat_dip_slip(slip, rake[i]); topi, bottomi=conversion_math.get_top_bottom(eqdep[i],W,dip[i]); xstart.append(xistart); ystart.append(yistart); xfinish.append(xifinish); yfinish.append(yifinish); Kode.append(100); rtlat.append(rtlati); reverse.append(reversei); top.append(topi); bottom.append(bottomi); comment.append(''); return [xstart, xfinish, ystart, yfinish, Kode, rtlat, reverse, top, bottom, comment];
def compute_params_for_slip_source(strike, dip, rake, depth, L, W, fault_lon, fault_lat, slip, zerolon, zerolat): [xcorner, ycorner] = conversion_math.latlon2xy(fault_lon, fault_lat, zerolon, zerolat) xstart, ystart = conversion_math.add_vector_to_point( xcorner, ycorner, 0, strike) xfinish, yfinish = conversion_math.add_vector_to_point( xcorner, ycorner, L, strike) rtlat, reverse = conversion_math.get_rtlat_dip_slip(slip, rake) top, bottom = conversion_math.get_top_bottom_from_top(depth, W, dip) Kode = 100 comment = '' return [ xstart, xfinish, ystart, yfinish, Kode, rtlat, reverse, top, bottom, comment ]
def compute_params_for_receiver(strike, dip, rake, length, width, lon, lat, depth, zerolon, zerolat): xstart=[]; xfinish=[]; ystart=[]; yfinish=[]; Kode=[]; rtlat=[]; reverse=[]; top=[]; bottom=[]; comment=[]; # Useful when you have a receiver and you want to compute stresses on it. # The depth/lon/lat parameters refer to the updip fault corner where you're looking down the strike direction, and the dip is off to your right. # Takes lists of parameters. for i in range(len(strike)): [xistart,yistart]=conversion_math.latlon2xy(lon[i],lat[i],zerolon,zerolat); xifinish,yifinish=conversion_math.add_vector_to_point(xistart,yistart,length[i],strike[i]); topi, bottomi=conversion_math.get_top_bottom_from_top(depth[i],width[i],dip[i]); xstart.append(xistart); ystart.append(yistart); xfinish.append(xifinish); yfinish.append(yifinish); Kode.append(100); rtlat.append(0); reverse.append(0); top.append(topi); bottom.append(bottomi); comment.append(''); return [xstart, xfinish, ystart, yfinish, Kode, rtlat, reverse, top, bottom, comment];
def split_subfault_receivers(params, inputs): strike_split = params.strike_num_receivers dip_split = params.dip_num_receivers if strike_split == 1 and dip_split == 1: # If we're not splitting the subfaults... subfaulted_receivers = inputs.receiver_object print("Not subdividing receiver faults further.") else: subfaulted_receivers = [] print("Splitting %d receiver faults into %d subfaults each." % (len(inputs.receiver_object), strike_split * dip_split)) for fault in inputs.receiver_object: # for each receiver... # We find the depths corresponding to the tops and bottoms of our new sub-faults zsplit_array = get_split_z_array(fault.top, fault.bottom, dip_split) for j in range(dip_split): # First we split it up by dip. # Get the new coordinates of the top of the fault plane. W = conversion_math.get_downdip_width(fault.top, zsplit_array[j], fault.dipangle) vector_mag = W * np.cos(np.deg2rad(fault.dipangle)) # how far the bottom edge is displaced downdip from map-view # Get the starting points for the next row of fault subpatches. [start_x_top, start_y_top] = conversion_math.add_vector_to_point( fault.xstart, fault.ystart, vector_mag, fault.strike + 90) [finish_x_top, finish_y_top] = conversion_math.add_vector_to_point( fault.xfinish, fault.yfinish, vector_mag, fault.strike + 90) [xsplit_array, ysplit_array ] = get_split_x_y_arrays(start_x_top, finish_x_top, start_y_top, finish_y_top, strike_split) for k in range(strike_split): single_subfaulted_receiver = coulomb_collections.Faults_object( xstart=xsplit_array[k], xfinish=xsplit_array[k + 1], ystart=ysplit_array[k], yfinish=ysplit_array[k + 1], Kode=fault.Kode, rtlat=0, reverse=0, potency=[], strike=fault.strike, dipangle=fault.dipangle, rake=fault.rake, top=zsplit_array[j], bottom=zsplit_array[j + 1], comment=fault.comment) subfaulted_receivers.append(single_subfaulted_receiver) subfaulted_objects = coulomb_collections.Input_object( PR1=inputs.PR1, FRIC=inputs.FRIC, depth=inputs.depth, start_gridx=inputs.start_gridx, finish_gridx=inputs.finish_gridx, start_gridy=inputs.start_gridy, finish_gridy=inputs.finish_gridy, xinc=inputs.xinc, yinc=inputs.yinc, minlon=inputs.minlon, maxlon=inputs.maxlon, zerolon=inputs.zerolon, minlat=inputs.minlat, maxlat=inputs.maxlat, zerolat=inputs.zerolat, source_object=inputs.source_object, receiver_object=subfaulted_receivers) return subfaulted_objects
def gps_residual_plot(obsfile, predfile, modelfile, output_dir): # NEXT: It will have the fault plane on those figures (conversion math!) # NEXT: Scale bar for horizontals and color bar for verticals [gps_lon, gps_lat, ux_obs, uy_obs, uz_obs] = io_gps_mcmc.read_gps_file(obsfile) [gps_lon, gps_lat, ux_pred, uy_pred, uz_pred] = io_gps_mcmc.read_gps_file(predfile) ux_obs = np.multiply(ux_obs, 1000) uy_obs = np.multiply(uy_obs, 1000) uz_obs = np.multiply(uz_obs, 1000) ux_pred = np.multiply(ux_pred, 1000) uy_pred = np.multiply(uy_pred, 1000) uz_pred = np.multiply(uz_pred, 1000) # converting to mm ux_res = np.subtract(ux_obs, ux_pred) uy_res = np.subtract(uy_obs, uy_pred) uz_res = np.subtract(uz_obs, uz_pred) # Read the fault parameters. # Length, width, dip, strike, dx, dy, lon0, lat0 # Reading the final model parameters # But reading lon0 and lat0 from the param section. ifile = open(modelfile, 'r') for line in ifile: if " strike" in line: strike = float(line.split()[1]) if " length" in line: length = float(line.split()[1]) if " width" in line: width = float(line.split()[1]) if " dip" in line: dip = float(line.split()[1]) if " dx" in line: dx = float(line.split()[1]) if " dy" in line: dy = float(line.split()[1]) if "lon0" in line: lon0 = float(line.split()[1]) if "lat0" in line: lat0 = float(line.split()[1]) # Calculate the box that gets drawn for the fault. x0, y0 = dx, dy x1, y1 = conversion_math.add_vector_to_point(x0, y0, length, strike) vector_mag = width * np.cos(np.deg2rad(dip)) # how far the middle is displaced from the top downdip from map-view xbackbottom, ybackbottom = conversion_math.add_vector_to_point( x0, y0, vector_mag, strike + 90) # strike+90 = downdip direction. xfrontbottom, yfrontbottom = conversion_math.add_vector_to_point( x1, y1, vector_mag, strike + 90) # strike+90 = downdip direction. start_lon, start_lat = conversion_math.xy2lonlat(x0, y0, lon0, lat0) end_lon, end_lat = conversion_math.xy2lonlat(x1, y1, lon0, lat0) b1lon, b1lat = conversion_math.xy2lonlat(xbackbottom, ybackbottom, lon0, lat0) b2lon, b2lat = conversion_math.xy2lonlat(xfrontbottom, yfrontbottom, lon0, lat0) thin_line_x = [start_lon, end_lon, b2lon, b1lon, start_lon] thin_line_y = [start_lat, end_lat, b2lat, b1lat, start_lat] thick_line_x = [start_lon, end_lon] thick_line_y = [start_lat, end_lat] # Plot formatting vmin = -6 vmax = 6 cmap = 'jet' scale = 50 fig, axarr = plt.subplots(1, 3, sharey=True, figsize=(20, 8), dpi=300) axarr[0].scatter(gps_lon, gps_lat, marker='o', s=150, c=uz_obs, vmin=vmin, vmax=vmax, cmap=cmap) axarr[0].quiver(gps_lon, gps_lat, ux_obs, uy_obs, linewidths=0.01, edgecolors=('k'), scale=scale) axarr[0].set_xlim([np.min(gps_lon), np.max(gps_lon)]) axarr[0].set_ylim([np.min(gps_lat), np.max(gps_lat)]) # Annotations axarr[0].plot(thick_line_x, thick_line_y, color='red', linewidth=2) axarr[0].plot(thin_line_x, thin_line_y, color='red', linewidth=1) rect = patches.Rectangle((0.05, 0.92), 0.3, 0.06, facecolor='white', transform=axarr[0].transAxes, edgecolor='black') axarr[0].add_patch(rect) axarr[0].quiver(0.08, 0.945, 5, 0, transform=axarr[0].transAxes, color='red', scale=scale, zorder=10) axarr[0].text(0.2, 0.935, "5 mm", transform=axarr[0].transAxes, color='red', fontsize=16) axarr[0].grid(True) axarr[0].tick_params(labelsize=16) axarr[0].set_title('Observed', fontsize=20) axarr[1].scatter(gps_lon, gps_lat, marker='o', s=150, c=uz_pred, vmin=vmin, vmax=vmax, cmap=cmap) axarr[1].quiver(gps_lon, gps_lat, ux_pred, uy_pred, linewidths=0.01, edgecolors=('k'), scale=scale) axarr[1].set_xlim([np.min(gps_lon), np.max(gps_lon)]) axarr[1].set_ylim([np.min(gps_lat), np.max(gps_lat)]) axarr[1].plot(thick_line_x, thick_line_y, color='red', linewidth=2) axarr[1].plot(thin_line_x, thin_line_y, color='red', linewidth=1) rect = patches.Rectangle((0.05, 0.92), 0.3, 0.06, facecolor='white', transform=axarr[1].transAxes, edgecolor='black') axarr[1].add_patch(rect) axarr[1].quiver(0.08, 0.945, 5, 0, transform=axarr[1].transAxes, color='red', scale=scale, zorder=10) axarr[1].text(0.2, 0.935, "5 mm", transform=axarr[1].transAxes, color='red', fontsize=16) axarr[1].grid(True) axarr[1].tick_params(labelsize=16) axarr[1].set_title('Modeled', fontsize=20) axarr[2].scatter(gps_lon, gps_lat, marker='o', s=150, c=uz_res, vmin=vmin, vmax=vmax, cmap=cmap) axarr[2].quiver(gps_lon, gps_lat, ux_res, uy_res, linewidths=0.01, edgecolors=('k'), scale=scale) axarr[2].set_xlim([np.min(gps_lon), np.max(gps_lon)]) axarr[2].set_ylim([np.min(gps_lat), np.max(gps_lat)]) axarr[2].plot(thick_line_x, thick_line_y, color='red', linewidth=2) axarr[2].plot(thin_line_x, thin_line_y, color='red', linewidth=1) rect = patches.Rectangle((0.05, 0.92), 0.3, 0.06, facecolor='white', transform=axarr[2].transAxes, edgecolor='black') axarr[2].add_patch(rect) axarr[2].quiver(0.08, 0.945, 5, 0, transform=axarr[2].transAxes, color='red', scale=scale, zorder=10) axarr[2].text(0.2, 0.935, "5 mm", transform=axarr[2].transAxes, color='red', fontsize=16) axarr[2].grid(True) axarr[2].tick_params(labelsize=16) axarr[2].set_title('Residual', fontsize=20) cbarax = fig.add_axes([0.85, 0.08, 0.1, 0.9], visible=False) color_boundary_object = matplotlib.colors.Normalize(vmin=vmin, vmax=vmax) custom_cmap = cm.ScalarMappable(norm=color_boundary_object, cmap=cmap) custom_cmap.set_array(np.arange(vmin, vmax, 1.5)) cb = plt.colorbar(custom_cmap, aspect=12, fraction=0.2, orientation='vertical') cb.set_label('Vertical (m)', fontsize=18) cb.ax.tick_params(labelsize=16) if output_dir != "": output_dir = output_dir + "/" fig.savefig(output_dir + 'residuals.png') return
def split_subfaults(params, inputs): receiver_object = inputs.receiver_object strike_split = params.strike_num_receivers dip_split = params.dip_num_receivers if strike_split == 1 and dip_split == 1: # If we're not splitting the subfaults... subfaulted_receivers = inputs.receiver_object print("Not subdividing receiver faults further.") else: print("Split %d receiver faults into %d subfaults each." % (len(receiver_object.xstart), strike_split * dip_split)) new_xstart = [] new_xfinish = [] new_ystart = [] new_yfinish = [] new_Kode = [] new_rtlat = [] new_reverse = [] new_strike = [] new_dipangle = [] new_rake = [] new_top = [] new_bottom = [] new_comment = [] for i in range(len(receiver_object.xstart)): # For each receiver... # We find the depths corresponding to the tops and bottoms of our new sub-faults zsplit_array = get_split_z_array(inputs.receiver_object.top[i], inputs.receiver_object.bottom[i], dip_split) x0 = inputs.receiver_object.xstart[i] y0 = inputs.receiver_object.ystart[i] x1 = inputs.receiver_object.xfinish[i] y1 = inputs.receiver_object.yfinish[i] for j in range(dip_split): # First we split it up by dip. # Get the new coordinates of the top of the fault plane. W = conversion_math.get_downdip_width( inputs.receiver_object.top[i], zsplit_array[j], inputs.receiver_object.dipangle[i]) vector_mag = W * np.cos( np.deg2rad(inputs.receiver_object.dipangle[i])) # how far the bottom edge is displaced downdip from map-view # Get the starting points for the next row of fault subpatches. [start_x_top, start_y_top] = conversion_math.add_vector_to_point( x0, y0, vector_mag, inputs.receiver_object.strike[i] + 90) [finish_x_top, finish_y_top] = conversion_math.add_vector_to_point( x1, y1, vector_mag, inputs.receiver_object.strike[i] + 90) [xsplit_array, ysplit_array ] = get_split_x_y_arrays(start_x_top, finish_x_top, start_y_top, finish_y_top, strike_split) for k in range(strike_split): new_xstart.append(xsplit_array[k]) new_xfinish.append(xsplit_array[k + 1]) new_ystart.append(ysplit_array[k]) new_yfinish.append(ysplit_array[k + 1]) new_Kode.append(receiver_object.Kode[i]) new_rtlat.append(receiver_object.rtlat[i]) new_reverse.append(receiver_object.reverse[i]) new_strike.append(receiver_object.strike[i]) new_dipangle.append(receiver_object.dipangle[i]) new_rake.append(receiver_object.rake[i]) new_top.append(zsplit_array[j]) new_bottom.append(zsplit_array[j + 1]) new_comment.append(receiver_object.comment[i]) subfaulted_receivers = coulomb_collections.Faults_object( xstart=new_xstart, xfinish=new_xfinish, ystart=new_ystart, yfinish=new_yfinish, Kode=new_Kode, rtlat=new_rtlat, reverse=new_reverse, strike=new_strike, dipangle=new_dipangle, rake=new_rake, top=new_top, bottom=new_bottom, comment=new_comment) subfaulted_inputs = coulomb_collections.Input_object( PR1=inputs.PR1, FRIC=inputs.FRIC, depth=inputs.depth, start_gridx=inputs.start_gridx, finish_gridx=inputs.finish_gridx, start_gridy=inputs.start_gridy, finish_gridy=inputs.finish_gridy, xinc=inputs.xinc, yinc=inputs.yinc, minlon=inputs.minlon, maxlon=inputs.maxlon, zerolon=inputs.zerolon, minlat=inputs.minlat, maxlat=inputs.maxlat, zerolat=inputs.zerolat, source_object=inputs.source_object, receiver_object=subfaulted_receivers) return subfaulted_inputs